Export get_prop to Rust

This commit is contained in:
topjohnwu 2023-05-21 23:51:30 -07:00
parent a5768e02ea
commit 9fe8741a02
6 changed files with 55 additions and 25 deletions

View File

@ -4,7 +4,11 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := libbase LOCAL_MODULE := libbase
LOCAL_C_INCLUDES := src/include $(LOCAL_PATH)/include out/generated LOCAL_C_INCLUDES := \
src/include \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/../external/cxx-rs/include \
out/generated
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_EXPORT_STATIC_LIBRARIES := libcxx LOCAL_EXPORT_STATIC_LIBRARIES := libcxx
LOCAL_STATIC_LIBRARIES := libcxx LOCAL_STATIC_LIBRARIES := libcxx

View File

@ -2,6 +2,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <cxx.h>
extern bool RECOVERY_MODE; extern bool RECOVERY_MODE;
extern std::atomic<ino_t> pkg_xml_ino; extern std::atomic<ino_t> pkg_xml_ino;
@ -28,6 +29,7 @@ void clear_pkg(const char *pkg, int user_id);
[[noreturn]] void install_module(const char *file); [[noreturn]] void install_module(const char *file);
// System properties // System properties
rust::String get_prop_rs(const char *name, bool persist);
std::string get_prop(const char *name, bool persist = false); std::string get_prop(const char *name, bool persist = false);
int delete_prop(const char *name, bool persist = false); int delete_prop(const char *name, bool persist = false);
int set_prop(const char *name, const char *value, bool skip_svc = false); int set_prop(const char *name, const char *value, bool skip_svc = false);

View File

@ -1,12 +1,18 @@
pub use base; pub use base;
use daemon::*; use daemon::*;
use logging::*; use logging::*;
use std::ffi::CStr;
mod daemon; mod daemon;
mod logging; mod logging;
#[cxx::bridge] #[cxx::bridge]
pub mod ffi { pub mod ffi {
extern "C++" {
include!("core.hpp");
unsafe fn get_prop_rs(name: *const c_char, persist: bool) -> String;
}
extern "Rust" { extern "Rust" {
fn rust_test_entry(); fn rust_test_entry();
fn android_logging(); fn android_logging();
@ -28,3 +34,7 @@ pub mod ffi {
} }
fn rust_test_entry() {} fn rust_test_entry() {}
pub fn get_prop(name: &CStr, persist: bool) -> String {
unsafe { ffi::get_prop_rs(name.as_ptr(), persist) }
}

View File

@ -223,23 +223,22 @@ private:
string_view _name; string_view _name;
}; };
string persist_get_prop(const char *name) { void persist_get_prop(const char *name, prop_cb *prop_cb) {
if (check_pb()) { if (check_pb()) {
match_prop_name cb(name); match_prop_name cb(name);
pb_get_prop(&cb); pb_get_prop(&cb);
if (cb.value[0]) { if (cb.value[0]) {
LOGD("resetprop: get prop (persist) [%s]: [%s]\n", name, cb.value); LOGD("resetprop: get prop (persist) [%s]: [%s]\n", name, cb.value);
return cb.value; prop_cb->exec(name, cb.value);
} }
} else { } else {
// Try to read from file // Try to read from file
char value[PROP_VALUE_MAX]; char value[PROP_VALUE_MAX];
if (file_get_prop(name, value)) { if (file_get_prop(name, value)) {
LOGD("resetprop: get prop (persist) [%s]: [%s]\n", name, value); LOGD("resetprop: get prop (persist) [%s]: [%s]\n", name, value);
return value; prop_cb->exec(name, value);
} }
} }
return "";
} }
bool persist_delete_prop(const char *name) { bool persist_delete_prop(const char *name) {

View File

@ -115,15 +115,19 @@ static void read_prop_with_cb(const prop_info *pi, void *cb) {
} }
} }
template<class StringType>
struct prop_to_string : prop_cb { struct prop_to_string : prop_cb {
explicit prop_to_string(string &s) : val(s) {}
void exec(const char *, const char *value) override { void exec(const char *, const char *value) override {
val = value; val = value;
} }
private: StringType val;
string &val;
}; };
template<> void prop_to_string<rust::String>::exec(const char *, const char *value) {
// We do not want to crash when values are not UTF-8
val = rust::String::lossy(value);
}
static int set_prop(const char *name, const char *value, PropFlags flags) { static int set_prop(const char *name, const char *value, PropFlags flags) {
if (!check_legal_property_name(name)) if (!check_legal_property_name(name))
return 1; return 1;
@ -170,31 +174,33 @@ static int set_prop(const char *name, const char *value, PropFlags flags) {
return ret; return ret;
} }
static string get_prop(const char *name, PropFlags flags) { template<class StringType>
static StringType get_prop(const char *name, PropFlags flags) {
if (!check_legal_property_name(name)) if (!check_legal_property_name(name))
return ""; return {};
prop_to_string<StringType> cb;
if (flags.isContext()) { if (flags.isContext()) {
auto val = __system_property_get_context(name) ?: ""; auto context = __system_property_get_context(name) ?: "";
LOGD("resetprop: prop context [%s]: [%s]\n", name, val); LOGD("resetprop: prop context [%s]: [%s]\n", name, context);
return val; cb.exec(name, context);
return cb.val;
} }
string val;
if (!flags.isPersistOnly()) { if (!flags.isPersistOnly()) {
if (auto pi = system_property_find(name)) { if (auto pi = system_property_find(name)) {
prop_to_string cb(val);
read_prop_with_cb(pi, &cb); read_prop_with_cb(pi, &cb);
LOGD("resetprop: get prop [%s]: [%s]\n", name, val.data()); LOGD("resetprop: get prop [%s]: [%s]\n", name, cb.val.c_str());
} }
} }
if (val.empty() && flags.isPersist() && str_starts(name, "persist.")) if (cb.val.empty() && flags.isPersist() && str_starts(name, "persist."))
val = persist_get_prop(name); persist_get_prop(name, &cb);
if (cb.val.empty())
if (val.empty())
LOGD("resetprop: prop [%s] does not exist\n", name); LOGD("resetprop: prop [%s] does not exist\n", name);
return val;
return cb.val;
} }
static void print_props(PropFlags flags) { static void print_props(PropFlags flags) {
@ -335,7 +341,7 @@ int resetprop_main(int argc, char *argv[]) {
print_props(flags); print_props(flags);
return 0; return 0;
case 1: { case 1: {
string val = get_prop(argv[0], flags); auto val = get_prop<string>(argv[0], flags);
if (val.empty()) if (val.empty())
return 1; return 1;
printf("%s\n", val.data()); printf("%s\n", val.data());
@ -352,11 +358,20 @@ int resetprop_main(int argc, char *argv[]) {
* Public APIs * Public APIs
****************/ ****************/
string get_prop(const char *name, bool persist) { template<class StringType>
static StringType get_prop_impl(const char *name, bool persist) {
InitOnce(); InitOnce();
PropFlags flags; PropFlags flags;
if (persist) flags.setPersist(); if (persist) flags.setPersist();
return get_prop(name, flags); return get_prop<StringType>(name, flags);
}
rust::String get_prop_rs(const char *name, bool persist) {
return get_prop_impl<rust::String>(name, persist);
}
string get_prop(const char *name, bool persist) {
return get_prop_impl<string>(name, persist);
} }
int delete_prop(const char *name, bool persist) { int delete_prop(const char *name, bool persist) {

View File

@ -21,7 +21,7 @@ private:
prop_list &list; prop_list &list;
}; };
std::string persist_get_prop(const char *name); void persist_get_prop(const char *name, prop_cb *prop_cb);
void persist_get_props(prop_cb *prop_cb); void persist_get_props(prop_cb *prop_cb);
bool persist_delete_prop(const char *name); bool persist_delete_prop(const char *name);
bool persist_set_prop(const char *name, const char *value); bool persist_set_prop(const char *name, const char *value);