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

Commit 8a98b40c authored by Todd Kennedy's avatar Todd Kennedy Committed by Android (Google) Code Review
Browse files

Merge "Merge commit 'c5e694e9' into...

Merge "Merge commit 'c5e694e9' into manual_merge_c5e694e9549da3911392abd01bae125444f56294"
parents 2586ff7f c611199b
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -67,10 +67,10 @@ AssetManager2::AssetManager2() {
}

bool AssetManager2::SetApkAssets(const std::vector<const ApkAssets*>& apk_assets,
                                 bool invalidate_caches) {
                                 bool invalidate_caches, bool filter_incompatible_configs) {
  apk_assets_ = apk_assets;
  BuildDynamicRefTable();
  RebuildFilterList();
  RebuildFilterList(filter_incompatible_configs);
  if (invalidate_caches) {
    InvalidateCaches(static_cast<uint32_t>(-1));
  }
@@ -825,7 +825,7 @@ uint32_t AssetManager2::GetResourceId(const std::string& resource_name,
  return 0u;
}

void AssetManager2::RebuildFilterList() {
void AssetManager2::RebuildFilterList(bool filter_incompatible_configs) {
  for (PackageGroup& group : package_groups_) {
    for (ConfiguredPackage& impl : group.packages_) {
      // Destroy it.
@@ -841,7 +841,7 @@ void AssetManager2::RebuildFilterList() {
        for (auto iter = spec->types; iter != iter_end; ++iter) {
          ResTable_config this_config;
          this_config.copyFromDtoH((*iter)->config);
          if (this_config.match(configuration_)) {
          if (!filter_incompatible_configs || this_config.match(configuration_)) {
            group.configurations.push_back(this_config);
            group.types.push_back(*iter);
          }
+34 −0
Original line number Diff line number Diff line
@@ -203,6 +203,39 @@ static bool VerifyResTableEntry(const ResTable_type* type, uint32_t entry_offset
  return true;
}

LoadedPackage::iterator::iterator(const LoadedPackage* lp, size_t ti, size_t ei)
    : loadedPackage_(lp),
      typeIndex_(ti),
      entryIndex_(ei),
      typeIndexEnd_(lp->resource_ids_.size() + 1) {
  while (typeIndex_ < typeIndexEnd_ && loadedPackage_->resource_ids_[typeIndex_] == 0) {
    typeIndex_++;
  }
}

LoadedPackage::iterator& LoadedPackage::iterator::operator++() {
  while (typeIndex_ < typeIndexEnd_) {
    if (entryIndex_ + 1 < loadedPackage_->resource_ids_[typeIndex_]) {
      entryIndex_++;
      break;
    }
    entryIndex_ = 0;
    typeIndex_++;
    if (typeIndex_ < typeIndexEnd_ && loadedPackage_->resource_ids_[typeIndex_] != 0) {
      break;
    }
  }
  return *this;
}

uint32_t LoadedPackage::iterator::operator*() const {
  if (typeIndex_ >= typeIndexEnd_) {
    return 0;
  }
  return make_resid(loadedPackage_->package_id_, typeIndex_ + loadedPackage_->type_id_offset_,
          entryIndex_);
}

const ResTable_entry* LoadedPackage::GetEntry(const ResTable_type* type_chunk,
                                              uint16_t entry_index) {
  uint32_t entry_offset = GetEntryOffset(type_chunk, entry_index);
@@ -488,6 +521,7 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
        std::unique_ptr<TypeSpecPtrBuilder>& builder_ptr = type_builder_map[type_spec->id - 1];
        if (builder_ptr == nullptr) {
          builder_ptr = util::make_unique<TypeSpecPtrBuilder>(type_spec, idmap_entry_header);
          loaded_package->resource_ids_.set(type_spec->id, entry_count);
        } else {
          LOG(WARNING) << StringPrintf("RES_TABLE_TYPE_SPEC_TYPE already defined for ID %02x",
                                       type_spec->id);
+7 −2
Original line number Diff line number Diff line
@@ -96,7 +96,12 @@ class AssetManager2 {
  // Only pass invalidate_caches=false when it is known that the structure
  // change in ApkAssets is due to a safe addition of resources with completely
  // new resource IDs.
  bool SetApkAssets(const std::vector<const ApkAssets*>& apk_assets, bool invalidate_caches = true);
  //
  // Only pass in filter_incompatible_configs=false when you want to load all
  // configurations (including incompatible ones) such as when constructing an
  // idmap.
  bool SetApkAssets(const std::vector<const ApkAssets*>& apk_assets, bool invalidate_caches = true,
          bool filter_incompatible_configs = true);

  inline const std::vector<const ApkAssets*> GetApkAssets() const {
    return apk_assets_;
@@ -274,7 +279,7 @@ class AssetManager2 {

  // Triggers the re-construction of lists of types that match the set configuration.
  // This should always be called when mutating the AssetManager's configuration or ApkAssets set.
  void RebuildFilterList();
  void RebuildFilterList(bool filter_incompatible_configs = true);

  // AssetManager2::GetBag(resid) wraps this function to track which resource ids have already
  // been seen while traversing bag parents.
+50 −0
Original line number Diff line number Diff line
@@ -78,6 +78,55 @@ using TypeSpecPtr = util::unique_cptr<TypeSpec>;

class LoadedPackage {
 public:
  class iterator {
   public:
    iterator& operator=(const iterator& rhs) {
      loadedPackage_ = rhs.loadedPackage_;
      typeIndex_ = rhs.typeIndex_;
      entryIndex_ = rhs.entryIndex_;
      return *this;
    }

    bool operator==(const iterator& rhs) const {
      return loadedPackage_ == rhs.loadedPackage_ &&
             typeIndex_ == rhs.typeIndex_ &&
             entryIndex_ == rhs.entryIndex_;
    }

    bool operator!=(const iterator& rhs) const {
      return !(*this == rhs);
    }

    iterator operator++(int) {
      size_t prevTypeIndex_ = typeIndex_;
      size_t prevEntryIndex_ = entryIndex_;
      operator++();
      return iterator(loadedPackage_, prevTypeIndex_, prevEntryIndex_);
    }

    iterator& operator++();

    uint32_t operator*() const;

   private:
    friend class LoadedPackage;

    iterator(const LoadedPackage* lp, size_t ti, size_t ei);

    const LoadedPackage* loadedPackage_;
    size_t typeIndex_;
    size_t entryIndex_;
    const size_t typeIndexEnd_;  // STL style end, so one past the last element
  };

  iterator begin() const {
    return iterator(this, 0, 0);
  }

  iterator end() const {
    return iterator(this, resource_ids_.size() + 1, 0);
  }

  static std::unique_ptr<const LoadedPackage> Load(const Chunk& chunk,
                                                   const LoadedIdmap* loaded_idmap, bool system,
                                                   bool load_as_shared_library);
@@ -182,6 +231,7 @@ class LoadedPackage {
  bool overlay_ = false;

  ByteBucketArray<TypeSpecPtr> type_specs_;
  ByteBucketArray<uint32_t> resource_ids_;
  std::vector<DynamicPackageEntry> dynamic_package_map_;
};

+48 −0
Original line number Diff line number Diff line
@@ -278,4 +278,52 @@ TEST(LoadedArscTest, LoadOverlay) {
// sizeof(Res_value) might not be backwards compatible.
TEST(LoadedArscTest, LoadingShouldBeForwardsAndBackwardsCompatible) { ASSERT_TRUE(false); }

TEST(LoadedArscTest, ResourceIdentifierIterator) {
  std::string contents;
  ASSERT_TRUE(
      ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc", &contents));

  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
  ASSERT_NE(nullptr, loaded_arsc);

  const std::vector<std::unique_ptr<const LoadedPackage>>& packages = loaded_arsc->GetPackages();
  ASSERT_EQ(1u, packages.size());
  EXPECT_EQ(std::string("com.android.basic"), packages[0]->GetPackageName());

  const auto& loaded_package = packages[0];
  auto iter = loaded_package->begin();
  auto end = loaded_package->end();

  ASSERT_NE(end, iter);
  ASSERT_EQ(0x7f010000u, *iter++);
  ASSERT_EQ(0x7f010001u, *iter++);
  ASSERT_EQ(0x7f020000u, *iter++);
  ASSERT_EQ(0x7f020001u, *iter++);
  ASSERT_EQ(0x7f030000u, *iter++);
  ASSERT_EQ(0x7f030001u, *iter++);
  ASSERT_EQ(0x7f030002u, *iter++);  // note: string without default, excluded by aapt2 dump
  ASSERT_EQ(0x7f040000u, *iter++);
  ASSERT_EQ(0x7f040001u, *iter++);
  ASSERT_EQ(0x7f040002u, *iter++);
  ASSERT_EQ(0x7f040003u, *iter++);
  ASSERT_EQ(0x7f040004u, *iter++);
  ASSERT_EQ(0x7f040005u, *iter++);
  ASSERT_EQ(0x7f040006u, *iter++);
  ASSERT_EQ(0x7f040007u, *iter++);
  ASSERT_EQ(0x7f040008u, *iter++);
  ASSERT_EQ(0x7f040009u, *iter++);
  ASSERT_EQ(0x7f04000au, *iter++);
  ASSERT_EQ(0x7f04000bu, *iter++);
  ASSERT_EQ(0x7f04000cu, *iter++);
  ASSERT_EQ(0x7f04000du, *iter++);
  ASSERT_EQ(0x7f050000u, *iter++);
  ASSERT_EQ(0x7f050001u, *iter++);
  ASSERT_EQ(0x7f060000u, *iter++);
  ASSERT_EQ(0x7f070000u, *iter++);
  ASSERT_EQ(0x7f070001u, *iter++);
  ASSERT_EQ(0x7f070002u, *iter++);
  ASSERT_EQ(0x7f070003u, *iter++);
  ASSERT_EQ(end, iter);
}

}  // namespace android