Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ad287c8 authored by Adam Lesinski's avatar Adam Lesinski
Browse files

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
parent 1187590d
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -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;
  }
}

+1 −1
Original line number Diff line number Diff line
@@ -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) {
+20 −1
Original line number Diff line number Diff line
@@ -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(
+36 −0
Original line number Diff line number Diff line
@@ -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));