diff options
Diffstat (limited to 'libs/androidfw/AssetManager2.cpp')
-rw-r--r-- | libs/androidfw/AssetManager2.cpp | 147 |
1 files changed, 54 insertions, 93 deletions
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index d604df3565d2..bc46cf5a98ce 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -91,14 +91,13 @@ struct FindEntryResult { StringPoolRef entry_string_ref; }; -AssetManager2::AssetManager2(ApkAssetsList apk_assets, const ResTable_config& configuration) - : configuration_(configuration) { - // Don't invalidate caches here as there's nothing cached yet. - SetApkAssets(apk_assets, false); +AssetManager2::AssetManager2() { + memset(&configuration_, 0, sizeof(configuration_)); } -bool AssetManager2::SetApkAssets(ApkAssetsList apk_assets, bool invalidate_caches) { - BuildDynamicRefTable(apk_assets); +bool AssetManager2::SetApkAssets(std::vector<const ApkAssets*> apk_assets, bool invalidate_caches) { + apk_assets_ = std::move(apk_assets); + BuildDynamicRefTable(); RebuildFilterList(); if (invalidate_caches) { InvalidateCaches(static_cast<uint32_t>(-1)); @@ -106,13 +105,7 @@ bool AssetManager2::SetApkAssets(ApkAssetsList apk_assets, bool invalidate_cache return true; } -bool AssetManager2::SetApkAssets(std::initializer_list<ApkAssetsPtr> apk_assets, - bool invalidate_caches) { - return SetApkAssets(ApkAssetsList(apk_assets.begin(), apk_assets.size()), invalidate_caches); -} - -void AssetManager2::BuildDynamicRefTable(ApkAssetsList apk_assets) { - apk_assets_.assign(apk_assets.begin(), apk_assets.end()); +void AssetManager2::BuildDynamicRefTable() { package_groups_.clear(); package_ids_.fill(0xff); @@ -123,19 +116,16 @@ void AssetManager2::BuildDynamicRefTable(ApkAssetsList apk_assets) { // Overlay resources are not directly referenced by an application so their resource ids // can change throughout the application's lifetime. Assign overlay package ids last. - std::vector<const ApkAssets*> sorted_apk_assets; - sorted_apk_assets.reserve(apk_assets_.size()); - for (auto& asset : apk_assets) { - sorted_apk_assets.push_back(asset.get()); - } - std::stable_partition(sorted_apk_assets.begin(), sorted_apk_assets.end(), - [](auto a) { return !a->IsOverlay(); }); + std::vector<const ApkAssets*> sorted_apk_assets(apk_assets_); + std::stable_partition(sorted_apk_assets.begin(), sorted_apk_assets.end(), [](const ApkAssets* a) { + return !a->IsOverlay(); + }); // The assets cookie must map to the position of the apk assets in the unsorted apk assets list. std::unordered_map<const ApkAssets*, ApkAssetsCookie> apk_assets_cookies; - apk_assets_cookies.reserve(apk_assets.size()); - for (size_t i = 0, n = apk_assets.size(); i < n; i++) { - apk_assets_cookies[apk_assets[i].get()] = static_cast<ApkAssetsCookie>(i); + apk_assets_cookies.reserve(apk_assets_.size()); + for (size_t i = 0, n = apk_assets_.size(); i < n; i++) { + apk_assets_cookies[apk_assets_[i]] = static_cast<ApkAssetsCookie>(i); } // 0x01 is reserved for the android package. @@ -252,8 +242,7 @@ void AssetManager2::DumpToLog() const { std::string list; for (const auto& apk_assets : apk_assets_) { - auto assets = apk_assets.promote(); - base::StringAppendF(&list, "%s,", assets ? assets->GetDebugName().c_str() : "nullptr"); + base::StringAppendF(&list, "%s,", apk_assets->GetDebugName().c_str()); } LOG(INFO) << "ApkAssets: " << list; @@ -290,8 +279,7 @@ const ResStringPool* AssetManager2::GetStringPoolForCookie(ApkAssetsCookie cooki if (cookie < 0 || static_cast<size_t>(cookie) >= apk_assets_.size()) { return nullptr; } - auto assets = apk_assets_[cookie].promote(); - return assets ? assets->GetLoadedArsc()->GetStringPool() : nullptr; + return apk_assets_[cookie]->GetLoadedArsc()->GetStringPool(); } const DynamicRefTable* AssetManager2::GetDynamicRefTableForPackage(uint32_t package_id) const { @@ -343,11 +331,7 @@ bool AssetManager2::GetOverlayablesToString(android::StringPiece package_name, std::string* out) const { uint8_t package_id = 0U; for (const auto& apk_assets : apk_assets_) { - auto assets = apk_assets.promote(); - if (!assets) { - continue; - } - const LoadedArsc* loaded_arsc = assets->GetLoadedArsc(); + const LoadedArsc* loaded_arsc = apk_assets->GetLoadedArsc(); if (loaded_arsc == nullptr) { continue; } @@ -400,10 +384,8 @@ bool AssetManager2::GetOverlayablesToString(android::StringPiece package_name, } bool AssetManager2::ContainsAllocatedTable() const { - return std::find_if(apk_assets_.begin(), apk_assets_.end(), [](auto&& assets_weak) { - auto assets = assets_weak.promote(); - return assets && assets->IsTableAllocated(); - }) != apk_assets_.end(); + return std::find_if(apk_assets_.begin(), apk_assets_.end(), + std::mem_fn(&ApkAssets::IsTableAllocated)) != apk_assets_.end(); } void AssetManager2::SetConfiguration(const ResTable_config& configuration) { @@ -416,8 +398,8 @@ void AssetManager2::SetConfiguration(const ResTable_config& configuration) { } } -std::set<AssetManager2::ApkAssetsPtr> AssetManager2::GetNonSystemOverlays() const { - std::set<ApkAssetsPtr> non_system_overlays; +std::set<const ApkAssets*> AssetManager2::GetNonSystemOverlays() const { + std::set<const ApkAssets*> non_system_overlays; for (const PackageGroup& package_group : package_groups_) { bool found_system_package = false; for (const ConfiguredPackage& package : package_group.packages_) { @@ -429,9 +411,7 @@ std::set<AssetManager2::ApkAssetsPtr> AssetManager2::GetNonSystemOverlays() cons if (!found_system_package) { for (const ConfiguredOverlay& overlay : package_group.overlays_) { - if (auto asset = apk_assets_[overlay.cookie].promote()) { - non_system_overlays.insert(std::move(asset)); - } + non_system_overlays.insert(apk_assets_[overlay.cookie]); } } } @@ -443,24 +423,21 @@ base::expected<std::set<ResTable_config>, IOError> AssetManager2::GetResourceCon bool exclude_system, bool exclude_mipmap) const { ATRACE_NAME("AssetManager::GetResourceConfigurations"); const auto non_system_overlays = - exclude_system ? GetNonSystemOverlays() : std::set<ApkAssetsPtr>(); + (exclude_system) ? GetNonSystemOverlays() : std::set<const ApkAssets*>(); std::set<ResTable_config> configurations; for (const PackageGroup& package_group : package_groups_) { for (size_t i = 0; i < package_group.packages_.size(); i++) { const ConfiguredPackage& package = package_group.packages_[i]; - if (exclude_system) { - if (package.loaded_package_->IsSystem()) { - continue; - } - if (!non_system_overlays.empty()) { - // Exclude overlays that target only system resources. - auto apk_assets = apk_assets_[package_group.cookies_[i]].promote(); - if (apk_assets && apk_assets->IsOverlay() && - non_system_overlays.find(apk_assets) == non_system_overlays.end()) { - continue; - } - } + if (exclude_system && package.loaded_package_->IsSystem()) { + continue; + } + + auto apk_assets = apk_assets_[package_group.cookies_[i]]; + if (exclude_system && apk_assets->IsOverlay() && + non_system_overlays.find(apk_assets) == non_system_overlays.end()) { + // Exclude overlays that target system resources. + continue; } auto result = package.loaded_package_->CollectConfigurations(exclude_mipmap, &configurations); @@ -477,23 +454,20 @@ std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system, ATRACE_NAME("AssetManager::GetResourceLocales"); std::set<std::string> locales; const auto non_system_overlays = - exclude_system ? GetNonSystemOverlays() : std::set<ApkAssetsPtr>(); + (exclude_system) ? GetNonSystemOverlays() : std::set<const ApkAssets*>(); for (const PackageGroup& package_group : package_groups_) { for (size_t i = 0; i < package_group.packages_.size(); i++) { const ConfiguredPackage& package = package_group.packages_[i]; - if (exclude_system) { - if (package.loaded_package_->IsSystem()) { - continue; - } - if (!non_system_overlays.empty()) { - // Exclude overlays that target only system resources. - auto apk_assets = apk_assets_[package_group.cookies_[i]].promote(); - if (apk_assets && apk_assets->IsOverlay() && - non_system_overlays.find(apk_assets) == non_system_overlays.end()) { - continue; - } - } + if (exclude_system && package.loaded_package_->IsSystem()) { + continue; + } + + auto apk_assets = apk_assets_[package_group.cookies_[i]]; + if (exclude_system && apk_assets->IsOverlay() && + non_system_overlays.find(apk_assets) == non_system_overlays.end()) { + // Exclude overlays that target system resources. + continue; } package.loaded_package_->CollectLocales(merge_equivalent_languages, &locales); @@ -518,12 +492,13 @@ std::unique_ptr<AssetDir> AssetManager2::OpenDir(const std::string& dirname) con ATRACE_NAME("AssetManager::OpenDir"); std::string full_path = "assets/" + dirname; - auto files = util::make_unique<SortedVector<AssetDir::FileInfo>>(); + std::unique_ptr<SortedVector<AssetDir::FileInfo>> files = + util::make_unique<SortedVector<AssetDir::FileInfo>>(); // Start from the back. for (auto iter = apk_assets_.rbegin(); iter != apk_assets_.rend(); ++iter) { - auto apk_assets = iter->promote(); - if (!apk_assets || apk_assets->IsOverlay()) { + const ApkAssets* apk_assets = *iter; + if (apk_assets->IsOverlay()) { continue; } @@ -552,15 +527,14 @@ std::unique_ptr<Asset> AssetManager2::OpenNonAsset(const std::string& filename, Asset::AccessMode mode, ApkAssetsCookie* out_cookie) const { for (int32_t i = apk_assets_.size() - 1; i >= 0; i--) { - const auto assets = apk_assets_[i].promote(); // Prevent RRO from modifying assets and other entries accessed by file // path. Explicitly asking for a path in a given package (denoted by a // cookie) is still OK. - if (!assets || assets->IsOverlay()) { + if (apk_assets_[i]->IsOverlay()) { continue; } - std::unique_ptr<Asset> asset = assets->GetAssetsProvider()->Open(filename, mode); + std::unique_ptr<Asset> asset = apk_assets_[i]->GetAssetsProvider()->Open(filename, mode); if (asset) { if (out_cookie != nullptr) { *out_cookie = i; @@ -581,8 +555,7 @@ std::unique_ptr<Asset> AssetManager2::OpenNonAsset(const std::string& filename, if (cookie < 0 || static_cast<size_t>(cookie) >= apk_assets_.size()) { return {}; } - auto assets = apk_assets_[cookie].promote(); - return assets ? assets->GetAssetsProvider()->Open(filename, mode) : nullptr; + return apk_assets_[cookie]->GetAssetsProvider()->Open(filename, mode); } base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( @@ -630,12 +603,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( } bool overlaid = false; - auto assets = apk_assets_[result->cookie].promote(); - if (!assets) { - ALOGE("Found expired ApkAssets #%d for resource ID 0x%08x.", result->cookie, resid); - return base::unexpected(std::nullopt); - } - if (!stop_at_first_match && !ignore_configuration && !assets->IsLoader()) { + if (!stop_at_first_match && !ignore_configuration && !apk_assets_[result->cookie]->IsLoader()) { for (const auto& id_map : package_group.overlays_) { auto overlay_entry = id_map.overlay_res_maps_.Lookup(resid); if (!overlay_entry) { @@ -665,7 +633,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( if (UNLIKELY(logging_enabled)) { last_resolution_.steps.push_back( Resolution::Step{Resolution::Step::Type::OVERLAID_INLINE, result->cookie, String8()}); - if (auto path = assets->GetPath()) { + if (auto path = apk_assets_[result->cookie]->GetPath()) { const std::string overlay_path = path->data(); if (IsFabricatedOverlay(overlay_path)) { // FRRO don't have package name so we use the creating package here. @@ -891,9 +859,7 @@ std::string AssetManager2::GetLastResourceResolution() const { } const uint32_t resid = last_resolution_.resid; - auto assets = apk_assets_[cookie].promote(); - const auto package = - assets ? assets->GetLoadedArsc()->GetPackageById(get_package_id(resid)) : nullptr; + const auto package = apk_assets_[cookie]->GetLoadedArsc()->GetPackageById(get_package_id(resid)); std::string resource_name_string; if (package != nullptr) { @@ -924,9 +890,7 @@ std::string AssetManager2::GetLastResourceResolution() const { continue; } const auto prefix = kStepStrings[int(step.type) - int(Resolution::Step::Type::INITIAL)]; - auto assets = apk_assets_[step.cookie].promote(); - log_stream << "\n\t" << prefix << ": " << (assets ? assets->GetDebugName() : "<null>") - << " #" << step.cookie; + log_stream << "\n\t" << prefix << ": " << apk_assets_[step.cookie]->GetDebugName(); if (!step.config_name.isEmpty()) { log_stream << " - " << step.config_name; } @@ -1591,14 +1555,11 @@ base::expected<std::monostate, IOError> Theme::SetTo(const Theme& source) { // Determine which ApkAssets are loaded in both theme AssetManagers. const auto& src_assets = source.asset_manager_->GetApkAssets(); for (size_t i = 0; i < src_assets.size(); i++) { - auto src_asset = src_assets[i].promote(); - if (!src_asset) { - continue; - } + const ApkAssets* src_asset = src_assets[i]; const auto& dest_assets = asset_manager_->GetApkAssets(); for (size_t j = 0; j < dest_assets.size(); j++) { - auto dest_asset = dest_assets[j].promote(); + const ApkAssets* dest_asset = dest_assets[j]; if (src_asset != dest_asset) { // ResourcesManager caches and reuses ApkAssets when the same apk must be present in // multiple AssetManagers. Two ApkAssets point to the same version of the same resources |