summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorElliott Hughes2018-05-29 18:59:50 -0500
committerGerrit Code Review2018-05-29 18:59:50 -0500
commitd580c441ab45a6b7278da003e19af64e9ea2cc71 (patch)
tree552abfafdbd95cc05f0e06500409bbf382348258 /base
parent420fe5fe9010081cbe61774ac661c0d5e7f09114 (diff)
parentdc803126283444431c0d06f0386eddada0fe6b77 (diff)
downloadplatform-system-core-d580c441ab45a6b7278da003e19af64e9ea2cc71.tar.gz
platform-system-core-d580c441ab45a6b7278da003e19af64e9ea2cc71.tar.xz
platform-system-core-d580c441ab45a6b7278da003e19af64e9ea2cc71.zip
Merge "libbase: add host properties support."
Diffstat (limited to 'base')
-rw-r--r--base/Android.bp6
-rw-r--r--base/include/android-base/properties.h8
-rw-r--r--base/properties.cpp59
-rw-r--r--base/properties_test.cpp28
4 files changed, 72 insertions, 29 deletions
diff --git a/base/Android.bp b/base/Android.bp
index 71bf1540c..3d80d9719 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -48,6 +48,7 @@ cc_defaults {
48 "file.cpp", 48 "file.cpp",
49 "logging.cpp", 49 "logging.cpp",
50 "parsenetaddress.cpp", 50 "parsenetaddress.cpp",
51 "properties.cpp",
51 "quick_exit.cpp", 52 "quick_exit.cpp",
52 "stringprintf.cpp", 53 "stringprintf.cpp",
53 "strings.cpp", 54 "strings.cpp",
@@ -58,9 +59,6 @@ cc_defaults {
58 shared_libs: ["liblog"], 59 shared_libs: ["liblog"],
59 target: { 60 target: {
60 android: { 61 android: {
61 srcs: [
62 "properties.cpp",
63 ],
64 sanitize: { 62 sanitize: {
65 misc_undefined: ["integer"], 63 misc_undefined: ["integer"],
66 }, 64 },
@@ -130,6 +128,7 @@ cc_test {
130 "parsedouble_test.cpp", 128 "parsedouble_test.cpp",
131 "parseint_test.cpp", 129 "parseint_test.cpp",
132 "parsenetaddress_test.cpp", 130 "parsenetaddress_test.cpp",
131 "properties_test.cpp",
133 "quick_exit_test.cpp", 132 "quick_exit_test.cpp",
134 "scopeguard_test.cpp", 133 "scopeguard_test.cpp",
135 "stringprintf_test.cpp", 134 "stringprintf_test.cpp",
@@ -139,7 +138,6 @@ cc_test {
139 ], 138 ],
140 target: { 139 target: {
141 android: { 140 android: {
142 srcs: ["properties_test.cpp"],
143 sanitize: { 141 sanitize: {
144 misc_undefined: ["integer"], 142 misc_undefined: ["integer"],
145 }, 143 },
diff --git a/base/include/android-base/properties.h b/base/include/android-base/properties.h
index 041586c2c..3a051435c 100644
--- a/base/include/android-base/properties.h
+++ b/base/include/android-base/properties.h
@@ -19,10 +19,6 @@
19 19
20#include <sys/cdefs.h> 20#include <sys/cdefs.h>
21 21
22#if !defined(__BIONIC__)
23#error Only bionic supports system properties.
24#endif
25
26#include <chrono> 22#include <chrono>
27#include <limits> 23#include <limits>
28#include <string> 24#include <string>
@@ -62,14 +58,18 @@ bool SetProperty(const std::string& key, const std::string& value);
62// Waits for the system property `key` to have the value `expected_value`. 58// Waits for the system property `key` to have the value `expected_value`.
63// Times out after `relative_timeout`. 59// Times out after `relative_timeout`.
64// Returns true on success, false on timeout. 60// Returns true on success, false on timeout.
61#if defined(__BIONIC__)
65bool WaitForProperty(const std::string& key, const std::string& expected_value, 62bool WaitForProperty(const std::string& key, const std::string& expected_value,
66 std::chrono::milliseconds relative_timeout = std::chrono::milliseconds::max()); 63 std::chrono::milliseconds relative_timeout = std::chrono::milliseconds::max());
64#endif
67 65
68// Waits for the system property `key` to be created. 66// Waits for the system property `key` to be created.
69// Times out after `relative_timeout`. 67// Times out after `relative_timeout`.
70// Returns true on success, false on timeout. 68// Returns true on success, false on timeout.
69#if defined(__BIONIC__)
71bool WaitForPropertyCreation(const std::string& key, std::chrono::milliseconds relative_timeout = 70bool WaitForPropertyCreation(const std::string& key, std::chrono::milliseconds relative_timeout =
72 std::chrono::milliseconds::max()); 71 std::chrono::milliseconds::max());
72#endif
73 73
74} // namespace base 74} // namespace base
75} // namespace android 75} // namespace android
diff --git a/base/properties.cpp b/base/properties.cpp
index 6cf43f9e2..d5a5918ce 100644
--- a/base/properties.cpp
+++ b/base/properties.cpp
@@ -14,16 +14,18 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
18
19#include "android-base/properties.h" 17#include "android-base/properties.h"
20 18
19#if defined(__BIONIC__)
20#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
21#include <sys/system_properties.h> 21#include <sys/system_properties.h>
22#include <sys/_system_properties.h> 22#include <sys/_system_properties.h>
23#endif
23 24
24#include <algorithm> 25#include <algorithm>
25#include <chrono> 26#include <chrono>
26#include <limits> 27#include <limits>
28#include <map>
27#include <string> 29#include <string>
28 30
29#include <android-base/parseint.h> 31#include <android-base/parseint.h>
@@ -31,24 +33,6 @@
31namespace android { 33namespace android {
32namespace base { 34namespace base {
33 35
34std::string GetProperty(const std::string& key, const std::string& default_value) {
35 const prop_info* pi = __system_property_find(key.c_str());
36 if (pi == nullptr) return default_value;
37
38 std::string property_value;
39 __system_property_read_callback(pi,
40 [](void* cookie, const char*, const char* value, unsigned) {
41 auto property_value = reinterpret_cast<std::string*>(cookie);
42 *property_value = value;
43 },
44 &property_value);
45
46 // If the property exists but is empty, also return the default value.
47 // Since we can't remove system properties, "empty" is traditionally
48 // the same as "missing" (this was true for cutils' property_get).
49 return property_value.empty() ? default_value : property_value;
50}
51
52bool GetBoolProperty(const std::string& key, bool default_value) { 36bool GetBoolProperty(const std::string& key, bool default_value) {
53 std::string value = GetProperty(key, ""); 37 std::string value = GetProperty(key, "");
54 if (value == "1" || value == "y" || value == "yes" || value == "on" || value == "true") { 38 if (value == "1" || value == "y" || value == "yes" || value == "on" || value == "true") {
@@ -85,10 +69,43 @@ template uint16_t GetUintProperty(const std::string&, uint16_t, uint16_t);
85template uint32_t GetUintProperty(const std::string&, uint32_t, uint32_t); 69template uint32_t GetUintProperty(const std::string&, uint32_t, uint32_t);
86template uint64_t GetUintProperty(const std::string&, uint64_t, uint64_t); 70template uint64_t GetUintProperty(const std::string&, uint64_t, uint64_t);
87 71
72#if !defined(__BIONIC__)
73static std::map<std::string, std::string>& g_properties = *new std::map<std::string, std::string>;
74static int __system_property_set(const char* key, const char* value) {
75 g_properties[key] = value;
76 return 0;
77}
78#endif
79
80std::string GetProperty(const std::string& key, const std::string& default_value) {
81 std::string property_value;
82#if defined(__BIONIC__)
83 const prop_info* pi = __system_property_find(key.c_str());
84 if (pi == nullptr) return default_value;
85
86 __system_property_read_callback(pi,
87 [](void* cookie, const char*, const char* value, unsigned) {
88 auto property_value = reinterpret_cast<std::string*>(cookie);
89 *property_value = value;
90 },
91 &property_value);
92#else
93 auto it = g_properties.find(key);
94 if (it == g_properties.end()) return default_value;
95 property_value = it->second;
96#endif
97 // If the property exists but is empty, also return the default value.
98 // Since we can't remove system properties, "empty" is traditionally
99 // the same as "missing" (this was true for cutils' property_get).
100 return property_value.empty() ? default_value : property_value;
101}
102
88bool SetProperty(const std::string& key, const std::string& value) { 103bool SetProperty(const std::string& key, const std::string& value) {
89 return (__system_property_set(key.c_str(), value.c_str()) == 0); 104 return (__system_property_set(key.c_str(), value.c_str()) == 0);
90} 105}
91 106
107#if defined(__BIONIC__)
108
92struct WaitForPropertyData { 109struct WaitForPropertyData {
93 bool done; 110 bool done;
94 const std::string* expected_value; 111 const std::string* expected_value;
@@ -175,5 +192,7 @@ bool WaitForPropertyCreation(const std::string& key,
175 return (WaitForPropertyCreation(key, relative_timeout, start_time) != nullptr); 192 return (WaitForPropertyCreation(key, relative_timeout, start_time) != nullptr);
176} 193}
177 194
195#endif
196
178} // namespace base 197} // namespace base
179} // namespace android 198} // namespace android
diff --git a/base/properties_test.cpp b/base/properties_test.cpp
index de5f3dcfa..e7d4880c2 100644
--- a/base/properties_test.cpp
+++ b/base/properties_test.cpp
@@ -23,7 +23,9 @@
23#include <string> 23#include <string>
24#include <thread> 24#include <thread>
25 25
26using namespace std::chrono_literals; 26#if !defined(_WIN32)
27using namespace std::literals;
28#endif
27 29
28TEST(properties, smoke) { 30TEST(properties, smoke) {
29 android::base::SetProperty("debug.libbase.property_test", "hello"); 31 android::base::SetProperty("debug.libbase.property_test", "hello");
@@ -126,6 +128,7 @@ TEST(properties, GetUintProperty_uint32_t) { CheckGetUintProperty<uint32_t>(); }
126TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); } 128TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); }
127 129
128TEST(properties, WaitForProperty) { 130TEST(properties, WaitForProperty) {
131#if defined(__BIONIC__)
129 std::atomic<bool> flag{false}; 132 std::atomic<bool> flag{false};
130 std::thread thread([&]() { 133 std::thread thread([&]() {
131 std::this_thread::sleep_for(100ms); 134 std::this_thread::sleep_for(100ms);
@@ -138,9 +141,13 @@ TEST(properties, WaitForProperty) {
138 flag = true; 141 flag = true;
139 ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", 1s)); 142 ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", 1s));
140 thread.join(); 143 thread.join();
144#else
145 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
146#endif
141} 147}
142 148
143TEST(properties, WaitForProperty_timeout) { 149TEST(properties, WaitForProperty_timeout) {
150#if defined(__BIONIC__)
144 auto t0 = std::chrono::steady_clock::now(); 151 auto t0 = std::chrono::steady_clock::now();
145 ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_timeout_test", "a", 152 ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_timeout_test", "a",
146 200ms)); 153 200ms));
@@ -149,9 +156,13 @@ TEST(properties, WaitForProperty_timeout) {
149 ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms); 156 ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms);
150 // Upper bounds on timing are inherently flaky, but let's try... 157 // Upper bounds on timing are inherently flaky, but let's try...
151 ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms); 158 ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
159#else
160 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
161#endif
152} 162}
153 163
154TEST(properties, WaitForProperty_MaxTimeout) { 164TEST(properties, WaitForProperty_MaxTimeout) {
165#if defined(__BIONIC__)
155 std::atomic<bool> flag{false}; 166 std::atomic<bool> flag{false};
156 std::thread thread([&]() { 167 std::thread thread([&]() {
157 android::base::SetProperty("debug.libbase.WaitForProperty_test", "a"); 168 android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
@@ -165,9 +176,13 @@ TEST(properties, WaitForProperty_MaxTimeout) {
165 // Test that this does not immediately return false due to overflow issues with the timeout. 176 // Test that this does not immediately return false due to overflow issues with the timeout.
166 ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b")); 177 ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b"));
167 thread.join(); 178 thread.join();
179#else
180 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
181#endif
168} 182}
169 183
170TEST(properties, WaitForProperty_NegativeTimeout) { 184TEST(properties, WaitForProperty_NegativeTimeout) {
185#if defined(__BIONIC__)
171 std::atomic<bool> flag{false}; 186 std::atomic<bool> flag{false};
172 std::thread thread([&]() { 187 std::thread thread([&]() {
173 android::base::SetProperty("debug.libbase.WaitForProperty_test", "a"); 188 android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
@@ -181,9 +196,13 @@ TEST(properties, WaitForProperty_NegativeTimeout) {
181 // Assert that this immediately returns with a negative timeout 196 // Assert that this immediately returns with a negative timeout
182 ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", -100ms)); 197 ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", -100ms));
183 thread.join(); 198 thread.join();
199#else
200 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
201#endif
184} 202}
185 203
186TEST(properties, WaitForPropertyCreation) { 204TEST(properties, WaitForPropertyCreation) {
205#if defined(__BIONIC__)
187 std::thread thread([&]() { 206 std::thread thread([&]() {
188 std::this_thread::sleep_for(100ms); 207 std::this_thread::sleep_for(100ms);
189 android::base::SetProperty("debug.libbase.WaitForPropertyCreation_test", "a"); 208 android::base::SetProperty("debug.libbase.WaitForPropertyCreation_test", "a");
@@ -192,9 +211,13 @@ TEST(properties, WaitForPropertyCreation) {
192 ASSERT_TRUE(android::base::WaitForPropertyCreation( 211 ASSERT_TRUE(android::base::WaitForPropertyCreation(
193 "debug.libbase.WaitForPropertyCreation_test", 1s)); 212 "debug.libbase.WaitForPropertyCreation_test", 1s));
194 thread.join(); 213 thread.join();
214#else
215 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
216#endif
195} 217}
196 218
197TEST(properties, WaitForPropertyCreation_timeout) { 219TEST(properties, WaitForPropertyCreation_timeout) {
220#if defined(__BIONIC__)
198 auto t0 = std::chrono::steady_clock::now(); 221 auto t0 = std::chrono::steady_clock::now();
199 ASSERT_FALSE(android::base::WaitForPropertyCreation( 222 ASSERT_FALSE(android::base::WaitForPropertyCreation(
200 "debug.libbase.WaitForPropertyCreation_timeout_test", 200ms)); 223 "debug.libbase.WaitForPropertyCreation_timeout_test", 200ms));
@@ -203,4 +226,7 @@ TEST(properties, WaitForPropertyCreation_timeout) {
203 ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms); 226 ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms);
204 // Upper bounds on timing are inherently flaky, but let's try... 227 // Upper bounds on timing are inherently flaky, but let's try...
205 ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms); 228 ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
229#else
230 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
231#endif
206} 232}