summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
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 {
"file.cpp",
"logging.cpp",
"parsenetaddress.cpp",
+ "properties.cpp",
"quick_exit.cpp",
"stringprintf.cpp",
"strings.cpp",
@@ -58,9 +59,6 @@ cc_defaults {
shared_libs: ["liblog"],
target: {
android: {
- srcs: [
- "properties.cpp",
- ],
sanitize: {
misc_undefined: ["integer"],
},
@@ -130,6 +128,7 @@ cc_test {
"parsedouble_test.cpp",
"parseint_test.cpp",
"parsenetaddress_test.cpp",
+ "properties_test.cpp",
"quick_exit_test.cpp",
"scopeguard_test.cpp",
"stringprintf_test.cpp",
@@ -139,7 +138,6 @@ cc_test {
],
target: {
android: {
- srcs: ["properties_test.cpp"],
sanitize: {
misc_undefined: ["integer"],
},
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 @@
#include <sys/cdefs.h>
-#if !defined(__BIONIC__)
-#error Only bionic supports system properties.
-#endif
-
#include <chrono>
#include <limits>
#include <string>
@@ -62,14 +58,18 @@ bool SetProperty(const std::string& key, const std::string& value);
// Waits for the system property `key` to have the value `expected_value`.
// Times out after `relative_timeout`.
// Returns true on success, false on timeout.
+#if defined(__BIONIC__)
bool WaitForProperty(const std::string& key, const std::string& expected_value,
std::chrono::milliseconds relative_timeout = std::chrono::milliseconds::max());
+#endif
// Waits for the system property `key` to be created.
// Times out after `relative_timeout`.
// Returns true on success, false on timeout.
+#if defined(__BIONIC__)
bool WaitForPropertyCreation(const std::string& key, std::chrono::milliseconds relative_timeout =
std::chrono::milliseconds::max());
+#endif
} // namespace base
} // 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 @@
* limitations under the License.
*/
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-
#include "android-base/properties.h"
+#if defined(__BIONIC__)
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/system_properties.h>
#include <sys/_system_properties.h>
+#endif
#include <algorithm>
#include <chrono>
#include <limits>
+#include <map>
#include <string>
#include <android-base/parseint.h>
@@ -31,24 +33,6 @@
namespace android {
namespace base {
-std::string GetProperty(const std::string& key, const std::string& default_value) {
- const prop_info* pi = __system_property_find(key.c_str());
- if (pi == nullptr) return default_value;
-
- std::string property_value;
- __system_property_read_callback(pi,
- [](void* cookie, const char*, const char* value, unsigned) {
- auto property_value = reinterpret_cast<std::string*>(cookie);
- *property_value = value;
- },
- &property_value);
-
- // If the property exists but is empty, also return the default value.
- // Since we can't remove system properties, "empty" is traditionally
- // the same as "missing" (this was true for cutils' property_get).
- return property_value.empty() ? default_value : property_value;
-}
-
bool GetBoolProperty(const std::string& key, bool default_value) {
std::string value = GetProperty(key, "");
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);
template uint32_t GetUintProperty(const std::string&, uint32_t, uint32_t);
template uint64_t GetUintProperty(const std::string&, uint64_t, uint64_t);
+#if !defined(__BIONIC__)
+static std::map<std::string, std::string>& g_properties = *new std::map<std::string, std::string>;
+static int __system_property_set(const char* key, const char* value) {
+ g_properties[key] = value;
+ return 0;
+}
+#endif
+
+std::string GetProperty(const std::string& key, const std::string& default_value) {
+ std::string property_value;
+#if defined(__BIONIC__)
+ const prop_info* pi = __system_property_find(key.c_str());
+ if (pi == nullptr) return default_value;
+
+ __system_property_read_callback(pi,
+ [](void* cookie, const char*, const char* value, unsigned) {
+ auto property_value = reinterpret_cast<std::string*>(cookie);
+ *property_value = value;
+ },
+ &property_value);
+#else
+ auto it = g_properties.find(key);
+ if (it == g_properties.end()) return default_value;
+ property_value = it->second;
+#endif
+ // If the property exists but is empty, also return the default value.
+ // Since we can't remove system properties, "empty" is traditionally
+ // the same as "missing" (this was true for cutils' property_get).
+ return property_value.empty() ? default_value : property_value;
+}
+
bool SetProperty(const std::string& key, const std::string& value) {
return (__system_property_set(key.c_str(), value.c_str()) == 0);
}
+#if defined(__BIONIC__)
+
struct WaitForPropertyData {
bool done;
const std::string* expected_value;
@@ -175,5 +192,7 @@ bool WaitForPropertyCreation(const std::string& key,
return (WaitForPropertyCreation(key, relative_timeout, start_time) != nullptr);
}
+#endif
+
} // namespace base
} // 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 @@
#include <string>
#include <thread>
-using namespace std::chrono_literals;
+#if !defined(_WIN32)
+using namespace std::literals;
+#endif
TEST(properties, smoke) {
android::base::SetProperty("debug.libbase.property_test", "hello");
@@ -126,6 +128,7 @@ TEST(properties, GetUintProperty_uint32_t) { CheckGetUintProperty<uint32_t>(); }
TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); }
TEST(properties, WaitForProperty) {
+#if defined(__BIONIC__)
std::atomic<bool> flag{false};
std::thread thread([&]() {
std::this_thread::sleep_for(100ms);
@@ -138,9 +141,13 @@ TEST(properties, WaitForProperty) {
flag = true;
ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", 1s));
thread.join();
+#else
+ GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
+#endif
}
TEST(properties, WaitForProperty_timeout) {
+#if defined(__BIONIC__)
auto t0 = std::chrono::steady_clock::now();
ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_timeout_test", "a",
200ms));
@@ -149,9 +156,13 @@ TEST(properties, WaitForProperty_timeout) {
ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms);
// Upper bounds on timing are inherently flaky, but let's try...
ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
+#endif
}
TEST(properties, WaitForProperty_MaxTimeout) {
+#if defined(__BIONIC__)
std::atomic<bool> flag{false};
std::thread thread([&]() {
android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
@@ -165,9 +176,13 @@ TEST(properties, WaitForProperty_MaxTimeout) {
// Test that this does not immediately return false due to overflow issues with the timeout.
ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b"));
thread.join();
+#else
+ GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
+#endif
}
TEST(properties, WaitForProperty_NegativeTimeout) {
+#if defined(__BIONIC__)
std::atomic<bool> flag{false};
std::thread thread([&]() {
android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
@@ -181,9 +196,13 @@ TEST(properties, WaitForProperty_NegativeTimeout) {
// Assert that this immediately returns with a negative timeout
ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", -100ms));
thread.join();
+#else
+ GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
+#endif
}
TEST(properties, WaitForPropertyCreation) {
+#if defined(__BIONIC__)
std::thread thread([&]() {
std::this_thread::sleep_for(100ms);
android::base::SetProperty("debug.libbase.WaitForPropertyCreation_test", "a");
@@ -192,9 +211,13 @@ TEST(properties, WaitForPropertyCreation) {
ASSERT_TRUE(android::base::WaitForPropertyCreation(
"debug.libbase.WaitForPropertyCreation_test", 1s));
thread.join();
+#else
+ GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
+#endif
}
TEST(properties, WaitForPropertyCreation_timeout) {
+#if defined(__BIONIC__)
auto t0 = std::chrono::steady_clock::now();
ASSERT_FALSE(android::base::WaitForPropertyCreation(
"debug.libbase.WaitForPropertyCreation_timeout_test", 200ms));
@@ -203,4 +226,7 @@ TEST(properties, WaitForPropertyCreation_timeout) {
ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms);
// Upper bounds on timing are inherently flaky, but let's try...
ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
+#endif
}