diff options
author | Adam Lesinski <adamlesinski@google.com> | 2017-09-25 13:10:14 -0700 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2017-09-25 18:24:41 -0700 |
commit | 03ebac8c68f9925592a172fcfd11d56f48cadaeb (patch) | |
tree | 65f977d44096c415c580614dd43a158d3b96aa23 | |
parent | 6833a07a078af8eeb868aee269bbb1860c01f244 (diff) |
A few fixes to AssetManager2 for compat
Theme copying should behave the way it did with the old AssetManager
(copy only the framework attributes when copying from a Theme object
from a different AssetManager).
Cleanup the dependencies on libziparchive in ApkAssets.
Test: make libandroidfw_tests
Test: out/host/<platform>/nativetests64/libandroidfw_tests/libandroidfw_tests --testdata=frameworks/base/libs/androidfw/tests/data
Change-Id: I973f7e6eb14ce311306e2ec66a623a4790c8d233
-rw-r--r-- | libs/androidfw/ApkAssets.cpp | 2 | ||||
-rw-r--r-- | libs/androidfw/AssetManager2.cpp | 16 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/ApkAssets.h | 10 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/AssetManager2.h | 5 | ||||
-rw-r--r-- | libs/androidfw/tests/Theme_test.cpp | 23 |
5 files changed, 36 insertions, 20 deletions
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index a5b1d29dbf91..0e577d1c9e3c 100644 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -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*/); } diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index ab7e14de48fb..f1f2e2d1417e 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -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); diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h index b7e66fb68be5..2e392d57b1c8 100644 --- a/libs/androidfw/include/androidfw/ApkAssets.h +++ b/libs/androidfw/include/androidfw/ApkAssets.h @@ -21,7 +21,6 @@ #include <string> #include "android-base/macros.h" -#include "ziparchive/zip_archive.h" #include "androidfw/Asset.h" #include "androidfw/LoadedArsc.h" @@ -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_; diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h index d2bc6ee45576..fd94144544a8 100644 --- a/libs/androidfw/include/androidfw/AssetManager2.h +++ b/libs/androidfw/include/androidfw/AssetManager2.h @@ -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; diff --git a/libs/androidfw/tests/Theme_test.cpp b/libs/androidfw/tests/Theme_test.cpp index dfff9c00922c..feb454e144e3 100644 --- a/libs/androidfw/tests/Theme_test.cpp +++ b/libs/androidfw/tests/Theme_test.cpp @@ -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; @@ -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_); @@ -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_; @@ -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 |