Un-deprecated __system_property_find_nth.

Netflix was using this, and looking the header file, although
__system_property_find_nth has been available since the beginning of time,
__system_property_foreach only appeared in 16. So anyone who wants to run
on pre-JellyBean devices would want to use __system_property_find_nth.

It's pretty much a one-liner in terms of __system_property_foreach anyway,
so it doesn't cost us anything to keep it.

Also restore slightly better tests than we originally removed.

Bug: http://b/36566667
Test: ran tests
Change-Id: Id268c2c2e848da17bb0a5a5420af234d9dcb829a
This commit is contained in:
Elliott Hughes 2017-04-17 14:53:07 -07:00
parent e4e69a174a
commit 438e01940b
3 changed files with 32 additions and 39 deletions

View File

@ -200,15 +200,6 @@ struct prop_info {
DISALLOW_IMPLICIT_CONSTRUCTORS(prop_info);
};
struct find_nth_cookie {
uint32_t count;
const uint32_t n;
const prop_info* pi;
explicit find_nth_cookie(uint32_t n) : count(0), n(n), pi(nullptr) {
}
};
// This is public because it was exposed in the NDK. As of 2017-01, ~60 apps reference this symbol.
prop_area* __system_property_area__ = nullptr;
@ -659,14 +650,6 @@ static int send_prop_msg(const prop_msg* msg) {
return result;
}
static void find_nth_fn(const prop_info* pi, void* ptr) {
find_nth_cookie* cookie = reinterpret_cast<find_nth_cookie*>(ptr);
if (cookie->n == cookie->count) cookie->pi = pi;
cookie->count++;
}
bool prop_area::foreach_property(prop_bt* const trie,
void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
if (!trie) return false;
@ -1456,20 +1439,19 @@ bool __system_property_wait(const prop_info* pi,
}
const prop_info* __system_property_find_nth(unsigned n) {
if (bionic_get_application_target_sdk_version() >= __ANDROID_API_O__) {
__libc_fatal(
"__system_property_find_nth is not supported since Android O,"
" please use __system_property_foreach instead.");
}
struct find_nth {
const uint32_t sought;
uint32_t current;
const prop_info* result;
find_nth_cookie cookie(n);
const int err = __system_property_foreach(find_nth_fn, &cookie);
if (err < 0) {
return nullptr;
}
return cookie.pi;
explicit find_nth(uint32_t n) : sought(n), current(0), result(nullptr) {}
static void fn(const prop_info* pi, void* ptr) {
find_nth* self = reinterpret_cast<find_nth*>(ptr);
if (self->current++ == self->sought) self->result = pi;
}
} state(n);
__system_property_foreach(find_nth::fn, &state);
return state.result;
}
int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
@ -1479,7 +1461,7 @@ int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie),
list_foreach(contexts, [propfn, cookie](context_node* l) {
if (l->check_access_and_open()) {
l->pa()->foreach (propfn, cookie);
l->pa()->foreach(propfn, cookie);
}
});
return 0;

View File

@ -91,11 +91,11 @@ bool __system_property_wait(const prop_info* pi,
/* Deprecated. In Android O and above, there's no limit on property name length. */
#define PROP_NAME_MAX 32
/* Deprecated. Use __system_property_read_callback instead. */
int __system_property_read(const prop_info *pi, char *name, char *value);
int __system_property_read(const prop_info* pi, char* name, char* value);
/* Deprecated. Use __system_property_read_callback instead. */
int __system_property_get(const char *name, char *value);
/* Deprecated. Use __system_property_foreach instead. Aborts in Android O and above. */
const prop_info *__system_property_find_nth(unsigned n) __REMOVED_IN(26);
int __system_property_get(const char* name, char* value);
/* Deprecated. Use __system_property_foreach instead. */
const prop_info* __system_property_find_nth(unsigned n);
__END_DECLS

View File

@ -253,10 +253,21 @@ TEST(properties, __system_property_find_nth) {
ASSERT_EQ(0, __system_property_add("other_property", 14, "value2", 6));
ASSERT_EQ(0, __system_property_add("property_other", 14, "value3", 6));
// This method is no longer supported and should result in abort
ASSERT_EXIT(__system_property_find_nth(0), testing::KilledBySignal(SIGABRT),
"__system_property_find_nth is not supported since Android O,"
" please use __system_property_foreach instead.");
char name[PROP_NAME_MAX];
char value[PROP_VALUE_MAX];
EXPECT_EQ(6, __system_property_read(__system_property_find_nth(0), name, value));
EXPECT_STREQ("property", name);
EXPECT_STREQ("value1", value);
EXPECT_EQ(6, __system_property_read(__system_property_find_nth(1), name, value));
EXPECT_STREQ("other_property", name);
EXPECT_STREQ("value2", value);
EXPECT_EQ(6, __system_property_read(__system_property_find_nth(2), name, value));
EXPECT_STREQ("property_other", name);
EXPECT_STREQ("value3", value);
for (unsigned i = 3; i < 1024; ++i) {
ASSERT_TRUE(__system_property_find_nth(i) == nullptr);
}
#else // __BIONIC__
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif // __BIONIC__