Skip to content

Commit dc61033

Browse files
committed
Support persist props bypassing property_service
1 parent f8d62a4 commit dc61033

File tree

3 files changed

+105
-62
lines changed

3 files changed

+105
-62
lines changed

native/src/core/resetprop/persist.cpp

Lines changed: 86 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ PB_BIND(PersistentProperties_PersistentPropertyRecord, PersistentProperties_Pers
7575
* End of auto generated code
7676
* ***************************/
7777

78+
#define PERSIST_PROP_DIR "/data/property"
79+
#define PERSIST_PROP PERSIST_PROP_DIR "/persistent_properties"
80+
7881
static bool name_decode(pb_istream_t *stream, const pb_field_t *, void **arg) {
7982
string &name = *static_cast<string *>(*arg);
8083
name.resize(stream->bytes_left);
@@ -102,7 +105,7 @@ static bool prop_encode(pb_ostream_t *stream, const pb_field_t *field, void * co
102105
PersistentProperties_PersistentPropertyRecord prop{};
103106
prop.name.funcs.encode = name_encode;
104107
prop.has_value = true;
105-
auto &list = *static_cast<prop_list *>(*arg);
108+
prop_list &list = *static_cast<prop_list *>(*arg);
106109
for (auto &p : list) {
107110
if (!pb_encode_tag_for_field(stream, field))
108111
return false;
@@ -119,8 +122,7 @@ static bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t coun
119122
return xwrite(fd, buf, count) == count;
120123
}
121124

122-
static pb_ostream_t create_ostream(const char *filename) {
123-
int fd = creat(filename, 0644);
125+
static pb_ostream_t create_ostream(int fd) {
124126
pb_ostream_t o = {
125127
.callback = write_callback,
126128
.state = (void*)(intptr_t)fd,
@@ -130,19 +132,40 @@ static pb_ostream_t create_ostream(const char *filename) {
130132
return o;
131133
}
132134

133-
static void pb_getprop(prop_cb *prop_cb) {
134-
LOGD("resetprop: decode with protobuf [" PERSISTENT_PROPERTY_DIR "/persistent_properties]\n");
135-
PersistentProperties props = {};
135+
static void pb_get_prop(prop_cb *prop_cb) {
136+
LOGD("resetprop: decode with protobuf [" PERSIST_PROP "]\n");
137+
PersistentProperties props{};
136138
props.properties.funcs.decode = prop_decode;
137139
props.properties.arg = prop_cb;
138-
auto m = mmap_data(PERSISTENT_PROPERTY_DIR "/persistent_properties");
140+
auto m = mmap_data(PERSIST_PROP);
139141
pb_istream_t stream = pb_istream_from_buffer(m.buf, m.sz);
140142
pb_decode(&stream, &PersistentProperties_msg, &props);
141143
}
142144

143-
static bool file_getprop(const char *name, char *value) {
145+
static bool pb_write_props(prop_list &list) {
146+
char tmp[4096];
147+
strscpy(tmp, PERSIST_PROP ".XXXXXX", sizeof(tmp));
148+
int fd = mkostemp(tmp, O_CLOEXEC);
149+
if (fd < 0)
150+
return false;
151+
152+
pb_ostream_t ostream = create_ostream(fd);
153+
PersistentProperties props{};
154+
props.properties.funcs.encode = prop_encode;
155+
props.properties.arg = &list;
156+
LOGD("resetprop: encode with protobuf [%s]\n", tmp);
157+
bool ret = pb_encode(&ostream, &PersistentProperties_msg, &props);
158+
close(fd);
159+
if (!ret)
160+
return false;
161+
162+
clone_attr(PERSIST_PROP, tmp);
163+
return rename(tmp, PERSIST_PROP) == 0;
164+
}
165+
166+
static bool file_get_prop(const char *name, char *value) {
144167
char path[4096];
145-
ssprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
168+
ssprintf(path, sizeof(path), PERSIST_PROP_DIR "/%s", name);
146169
int fd = open(path, O_RDONLY | O_CLOEXEC);
147170
if (fd < 0)
148171
return false;
@@ -152,20 +175,38 @@ static bool file_getprop(const char *name, char *value) {
152175
return value[0] != '\0';
153176
}
154177

178+
static bool file_set_prop(const char *name, const char *value) {
179+
char tmp[4096];
180+
strscpy(tmp, PERSIST_PROP_DIR "/prop.XXXXXX", sizeof(tmp));
181+
int fd = mkostemp(tmp, O_CLOEXEC);
182+
if (fd < 0)
183+
return false;
184+
auto len = strlen(value);
185+
LOGD("resetprop: write prop to [%s]\n", tmp);
186+
bool ret = write(fd, value, len) == len;
187+
close(fd);
188+
if (!ret)
189+
return false;
190+
191+
char path[4096];
192+
ssprintf(path, sizeof(path), PERSIST_PROP_DIR "/%s", name);
193+
return rename(tmp, path) == 0;
194+
}
195+
155196
static bool check_pb() {
156-
static bool use_pb = access(PERSISTENT_PROPERTY_DIR "/persistent_properties", R_OK) == 0;
197+
static bool use_pb = access(PERSIST_PROP, R_OK) == 0;
157198
return use_pb;
158199
}
159200

160-
void persist_getprops(prop_cb *prop_cb) {
201+
void persist_get_props(prop_cb *prop_cb) {
161202
if (check_pb()) {
162-
pb_getprop(prop_cb);
203+
pb_get_prop(prop_cb);
163204
} else {
164-
auto dir = open_dir(PERSISTENT_PROPERTY_DIR);
205+
auto dir = open_dir(PERSIST_PROP_DIR);
165206
if (!dir) return;
207+
char value[PROP_VALUE_MAX];
166208
for (dirent *entry; (entry = xreaddir(dir.get()));) {
167-
char value[PROP_VALUE_MAX];
168-
if (file_getprop(entry->d_name, value))
209+
if (file_get_prop(entry->d_name, value))
169210
prop_cb->exec(entry->d_name, value);
170211
}
171212
}
@@ -174,67 +215,64 @@ void persist_getprops(prop_cb *prop_cb) {
174215
struct match_prop_name : prop_cb {
175216
explicit match_prop_name(const char *name) : _name(name) { value[0] = '\0'; }
176217
void exec(const char *name, const char *val) override {
177-
if (std::strcmp(name, _name) == 0)
218+
if (value[0] == '\0' && _name == name)
178219
strscpy(value, val, sizeof(value));
179220
}
180221
char value[PROP_VALUE_MAX];
181222
private:
182-
const char *_name;
223+
string_view _name;
183224
};
184225

185-
string persist_getprop(const char *name) {
226+
string persist_get_prop(const char *name) {
186227
if (check_pb()) {
187-
auto prop = match_prop_name(name);
188-
pb_getprop(&prop);
189-
if (prop.value[0]) {
190-
LOGD("resetprop: get prop (persist) [%s]: [%s]\n", name, prop.value);
191-
return prop.value;
228+
match_prop_name cb(name);
229+
pb_get_prop(&cb);
230+
if (cb.value[0]) {
231+
LOGD("resetprop: get prop (persist) [%s]: [%s]\n", name, cb.value);
232+
return cb.value;
192233
}
193234
} else {
194235
// Try to read from file
195236
char value[PROP_VALUE_MAX];
196-
if (file_getprop(name, value)) {
237+
if (file_get_prop(name, value)) {
197238
LOGD("resetprop: get prop (persist) [%s]: [%s]\n", name, value);
198239
return value;
199240
}
200241
}
201-
return string();
242+
return "";
202243
}
203244

204-
bool persist_deleteprop(const char *name) {
245+
bool persist_delete_prop(const char *name) {
205246
if (check_pb()) {
206247
prop_list list;
207248
prop_collector collector(list);
208-
persist_getprops(&collector);
209-
210-
for (auto it = list.begin(); it != list.end(); ++it) {
211-
if (it->first == name) {
212-
list.erase(it);
213-
// Dump the props back
214-
PersistentProperties props{};
215-
pb_ostream_t ostream = create_ostream(PERSISTENT_PROPERTY_DIR
216-
"/persistent_properties.tmp");
217-
props.properties.funcs.encode = prop_encode;
218-
props.properties.arg = &list;
219-
LOGD("resetprop: encode with protobuf [" PERSISTENT_PROPERTY_DIR
220-
"/persistent_properties.tmp]\n");
221-
if (!pb_encode(&ostream, &PersistentProperties_msg, &props))
222-
return false;
223-
clone_attr(PERSISTENT_PROPERTY_DIR "/persistent_properties",
224-
PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp");
225-
rename(PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp",
226-
PERSISTENT_PROPERTY_DIR "/persistent_properties");
227-
return true;
228-
}
249+
pb_get_prop(&collector);
250+
251+
auto it = list.find(name);
252+
if (it != list.end()) {
253+
list.erase(it);
254+
return pb_write_props(list);
229255
}
230256
return false;
231257
} else {
232258
char path[4096];
233-
ssprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
259+
ssprintf(path, sizeof(path), PERSIST_PROP_DIR "/%s", name);
234260
if (unlink(path) == 0) {
235261
LOGD("resetprop: unlink [%s]\n", path);
236262
return true;
237263
}
238264
}
239265
return false;
240266
}
267+
268+
bool persist_set_prop(const char *name, const char *value) {
269+
if (check_pb()) {
270+
prop_list list;
271+
prop_collector collector(list);
272+
pb_get_prop(&collector);
273+
list[name] = value;
274+
return pb_write_props(list);
275+
} else {
276+
return file_set_prop(name, value);
277+
}
278+
}

native/src/core/resetprop/resetprop.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ static int set_prop(const char *name, const char *value, PropFlags flags) {
154154
LOGD("resetprop: create prop [%s]: [%s] by %s\n", name, value, msg);
155155
}
156156

157+
// When bypassing property_service, persistent props won't be stored in storage.
158+
// Explicitly handle this situation.
159+
if (ret == 0 && flags.isSkipSvc() && flags.isPersist() && str_starts(name, "persist.")) {
160+
ret = persist_set_prop(name, value) ? 0 : 1;
161+
}
162+
157163
if (ret) {
158164
LOGW("resetprop: set prop error\n");
159165
}
@@ -172,15 +178,15 @@ static string get_prop(const char *name, PropFlags flags) {
172178
}
173179

174180
string val;
175-
auto pi = system_property_find(name);
176-
if (pi == nullptr)
177-
return val;
178-
auto cb = prop_to_string(val);
179-
read_prop_with_cb(pi, &cb);
180-
LOGD("resetprop: get prop [%s]: [%s]\n", name, val.data());
181+
if (auto pi = system_property_find(name)) {
182+
prop_to_string cb(val);
183+
read_prop_with_cb(pi, &cb);
184+
LOGD("resetprop: get prop [%s]: [%s]\n", name, val.data());
185+
}
181186

182187
if (val.empty() && flags.isPersist() && str_starts(name, "persist."))
183-
val = persist_getprop(name);
188+
val = persist_get_prop(name);
189+
184190
if (val.empty())
185191
LOGD("resetprop: prop [%s] does not exist\n", name);
186192
return val;
@@ -191,7 +197,7 @@ static void print_props(PropFlags flags) {
191197
prop_collector collector(list);
192198
system_property_foreach(read_prop_with_cb, &collector);
193199
if (flags.isPersist())
194-
persist_getprops(&collector);
200+
persist_get_props(&collector);
195201
for (auto &[key, val] : list) {
196202
const char *v = flags.isContext() ?
197203
(__system_property_get_context(key.data()) ?: "") :
@@ -208,7 +214,7 @@ static int delete_prop(const char *name, PropFlags flags) {
208214

209215
int ret = __system_property_delete(name, true);
210216
if (flags.isPersist() && str_starts(name, "persist.")) {
211-
if (persist_deleteprop(name))
217+
if (persist_delete_prop(name))
212218
ret = 0;
213219
}
214220
return ret;

native/src/core/resetprop/resetprop.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
77
#include <api/_system_properties.h>
88

9-
#define PERSISTENT_PROPERTY_DIR "/data/property"
10-
119
struct prop_cb {
1210
virtual void exec(const char *name, const char *value) = 0;
1311
};
@@ -23,6 +21,7 @@ struct prop_collector : prop_cb {
2321
prop_list &list;
2422
};
2523

26-
std::string persist_getprop(const char *name);
27-
void persist_getprops(prop_cb *prop_cb);
28-
bool persist_deleteprop(const char *name);
24+
std::string persist_get_prop(const char *name);
25+
void persist_get_props(prop_cb *prop_cb);
26+
bool persist_delete_prop(const char *name);
27+
bool persist_set_prop(const char *name, const char *value);

0 commit comments

Comments
 (0)