Loading libs/androidfw/ApkAssets.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ namespace android { ApkAssets::ApkAssets() : zip_handle_(nullptr, ::CloseArchive) {} std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) { return ApkAssets::LoadImpl(path, system, false /*load_as_shared_library*/); } Loading libs/androidfw/AssetManager2.cpp +11 −5 Original line number Diff line number Diff line Loading @@ -902,26 +902,32 @@ bool Theme::SetTo(const Theme& o) { return true; } if (asset_manager_ != o.asset_manager_) { return false; } type_spec_flags_ = o.type_spec_flags_; const bool copy_only_system = asset_manager_ != o.asset_manager_; for (size_t p = 0; p < packages_.size(); p++) { const Package* package = o.packages_[p].get(); if (package == nullptr) { if (package == nullptr || (copy_only_system && p != 0x01)) { // The other theme doesn't have this package, clear ours. packages_[p].reset(); continue; } if (packages_[p] == nullptr) { // The other theme has this package, but we don't. Make one. packages_[p].reset(new Package()); } for (size_t t = 0; t < package->types.size(); t++) { const Type* type = package->types[t].get(); if (type == nullptr) { // The other theme doesn't have this type, clear ours. packages_[p]->types[t].reset(); continue; } // Create a new type and update it to theirs. const size_t type_alloc_size = sizeof(Type) + (type->entry_capacity * sizeof(Entry)); void* copied_data = malloc(type_alloc_size); memcpy(copied_data, type, type_alloc_size); Loading libs/androidfw/include/androidfw/ApkAssets.h +2 −8 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ #include <string> #include "android-base/macros.h" #include "ziparchive/zip_archive.h" #include "androidfw/Asset.h" #include "androidfw/LoadedArsc.h" Loading Loading @@ -52,14 +51,9 @@ class ApkAssets { static std::unique_ptr<const ApkAssets> LoadImpl(const std::string& path, bool system, bool load_as_shared_library); ApkAssets() = default; ApkAssets(); struct ZipArchivePtrCloser { void operator()(::ZipArchiveHandle handle) { ::CloseArchive(handle); } }; using ZipArchivePtr = std::unique_ptr<typename std::remove_pointer<::ZipArchiveHandle>::type, ZipArchivePtrCloser>; using ZipArchivePtr = std::unique_ptr<void, void(*)(void*)>; ZipArchivePtr zip_handle_; std::string path_; Loading libs/androidfw/include/androidfw/AssetManager2.h +2 −3 Original line number Diff line number Diff line Loading @@ -70,9 +70,8 @@ struct ResolvedBag { }; // AssetManager2 is the main entry point for accessing assets and resources. // AssetManager2 provides caching of resources retrieved via the underlying // ApkAssets. class AssetManager2 : public ::AAssetManager { // AssetManager2 provides caching of resources retrieved via the underlying ApkAssets. class AssetManager2 { public: struct ResourceName { const char* package = nullptr; Loading libs/androidfw/tests/Theme_test.cpp +19 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "data/lib_one/R.h" #include "data/libclient/R.h" #include "data/styles/R.h" #include "data/system/R.h" namespace app = com::android::app; namespace lib_one = com::android::lib_one; Loading @@ -33,6 +34,9 @@ namespace android { class ThemeTest : public ::testing::Test { public: void SetUp() override { system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk", true /*system*/); ASSERT_NE(nullptr, system_assets_); style_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); ASSERT_NE(nullptr, style_assets_); Loading @@ -47,6 +51,7 @@ class ThemeTest : public ::testing::Test { } protected: std::unique_ptr<const ApkAssets> system_assets_; std::unique_ptr<const ApkAssets> style_assets_; std::unique_ptr<const ApkAssets> libclient_assets_; std::unique_ptr<const ApkAssets> lib_one_assets_; Loading Loading @@ -262,20 +267,30 @@ TEST_F(ThemeTest, CopyThemeSameAssetManager) { EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); } TEST_F(ThemeTest, FailToCopyThemeWithDifferentAssetManager) { TEST_F(ThemeTest, OnlyCopySystemThemeWhenAssetManagersDiffer) { AssetManager2 assetmanager_one; assetmanager_one.SetApkAssets({style_assets_.get()}); assetmanager_one.SetApkAssets({system_assets_.get(), style_assets_.get()}); AssetManager2 assetmanager_two; assetmanager_two.SetApkAssets({style_assets_.get()}); assetmanager_two.SetApkAssets({system_assets_.get(), style_assets_.get()}); auto theme_one = assetmanager_one.NewTheme(); ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne)); auto theme_two = assetmanager_two.NewTheme(); ASSERT_TRUE(theme_two->ApplyStyle(R::style::Theme_One)); ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleTwo)); EXPECT_FALSE(theme_one->SetTo(*theme_two)); EXPECT_TRUE(theme_one->SetTo(*theme_two)); Res_value value; uint32_t flags; // No app resources. EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags)); // Only system. EXPECT_NE(kInvalidCookie, theme_one->GetAttribute(R::attr::foreground, &value, &flags)); } } // namespace android Loading
libs/androidfw/ApkAssets.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ namespace android { ApkAssets::ApkAssets() : zip_handle_(nullptr, ::CloseArchive) {} std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) { return ApkAssets::LoadImpl(path, system, false /*load_as_shared_library*/); } Loading
libs/androidfw/AssetManager2.cpp +11 −5 Original line number Diff line number Diff line Loading @@ -902,26 +902,32 @@ bool Theme::SetTo(const Theme& o) { return true; } if (asset_manager_ != o.asset_manager_) { return false; } type_spec_flags_ = o.type_spec_flags_; const bool copy_only_system = asset_manager_ != o.asset_manager_; for (size_t p = 0; p < packages_.size(); p++) { const Package* package = o.packages_[p].get(); if (package == nullptr) { if (package == nullptr || (copy_only_system && p != 0x01)) { // The other theme doesn't have this package, clear ours. packages_[p].reset(); continue; } if (packages_[p] == nullptr) { // The other theme has this package, but we don't. Make one. packages_[p].reset(new Package()); } for (size_t t = 0; t < package->types.size(); t++) { const Type* type = package->types[t].get(); if (type == nullptr) { // The other theme doesn't have this type, clear ours. packages_[p]->types[t].reset(); continue; } // Create a new type and update it to theirs. const size_t type_alloc_size = sizeof(Type) + (type->entry_capacity * sizeof(Entry)); void* copied_data = malloc(type_alloc_size); memcpy(copied_data, type, type_alloc_size); Loading
libs/androidfw/include/androidfw/ApkAssets.h +2 −8 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ #include <string> #include "android-base/macros.h" #include "ziparchive/zip_archive.h" #include "androidfw/Asset.h" #include "androidfw/LoadedArsc.h" Loading Loading @@ -52,14 +51,9 @@ class ApkAssets { static std::unique_ptr<const ApkAssets> LoadImpl(const std::string& path, bool system, bool load_as_shared_library); ApkAssets() = default; ApkAssets(); struct ZipArchivePtrCloser { void operator()(::ZipArchiveHandle handle) { ::CloseArchive(handle); } }; using ZipArchivePtr = std::unique_ptr<typename std::remove_pointer<::ZipArchiveHandle>::type, ZipArchivePtrCloser>; using ZipArchivePtr = std::unique_ptr<void, void(*)(void*)>; ZipArchivePtr zip_handle_; std::string path_; Loading
libs/androidfw/include/androidfw/AssetManager2.h +2 −3 Original line number Diff line number Diff line Loading @@ -70,9 +70,8 @@ struct ResolvedBag { }; // AssetManager2 is the main entry point for accessing assets and resources. // AssetManager2 provides caching of resources retrieved via the underlying // ApkAssets. class AssetManager2 : public ::AAssetManager { // AssetManager2 provides caching of resources retrieved via the underlying ApkAssets. class AssetManager2 { public: struct ResourceName { const char* package = nullptr; Loading
libs/androidfw/tests/Theme_test.cpp +19 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "data/lib_one/R.h" #include "data/libclient/R.h" #include "data/styles/R.h" #include "data/system/R.h" namespace app = com::android::app; namespace lib_one = com::android::lib_one; Loading @@ -33,6 +34,9 @@ namespace android { class ThemeTest : public ::testing::Test { public: void SetUp() override { system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk", true /*system*/); ASSERT_NE(nullptr, system_assets_); style_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); ASSERT_NE(nullptr, style_assets_); Loading @@ -47,6 +51,7 @@ class ThemeTest : public ::testing::Test { } protected: std::unique_ptr<const ApkAssets> system_assets_; std::unique_ptr<const ApkAssets> style_assets_; std::unique_ptr<const ApkAssets> libclient_assets_; std::unique_ptr<const ApkAssets> lib_one_assets_; Loading Loading @@ -262,20 +267,30 @@ TEST_F(ThemeTest, CopyThemeSameAssetManager) { EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags); } TEST_F(ThemeTest, FailToCopyThemeWithDifferentAssetManager) { TEST_F(ThemeTest, OnlyCopySystemThemeWhenAssetManagersDiffer) { AssetManager2 assetmanager_one; assetmanager_one.SetApkAssets({style_assets_.get()}); assetmanager_one.SetApkAssets({system_assets_.get(), style_assets_.get()}); AssetManager2 assetmanager_two; assetmanager_two.SetApkAssets({style_assets_.get()}); assetmanager_two.SetApkAssets({system_assets_.get(), style_assets_.get()}); auto theme_one = assetmanager_one.NewTheme(); ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne)); auto theme_two = assetmanager_two.NewTheme(); ASSERT_TRUE(theme_two->ApplyStyle(R::style::Theme_One)); ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleTwo)); EXPECT_FALSE(theme_one->SetTo(*theme_two)); EXPECT_TRUE(theme_one->SetTo(*theme_two)); Res_value value; uint32_t flags; // No app resources. EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags)); // Only system. EXPECT_NE(kInvalidCookie, theme_one->GetAttribute(R::attr::foreground, &value, &flags)); } } // namespace android