blob: 0f0f6382fcaedd9641c58357ab1b85ad4a7bf558 [file] [log] [blame]
Elliott Hughes1e88c8c2016-09-21 16:53:15 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Elliott Hughesb30769a2017-02-10 19:02:51 -080017#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
18
Elliott Hughes1e88c8c2016-09-21 16:53:15 -070019#include "android-base/properties.h"
20
21#include <sys/system_properties.h>
Elliott Hughesb30769a2017-02-10 19:02:51 -080022#include <sys/_system_properties.h>
Elliott Hughes1e88c8c2016-09-21 16:53:15 -070023
24#include <string>
25
26#include <android-base/parseint.h>
27
28namespace android {
29namespace base {
30
31std::string GetProperty(const std::string& key, const std::string& default_value) {
32 const prop_info* pi = __system_property_find(key.c_str());
33 if (pi == nullptr) return default_value;
34
35 char buf[PROP_VALUE_MAX];
36 if (__system_property_read(pi, nullptr, buf) > 0) return buf;
37
38 // If the property exists but is empty, also return the default value.
39 // Since we can't remove system properties, "empty" is traditionally
40 // the same as "missing" (this was true for cutils' property_get).
41 return default_value;
42}
43
44bool GetBoolProperty(const std::string& key, bool default_value) {
45 std::string value = GetProperty(key, "");
46 if (value == "1" || value == "y" || value == "yes" || value == "on" || value == "true") {
47 return true;
48 } else if (value == "0" || value == "n" || value == "no" || value == "off" || value == "false") {
49 return false;
50 }
51 return default_value;
52}
53
54template <typename T>
55T GetIntProperty(const std::string& key, T default_value, T min, T max) {
56 T result;
57 std::string value = GetProperty(key, "");
Elliott Hughesda46b392016-10-11 17:09:00 -070058 if (!value.empty() && android::base::ParseInt(value, &result, min, max)) return result;
Elliott Hughes1e88c8c2016-09-21 16:53:15 -070059 return default_value;
60}
61
62template <typename T>
63T GetUintProperty(const std::string& key, T default_value, T max) {
64 T result;
65 std::string value = GetProperty(key, "");
Elliott Hughesda46b392016-10-11 17:09:00 -070066 if (!value.empty() && android::base::ParseUint(value, &result, max)) return result;
Elliott Hughes1e88c8c2016-09-21 16:53:15 -070067 return default_value;
68}
69
70template int8_t GetIntProperty(const std::string&, int8_t, int8_t, int8_t);
71template int16_t GetIntProperty(const std::string&, int16_t, int16_t, int16_t);
72template int32_t GetIntProperty(const std::string&, int32_t, int32_t, int32_t);
73template int64_t GetIntProperty(const std::string&, int64_t, int64_t, int64_t);
74
75template uint8_t GetUintProperty(const std::string&, uint8_t, uint8_t);
76template uint16_t GetUintProperty(const std::string&, uint16_t, uint16_t);
77template uint32_t GetUintProperty(const std::string&, uint32_t, uint32_t);
78template uint64_t GetUintProperty(const std::string&, uint64_t, uint64_t);
79
80bool SetProperty(const std::string& key, const std::string& value) {
81 return (__system_property_set(key.c_str(), value.c_str()) == 0);
82}
83
Elliott Hughesb30769a2017-02-10 19:02:51 -080084struct WaitForPropertyData {
85 bool done;
86 const std::string* expected_value;
87 unsigned last_read_serial;
88};
89
90static void WaitForPropertyCallback(void* data_ptr, const char*, const char* value, unsigned serial) {
91 WaitForPropertyData* data = reinterpret_cast<WaitForPropertyData*>(data_ptr);
92 if (*data->expected_value == value) {
93 data->done = true;
94 } else {
95 data->last_read_serial = serial;
96 }
97}
98
99void WaitForProperty(const std::string& key, const std::string& expected_value) {
100 // Find the property's prop_info*.
101 const prop_info* pi;
102 unsigned global_serial = 0;
103 while ((pi = __system_property_find(key.c_str())) == nullptr) {
104 // The property doesn't even exist yet.
105 // Wait for a global change and then look again.
106 global_serial = __system_property_wait_any(global_serial);
107 }
108
109 WaitForPropertyData data;
110 data.expected_value = &expected_value;
111 data.done = false;
112 while (true) {
113 // Check whether the property has the value we're looking for?
114 __system_property_read_callback(pi, WaitForPropertyCallback, &data);
115 if (data.done) return;
116
117 // It didn't so wait for it to change before checking again.
118 __system_property_wait(pi, data.last_read_serial);
119 }
120}
121
Elliott Hughes1e88c8c2016-09-21 16:53:15 -0700122} // namespace base
123} // namespace android