diff options
Diffstat (limited to 'init/property_service.cpp')
-rw-r--r-- | init/property_service.cpp | 274 |
1 files changed, 42 insertions, 232 deletions
diff --git a/init/property_service.cpp b/init/property_service.cpp index 2d67bf5d7..a89504e59 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -44,7 +44,6 @@ #include <mutex> #include <optional> #include <queue> -#include <string_view> #include <thread> #include <vector> @@ -52,7 +51,6 @@ #include <android-base/chrono_utils.h> #include <android-base/file.h> #include <android-base/logging.h> -#include <android-base/parseint.h> #include <android-base/properties.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> @@ -68,7 +66,6 @@ #include "persistent_properties.h" #include "property_type.h" #include "proto_utils.h" -#include "second_stage_resources.h" #include "selinux.h" #include "subcontext.h" #include "system/core/init/property_service.pb.h" @@ -77,7 +74,6 @@ using namespace std::literals; using android::base::GetProperty; -using android::base::ParseInt; using android::base::ReadFileToString; using android::base::Split; using android::base::StartsWith; @@ -94,12 +90,6 @@ using android::sysprop::InitProperties::is_userspace_reboot_supported; namespace android { namespace init { -constexpr auto FINGERPRINT_PROP = "ro.build.fingerprint"; -constexpr auto LEGACY_FINGERPRINT_PROP = "ro.build.legacy.fingerprint"; -constexpr auto ID_PROP = "ro.build.id"; -constexpr auto LEGACY_ID_PROP = "ro.build.legacy.id"; -constexpr auto VBMETA_DIGEST_PROP = "ro.boot.vbmeta.digest"; -constexpr auto DIGEST_SIZE_USED = 8; static bool persistent_properties_loaded = false; @@ -501,9 +491,6 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value, } LOG(INFO) << "Received sys.powerctl='" << value << "' from pid: " << cr.pid << process_log_string; - if (!value.empty()) { - DebugRebootLogging(); - } if (value == "reboot,userspace" && !is_userspace_reboot_supported().value_or(false)) { *error = "Userspace reboot is not supported by this device"; return PROP_ERROR_INVALID_VALUE; @@ -640,11 +627,9 @@ static void LoadProperties(char* data, const char* filter, const char* filename, char *key, *value, *eol, *sol, *tmp, *fn; size_t flen = 0; - static constexpr const char* const kVendorPathPrefixes[4] = { + static constexpr const char* const kVendorPathPrefixes[2] = { "/vendor", "/odm", - "/vendor_dlkm", - "/odm_dlkm", }; const char* context = kInitContext; @@ -723,8 +708,8 @@ static void LoadProperties(char* data, const char* filter, const char* filename, if (it == properties->end()) { (*properties)[key] = value; } else if (it->second != value) { - LOG(WARNING) << "Overriding previous property '" << key << "':'" << it->second - << "' with new value '" << value << "'"; + LOG(WARNING) << "Overriding previous 'ro.' property '" << key << "':'" + << it->second << "' with new value '" << value << "'"; it->second = value; } } else { @@ -753,15 +738,6 @@ static bool load_properties_from_file(const char* filename, const char* filter, return true; } -static void LoadPropertiesFromSecondStageRes(std::map<std::string, std::string>* properties) { - std::string prop = GetRamdiskPropForSecondStage(); - if (access(prop.c_str(), R_OK) != 0) { - CHECK(errno == ENOENT) << "Cannot access " << prop << ": " << strerror(errno); - return; - } - load_properties_from_file(prop.c_str(), nullptr, properties); -} - // persist.sys.usb.config values can't be combined on build-time when property // files are split into each partition. // So we need to apply the same rule of build/make/tools/post_process_props.py @@ -863,44 +839,23 @@ static void property_initialize_ro_product_props() { } } -static void property_initialize_build_id() { - std::string build_id = GetProperty(ID_PROP, ""); - if (!build_id.empty()) { +// If the ro.build.fingerprint property has not been set, derive it from constituent pieces +static void property_derive_build_fingerprint() { + std::string build_fingerprint = GetProperty("ro.build.fingerprint", ""); + if (!build_fingerprint.empty()) { return; } - std::string legacy_build_id = GetProperty(LEGACY_ID_PROP, ""); - std::string vbmeta_digest = GetProperty(VBMETA_DIGEST_PROP, ""); - if (vbmeta_digest.size() < DIGEST_SIZE_USED) { - LOG(ERROR) << "vbmeta digest size too small " << vbmeta_digest; - // Still try to set the id field in the unexpected case. - build_id = legacy_build_id; - } else { - // Derive the ro.build.id by appending the vbmeta digest to the base value. - build_id = legacy_build_id + "." + vbmeta_digest.substr(0, DIGEST_SIZE_USED); - } - - std::string error; - auto res = PropertySet(ID_PROP, build_id, &error); - if (res != PROP_SUCCESS) { - LOG(ERROR) << "Failed to set " << ID_PROP << " to " << build_id; - } -} - -static std::string ConstructBuildFingerprint(bool legacy) { const std::string UNKNOWN = "unknown"; - std::string build_fingerprint = GetProperty("ro.product.brand", UNKNOWN); + build_fingerprint = GetProperty("ro.product.brand", UNKNOWN); build_fingerprint += '/'; build_fingerprint += GetProperty("ro.product.name", UNKNOWN); build_fingerprint += '/'; build_fingerprint += GetProperty("ro.product.device", UNKNOWN); build_fingerprint += ':'; - build_fingerprint += GetProperty("ro.build.version.release_or_codename", UNKNOWN); + build_fingerprint += GetProperty("ro.build.version.release", UNKNOWN); build_fingerprint += '/'; - - std::string build_id = - legacy ? GetProperty(LEGACY_ID_PROP, UNKNOWN) : GetProperty(ID_PROP, UNKNOWN); - build_fingerprint += build_id; + build_fingerprint += GetProperty("ro.build.id", UNKNOWN); build_fingerprint += '/'; build_fingerprint += GetProperty("ro.build.version.incremental", UNKNOWN); build_fingerprint += ':'; @@ -908,181 +863,41 @@ static std::string ConstructBuildFingerprint(bool legacy) { build_fingerprint += '/'; build_fingerprint += GetProperty("ro.build.tags", UNKNOWN); - return build_fingerprint; -} - -// Derive the legacy build fingerprint if we overwrite the build id at runtime. -static void property_derive_legacy_build_fingerprint() { - std::string legacy_build_fingerprint = GetProperty(LEGACY_FINGERPRINT_PROP, ""); - if (!legacy_build_fingerprint.empty()) { - return; - } - - // The device doesn't have a legacy build id, skipping the legacy fingerprint. - std::string legacy_build_id = GetProperty(LEGACY_ID_PROP, ""); - if (legacy_build_id.empty()) { - return; - } - - legacy_build_fingerprint = ConstructBuildFingerprint(true /* legacy fingerprint */); - LOG(INFO) << "Setting property '" << LEGACY_FINGERPRINT_PROP << "' to '" - << legacy_build_fingerprint << "'"; - - std::string error; - uint32_t res = PropertySet(LEGACY_FINGERPRINT_PROP, legacy_build_fingerprint, &error); - if (res != PROP_SUCCESS) { - LOG(ERROR) << "Error setting property '" << LEGACY_FINGERPRINT_PROP << "': err=" << res - << " (" << error << ")"; - } -} - -// If the ro.build.fingerprint property has not been set, derive it from constituent pieces -static void property_derive_build_fingerprint() { - std::string build_fingerprint = GetProperty("ro.build.fingerprint", ""); - if (!build_fingerprint.empty()) { - return; - } - - build_fingerprint = ConstructBuildFingerprint(false /* legacy fingerprint */); - LOG(INFO) << "Setting property '" << FINGERPRINT_PROP << "' to '" << build_fingerprint << "'"; + LOG(INFO) << "Setting property 'ro.build.fingerprint' to '" << build_fingerprint << "'"; std::string error; - uint32_t res = PropertySet(FINGERPRINT_PROP, build_fingerprint, &error); + uint32_t res = PropertySet("ro.build.fingerprint", build_fingerprint, &error); if (res != PROP_SUCCESS) { - LOG(ERROR) << "Error setting property '" << FINGERPRINT_PROP << "': err=" << res << " (" - << error << ")"; - } -} - -// If the ro.product.cpu.abilist* properties have not been explicitly -// set, derive them from ro.${partition}.product.cpu.abilist* properties. -static void property_initialize_ro_cpu_abilist() { - // From high to low priority. - const char* kAbilistSources[] = { - "product", - "odm", - "vendor", - "system", - }; - const std::string EMPTY = ""; - const char* kAbilistProp = "ro.product.cpu.abilist"; - const char* kAbilist32Prop = "ro.product.cpu.abilist32"; - const char* kAbilist64Prop = "ro.product.cpu.abilist64"; - - // If the properties are defined explicitly, just use them. - if (GetProperty(kAbilistProp, EMPTY) != EMPTY) { - return; - } - - // Find the first source defining these properties by order. - std::string abilist32_prop_val; - std::string abilist64_prop_val; - for (const auto& source : kAbilistSources) { - const auto abilist32_prop = std::string("ro.") + source + ".product.cpu.abilist32"; - const auto abilist64_prop = std::string("ro.") + source + ".product.cpu.abilist64"; - abilist32_prop_val = GetProperty(abilist32_prop, EMPTY); - abilist64_prop_val = GetProperty(abilist64_prop, EMPTY); - // The properties could be empty on 32-bit-only or 64-bit-only devices, - // but we cannot identify a property is empty or undefined by GetProperty(). - // So, we assume both of these 2 properties are empty as undefined. - if (abilist32_prop_val != EMPTY || abilist64_prop_val != EMPTY) { - break; - } - } - - // Merge ABI lists for ro.product.cpu.abilist - auto abilist_prop_val = abilist64_prop_val; - if (abilist32_prop_val != EMPTY) { - if (abilist_prop_val != EMPTY) { - abilist_prop_val += ","; - } - abilist_prop_val += abilist32_prop_val; - } - - // Set these properties - const std::pair<const char*, const std::string&> set_prop_list[] = { - {kAbilistProp, abilist_prop_val}, - {kAbilist32Prop, abilist32_prop_val}, - {kAbilist64Prop, abilist64_prop_val}, - }; - for (const auto& [prop, prop_val] : set_prop_list) { - LOG(INFO) << "Setting property '" << prop << "' to '" << prop_val << "'"; - - std::string error; - uint32_t res = PropertySet(prop, prop_val, &error); - if (res != PROP_SUCCESS) { - LOG(ERROR) << "Error setting property '" << prop << "': err=" << res << " (" << error - << ")"; - } + LOG(ERROR) << "Error setting property 'ro.build.fingerprint': err=" << res << " (" << error + << ")"; } } void PropertyLoadBootDefaults() { + // TODO(b/117892318): merge prop.default and build.prop files into one // We read the properties and their values into a map, in order to always allow properties // loaded in the later property files to override the properties in loaded in the earlier // property files, regardless of if they are "ro." properties or not. std::map<std::string, std::string> properties; - - if (IsRecoveryMode()) { - load_properties_from_file("/prop.default", nullptr, &properties); - } - - // /<part>/etc/build.prop is the canonical location of the build-time properties since S. - // Falling back to /<part>/defalt.prop and /<part>/build.prop only when legacy path has to - // be supported, which is controlled by the support_legacy_path_until argument. - const auto load_properties_from_partition = [&properties](const std::string& partition, - int support_legacy_path_until) { - auto path = "/" + partition + "/etc/build.prop"; - if (load_properties_from_file(path.c_str(), nullptr, &properties)) { - return; + if (!load_properties_from_file("/system/etc/prop.default", nullptr, &properties)) { + // Try recovery path + if (!load_properties_from_file("/prop.default", nullptr, &properties)) { + // Try legacy path + load_properties_from_file("/default.prop", nullptr, &properties); } - // To read ro.<partition>.build.version.sdk, temporarily load the legacy paths into a - // separate map. Then by comparing its value with legacy_version, we know that if the - // partition is old enough so that we need to respect the legacy paths. - std::map<std::string, std::string> temp; - auto legacy_path1 = "/" + partition + "/default.prop"; - auto legacy_path2 = "/" + partition + "/build.prop"; - load_properties_from_file(legacy_path1.c_str(), nullptr, &temp); - load_properties_from_file(legacy_path2.c_str(), nullptr, &temp); - bool support_legacy_path = false; - auto version_prop_name = "ro." + partition + ".build.version.sdk"; - auto it = temp.find(version_prop_name); - if (it == temp.end()) { - // This is embarassing. Without the prop, we can't determine how old the partition is. - // Let's be conservative by assuming it is very very old. - support_legacy_path = true; - } else if (int value; - ParseInt(it->second.c_str(), &value) && value <= support_legacy_path_until) { - support_legacy_path = true; - } - if (support_legacy_path) { - // We don't update temp into properties directly as it might skip any (future) logic - // for resolving duplicates implemented in load_properties_from_file. Instead, read - // the files again into the properties map. - load_properties_from_file(legacy_path1.c_str(), nullptr, &properties); - load_properties_from_file(legacy_path2.c_str(), nullptr, &properties); - } else { - LOG(FATAL) << legacy_path1 << " and " << legacy_path2 << " were not loaded " - << "because " << version_prop_name << "(" << it->second << ") is newer " - << "than " << support_legacy_path_until; - } - }; - - // Order matters here. The more the partition is specific to a product, the higher its - // precedence is. - LoadPropertiesFromSecondStageRes(&properties); + } load_properties_from_file("/system/build.prop", nullptr, &properties); - load_properties_from_partition("system_ext", /* support_legacy_path_until */ 30); - // TODO(b/117892318): uncomment the following condition when vendor.imgs for aosp_* targets are - // all updated. - // if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_R__) { + load_properties_from_file("/system_ext/build.prop", nullptr, &properties); load_properties_from_file("/vendor/default.prop", nullptr, &properties); - // } load_properties_from_file("/vendor/build.prop", nullptr, &properties); - load_properties_from_file("/vendor_dlkm/etc/build.prop", nullptr, &properties); - load_properties_from_file("/odm_dlkm/etc/build.prop", nullptr, &properties); - load_properties_from_partition("odm", /* support_legacy_path_until */ 28); - load_properties_from_partition("product", /* support_legacy_path_until */ 30); + if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_Q__) { + load_properties_from_file("/odm/etc/build.prop", nullptr, &properties); + } else { + load_properties_from_file("/odm/default.prop", nullptr, &properties); + load_properties_from_file("/odm/build.prop", nullptr, &properties); + } + load_properties_from_file("/product/build.prop", nullptr, &properties); + load_properties_from_file("/factory/factory.prop", "ro.*", &properties); if (access(kDebugRamdiskProp, R_OK) == 0) { LOG(INFO) << "Loading " << kDebugRamdiskProp; @@ -1098,10 +913,7 @@ void PropertyLoadBootDefaults() { } property_initialize_ro_product_props(); - property_initialize_build_id(); property_derive_build_fingerprint(); - property_derive_legacy_build_fingerprint(); - property_initialize_ro_cpu_abilist(); update_sys_usb_config(); } @@ -1133,7 +945,7 @@ void CreateSerializedPropertyInfo() { &property_infos)) { return; } - // Don't check for failure here, since we don't always have all of these partitions. + // Don't check for failure here, so we always have a sane list of properties. // E.g. In case of recovery, the vendor partition will not have mounted and we // still need the system / platform properties to function. if (access("/system_ext/etc/selinux/system_ext_property_contexts", R_OK) != -1) { @@ -1228,23 +1040,22 @@ static void ProcessKernelDt() { } } -constexpr auto ANDROIDBOOT_PREFIX = "androidboot."sv; - static void ProcessKernelCmdline() { + bool for_emulator = false; ImportKernelCmdline([&](const std::string& key, const std::string& value) { - if (StartsWith(key, ANDROIDBOOT_PREFIX)) { - InitPropertySet("ro.boot." + key.substr(ANDROIDBOOT_PREFIX.size()), value); + if (key == "qemu") { + for_emulator = true; + } else if (StartsWith(key, "androidboot.")) { + InitPropertySet("ro.boot." + key.substr(12), value); } }); -} - -static void ProcessBootconfig() { - ImportBootconfig([&](const std::string& key, const std::string& value) { - if (StartsWith(key, ANDROIDBOOT_PREFIX)) { - InitPropertySet("ro.boot." + key.substr(ANDROIDBOOT_PREFIX.size()), value); - } - }); + if (for_emulator) { + ImportKernelCmdline([&](const std::string& key, const std::string& value) { + // In the emulator, export any kernel option with the "ro.kernel." prefix. + InitPropertySet("ro.kernel." + key, value); + }); + } } void PropertyInit() { @@ -1265,7 +1076,6 @@ void PropertyInit() { // properties set in DT always have priority over the command-line ones. ProcessKernelDt(); ProcessKernelCmdline(); - ProcessBootconfig(); // Propagate the kernel variables to internal variables // used by init as well as the current required properties. |