diff options
| -rw-r--r-- | libs/androidfw/ResourceTypes.cpp | 92 |
1 files changed, 62 insertions, 30 deletions
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index f7fb89e54ef3..2fe98b00f3a2 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -7035,40 +7035,70 @@ status_t DynamicRefTable::lookupResourceValue(Res_value* value) const { return NO_ERROR; } -struct IdmapMatchingResources { - void Add(uint32_t targetResId, uint32_t overlayResId) { - uint8_t targetTypeid = Res_GETTYPE(targetResId); - if (typeMappings.find(targetTypeid) == typeMappings.end()) { - typeMappings.emplace(targetTypeid, std::set<std::pair<uint32_t, uint32_t>>()); +class IdmapMatchingResources; + +class IdmapTypeMapping { +public: + void add(uint32_t targetResId, uint32_t overlayResId) { + uint8_t targetTypeId = Res_GETTYPE(targetResId); + if (mData.find(targetTypeId) == mData.end()) { + mData.emplace(targetTypeId, std::set<std::pair<uint32_t, uint32_t>>()); } - auto& entries = typeMappings[targetTypeid]; + auto& entries = mData[targetTypeId]; entries.insert(std::make_pair(targetResId, overlayResId)); } - void FixPadding() { - for (auto ti = typeMappings.cbegin(); ti != typeMappings.cend(); ++ti) { - uint32_t last_seen = 0xffffffff; - size_t total_entries = 0; + bool empty() const { + return mData.empty(); + } + +private: + // resource type ID in context of target -> set of resource entries mapping target -> overlay + std::map<uint8_t, std::set<std::pair<uint32_t, uint32_t>>> mData; + + friend IdmapMatchingResources; +}; + +class IdmapMatchingResources { +public: + IdmapMatchingResources(std::unique_ptr<IdmapTypeMapping> tm) : mTypeMapping(std::move(tm)) { + assert(mTypeMapping); + for (auto ti = mTypeMapping->mData.cbegin(); ti != mTypeMapping->mData.cend(); ++ti) { + uint32_t lastSeen = 0xffffffff; + size_t totalEntries = 0; for (auto ei = ti->second.cbegin(); ei != ti->second.cend(); ++ei) { - assert(last_seen == 0xffffffff || last_seen < ei->first); - entryPadding[ei->first] = (last_seen == 0xffffffff) ? 0 : ei->first - last_seen - 1; - last_seen = ei->first; - total_entries += 1 + entryPadding[ei->first]; + assert(lastSeen == 0xffffffff || lastSeen < ei->first); + mEntryPadding[ei->first] = (lastSeen == 0xffffffff) ? 0 : ei->first - lastSeen - 1; + lastSeen = ei->first; + totalEntries += 1 + mEntryPadding[ei->first]; } - numberOfEntriesIncludingPadding[ti->first] = total_entries; + mNumberOfEntriesIncludingPadding[ti->first] = totalEntries; } } + const auto& getTypeMapping() const { + return mTypeMapping->mData; + } + + size_t getNumberOfEntriesIncludingPadding(uint8_t type) const { + return mNumberOfEntriesIncludingPadding.at(type); + } + + size_t getPadding(uint32_t resid) const { + return mEntryPadding.at(resid); + } + +private: // resource type ID in context of target -> set of resource entries mapping target -> overlay - std::map<uint8_t, std::set<std::pair<uint32_t, uint32_t>>> typeMappings; + const std::unique_ptr<IdmapTypeMapping> mTypeMapping; // resource ID in context of target -> trailing padding for that resource (call FixPadding // before use) - std::map<uint32_t, size_t> entryPadding; + std::map<uint32_t, size_t> mEntryPadding; // resource type ID in context of target -> total number of entries, including padding entries, // for that type (call FixPadding before use) - std::map<uint8_t, size_t> numberOfEntriesIncludingPadding; + std::map<uint8_t, size_t> mNumberOfEntriesIncludingPadding; }; status_t ResTable::createIdmap(const ResTable& targetResTable, @@ -7098,7 +7128,8 @@ status_t ResTable::createIdmap(const ResTable& targetResTable, return UNKNOWN_ERROR; } - const ResTable_package* targetPackageStruct = targetResTable.mPackageGroups[0]->packages[0]->package; + const ResTable_package* targetPackageStruct = + targetResTable.mPackageGroups[0]->packages[0]->package; const size_t tmpNameSize = arraysize(targetPackageStruct->name); char16_t tmpName[tmpNameSize]; strcpy16_dtoh(tmpName, targetPackageStruct->name, tmpNameSize); @@ -7110,7 +7141,7 @@ status_t ResTable::createIdmap(const ResTable& targetResTable, size_t forcedOverlayCount = 0u; // find the resources that exist in both packages - IdmapMatchingResources matchingResources; + auto typeMapping = std::make_unique<IdmapTypeMapping>(); for (size_t typeIndex = 0; typeIndex < packageGroup->types.size(); ++typeIndex) { const TypeList& typeList = packageGroup->types[typeIndex]; if (typeList.isEmpty()) { @@ -7144,24 +7175,25 @@ status_t ResTable::createIdmap(const ResTable& targetResTable, ++forcedOverlayCount; } - matchingResources.Add(target_resid, overlay_resid); + typeMapping->add(target_resid, overlay_resid); } } - if (matchingResources.typeMappings.empty()) { + if (typeMapping->empty()) { ALOGE("idmap: no matching resources"); return UNKNOWN_ERROR; } - matchingResources.FixPadding(); + const IdmapMatchingResources matchingResources(std::move(typeMapping)); // write idmap *outSize = ResTable::IDMAP_HEADER_SIZE_BYTES; // magic, version, target and overlay crc *outSize += 2 * sizeof(uint16_t); // target package id, type count - const auto typesEnd = matchingResources.typeMappings.cend(); - for (auto ti = matchingResources.typeMappings.cbegin(); ti != typesEnd; ++ti) { + auto fixedTypeMapping = matchingResources.getTypeMapping(); + const auto typesEnd = fixedTypeMapping.cend(); + for (auto ti = fixedTypeMapping.cbegin(); ti != typesEnd; ++ti) { *outSize += 4 * sizeof(uint16_t); // target type, overlay type, entry count, entry offset - *outSize += matchingResources.numberOfEntriesIncludingPadding[ti->first] * + *outSize += matchingResources.getNumberOfEntriesIncludingPadding(ti->first) * sizeof(uint32_t); // entries } if ((*outData = malloc(*outSize)) == NULL) { @@ -7190,11 +7222,11 @@ status_t ResTable::createIdmap(const ResTable& targetResTable, uint16_t* typeData = reinterpret_cast<uint16_t*>(data); *typeData++ = htods(targetPackageStruct->id); // write: target package id *typeData++ = - htods(static_cast<uint16_t>(matchingResources.typeMappings.size())); // write: type count + htods(static_cast<uint16_t>(fixedTypeMapping.size())); // write: type count // write idmap data - for (auto ti = matchingResources.typeMappings.cbegin(); ti != typesEnd; ++ti) { - const size_t entryCount = matchingResources.numberOfEntriesIncludingPadding[ti->first]; + for (auto ti = fixedTypeMapping.cbegin(); ti != typesEnd; ++ti) { + const size_t entryCount = matchingResources.getNumberOfEntriesIncludingPadding(ti->first); auto ei = ti->second.cbegin(); *typeData++ = htods(Res_GETTYPE(ei->first) + 1); // write: target type id *typeData++ = htods(Res_GETTYPE(ei->second) + 1); // write: overlay type id @@ -7202,7 +7234,7 @@ status_t ResTable::createIdmap(const ResTable& targetResTable, *typeData++ = htods(Res_GETENTRY(ei->first)); // write: (target) entry offset uint32_t *entryData = reinterpret_cast<uint32_t*>(typeData); for (; ei != ti->second.cend(); ++ei) { - const size_t padding = matchingResources.entryPadding[ei->first]; + const size_t padding = matchingResources.getPadding(ei->first); for (size_t i = 0; i < padding; ++i) { *entryData++ = htodl(0xffffffff); // write: padding } |