Submodule src/incremental_delivery contains modified content diff --git a/src/incremental_delivery/sysprop/IncrementalProperties.sysprop.cpp b/src/incremental_delivery/sysprop/IncrementalProperties.sysprop.cpp new file mode 100644 index 0000000..dfe0671 --- /dev/null +++ b/src/incremental_delivery/sysprop/IncrementalProperties.sysprop.cpp @@ -0,0 +1,217 @@ +// Generated by the sysprop generator. DO NOT EDIT! + +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef __BIONIC__ +#include +[[maybe_unused]] static bool SetProp(const char* key, const char* value) { + return __system_property_set(key, value) == 0; +} +#else +#include +[[maybe_unused]] static bool SetProp(const char* key, const char* value) { + android::base::SetProperty(key, value); + return true; +} +#endif + +#include +#include + +namespace { + +using namespace android::sysprop::IncrementalProperties; + +template +T DoParse(const char* str); + +template +constexpr bool is_vector = false; + +template +constexpr bool is_vector> = true; + +template <> +[[maybe_unused]] std::optional DoParse(const char* str) { + static constexpr const char* kYes[] = {"1", "true"}; + static constexpr const char* kNo[] = {"0", "false"}; + + for (const char* yes : kYes) { + if (strcasecmp(yes, str) == 0) return std::make_optional(true); + } + + for (const char* no : kNo) { + if (strcasecmp(no, str) == 0) return std::make_optional(false); + } + + return std::nullopt; +} + +template <> +[[maybe_unused]] std::optional DoParse(const char* str) { + std::int32_t ret; + return android::base::ParseInt(str, &ret) ? std::make_optional(ret) : std::nullopt; +} + +template <> +[[maybe_unused]] std::optional DoParse(const char* str) { + std::uint32_t ret; + return android::base::ParseUint(str, &ret) ? std::make_optional(ret) : std::nullopt; +} + +template <> +[[maybe_unused]] std::optional DoParse(const char* str) { + std::int64_t ret; + return android::base::ParseInt(str, &ret) ? std::make_optional(ret) : std::nullopt; +} + +template <> +[[maybe_unused]] std::optional DoParse(const char* str) { + std::uint64_t ret; + return android::base::ParseUint(str, &ret) ? std::make_optional(ret) : std::nullopt; +} + +template <> +[[maybe_unused]] std::optional DoParse(const char* str) { + int old_errno = errno; + errno = 0; + char* end; + double ret = std::strtod(str, &end); + if (errno != 0) { + return std::nullopt; + } + if (str == end || *end != '\0') { + errno = EINVAL; + return std::nullopt; + } + errno = old_errno; + return std::make_optional(ret); +} + +template <> +[[maybe_unused]] std::optional DoParse(const char* str) { + return *str == '\0' ? std::nullopt : std::make_optional(str); +} + +template +[[maybe_unused]] Vec DoParseList(const char* str) { + Vec ret; + if (*str == '\0') return ret; + const char* p = str; + for (;;) { + const char* r = p; + std::string value; + while (*r != ',') { + if (*r == '\\') ++r; + if (*r == '\0') break; + value += *r++; + } + ret.emplace_back(DoParse(value.c_str())); + if (*r == '\0') break; + p = r + 1; + } + return ret; +} + +template +inline T TryParse(const char* str) { + if constexpr (is_vector) { + return DoParseList(str); + } else { + return DoParse(str); + } +} + +[[maybe_unused]] std::string FormatValue(const std::optional& value) { + return value ? std::to_string(*value) : ""; +} + +[[maybe_unused]] std::string FormatValue(const std::optional& value) { + return value ? std::to_string(*value) : ""; +} + +[[maybe_unused]] std::string FormatValue(const std::optional& value) { + return value ? std::to_string(*value) : ""; +} + +[[maybe_unused]] std::string FormatValue(const std::optional& value) { + return value ? std::to_string(*value) : ""; +} + +[[maybe_unused]] std::string FormatValue(const std::optional& value) { + if (!value) return ""; + char buf[1024]; + std::sprintf(buf, "%.*g", std::numeric_limits::max_digits10, *value); + return buf; +} + +[[maybe_unused]] std::string FormatValue(const std::optional& value) { + return value ? (*value ? "true" : "false") : ""; +} + +template +[[maybe_unused]] std::string FormatValue(const std::vector& value) { + if (value.empty()) return ""; + + std::string ret; + bool first = true; + + for (auto&& element : value) { + if (!first) + ret += ','; + else + first = false; + if constexpr (std::is_same_v>) { + if (element) { + for (char c : *element) { + if (c == '\\' || c == ',') ret += '\\'; + ret += c; + } + } + } else { + ret += FormatValue(element); + } + } + + return ret; +} + +template +T GetProp(const char* key, const char* legacy = nullptr) { + std::string value; +#ifdef __BIONIC__ + auto pi = __system_property_find(key); + if (pi != nullptr) { + __system_property_read_callback( + pi, + [](void* cookie, const char*, const char* value, std::uint32_t) { + *static_cast(cookie) = value; + }, + &value); + } +#else + value = android::base::GetProperty(key, ""); +#endif + if (value.empty() && legacy) { + ALOGV("prop %s doesn't exist; fallback to legacy prop %s", key, legacy); + return GetProp(legacy); + } + return TryParse(value.c_str()); +} + +} // namespace + +namespace android::sysprop::IncrementalProperties { + +std::optional enable() { + return GetProp>("ro.incremental.enable"); +} + +} // namespace android::sysprop::IncrementalProperties \ No newline at end of file diff --git a/src/incremental_delivery/sysprop/include/IncrementalProperties.sysprop.h b/src/incremental_delivery/sysprop/include/IncrementalProperties.sysprop.h new file mode 100644 index 0000000..19e2fea --- /dev/null +++ b/src/incremental_delivery/sysprop/include/IncrementalProperties.sysprop.h @@ -0,0 +1,14 @@ +// Generated by the sysprop generator. DO NOT EDIT! + +#pragma once + +#include +#include +#include +#include + +namespace android::sysprop::IncrementalProperties { + +std::optional enable(); + +} // namespace android::sysprop::IncrementalProperties \ No newline at end of file