libandroidfw: Make sure to set the 'app as lib' flag
When an app is loaded as a shared library (eg. monochrome), make sure to set the bit that it loaded as such, so that conversions from package ID 7f -> shared library ID are done. Bug: 72511998 Test: make libandroidfw_tests Test: out/host/<host_os>/nativetest64/libandroidfw_tests/libandroidfw_tests Change-Id: Icd11b7a5adff351165ca16d5853fb5a0002c34b1
This commit is contained in:
@@ -74,7 +74,9 @@ void AssetManager2::BuildDynamicRefTable() {
|
||||
if (idx == 0xff) {
|
||||
package_ids_[package_id] = idx = static_cast<uint8_t>(package_groups_.size());
|
||||
package_groups_.push_back({});
|
||||
package_groups_.back().dynamic_ref_table.mAssignedPackageId = package_id;
|
||||
DynamicRefTable& ref_table = package_groups_.back().dynamic_ref_table;
|
||||
ref_table.mAssignedPackageId = package_id;
|
||||
ref_table.mAppAsLib = package->IsDynamic() && package->GetPackageId() == 0x7f;
|
||||
}
|
||||
PackageGroup* package_group = &package_groups_[idx];
|
||||
|
||||
@@ -105,7 +107,15 @@ void AssetManager2::BuildDynamicRefTable() {
|
||||
void AssetManager2::DumpToLog() const {
|
||||
base::ScopedLogSeverity _log(base::INFO);
|
||||
|
||||
LOG(INFO) << base::StringPrintf("AssetManager2(this=%p)", this);
|
||||
|
||||
std::string list;
|
||||
for (const auto& apk_assets : apk_assets_) {
|
||||
base::StringAppendF(&list, "%s,", apk_assets->GetPath().c_str());
|
||||
}
|
||||
LOG(INFO) << "ApkAssets: " << list;
|
||||
|
||||
list = "";
|
||||
for (size_t i = 0; i < package_ids_.size(); i++) {
|
||||
if (package_ids_[i] != 0xff) {
|
||||
base::StringAppendF(&list, "%02x -> %d, ", (int) i, package_ids_[i]);
|
||||
@@ -116,9 +126,12 @@ void AssetManager2::DumpToLog() const {
|
||||
for (const auto& package_group: package_groups_) {
|
||||
list = "";
|
||||
for (const auto& package : package_group.packages_) {
|
||||
base::StringAppendF(&list, "%s(%02x), ", package->GetPackageName().c_str(), package->GetPackageId());
|
||||
base::StringAppendF(&list, "%s(%02x%s), ", package->GetPackageName().c_str(),
|
||||
package->GetPackageId(), (package->IsDynamic() ? " dynamic" : ""));
|
||||
}
|
||||
LOG(INFO) << base::StringPrintf("PG (%02x): ", package_group.dynamic_ref_table.mAssignedPackageId) << list;
|
||||
LOG(INFO) << base::StringPrintf("PG (%02x): ",
|
||||
package_group.dynamic_ref_table.mAssignedPackageId)
|
||||
<< list;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ bool ExtractResourceName(const StringPiece& str, StringPiece* out_package, Strin
|
||||
StringPiece* out_entry);
|
||||
|
||||
inline uint32_t fix_package_id(uint32_t resid, uint8_t package_id) {
|
||||
return resid | (static_cast<uint32_t>(package_id) << 24);
|
||||
return (resid & 0x00ffffffu) | (static_cast<uint32_t>(package_id) << 24);
|
||||
}
|
||||
|
||||
inline uint8_t get_package_id(uint32_t resid) {
|
||||
|
||||
@@ -59,7 +59,7 @@ class AssetManager2Test : public ::testing::Test {
|
||||
libclient_assets_ = ApkAssets::Load(GetTestDataPath() + "/libclient/libclient.apk");
|
||||
ASSERT_NE(nullptr, libclient_assets_);
|
||||
|
||||
appaslib_assets_ = ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk");
|
||||
appaslib_assets_ = ApkAssets::LoadAsSharedLibrary(GetTestDataPath() + "/appaslib/appaslib.apk");
|
||||
ASSERT_NE(nullptr, appaslib_assets_);
|
||||
|
||||
system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk", true /*system*/);
|
||||
@@ -228,6 +228,25 @@ TEST_F(AssetManager2Test, FindsBagResourceFromMultipleApkAssets) {}
|
||||
TEST_F(AssetManager2Test, FindsBagResourceFromSharedLibrary) {
|
||||
AssetManager2 assetmanager;
|
||||
|
||||
// libclient is built with lib_one and then lib_two in order.
|
||||
// Reverse the order to test that proper package ID re-assignment is happening.
|
||||
assetmanager.SetApkAssets(
|
||||
{lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()});
|
||||
|
||||
const ResolvedBag* bag = assetmanager.GetBag(fix_package_id(lib_one::R::style::Theme, 0x03));
|
||||
ASSERT_NE(nullptr, bag);
|
||||
ASSERT_GE(bag->entry_count, 2u);
|
||||
|
||||
// First two attributes come from lib_one.
|
||||
EXPECT_EQ(1, bag->entries[0].cookie);
|
||||
EXPECT_EQ(0x03, get_package_id(bag->entries[0].key));
|
||||
EXPECT_EQ(1, bag->entries[1].cookie);
|
||||
EXPECT_EQ(0x03, get_package_id(bag->entries[1].key));
|
||||
}
|
||||
|
||||
TEST_F(AssetManager2Test, FindsStyleResourceWithParentFromSharedLibrary) {
|
||||
AssetManager2 assetmanager;
|
||||
|
||||
// libclient is built with lib_one and then lib_two in order.
|
||||
// Reverse the order to test that proper package ID re-assignment is happening.
|
||||
assetmanager.SetApkAssets(
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "android-base/logging.h"
|
||||
#include "android-base/macros.h"
|
||||
#include "androidfw/AssetManager2.h"
|
||||
#include "androidfw/ResourceUtils.h"
|
||||
|
||||
#include "TestHelpers.h"
|
||||
#include "data/styles/R.h"
|
||||
@@ -64,6 +65,41 @@ class AttributeResolutionXmlTest : public AttributeResolutionTest {
|
||||
ResXMLTree xml_parser_;
|
||||
};
|
||||
|
||||
TEST(AttributeResolutionLibraryTest, ApplyStyleWithDefaultStyleResId) {
|
||||
AssetManager2 assetmanager;
|
||||
auto apk_assets = ApkAssets::LoadAsSharedLibrary(GetTestDataPath() + "/styles/styles.apk");
|
||||
ASSERT_NE(nullptr, apk_assets);
|
||||
assetmanager.SetApkAssets({apk_assets.get()});
|
||||
|
||||
std::unique_ptr<Theme> theme = assetmanager.NewTheme();
|
||||
|
||||
std::array<uint32_t, 2> attrs{
|
||||
{fix_package_id(R::attr::attr_one, 0x02), fix_package_id(R::attr::attr_two, 0x02)}};
|
||||
std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
|
||||
std::array<uint32_t, attrs.size() + 1> indices;
|
||||
ApplyStyle(theme.get(), nullptr /*xml_parser*/, 0u /*def_style_attr*/,
|
||||
fix_package_id(R::style::StyleOne, 0x02), attrs.data(), attrs.size(), values.data(),
|
||||
indices.data());
|
||||
|
||||
const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
|
||||
|
||||
const uint32_t* values_cursor = values.data();
|
||||
EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
|
||||
EXPECT_EQ(1u, values_cursor[STYLE_DATA]);
|
||||
EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
|
||||
EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
|
||||
EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
|
||||
EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
|
||||
|
||||
values_cursor += STYLE_NUM_ENTRIES;
|
||||
EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]);
|
||||
EXPECT_EQ(2u, values_cursor[STYLE_DATA]);
|
||||
EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]);
|
||||
EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]);
|
||||
EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
|
||||
EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
|
||||
}
|
||||
|
||||
TEST_F(AttributeResolutionTest, Theme) {
|
||||
std::unique_ptr<Theme> theme = assetmanager_.NewTheme();
|
||||
ASSERT_TRUE(theme->ApplyStyle(R::style::StyleTwo));
|
||||
|
||||
Reference in New Issue
Block a user