1 // Generated by the sysprop generator. DO NOT EDIT!
2
3 #include <ApexProperties.sysprop.h>
4
5 #include <cctype>
6 #include <cerrno>
7 #include <cstdio>
8 #include <cstring>
9 #include <limits>
10 #include <utility>
11
12 #include <strings.h>
13 #ifdef __BIONIC__
14 #include <sys/system_properties.h>
SetProp(const char * key,const char * value)15 [[maybe_unused]] static bool SetProp(const char* key, const char* value) {
16 return __system_property_set(key, value) == 0;
17 }
18 #else
19 #include <android-base/properties.h>
SetProp(const char * key,const char * value)20 [[maybe_unused]] static bool SetProp(const char* key, const char* value) {
21 android::base::SetProperty(key, value);
22 return true;
23 }
24 #endif
25
26 #include <android-base/parseint.h>
27 #include <log/log.h>
28
29 namespace {
30
31 using namespace android::sysprop::ApexProperties;
32
33 template <typename T> T DoParse(const char* str);
34
35 template <typename T> constexpr bool is_vector = false;
36
37 template <typename T> constexpr bool is_vector<std::vector<T>> = true;
38
DoParse(const char * str)39 template <> [[maybe_unused]] std::optional<bool> DoParse(const char* str) {
40 static constexpr const char* kYes[] = {"1", "true"};
41 static constexpr const char* kNo[] = {"0", "false"};
42
43 for (const char* yes : kYes) {
44 if (strcasecmp(yes, str) == 0) return std::make_optional(true);
45 }
46
47 for (const char* no : kNo) {
48 if (strcasecmp(no, str) == 0) return std::make_optional(false);
49 }
50
51 return std::nullopt;
52 }
53
DoParse(const char * str)54 template <> [[maybe_unused]] std::optional<std::int32_t> DoParse(const char* str) {
55 std::int32_t ret;
56 return android::base::ParseInt(str, &ret) ? std::make_optional(ret) : std::nullopt;
57 }
58
DoParse(const char * str)59 template <> [[maybe_unused]] std::optional<std::uint32_t> DoParse(const char* str) {
60 std::uint32_t ret;
61 return android::base::ParseUint(str, &ret) ? std::make_optional(ret) : std::nullopt;
62 }
63
DoParse(const char * str)64 template <> [[maybe_unused]] std::optional<std::int64_t> DoParse(const char* str) {
65 std::int64_t ret;
66 return android::base::ParseInt(str, &ret) ? std::make_optional(ret) : std::nullopt;
67 }
68
DoParse(const char * str)69 template <> [[maybe_unused]] std::optional<std::uint64_t> DoParse(const char* str) {
70 std::uint64_t ret;
71 return android::base::ParseUint(str, &ret) ? std::make_optional(ret) : std::nullopt;
72 }
73
DoParse(const char * str)74 template <> [[maybe_unused]] std::optional<double> DoParse(const char* str) {
75 int old_errno = errno;
76 errno = 0;
77 char* end;
78 double ret = std::strtod(str, &end);
79 if (errno != 0) {
80 return std::nullopt;
81 }
82 if (str == end || *end != '\0') {
83 errno = EINVAL;
84 return std::nullopt;
85 }
86 errno = old_errno;
87 return std::make_optional(ret);
88 }
89
DoParse(const char * str)90 template <> [[maybe_unused]] std::optional<std::string> DoParse(const char* str) {
91 return *str == '\0' ? std::nullopt : std::make_optional(str);
92 }
93
DoParseList(const char * str)94 template <typename Vec> [[maybe_unused]] Vec DoParseList(const char* str) {
95 Vec ret;
96 if (*str == '\0') return ret;
97 const char* p = str;
98 for (;;) {
99 const char* r = p;
100 std::string value;
101 while (*r != ',') {
102 if (*r == '\\') ++r;
103 if (*r == '\0') break;
104 value += *r++;
105 }
106 ret.emplace_back(DoParse<typename Vec::value_type>(value.c_str()));
107 if (*r == '\0') break;
108 p = r + 1;
109 }
110 return ret;
111 }
112
TryParse(const char * str)113 template <typename T> inline T TryParse(const char* str) {
114 if constexpr(is_vector<T>) {
115 return DoParseList<T>(str);
116 } else {
117 return DoParse<T>(str);
118 }
119 }
120
FormatValue(const std::optional<std::int32_t> & value)121 [[maybe_unused]] std::string FormatValue(const std::optional<std::int32_t>& value) {
122 return value ? std::to_string(*value) : "";
123 }
124
FormatValue(const std::optional<std::uint32_t> & value)125 [[maybe_unused]] std::string FormatValue(const std::optional<std::uint32_t>& value) {
126 return value ? std::to_string(*value) : "";
127 }
128
FormatValue(const std::optional<std::int64_t> & value)129 [[maybe_unused]] std::string FormatValue(const std::optional<std::int64_t>& value) {
130 return value ? std::to_string(*value) : "";
131 }
132
FormatValue(const std::optional<std::uint64_t> & value)133 [[maybe_unused]] std::string FormatValue(const std::optional<std::uint64_t>& value) {
134 return value ? std::to_string(*value) : "";
135 }
136
FormatValue(const std::optional<double> & value)137 [[maybe_unused]] std::string FormatValue(const std::optional<double>& value) {
138 if (!value) return "";
139 char buf[1024];
140 std::sprintf(buf, "%.*g", std::numeric_limits<double>::max_digits10, *value);
141 return buf;
142 }
143
FormatValue(const std::optional<bool> & value)144 [[maybe_unused]] std::string FormatValue(const std::optional<bool>& value) {
145 return value ? (*value ? "true" : "false") : "";
146 }
147
148 template <typename T>
FormatValue(const std::vector<T> & value)149 [[maybe_unused]] std::string FormatValue(const std::vector<T>& value) {
150 if (value.empty()) return "";
151
152 std::string ret;
153 bool first = true;
154
155 for (auto&& element : value) {
156 if (!first) ret += ',';
157 else first = false;
158 if constexpr(std::is_same_v<T, std::optional<std::string>>) {
159 if (element) {
160 for (char c : *element) {
161 if (c == '\\' || c == ',') ret += '\\';
162 ret += c;
163 }
164 }
165 } else {
166 ret += FormatValue(element);
167 }
168 }
169
170 return ret;
171 }
172
173 template <typename T>
GetProp(const char * key,const char * legacy=nullptr)174 T GetProp(const char* key, const char* legacy = nullptr) {
175 std::string value;
176 #ifdef __BIONIC__
177 auto pi = __system_property_find(key);
178 if (pi != nullptr) {
179 __system_property_read_callback(pi, [](void* cookie, const char*, const char* value, std::uint32_t) {
180 *static_cast<std::string*>(cookie) = value;
181 }, &value);
182 }
183 #else
184 value = android::base::GetProperty(key, "");
185 #endif
186 if (value.empty() && legacy) {
187 ALOGV("prop %s doesn't exist; fallback to legacy prop %s", key, legacy);
188 return GetProp<T>(legacy);
189 }
190 return TryParse<T>(value.c_str());
191 }
192
193 } // namespace
194
195 namespace android::sysprop::ApexProperties {
196
updatable()197 std::optional<bool> updatable() {
198 return GetProp<std::optional<bool>>("ro.apex.updatable");
199 }
200
dm_delete_timeout()201 std::optional<std::uint32_t> dm_delete_timeout() {
202 return GetProp<std::optional<std::uint32_t>>("apexd.config.dm_delete.timeout");
203 }
204
dm_create_timeout()205 std::optional<std::uint32_t> dm_create_timeout() {
206 return GetProp<std::optional<std::uint32_t>>("apexd.config.dm_create.timeout");
207 }
208
loop_wait_attempts()209 std::optional<std::uint32_t> loop_wait_attempts() {
210 return GetProp<std::optional<std::uint32_t>>("apexd.config.loop_wait.attempts");
211 }
212
boot_activation_threads()213 std::optional<std::uint32_t> boot_activation_threads() {
214 return GetProp<std::optional<std::uint32_t>>("apexd.config.boot_activation.threads");
215 }
216
loopback_readahead()217 std::optional<std::uint32_t> loopback_readahead() {
218 return GetProp<std::optional<std::uint32_t>>("apexd.config.loopback.readahead");
219 }
220
221 } // namespace android::sysprop::ApexProperties
222