diff --git a/native/src/core/daemon.cpp b/native/src/core/daemon.cpp index 6b884d749..da8e3a514 100644 --- a/native/src/core/daemon.cpp +++ b/native/src/core/daemon.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/native/src/core/deny/logcat.cpp b/native/src/core/deny/logcat.cpp index c442b8258..08654118e 100644 --- a/native/src/core/deny/logcat.cpp +++ b/native/src/core/deny/logcat.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include diff --git a/native/src/core/deny/utils.cpp b/native/src/core/deny/utils.cpp index 153493b7b..e0e6a7fce 100644 --- a/native/src/core/deny/utils.cpp +++ b/native/src/core/deny/utils.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include diff --git a/native/src/core/include/resetprop.hpp b/native/src/core/include/resetprop.hpp index d4815acc0..a4eb2b746 100644 --- a/native/src/core/include/resetprop.hpp +++ b/native/src/core/include/resetprop.hpp @@ -1,22 +1,17 @@ #pragma once #include -#include #include -struct prop_cb { +struct prop_info; + +struct prop_callback { + virtual ~prop_callback() = default; virtual void exec(const char *name, const char *value, uint32_t serial) = 0; -}; - -using prop_list = std::map; - -struct prop_collector : prop_cb { - explicit prop_collector(prop_list &list) : list(list) {} - void exec(const char *name, const char *value, uint32_t) override { - list.insert({name, value}); + void exec(Utf8CStr name, Utf8CStr value) { + exec(name.data(), value.data(), INT_MAX); } -private: - prop_list &list; + void read(const prop_info *pi); }; // System properties @@ -32,7 +27,4 @@ static inline int set_prop_rs(Utf8CStr name, Utf8CStr value, bool skip_svc) { } static inline void load_prop_file_rs(Utf8CStr filename, bool skip_svc) { load_prop_file(filename.data(), skip_svc); -} -static inline void prop_cb_exec(prop_cb &cb, Utf8CStr name, Utf8CStr value, uint32_t serial) { - cb.exec(name.data(), value.data(), serial); } \ No newline at end of file diff --git a/native/src/core/lib.rs b/native/src/core/lib.rs index 070004b78..f1a93fbe6 100644 --- a/native/src/core/lib.rs +++ b/native/src/core/lib.rs @@ -167,15 +167,16 @@ pub mod ffi { include!("include/resetprop.hpp"); - #[cxx_name = "prop_cb"] - type PropCb; + #[cxx_name = "prop_callback"] + type PropCallback; + fn exec(self: Pin<&mut PropCallback>, name: Utf8CStrRef, value: Utf8CStrRef); + #[cxx_name = "get_prop_rs"] fn get_prop(name: Utf8CStrRef, persist: bool) -> String; #[cxx_name = "set_prop_rs"] fn set_prop(name: Utf8CStrRef, value: Utf8CStrRef, skip_svc: bool) -> i32; #[cxx_name = "load_prop_file_rs"] fn load_prop_file(filename: Utf8CStrRef, skip_svc: bool); - fn prop_cb_exec(cb: Pin<&mut PropCb>, name: Utf8CStrRef, value: Utf8CStrRef, serial: u32); } extern "Rust" { @@ -188,8 +189,8 @@ pub mod ffi { fn revert_unmount(pid: i32); fn remove_modules(); fn zygisk_should_load_module(flags: u32) -> bool; - unsafe fn persist_get_prop(name: Utf8CStrRef, prop_cb: Pin<&mut PropCb>); - unsafe fn persist_get_props(prop_cb: Pin<&mut PropCb>); + unsafe fn persist_get_prop(name: Utf8CStrRef, prop_cb: Pin<&mut PropCallback>); + unsafe fn persist_get_props(prop_cb: Pin<&mut PropCallback>); unsafe fn persist_delete_prop(name: Utf8CStrRef) -> bool; unsafe fn persist_set_prop(name: Utf8CStrRef, value: Utf8CStrRef) -> bool; fn send_fd(socket: i32, fd: i32) -> bool; diff --git a/native/src/core/resetprop/persist.rs b/native/src/core/resetprop/persist.rs index a37d76d81..aab9cd362 100644 --- a/native/src/core/resetprop/persist.rs +++ b/native/src/core/resetprop/persist.rs @@ -2,14 +2,13 @@ use std::io::Read; use std::{ fs::File, io::{BufWriter, Write}, - ops::{Deref, DerefMut}, os::fd::FromRawFd, pin::Pin, }; use quick_protobuf::{BytesReader, MessageRead, MessageWrite, Writer}; -use crate::ffi::{PropCb, prop_cb_exec}; +use crate::ffi::PropCallback; use crate::resetprop::proto::persistent_properties::{ PersistentProperties, mod_PersistentProperties::PersistentPropertyRecord, }; @@ -23,30 +22,6 @@ use base::{ const PERSIST_PROP_DIR: &str = "/data/property"; const PERSIST_PROP: &str = concatcp!(PERSIST_PROP_DIR, "/persistent_properties"); -trait PropCbExec { - fn exec(&mut self, name: &Utf8CStr, value: &Utf8CStr); -} - -impl PropCbExec for Pin<&mut PropCb> { - fn exec(&mut self, name: &Utf8CStr, value: &Utf8CStr) { - prop_cb_exec(self.as_mut(), name, value, u32::MAX) - } -} - -impl Deref for PersistentProperties { - type Target = Vec; - - fn deref(&self) -> &Self::Target { - &self.properties - } -} - -impl DerefMut for PersistentProperties { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.properties - } -} - trait PropExt { fn find_index(&self, name: &Utf8CStr) -> Result; fn find(&mut self, name: &Utf8CStr) -> LoggedResult<&mut PersistentPropertyRecord>; @@ -54,12 +29,13 @@ trait PropExt { impl PropExt for PersistentProperties { fn find_index(&self, name: &Utf8CStr) -> Result { - self.binary_search_by(|p| p.name.as_deref().cmp(&Some(name.deref()))) + self.properties + .binary_search_by(|p| p.name.as_deref().cmp(&Some(name.as_str()))) } fn find(&mut self, name: &Utf8CStr) -> LoggedResult<&mut PersistentPropertyRecord> { let idx = self.find_index(name).silent()?; - Ok(&mut self[idx]) + Ok(&mut self.properties[idx]) } } @@ -110,7 +86,9 @@ fn proto_read_props() -> LoggedResult { let mut r = BytesReader::from_bytes(m); let mut props = PersistentProperties::from_reader(&mut r, m)?; // Keep the list sorted for binary search - props.sort_unstable_by(|a, b| a.name.cmp(&b.name)); + props + .properties + .sort_unstable_by(|a, b| a.name.cmp(&b.name)); Ok(props) } @@ -130,7 +108,7 @@ fn proto_write_props(props: &PersistentProperties) -> LoggedResult<()> { Ok(()) } -pub fn persist_get_prop(name: &Utf8CStr, mut prop_cb: Pin<&mut PropCb>) { +pub fn persist_get_prop(name: &Utf8CStr, prop_cb: Pin<&mut PropCallback>) { let res: LoggedResult<()> = try { if check_proto() { let mut props = proto_read_props()?; @@ -151,17 +129,19 @@ pub fn persist_get_prop(name: &Utf8CStr, mut prop_cb: Pin<&mut PropCb>) { res.ok(); } -pub fn persist_get_props(mut prop_cb: Pin<&mut PropCb>) { +pub fn persist_get_props(mut prop_cb: Pin<&mut PropCallback>) { let res: LoggedResult<()> = try { if check_proto() { let mut props = proto_read_props()?; - props.iter_mut().for_each(|prop| { + props.properties.iter_mut().for_each(|prop| { if let PersistentPropertyRecord { name: Some(n), value: Some(v), } = prop { - prop_cb.exec(Utf8CStr::from_string(n), Utf8CStr::from_string(v)); + prop_cb + .as_mut() + .exec(Utf8CStr::from_string(n), Utf8CStr::from_string(v)); } }); } else { @@ -170,7 +150,9 @@ pub fn persist_get_props(mut prop_cb: Pin<&mut PropCb>) { if e.is_file() && let Ok(mut value) = file_get_prop(e.name()) { - prop_cb.exec(e.name(), Utf8CStr::from_string(&mut value)); + prop_cb + .as_mut() + .exec(e.name(), Utf8CStr::from_string(&mut value)); } // Do not traverse recursively Ok(WalkResult::Skip) @@ -185,7 +167,7 @@ pub fn persist_delete_prop(name: &Utf8CStr) -> bool { if check_proto() { let mut props = proto_read_props()?; let idx = props.find_index(name).silent()?; - props.remove(idx); + props.properties.remove(idx); proto_write_props(&props)?; } else { file_set_prop(name, None)?; @@ -199,8 +181,8 @@ pub fn persist_set_prop(name: &Utf8CStr, value: &Utf8CStr) -> bool { if check_proto() { let mut props = proto_read_props()?; match props.find_index(name) { - Ok(idx) => props[idx].value = Some(value.to_string()), - Err(idx) => props.insert( + Ok(idx) => props.properties[idx].value = Some(value.to_string()), + Err(idx) => props.properties.insert( idx, PersistentPropertyRecord { name: Some(name.to_string()), diff --git a/native/src/core/resetprop/resetprop.cpp b/native/src/core/resetprop/resetprop.cpp index abd834e2e..b8f0ad274 100644 --- a/native/src/core/resetprop/resetprop.cpp +++ b/native/src/core/resetprop/resetprop.cpp @@ -14,7 +14,6 @@ using namespace std; #ifdef APPLET_STUB_MAIN #define system_property_set __system_property_set -#define system_property_read(...) #define system_property_find __system_property_find #define system_property_read_callback __system_property_read_callback #define system_property_foreach __system_property_foreach @@ -111,30 +110,21 @@ illegal: return false; } -static void read_prop_with_cb(const prop_info *pi, void *cb) { - if (system_property_read_callback) { - auto callback = [](void *cb, const char *name, const char *value, uint32_t serial) { - static_cast(cb)->exec(name, value, serial); - }; - system_property_read_callback(pi, callback, cb); - } else { - char name[PROP_NAME_MAX]; - char value[PROP_VALUE_MAX]; - name[0] = '\0'; - value[0] = '\0'; - system_property_read(pi, name, value); - static_cast(cb)->exec(name, value, pi->serial); - } +void prop_callback::read(const prop_info *pi) { + auto fn = [](void *cb, const char *name, const char *value, uint32_t serial) { + static_cast(cb)->exec(name, value, serial); + }; + system_property_read_callback(pi, fn, this); } template -struct prop_to_string : prop_cb { +struct prop_to_string : prop_callback { void exec(const char *, const char *value, uint32_t s) override { val = value; serial = s; } StringType val; - uint32_t serial; + uint32_t serial = 0; }; template<> void prop_to_string::exec(const char *, const char *value, uint32_t s) { @@ -212,7 +202,7 @@ static StringType get_prop(const char *name, PropFlags flags) { if (!flags.isPersistOnly()) { if (auto pi = system_property_find(name)) { - read_prop_with_cb(pi, &cb); + cb.read(pi); LOGD("resetprop: get prop [%s]: [%s]\n", name, cb.val.c_str()); } } @@ -238,13 +228,13 @@ static StringType wait_prop(const char *name, const char *old_value) { } prop_to_string cb; - read_prop_with_cb(pi, &cb); + cb.read(pi); while (old_value == nullptr || cb.val == old_value) { LOGD("resetprop: waiting for prop [%s]\n", name); uint32_t new_serial; system_property_wait(pi, cb.serial, &new_serial, nullptr); - read_prop_with_cb(pi, &cb); + cb.read(pi); if (old_value == nullptr) break; } @@ -252,14 +242,23 @@ static StringType wait_prop(const char *name, const char *old_value) { return cb.val; } +struct prop_collector : prop_callback { + void exec(const char *name, const char *value, uint32_t) override { + list.insert({name, value}); + } + map list; +}; + static void print_props(PropFlags flags) { - prop_list list; - prop_collector collector(list); - if (!flags.isPersistOnly()) - system_property_foreach(read_prop_with_cb, &collector); + prop_collector collector; + if (!flags.isPersistOnly()) { + system_property_foreach([](const prop_info *pi, void *cb) { + static_cast(cb)->read(pi); + }, &collector); + } if (flags.isPersist()) persist_get_props(collector); - for (auto &[key, val] : list) { + for (auto &[key, val] : collector.list) { const char *v = flags.isContext() ? (__system_property_get_context(key.data()) ?: "") : val.data(); @@ -305,6 +304,17 @@ struct Initialize { // The platform API only exist on API 26+ system_property_wait = __system_property_wait; } + if (system_property_read_callback == nullptr) { + // The platform API only exist on API 26+, create a polyfill + system_property_read_callback = [](const prop_info *pi, auto fn, void *cookie) { + char name[PROP_NAME_MAX]; + char value[PROP_VALUE_MAX]; + name[0] = '\0'; + value[0] = '\0'; + system_property_read(pi, name, value); + fn(cookie, name, value, pi->serial); + }; + } #endif if (__system_properties_init()) { LOGE("resetprop: __system_properties_init error\n"); @@ -313,7 +323,7 @@ struct Initialize { }; static void InitOnce() { - static struct Initialize init; + static Initialize init; } #define consume_next(val) \