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

Commit c611199b authored by Todd Kennedy's avatar Todd Kennedy
Browse files

Merge commit 'c5e694e9' into...

Merge commit 'c5e694e9' into manual_merge_c5e694e9549da3911392abd01bae125444f56294

Change-Id: Ia48491cbcef8c3696c24619db2c3b7229f5bccc6
parents c472b0ac c5e694e9
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