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
This commit is contained in:
@@ -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*/);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user