diff options
author | Ryan Mitchell <rtmitchell@google.com> | 2020-03-27 17:49:56 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-03-27 17:49:56 +0000 |
commit | 376991173605dd7441ec9f880ccc3410a9c81931 (patch) | |
tree | 19eac4f40d6131f49f133646a36ab547a0671c59 /libs/androidfw | |
parent | 74f0a82390513835a623d6c3c7779985d93d6057 (diff) | |
parent | 8275fb7d66ff7959ba0cea0e721921c54a0b8c2d (diff) |
Merge changes If7ea17d5,If6364fd6 into rvc-dev am: 8275fb7d66
Change-Id: Iaa34df4fc6cce09177547a11497d28fa1ce9cdb5
Diffstat (limited to 'libs/androidfw')
-rw-r--r-- | libs/androidfw/Android.bp | 1 | ||||
-rw-r--r-- | libs/androidfw/AssetManager2.cpp | 73 | ||||
-rw-r--r-- | libs/androidfw/DynamicLibManager.cpp | 34 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/AssetManager2.h | 13 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/DynamicLibManager.h | 48 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/MutexGuard.h | 3 | ||||
-rw-r--r-- | libs/androidfw/tests/AssetManager2_test.cpp | 63 |
7 files changed, 64 insertions, 171 deletions
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp index f87f98a59a12..02c85aa34f4b 100644 --- a/libs/androidfw/Android.bp +++ b/libs/androidfw/Android.bp @@ -44,7 +44,6 @@ cc_library { "AttributeResolution.cpp", "ChunkIterator.cpp", "ConfigDescription.cpp", - "DynamicLibManager.cpp", "Idmap.cpp", "LoadedArsc.cpp", "Locale.cpp", diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index f20e18453f8b..eaf452b5fa71 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -25,7 +25,6 @@ #include "android-base/logging.h" #include "android-base/stringprintf.h" -#include "androidfw/DynamicLibManager.h" #include "androidfw/ResourceUtils.h" #include "androidfw/Util.h" #include "utils/ByteOrder.h" @@ -67,12 +66,7 @@ struct FindEntryResult { StringPoolRef entry_string_ref; }; -AssetManager2::AssetManager2() : dynamic_lib_manager_(std::make_unique<DynamicLibManager>()) { - memset(&configuration_, 0, sizeof(configuration_)); -} - -AssetManager2::AssetManager2(DynamicLibManager* dynamic_lib_manager) - : dynamic_lib_manager_(dynamic_lib_manager) { +AssetManager2::AssetManager2() { memset(&configuration_, 0, sizeof(configuration_)); } @@ -91,6 +85,9 @@ void AssetManager2::BuildDynamicRefTable() { package_groups_.clear(); package_ids_.fill(0xff); + // A mapping from apk assets path to the runtime package id of its first loaded package. + std::unordered_map<std::string, uint8_t> apk_assets_package_ids; + // 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(apk_assets_); @@ -98,37 +95,25 @@ void AssetManager2::BuildDynamicRefTable() { return !a->IsOverlay(); }); - std::unordered_map<std::string, uint8_t> apk_assets_package_ids; - std::unordered_map<std::string, uint8_t> package_name_package_ids; - - // Assign stable package ids to application packages. - uint8_t next_available_package_id = 0U; - for (const auto& apk_assets : sorted_apk_assets) { - for (const auto& package : apk_assets->GetLoadedArsc()->GetPackages()) { - uint8_t package_id = package->GetPackageId(); - if (package->IsOverlay()) { - package_id = GetDynamicLibManager()->FindUnassignedId(next_available_package_id); - next_available_package_id = package_id + 1; - } else if (package->IsDynamic()) { - package_id = GetDynamicLibManager()->GetAssignedId(package->GetPackageName()); - } - - // Map the path of the apk assets to the package id of its first loaded package. - apk_assets_package_ids[apk_assets->GetPath()] = package_id; - - // Map the package name of the package to the first loaded package with that package id. - package_name_package_ids[package->GetPackageName()] = package_id; - } + // 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]] = static_cast<ApkAssetsCookie>(i); } - const int apk_assets_count = apk_assets_.size(); - for (int i = 0; i < apk_assets_count; i++) { - const auto& apk_assets = apk_assets_[i]; - for (const auto& package : apk_assets->GetLoadedArsc()->GetPackages()) { - const auto package_id_entry = package_name_package_ids.find(package->GetPackageName()); - CHECK(package_id_entry != package_name_package_ids.end()) - << "no package id assgined to package " << package->GetPackageName(); - const uint8_t package_id = package_id_entry->second; + // 0x01 is reserved for the android package. + int next_package_id = 0x02; + for (const ApkAssets* apk_assets : sorted_apk_assets) { + const LoadedArsc* loaded_arsc = apk_assets->GetLoadedArsc(); + for (const std::unique_ptr<const LoadedPackage>& package : loaded_arsc->GetPackages()) { + // Get the package ID or assign one if a shared library. + int package_id; + if (package->IsDynamic()) { + package_id = next_package_id++; + } else { + package_id = package->GetPackageId(); + } // Add the mapping for package ID to index if not present. uint8_t idx = package_ids_[package_id]; @@ -162,7 +147,7 @@ void AssetManager2::BuildDynamicRefTable() { target_package_group.overlays_.push_back( ConfiguredOverlay{loaded_idmap->GetTargetResourcesMap(target_package_id, overlay_table.get()), - static_cast<ApkAssetsCookie>(i)}); + apk_assets_cookies[apk_assets]}); } } @@ -174,7 +159,7 @@ void AssetManager2::BuildDynamicRefTable() { // Add the package and to the set of packages with the same ID. package_group->packages_.push_back(ConfiguredPackage{package.get(), {}}); - package_group->cookies_.push_back(static_cast<ApkAssetsCookie>(i)); + package_group->cookies_.push_back(apk_assets_cookies[apk_assets]); // Add the package name -> build time ID mappings. for (const DynamicPackageEntry& entry : package->GetDynamicPackageMap()) { @@ -182,6 +167,8 @@ void AssetManager2::BuildDynamicRefTable() { package_group->dynamic_ref_table->mEntries.replaceValueFor( package_name, static_cast<uint8_t>(entry.package_id)); } + + apk_assets_package_ids.insert(std::make_pair(apk_assets->GetPath(), package_id)); } } @@ -1329,16 +1316,6 @@ uint8_t AssetManager2::GetAssignedPackageId(const LoadedPackage* package) const return 0; } -DynamicLibManager* AssetManager2::GetDynamicLibManager() const { - auto dynamic_lib_manager = - std::get_if<std::unique_ptr<DynamicLibManager>>(&dynamic_lib_manager_); - if (dynamic_lib_manager) { - return (*dynamic_lib_manager).get(); - } else { - return *std::get_if<DynamicLibManager*>(&dynamic_lib_manager_); - } -} - std::unique_ptr<Theme> AssetManager2::NewTheme() { return std::unique_ptr<Theme>(new Theme(this)); } diff --git a/libs/androidfw/DynamicLibManager.cpp b/libs/androidfw/DynamicLibManager.cpp deleted file mode 100644 index 895b7695bf26..000000000000 --- a/libs/androidfw/DynamicLibManager.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "androidfw/DynamicLibManager.h" - -namespace android { - -uint8_t DynamicLibManager::GetAssignedId(const std::string& library_package_name) { - auto lib_entry = shared_lib_package_ids_.find(library_package_name); - if (lib_entry != shared_lib_package_ids_.end()) { - return lib_entry->second; - } - - return shared_lib_package_ids_[library_package_name] = next_package_id_++; -} - -uint8_t DynamicLibManager::FindUnassignedId(uint8_t start_package_id) { - return (start_package_id < next_package_id_) ? next_package_id_ : start_package_id; -} - -} // namespace android diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h index b2cec2a42994..e21abade99a4 100644 --- a/libs/androidfw/include/androidfw/AssetManager2.h +++ b/libs/androidfw/include/androidfw/AssetManager2.h @@ -27,7 +27,6 @@ #include "androidfw/ApkAssets.h" #include "androidfw/Asset.h" #include "androidfw/AssetManager.h" -#include "androidfw/DynamicLibManager.h" #include "androidfw/ResourceTypes.h" #include "androidfw/Util.h" @@ -95,7 +94,6 @@ class AssetManager2 { }; AssetManager2(); - explicit AssetManager2(DynamicLibManager* dynamic_lib_manager); // Sets/resets the underlying ApkAssets for this AssetManager. The ApkAssets // are not owned by the AssetManager, and must have a longer lifetime. @@ -126,6 +124,9 @@ class AssetManager2 { // This may be nullptr if the APK represented by `cookie` has no resource table. std::shared_ptr<const DynamicRefTable> GetDynamicRefTableForCookie(ApkAssetsCookie cookie) const; + // Retrieve the assigned package id of the package if loaded into this AssetManager + uint8_t GetAssignedPackageId(const LoadedPackage* package) const; + // Returns a string representation of the overlayable API of a package. bool GetOverlayablesToString(const android::StringPiece& package_name, std::string* out) const; @@ -370,11 +371,6 @@ class AssetManager2 { // been seen while traversing bag parents. const ResolvedBag* GetBag(uint32_t resid, std::vector<uint32_t>& child_resids); - // Retrieve the assigned package id of the package if loaded into this AssetManager - uint8_t GetAssignedPackageId(const LoadedPackage* package) const; - - DynamicLibManager* GetDynamicLibManager() const; - // The ordered list of ApkAssets to search. These are not owned by the AssetManager, and must // have a longer lifetime. std::vector<const ApkAssets*> apk_assets_; @@ -393,9 +389,6 @@ class AssetManager2 { // may need to be purged. ResTable_config configuration_; - // Component responsible for assigning package ids to shared libraries. - std::variant<std::unique_ptr<DynamicLibManager>, DynamicLibManager*> dynamic_lib_manager_; - // Cached set of bags. These are cached because they can inherit keys from parent bags, // which involves some calculation. std::unordered_map<uint32_t, util::unique_cptr<ResolvedBag>> cached_bags_; diff --git a/libs/androidfw/include/androidfw/DynamicLibManager.h b/libs/androidfw/include/androidfw/DynamicLibManager.h deleted file mode 100644 index 1ff7079573d2..000000000000 --- a/libs/androidfw/include/androidfw/DynamicLibManager.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROIDFW_DYNAMICLIBMANAGER_H -#define ANDROIDFW_DYNAMICLIBMANAGER_H - -#include <string> -#include <unordered_map> - -#include "android-base/macros.h" - -namespace android { - -// Manages assigning resource ids for dynamic resources. -class DynamicLibManager { - public: - DynamicLibManager() = default; - - // Retrieves the assigned package id for the library. - uint8_t GetAssignedId(const std::string& library_package_name); - - // Queries in ascending order for the first available package id that is not currently assigned to - // a library. - uint8_t FindUnassignedId(uint8_t start_package_id); - - private: - DISALLOW_COPY_AND_ASSIGN(DynamicLibManager); - - uint8_t next_package_id_ = 0x02; - std::unordered_map<std::string, uint8_t> shared_lib_package_ids_; -}; - -} // namespace android - -#endif //ANDROIDFW_DYNAMICLIBMANAGER_H diff --git a/libs/androidfw/include/androidfw/MutexGuard.h b/libs/androidfw/include/androidfw/MutexGuard.h index 8891512958f0..64924f433245 100644 --- a/libs/androidfw/include/androidfw/MutexGuard.h +++ b/libs/androidfw/include/androidfw/MutexGuard.h @@ -47,8 +47,7 @@ class Guarded { static_assert(!std::is_pointer<T>::value, "T must not be a raw pointer"); public: - template <typename ...Args> - explicit Guarded(Args&& ...args) : guarded_(std::forward<Args>(args)...) { + explicit Guarded() : guarded_() { } template <typename U = T> diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp index ac32699c6dfd..8c255d16fe1f 100644 --- a/libs/androidfw/tests/AssetManager2_test.cpp +++ b/libs/androidfw/tests/AssetManager2_test.cpp @@ -17,9 +17,9 @@ #include "androidfw/AssetManager2.h" #include "androidfw/AssetManager.h" -#include "android-base/logging.h" - #include "TestHelpers.h" +#include "android-base/file.h" +#include "android-base/logging.h" #include "androidfw/ResourceUtils.h" #include "data/appaslib/R.h" #include "data/basic/R.h" @@ -45,37 +45,43 @@ namespace android { class AssetManager2Test : public ::testing::Test { public: void SetUp() override { - basic_assets_ = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); + // Move to the test data directory so the idmap can locate the overlay APK. + std::string original_path = base::GetExecutableDirectory(); + chdir(GetTestDataPath().c_str()); + + basic_assets_ = ApkAssets::Load("basic/basic.apk"); ASSERT_NE(nullptr, basic_assets_); - basic_de_fr_assets_ = ApkAssets::Load(GetTestDataPath() + "/basic/basic_de_fr.apk"); + basic_de_fr_assets_ = ApkAssets::Load("basic/basic_de_fr.apk"); ASSERT_NE(nullptr, basic_de_fr_assets_); - style_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); + style_assets_ = ApkAssets::Load("styles/styles.apk"); ASSERT_NE(nullptr, style_assets_); - lib_one_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_one/lib_one.apk"); + lib_one_assets_ = ApkAssets::Load("lib_one/lib_one.apk"); ASSERT_NE(nullptr, lib_one_assets_); - lib_two_assets_ = ApkAssets::Load(GetTestDataPath() + "/lib_two/lib_two.apk"); + lib_two_assets_ = ApkAssets::Load("lib_two/lib_two.apk"); ASSERT_NE(nullptr, lib_two_assets_); - libclient_assets_ = ApkAssets::Load(GetTestDataPath() + "/libclient/libclient.apk"); + libclient_assets_ = ApkAssets::Load("libclient/libclient.apk"); ASSERT_NE(nullptr, libclient_assets_); - appaslib_assets_ = ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk", - PROPERTY_DYNAMIC); + appaslib_assets_ = ApkAssets::Load("appaslib/appaslib.apk", PROPERTY_DYNAMIC); ASSERT_NE(nullptr, appaslib_assets_); - system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk", - PROPERTY_SYSTEM); + system_assets_ = ApkAssets::Load("system/system.apk", PROPERTY_SYSTEM); ASSERT_NE(nullptr, system_assets_); - app_assets_ = ApkAssets::Load(GetTestDataPath() + "/app/app.apk"); + app_assets_ = ApkAssets::Load("app/app.apk"); ASSERT_THAT(app_assets_, NotNull()); - overlayable_assets_ = ApkAssets::Load(GetTestDataPath() + "/overlayable/overlayable.apk"); + overlay_assets_ = ApkAssets::LoadOverlay("overlay/overlay.idmap"); + ASSERT_NE(nullptr, overlay_assets_); + + overlayable_assets_ = ApkAssets::Load("overlayable/overlayable.apk"); ASSERT_THAT(overlayable_assets_, NotNull()); + chdir(original_path.c_str()); } protected: @@ -88,6 +94,7 @@ class AssetManager2Test : public ::testing::Test { std::unique_ptr<const ApkAssets> appaslib_assets_; std::unique_ptr<const ApkAssets> system_assets_; std::unique_ptr<const ApkAssets> app_assets_; + std::unique_ptr<const ApkAssets> overlay_assets_; std::unique_ptr<const ApkAssets> overlayable_assets_; }; @@ -216,23 +223,24 @@ TEST_F(AssetManager2Test, FindsResourceFromAppLoadedAsSharedLibrary) { EXPECT_EQ(fix_package_id(appaslib::R::array::integerArray1, 0x02), value.data); } -TEST_F(AssetManager2Test, AssignsUnchangingPackageIdToSharedLibrary) { - DynamicLibManager lib_manager; - AssetManager2 assetmanager(&lib_manager); +TEST_F(AssetManager2Test, AssignsOverlayPackageIdLast) { + AssetManager2 assetmanager; assetmanager.SetApkAssets( - {lib_one_assets_.get(), lib_two_assets_.get(), libclient_assets_.get()}); - - AssetManager2 assetmanager2(&lib_manager); - assetmanager2.SetApkAssets( - {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()}); + {overlayable_assets_.get(), overlay_assets_.get(), lib_one_assets_.get()}); - uint32_t res_id = assetmanager.GetResourceId("com.android.lib_one:string/foo"); - ASSERT_NE(0U, res_id); + auto apk_assets = assetmanager.GetApkAssets(); + ASSERT_EQ(3, apk_assets.size()); + ASSERT_EQ(overlayable_assets_.get(), apk_assets[0]); + ASSERT_EQ(overlay_assets_.get(), apk_assets[1]); + ASSERT_EQ(lib_one_assets_.get(), apk_assets[2]); - uint32_t res_id_2 = assetmanager2.GetResourceId("com.android.lib_one:string/foo"); - ASSERT_NE(0U, res_id_2); + auto get_first_package_id = [&assetmanager](const ApkAssets* apkAssets) -> uint8_t { + return assetmanager.GetAssignedPackageId(apkAssets->GetLoadedArsc()->GetPackages()[0].get()); + }; - ASSERT_EQ(res_id, res_id_2); + ASSERT_EQ(get_first_package_id(overlayable_assets_.get()), 0x7f); + ASSERT_EQ(get_first_package_id(overlay_assets_.get()), 0x03); + ASSERT_EQ(get_first_package_id(lib_one_assets_.get()), 0x02); } TEST_F(AssetManager2Test, GetSharedLibraryResourceName) { @@ -770,7 +778,6 @@ TEST_F(AssetManager2Test, GetOverlayablesToString) { ASSERT_EQ(api.find("not_overlayable"), std::string::npos); ASSERT_NE(api.find("resource='com.android.overlayable:string/overlayable2' overlayable='OverlayableResources1' actor='overlay://theme' policy='0x0000000a'\n"), std::string::npos); - } } // namespace android |