Loading cmds/idmap2/Android.bp +4 −0 Original line number Original line Diff line number Diff line Loading @@ -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-*", Loading @@ -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", Loading cmds/idmap2/idmap2d/Idmap2Service.cpp +34 −10 Original line number Original line Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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) { Loading cmds/idmap2/idmap2d/Idmap2Service.h +14 −1 Original line number Original line Diff line number Diff line Loading @@ -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_; Loading Loading
cmds/idmap2/Android.bp +4 −0 Original line number Original line Diff line number Diff line Loading @@ -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-*", Loading @@ -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", Loading
cmds/idmap2/idmap2d/Idmap2Service.cpp +34 −10 Original line number Original line Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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) { Loading
cmds/idmap2/idmap2d/Idmap2Service.h +14 −1 Original line number Original line Diff line number Diff line Loading @@ -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_; Loading