From a0e5d06c80c4c7cd8ae96e75d6b17c696a97a21d Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 17 Apr 2017 14:53:07 -0700 Subject: [PATCH] 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 (cherry picked from commit 438e01940b90a2b6061a9b9809e08466e1e9faac) Change-Id: I639f2142ad4ba049b990b13ccccd255be4b4f479 --- libc/bionic/system_properties.cpp | 46 +++++++++++------------------------- libc/include/sys/system_properties.h | 8 +++---- tests/system_properties_test.cpp | 19 +++++++++++---- 3 files changed, 33 insertions(+), 40 deletions(-) diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp index 2a423905c..09106ade8 100644 --- a/libc/bionic/system_properties.cpp +++ b/libc/bionic/system_properties.cpp @@ -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(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."); - } - - find_nth_cookie cookie(n); - - const int err = __system_property_foreach(find_nth_fn, &cookie); - if (err < 0) { - return nullptr; - } - - return cookie.pi; + struct find_nth { + const uint32_t sought; + uint32_t current; + const prop_info* result; + + 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(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; diff --git a/libc/include/sys/system_properties.h b/libc/include/sys/system_properties.h index b55566e69..c0bd44516 100644 --- a/libc/include/sys/system_properties.h +++ b/libc/include/sys/system_properties.h @@ -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 diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp index 23d0cad3b..7415b3ca1 100644 --- a/tests/system_properties_test.cpp +++ b/tests/system_properties_test.cpp @@ -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__ -- 2.11.0