Cleanup resetprop code

This commit is contained in:
topjohnwu
2025-08-18 11:12:31 -07:00
committed by John Wu
parent 2e4fa6864c
commit 42d9f87bc9
7 changed files with 71 additions and 83 deletions

View File

@@ -4,6 +4,7 @@
#include <sys/mount.h>
#include <sys/sysmacros.h>
#include <linux/input.h>
#include <map>
#include <consts.hpp>
#include <base.hpp>

View File

@@ -2,6 +2,7 @@
#include <android/log.h>
#include <sys/syscall.h>
#include <string>
#include <map>
#include <core.hpp>

View File

@@ -5,6 +5,7 @@
#include <fcntl.h>
#include <dirent.h>
#include <set>
#include <map>
#include <consts.hpp>
#include <sqlite.hpp>

View File

@@ -1,22 +1,17 @@
#pragma once
#include <string>
#include <map>
#include <cxx.h>
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<std::string, std::string>;
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);
}

View File

@@ -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;

View File

@@ -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<PersistentPropertyRecord>;
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<usize, usize>;
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<usize, usize> {
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<PersistentProperties> {
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()),

View File

@@ -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<prop_cb*>(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<prop_cb*>(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<prop_callback*>(cb)->exec(name, value, serial);
};
system_property_read_callback(pi, fn, this);
}
template<class StringType>
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<rust::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<StringType> 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<string, string> 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<prop_callback*>(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) \