Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e1ae78cd authored by Kelvin Zhang's avatar Kelvin Zhang
Browse files

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
parent a9fff2f0
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -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<std::string, std::string>* metadata) {
  CHECK(metadata != nullptr);
@@ -151,7 +154,8 @@ static bool CheckAbSpecificMetadata(const std::map<std::string, std::string>& 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<std::string, std::string>& 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();
}
+28 −0
Original line number Diff line number Diff line
@@ -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<std::string>{
          "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<int64_t>::max()),
      },
      "\n");
  TestCheckPackageMetadata(metadata, OtaType::AB, true);

  metadata = android::base::Join(
      std::vector<std::string>{
          "ota-type=AB",
          "pre-device=" + device,
          "pre-build=dummy_build_fingerprint",
          "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::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);