OSDN Git Service

Un-deprecated __system_property_find_nth.
authorElliott Hughes <enh@google.com>
Mon, 17 Apr 2017 21:53:07 +0000 (14:53 -0700)
committerElliott Hughes <enh@google.com>
Tue, 18 Apr 2017 00:16:44 +0000 (17:16 -0700)
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
libc/include/sys/system_properties.h
tests/system_properties_test.cpp

index 2a42390..09106ad 100644 (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.");
-  }
-
-  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<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;
index b55566e..c0bd445 100644 (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
 
index 23d0cad..7415b3c 100644 (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__