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

Commit 972f2efb authored by Ryan Mitchell's avatar Ryan Mitchell Committed by Automerger Merge Worker
Browse files

Merge "Reduce OMS start time" into rvc-dev am: 84a84ac6 am: 04fa9c9f

Change-Id: If7cd95e2da133e259315df76c118fa25a9025f59
parents 4b444f45 04fa9c9f
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -34,11 +34,13 @@
#include "idmap2/FileUtils.h"
#include "idmap2/Idmap.h"
#include "idmap2/SysTrace.h"
#include "idmap2/ZipFile.h"
#include "utils/String8.h"

using android::IPCThreadState;
using android::binder::Status;
using android::idmap2::BinaryStreamVisitor;
using android::idmap2::GetPackageCrc;
using android::idmap2::Idmap;
using android::idmap2::IdmapHeader;
using android::idmap2::utils::kIdmapCacheDir;
@@ -49,6 +51,8 @@ using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask

namespace {

constexpr const char* kFrameworkPath = "/system/framework/framework-res.apk";

Status ok() {
  return Status::ok();
}
@@ -109,8 +113,32 @@ Status Idmap2Service::verifyIdmap(const std::string& target_apk_path,
    return error("failed to parse idmap header");
  }

  *_aidl_return =
      strcmp(header->GetTargetPath().data(), target_apk_path.data()) == 0 && header->IsUpToDate();
  if (strcmp(header->GetTargetPath().data(), target_apk_path.data()) != 0) {
    *_aidl_return = false;
    return ok();
  }

  if (target_apk_path != kFrameworkPath) {
    *_aidl_return = (bool) header->IsUpToDate();
  } else {
    if (!android_crc_) {
      // Loading the framework zip can take several milliseconds. Cache the crc of the framework
      // resource APK to reduce repeated work during boot.
      const auto target_zip = idmap2::ZipFile::Open(target_apk_path);
      if (!target_zip) {
        return error(base::StringPrintf("failed to open target %s", target_apk_path.c_str()));
      }

      const auto target_crc = GetPackageCrc(*target_zip);
      if (!target_crc) {
        return error(target_crc.GetErrorMessage());
      }

      android_crc_ = *target_crc;
    }

    *_aidl_return = (bool) header->IsUpToDate(android_crc_.value());
  }

  // TODO(b/119328308): Check that the set of fulfilled policies of the overlay has not changed
  return ok();
+4 −0
Original line number Diff line number Diff line
@@ -46,6 +46,10 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 {
                             const std::string& overlay_apk_path, int32_t fulfilled_policies,
                             bool enforce_overlayable, int32_t user_id,
                             aidl::nullable<std::string>* _aidl_return) override;

 private:
  // Cache the crc of the android framework package since the crc cannot change without a reboot.
  std::optional<uint32_t> android_crc_;
};

}  // namespace android::os
+5 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
#include "idmap2/ResourceMapping.h"
#include "idmap2/ZipFile.h"

namespace android::idmap2 {

@@ -93,6 +94,9 @@ static constexpr const uint32_t kIdmapCurrentVersion = android::kIdmapCurrentVer
// terminating null)
static constexpr const size_t kIdmapStringLength = 256;

// Retrieves a crc generated using all of the files within the zip that can affect idmap generation.
Result<uint32_t> GetPackageCrc(const ZipFile& zip_info);

class IdmapHeader {
 public:
  static std::unique_ptr<const IdmapHeader> FromBinaryStream(std::istream& stream);
@@ -129,6 +133,7 @@ class IdmapHeader {
  // field *must* be incremented. Because of this, we know that if the idmap
  // header is up-to-date the entire file is up-to-date.
  Result<Unit> IsUpToDate() const;
  Result<Unit> IsUpToDate(uint32_t target_crc_) const;

  void accept(Visitor* v) const;

+21 −17
Original line number Diff line number Diff line
@@ -100,7 +100,9 @@ Result<std::string> ReadString(std::istream& stream) {
  return buf;
}

Result<uint32_t> GetCrc(const ZipFile& zip) {
}  // namespace

Result<uint32_t> GetPackageCrc(const ZipFile& zip) {
  const Result<uint32_t> a = zip.Crc("resources.arsc");
  const Result<uint32_t> b = zip.Crc("AndroidManifest.xml");
  return a && b
@@ -108,8 +110,6 @@ Result<uint32_t> GetCrc(const ZipFile& zip) {
             : Error("failed to get CRC for \"%s\"", a ? "AndroidManifest.xml" : "resources.arsc");
}

}  // namespace

std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) {
  std::unique_ptr<IdmapHeader> idmap_header(new IdmapHeader());

@@ -130,27 +130,31 @@ std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& s
}

Result<Unit> IdmapHeader::IsUpToDate() const {
  if (magic_ != kIdmapMagic) {
    return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic);
  }

  if (version_ != kIdmapCurrentVersion) {
    return Error("bad version: actual 0x%08x, expected 0x%08x", version_, kIdmapCurrentVersion);
  }

  const std::unique_ptr<const ZipFile> target_zip = ZipFile::Open(target_path_);
  if (!target_zip) {
    return Error("failed to open target %s", GetTargetPath().to_string().c_str());
  }

  Result<uint32_t> target_crc = GetCrc(*target_zip);
  Result<uint32_t> target_crc = GetPackageCrc(*target_zip);
  if (!target_crc) {
    return Error("failed to get target crc");
  }

  if (target_crc_ != *target_crc) {
  return IsUpToDate(*target_crc);
}

Result<Unit> IdmapHeader::IsUpToDate(uint32_t target_crc) const {
  if (magic_ != kIdmapMagic) {
    return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic);
  }

  if (version_ != kIdmapCurrentVersion) {
    return Error("bad version: actual 0x%08x, expected 0x%08x", version_, kIdmapCurrentVersion);
  }

  if (target_crc_ != target_crc) {
    return Error("bad target crc: idmap version 0x%08x, file system version 0x%08x", target_crc_,
                 *target_crc);
                 target_crc);
  }

  const std::unique_ptr<const ZipFile> overlay_zip = ZipFile::Open(overlay_path_);
@@ -158,7 +162,7 @@ Result<Unit> IdmapHeader::IsUpToDate() const {
    return Error("failed to open overlay %s", GetOverlayPath().to_string().c_str());
  }

  Result<uint32_t> overlay_crc = GetCrc(*overlay_zip);
  Result<uint32_t> overlay_crc = GetPackageCrc(*overlay_zip);
  if (!overlay_crc) {
    return Error("failed to get overlay crc");
  }
@@ -304,13 +308,13 @@ Result<std::unique_ptr<const Idmap>> Idmap::FromApkAssets(const ApkAssets& targe
  header->magic_ = kIdmapMagic;
  header->version_ = kIdmapCurrentVersion;

  Result<uint32_t> crc = GetCrc(*target_zip);
  Result<uint32_t> crc = GetPackageCrc(*target_zip);
  if (!crc) {
    return Error(crc.GetError(), "failed to get zip CRC for target");
  }
  header->target_crc_ = *crc;

  crc = GetCrc(*overlay_zip);
  crc = GetPackageCrc(*overlay_zip);
  if (!crc) {
    return Error(crc.GetError(), "failed to get zip CRC for overlay");
  }
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ class IdmapDaemon {

    // The amount of time in milliseconds to wait when attempting to connect to idmap service.
    private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000;
    private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 200;
    private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 5;

    private static final String IDMAP_DAEMON = "idmap2d";

Loading