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

Commit ca445c49 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix resourcesMap to work with shared libraries"

parents ab1d9d6c 5035d66a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -37,6 +37,10 @@ typedef uint16_t EntryId; // eeee in 0xpptteeee

namespace utils {

// Returns whether the Res_value::data_type represents a dynamic or regular resource reference.
bool IsReference(uint8_t data_type);

// Converts the Res_value::data_type to a human-readable string representation.
StringPiece DataTypeToString(uint8_t data_type);

struct OverlayManifestInfo {
+10 −7
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "idmap2/ResourceUtils.h"

using android::base::StringPrintf;
using android::idmap2::utils::IsReference;
using android::idmap2::utils::ResToTypeEntryName;

namespace android::idmap2 {
@@ -200,8 +201,7 @@ Result<ResourceMapping> ResourceMapping::CreateResourceMapping(const AssetManage
    // Only rewrite resources defined within the overlay package to their corresponding target
    // resource ids at runtime.
    bool rewrite_overlay_reference =
        (overlay_resource->dataType == Res_value::TYPE_REFERENCE ||
         overlay_resource->dataType == Res_value::TYPE_DYNAMIC_REFERENCE)
        IsReference(overlay_resource->dataType)
            ? overlay_package_id == EXTRACT_PACKAGE(overlay_resource->data)
            : false;

@@ -331,8 +331,13 @@ Result<ResourceMapping> ResourceMapping::FromApkAssets(const ApkAssets& target_a
  std::unique_ptr<uint8_t[]> string_pool_data;
  Result<ResourceMapping> resource_mapping = {{}};
  if (overlay_info.resource_mapping != 0U) {
    // Use the dynamic reference table to find the assigned resource id of the map xml.
    const auto& ref_table = overlay_asset_manager.GetDynamicRefTableForCookie(0);
    uint32_t resource_mapping_id = overlay_info.resource_mapping;
    ref_table->lookupResourceId(&resource_mapping_id);

    // Load the overlay resource mappings from the file specified using android:resourcesMap.
    auto asset = OpenNonAssetFromResource(overlay_info.resource_mapping, overlay_asset_manager);
    auto asset = OpenNonAssetFromResource(resource_mapping_id, overlay_asset_manager);
    if (!asset) {
      return Error("failed opening xml for android:resourcesMap: %s",
                   asset.GetErrorMessage().c_str());
@@ -404,8 +409,7 @@ Result<Unit> ResourceMapping::AddMapping(ResourceId target_resource,

  target_map_.insert(std::make_pair(target_resource, TargetValue{data_type, data_value}));

  if (rewrite_overlay_reference &&
      (data_type == Res_value::TYPE_REFERENCE || data_type == Res_value::TYPE_DYNAMIC_REFERENCE)) {
  if (rewrite_overlay_reference && IsReference(data_type)) {
    overlay_map_.insert(std::make_pair(data_value, target_resource));
  }

@@ -421,8 +425,7 @@ void ResourceMapping::RemoveMapping(ResourceId target_resource) {
  const TargetValue value = target_iter->second;
  target_map_.erase(target_iter);

  if (value.data_type != Res_value::TYPE_REFERENCE &&
      value.data_type != Res_value::TYPE_DYNAMIC_REFERENCE) {
  if (!IsReference(value.data_type)) {
    return;
  }

+5 −1
Original line number Diff line number Diff line
@@ -33,6 +33,10 @@ using android::util::Utf16ToUtf8;

namespace android::idmap2::utils {

bool IsReference(uint8_t data_type) {
  return data_type == Res_value::TYPE_REFERENCE || data_type == Res_value::TYPE_DYNAMIC_REFERENCE;
}

StringPiece DataTypeToString(uint8_t data_type) {
  switch (data_type) {
    case Res_value::TYPE_NULL:
@@ -133,7 +137,7 @@ Result<OverlayManifestInfo> ExtractOverlayManifestInfo(const std::string& path,
  }

  if (auto result_value = overlay_it->GetAttributeValue("resourcesMap")) {
    if ((*result_value).dataType == Res_value::TYPE_REFERENCE) {
    if (IsReference((*result_value).dataType)) {
      info.resource_mapping = (*result_value).data;
    } else {
      return Error("android:resourcesMap is not a reference in AndroidManifest.xml of %s",
+2 −2
Original line number Diff line number Diff line
@@ -56,12 +56,12 @@ TEST(FileUtilsTests, FindFilesFindApkFilesRecursive) {
    return type == DT_REG && path.size() > 4 && path.compare(path.size() - 4, 4, ".apk") == 0;
  });
  ASSERT_THAT(v, NotNull());
  ASSERT_EQ(v->size(), 10U);
  ASSERT_EQ(v->size(), 11U);
  ASSERT_EQ(std::set<std::string>(v->begin(), v->end()),
            std::set<std::string>(
                {root + "/target/target.apk", root + "/target/target-no-overlayable.apk",
                 root + "/overlay/overlay.apk", root + "/overlay/overlay-no-name.apk",
                 root + "/overlay/overlay-no-name-static.apk",
                 root + "/overlay/overlay-no-name-static.apk", root + "/overlay/overlay-shared.apk",
                 root + "/overlay/overlay-static-1.apk", root + "/overlay/overlay-static-2.apk",
                 root + "/signature-overlay/signature-overlay.apk",
                 root + "/system-overlay/system-overlay.apk",
+37 −0
Original line number Diff line number Diff line
@@ -247,6 +247,43 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssets) {
  ASSERT_OVERLAY_ENTRY(overlay_entries[3], 0x7f020002, 0x7f02000f);
}

TEST(IdmapTests, CreateIdmapDataFromApkAssetsSharedLibOverlay) {
  std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
  std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-shared.apk";

  std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
  ASSERT_THAT(target_apk, NotNull());

  std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
  ASSERT_THAT(overlay_apk, NotNull());

  auto idmap_result = Idmap::FromApkAssets(*target_apk, *overlay_apk, PolicyFlags::POLICY_PUBLIC,
                                           /* enforce_overlayable */ true);
  ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage();
  auto& idmap = *idmap_result;
  ASSERT_THAT(idmap, NotNull());

  const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
  ASSERT_EQ(dataBlocks.size(), 1U);

  const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
  ASSERT_THAT(data, NotNull());

  const auto& target_entries = data->GetTargetEntries();
  ASSERT_EQ(target_entries.size(), 4U);
  ASSERT_TARGET_ENTRY(target_entries[0], 0x7f010000, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00010000);
  ASSERT_TARGET_ENTRY(target_entries[1], 0x7f02000c, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00020000);
  ASSERT_TARGET_ENTRY(target_entries[2], 0x7f02000e, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00020001);
  ASSERT_TARGET_ENTRY(target_entries[3], 0x7f02000f, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00020002);

  const auto& overlay_entries = data->GetOverlayEntries();
  ASSERT_EQ(target_entries.size(), 4U);
  ASSERT_OVERLAY_ENTRY(overlay_entries[0], 0x00010000, 0x7f010000);
  ASSERT_OVERLAY_ENTRY(overlay_entries[1], 0x00020000, 0x7f02000c);
  ASSERT_OVERLAY_ENTRY(overlay_entries[2], 0x00020001, 0x7f02000e);
  ASSERT_OVERLAY_ENTRY(overlay_entries[3], 0x00020002, 0x7f02000f);
}

TEST(IdmapTests, CreateIdmapDataDoNotRewriteNonOverlayResourceId) {
  OverlayManifestInfo info{};
  info.target_package = "test.target";
Loading