mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-10-27 12:49:09 +00:00
Cleanup resetprop code
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <linux/input.h>
|
||||
#include <map>
|
||||
|
||||
#include <consts.hpp>
|
||||
#include <base.hpp>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <android/log.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include <core.hpp>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include <consts.hpp>
|
||||
#include <sqlite.hpp>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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()),
|
||||
|
||||
@@ -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) \
|
||||
|
||||
Reference in New Issue
Block a user