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

Commit a33cd07e authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi Committed by Android (Google) Code Review
Browse files

Merge "[idmap] Cache target apks as they are often reused"

parents ec0b89f5 70ded194
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -28,11 +28,14 @@ cc_defaults {
    tidy_checks: [
    tidy_checks: [
        "modernize-*",
        "modernize-*",
        "-modernize-avoid-c-arrays",
        "-modernize-avoid-c-arrays",
        "-modernize-use-nodiscard",
        "-modernize-use-trailing-return-type",
        "-modernize-use-trailing-return-type",
        "android-*",
        "android-*",
        "misc-*",
        "misc-*",
        "-misc-const-correctness",
        "readability-*",
        "readability-*",
        "-readability-identifier-length",
        "-readability-identifier-length",
        "-readability-implicit-bool-conversion",
    ],
    ],
    tidy_checks_as_errors: [
    tidy_checks_as_errors: [
        "modernize-*",
        "modernize-*",
@@ -56,6 +59,7 @@ cc_defaults {
        "-readability-const-return-type",
        "-readability-const-return-type",
        "-readability-convert-member-functions-to-static",
        "-readability-convert-member-functions-to-static",
        "-readability-duplicate-include",
        "-readability-duplicate-include",
        "-readability-implicit-bool-conversion",
        "-readability-else-after-return",
        "-readability-else-after-return",
        "-readability-named-parameter",
        "-readability-named-parameter",
        "-readability-redundant-access-specifiers",
        "-readability-redundant-access-specifiers",
+34 −10
Original line number Original line Diff line number Diff line
@@ -59,7 +59,7 @@ using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask


namespace {
namespace {


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


Status ok() {
Status ok() {
  return Status::ok();
  return Status::ok();
@@ -207,25 +207,49 @@ Status Idmap2Service::createIdmap(const std::string& target_path, const std::str


idmap2::Result<Idmap2Service::TargetResourceContainerPtr> Idmap2Service::GetTargetContainer(
idmap2::Result<Idmap2Service::TargetResourceContainerPtr> Idmap2Service::GetTargetContainer(
    const std::string& target_path) {
    const std::string& target_path) {
  if (target_path == kFrameworkPath) {
  const bool is_framework = target_path == kFrameworkPath;
    if (framework_apk_cache_ == nullptr) {
  bool use_cache;
      // Initialize the framework APK cache.
  struct stat st = {};
      auto target = TargetResourceContainer::FromPath(target_path);
  if (is_framework || !::stat(target_path.c_str(), &st)) {
      if (!target) {
    use_cache = true;
        return target.GetError();
  } else {
    LOG(WARNING) << "failed to stat target path '" << target_path << "' for the cache";
    use_cache = false;
  }
  }
      framework_apk_cache_ = std::move(*target);

  if (use_cache) {
    std::lock_guard lock(container_cache_mutex_);
    if (auto cache_it = container_cache_.find(target_path); cache_it != container_cache_.end()) {
      const auto& item = cache_it->second;
      if (is_framework ||
        (item.dev == st.st_dev && item.inode == st.st_ino && item.size == st.st_size
          && item.mtime.tv_sec == st.st_mtim.tv_sec && item.mtime.tv_nsec == st.st_mtim.tv_nsec)) {
        return {item.apk.get()};
      }
      container_cache_.erase(cache_it);
    }
    }
    return {framework_apk_cache_.get()};
  }
  }


  auto target = TargetResourceContainer::FromPath(target_path);
  auto target = TargetResourceContainer::FromPath(target_path);
  if (!target) {
  if (!target) {
    return target.GetError();
    return target.GetError();
  }
  }
  if (!use_cache) {
    return {std::move(*target)};
    return {std::move(*target)};
  }
  }


  const auto res = target->get();
  std::lock_guard lock(container_cache_mutex_);
  container_cache_.emplace(target_path, CachedContainer {
    .dev = dev_t(st.st_dev),
    .inode = ino_t(st.st_ino),
    .size = st.st_size,
    .mtime = st.st_mtim,
    .apk = std::move(*target)
  });
  return {res};
}

Status Idmap2Service::createFabricatedOverlay(
Status Idmap2Service::createFabricatedOverlay(
    const os::FabricatedOverlayInternal& overlay,
    const os::FabricatedOverlayInternal& overlay,
    std::optional<os::FabricatedOverlayInfo>* _aidl_return) {
    std::optional<os::FabricatedOverlayInfo>* _aidl_return) {
+14 −1
Original line number Original line Diff line number Diff line
@@ -75,7 +75,20 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 {
 private:
 private:
  // idmap2d is killed after a period of inactivity, so any information stored on this class should
  // idmap2d is killed after a period of inactivity, so any information stored on this class should
  // be able to be recalculated if idmap2 dies and restarts.
  // be able to be recalculated if idmap2 dies and restarts.
  std::unique_ptr<idmap2::TargetResourceContainer> framework_apk_cache_;

  // A cache item for the resource containers (apks or frros), with all information needed to
  // detect if it has changed since it was parsed:
  //  - (dev, inode) pair uniquely identifies a file on a particular device partition (see stat(2)).
  //  - (mtime, size) ensure the file data hasn't changed inside that file.
  struct CachedContainer {
    dev_t dev;
    ino_t inode;
    int64_t size;
    struct timespec mtime;
    std::unique_ptr<idmap2::TargetResourceContainer> apk;
  };
  std::unordered_map<std::string, CachedContainer> container_cache_;
  std::mutex container_cache_mutex_;


  int32_t frro_iter_id_ = 0;
  int32_t frro_iter_id_ = 0;
  std::optional<std::filesystem::directory_iterator> frro_iter_;
  std::optional<std::filesystem::directory_iterator> frro_iter_;