From e1ae78cd547d68192df7803a86bbffee6ed52703 Mon Sep 17 00:00:00 2001 From: Kelvin Zhang Date: Fri, 26 Jun 2020 11:06:00 -0400 Subject: Add recovery support of dynamic fingerprints After http://go/aog/1306461, the metadata in the OTA package can have multiple fingerprints or device names e.g. from pre-device=lmiin to pre-device=lmiin|lmiinpro This CL updates recovery code to recognize them Test: Added unit tests for this Bug: 159850736 Change-Id: If6315bf2d3dea77abb9d7d83145f55b0148cdfb1 --- install/install.cpp | 26 +++++++++++++++++++++++--- tests/unit/install_test.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/install/install.cpp b/install/install.cpp index d404997dc..1c711f6b3 100644 --- a/install/install.cpp +++ b/install/install.cpp @@ -67,8 +67,11 @@ static_assert(kRecoveryApiVersion == RECOVERY_API_VERSION, "Mismatching recovery // Default allocation of progress bar segments to operations static constexpr int VERIFICATION_PROGRESS_TIME = 60; static constexpr float VERIFICATION_PROGRESS_FRACTION = 0.25; - +// The charater used to separate dynamic fingerprints. e.x. sargo|aosp-sargo +static const char* FINGERPRING_SEPARATOR = "|"; static std::condition_variable finish_log_temperature; +static bool isInStringList(const std::string& target_token, const std::string& str_list, + const std::string& deliminator); bool ReadMetadataFromPackage(ZipArchiveHandle zip, std::map* metadata) { CHECK(metadata != nullptr); @@ -151,7 +154,8 @@ static bool CheckAbSpecificMetadata(const std::map& me auto device_fingerprint = android::base::GetProperty("ro.build.fingerprint", ""); auto pkg_pre_build_fingerprint = get_value(metadata, "pre-build"); - if (!pkg_pre_build_fingerprint.empty() && pkg_pre_build_fingerprint != device_fingerprint) { + if (!pkg_pre_build_fingerprint.empty() && + !isInStringList(device_fingerprint, pkg_pre_build_fingerprint, FINGERPRING_SEPARATOR)) { LOG(ERROR) << "Package is for source build " << pkg_pre_build_fingerprint << " but expected " << device_fingerprint; return false; @@ -199,7 +203,8 @@ bool CheckPackageMetadata(const std::map& metadata, Ot auto device = android::base::GetProperty("ro.product.device", ""); auto pkg_device = get_value(metadata, "pre-device"); - if (pkg_device != device || pkg_device.empty()) { + // device name can be a | separated list, so need to check + if (pkg_device.empty() || !isInStringList(device, pkg_device, FINGERPRING_SEPARATOR)) { LOG(ERROR) << "Package is for product " << pkg_device << " but expected " << device; return false; } @@ -699,3 +704,18 @@ bool SetupPackageMount(const std::string& package_path, bool* should_use_fuse) { } return true; } + +// Check if `target_token` is in string `str_list`, where `str_list` is expected to be a +// list delimited by `deliminator` +// E.X. isInStringList("a", "a|b|c|d", "|") => true +// E.X. isInStringList("abc", "abc", "|") => true +static bool isInStringList(const std::string& target_token, const std::string& str_list, + const std::string& deliminator) { + if (target_token.length() > str_list.length()) { + return false; + } else if (target_token.length() == str_list.length() || deliminator.length() == 0) { + return target_token == str_list; + } + auto&& list = android::base::Split(str_list, deliminator); + return std::find(list.begin(), list.end(), target_token) != list.end(); +} diff --git a/tests/unit/install_test.cpp b/tests/unit/install_test.cpp index ee753494c..90c4b1409 100644 --- a/tests/unit/install_test.cpp +++ b/tests/unit/install_test.cpp @@ -466,6 +466,34 @@ TEST(InstallTest, CheckPackageMetadata_ab_fingerprint) { TestCheckPackageMetadata(metadata, OtaType::AB, false); } +TEST(InstallTest, CheckPackageMetadata_dynamic_fingerprint) { + std::string device = android::base::GetProperty("ro.product.device", ""); + ASSERT_FALSE(device.empty()); + + std::string finger_print = android::base::GetProperty("ro.build.fingerprint", ""); + ASSERT_FALSE(finger_print.empty()); + + std::string metadata = android::base::Join( + std::vector{ + "ota-type=AB", + "pre-device=please|work|" + device + "|please|work", + "pre-build=" + finger_print = "pass|this|test", + "post-timestamp=" + std::to_string(std::numeric_limits::max()), + }, + "\n"); + TestCheckPackageMetadata(metadata, OtaType::AB, true); + + metadata = android::base::Join( + std::vector{ + "ota-type=AB", + "pre-device=" + device, + "pre-build=dummy_build_fingerprint", + "post-timestamp=" + std::to_string(std::numeric_limits::max()), + }, + "\n"); + TestCheckPackageMetadata(metadata, OtaType::AB, false); +} + TEST(InstallTest, CheckPackageMetadata_ab_post_timestamp) { std::string device = android::base::GetProperty("ro.product.device", ""); ASSERT_NE("", device); -- cgit v1.2.3