Loading libs/androidfw/AssetManager2.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,16 @@ void AssetManager2::BuildDynamicRefTable() { for (auto iter2 = package_groups_.begin(); iter2 != package_groups_end; ++iter2) { iter2->dynamic_ref_table->addMapping(String16(package_name.c_str(), package_name.size()), iter->dynamic_ref_table->mAssignedPackageId); // Add the alias resources to the dynamic reference table of every package group. Since // staging aliases can only be defined by the framework package (which is not a shared // library), the compile-time package id of the framework is the same across all packages // that compile against the framework. for (const auto& package : iter2->packages_) { for (const auto& entry : package.loaded_package_->GetAliasResourceIdMap()) { iter->dynamic_ref_table->addAlias(entry.first, entry.second); } } } } } Loading libs/androidfw/LoadedArsc.cpp +37 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ using android::base::StringPrintf; namespace android { constexpr const static int kFrameworkPackageId = 0x01; constexpr const static int kAppPackageId = 0x7f; namespace { Loading Loading @@ -675,6 +676,42 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, } } break; case RES_TABLE_STAGED_ALIAS_TYPE: { if (loaded_package->package_id_ != kFrameworkPackageId) { LOG(WARNING) << "Alias chunk ignored for non-framework package '" << loaded_package->package_name_ << "'"; break; } std::unordered_set<uint32_t> finalized_ids; const auto lib_alias = child_chunk.header<ResTable_staged_alias_header>(); if (!lib_alias) { return {}; } const auto entry_begin = child_chunk.data_ptr().convert<ResTable_staged_alias_entry>(); const auto entry_end = entry_begin + dtohl(lib_alias->count); for (auto entry_iter = entry_begin; entry_iter != entry_end; ++entry_iter) { if (!entry_iter) { return {}; } auto finalized_id = dtohl(entry_iter->finalizedResId); if (!finalized_ids.insert(finalized_id).second) { LOG(ERROR) << StringPrintf("Repeated finalized resource id '%08x' in staged aliases.", finalized_id); return {}; } auto staged_id = dtohl(entry_iter->stagedResId); auto [_, success] = loaded_package->alias_id_map_.insert(std::make_pair(staged_id, finalized_id)); if (!success) { LOG(ERROR) << StringPrintf("Repeated staged resource id '%08x' in staged aliases.", staged_id); return {}; } } } break; default: LOG(WARNING) << StringPrintf("Unknown chunk type '%02x'.", chunk.type()); break; Loading libs/androidfw/ResourceTypes.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -7079,6 +7079,10 @@ void DynamicRefTable::addMapping(uint8_t buildPackageId, uint8_t runtimePackageI mLookupTable[buildPackageId] = runtimePackageId; } void DynamicRefTable::addAlias(uint32_t stagedId, uint32_t finalizedId) { mAliasId[stagedId] = finalizedId; } status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const { uint32_t res = *resId; size_t packageId = Res_GETPACKAGE(res) + 1; Loading @@ -7088,8 +7092,16 @@ status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const { return NO_ERROR; } if (packageId == APP_PACKAGE_ID && !mAppAsLib) { // No lookup needs to be done, app package IDs are absolute. auto alias_id = mAliasId.find(res); if (alias_id != mAliasId.end()) { // Rewrite the resource id to its alias resource id. Since the alias resource id is a // compile-time id, it still needs to be resolved further. res = alias_id->second; } if (packageId == SYS_PACKAGE_ID || (packageId == APP_PACKAGE_ID && !mAppAsLib)) { // No lookup needs to be done, app and framework package IDs are absolute. *resId = res; return NO_ERROR; } Loading libs/androidfw/include/androidfw/LoadedArsc.h +16 −10 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #ifndef LOADEDARSC_H_ #define LOADEDARSC_H_ #include <map> #include <memory> #include <set> #include <vector> Loading Loading @@ -171,51 +172,51 @@ class LoadedPackage { incfs::verified_map_ptr<ResTable_type> type_chunk, uint32_t offset); // Returns the string pool where type names are stored. inline const ResStringPool* GetTypeStringPool() const { const ResStringPool* GetTypeStringPool() const { return &type_string_pool_; } // Returns the string pool where the names of resource entries are stored. inline const ResStringPool* GetKeyStringPool() const { const ResStringPool* GetKeyStringPool() const { return &key_string_pool_; } inline const std::string& GetPackageName() const { const std::string& GetPackageName() const { return package_name_; } inline int GetPackageId() const { int GetPackageId() const { return package_id_; } // Returns true if this package is dynamic (shared library) and needs to have an ID assigned. inline bool IsDynamic() const { bool IsDynamic() const { return (property_flags_ & PROPERTY_DYNAMIC) != 0; } // Returns true if this package is a Runtime Resource Overlay. inline bool IsOverlay() const { bool IsOverlay() const { return (property_flags_ & PROPERTY_OVERLAY) != 0; } // Returns true if this package originates from a system provided resource. inline bool IsSystem() const { bool IsSystem() const { return (property_flags_ & PROPERTY_SYSTEM) != 0; } // Returns true if this package is a custom loader and should behave like an overlay. inline bool IsCustomLoader() const { bool IsCustomLoader() const { return (property_flags_ & PROPERTY_LOADER) != 0; } inline package_property_t GetPropertyFlags() const { package_property_t GetPropertyFlags() const { return property_flags_; } // Returns the map of package name to package ID used in this LoadedPackage. At runtime, a // package could have been assigned a different package ID than what this LoadedPackage was // compiled with. AssetManager rewrites the package IDs so that they are compatible at runtime. inline const std::vector<DynamicPackageEntry>& GetDynamicPackageMap() const { const std::vector<DynamicPackageEntry>& GetDynamicPackageMap() const { return dynamic_package_map_; } Loading Loading @@ -270,6 +271,10 @@ class LoadedPackage { return overlayable_map_; } const std::map<uint32_t, uint32_t>& GetAliasResourceIdMap() const { return alias_id_map_; } private: DISALLOW_COPY_AND_ASSIGN(LoadedPackage); Loading @@ -287,6 +292,7 @@ class LoadedPackage { ByteBucketArray<uint32_t> resource_ids_; std::vector<DynamicPackageEntry> dynamic_package_map_; std::vector<const std::pair<OverlayableInfo, std::unordered_set<uint32_t>>> overlayable_infos_; std::map<uint32_t, uint32_t> alias_id_map_; // A map of overlayable name to actor std::unordered_map<std::string, std::string> overlayable_map_; Loading libs/androidfw/include/androidfw/ResourceTypes.h +45 −17 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <android/configuration.h> #include <array> #include <map> #include <memory> namespace android { Loading Loading @@ -253,6 +254,7 @@ enum { RES_TABLE_LIBRARY_TYPE = 0x0203, RES_TABLE_OVERLAYABLE_TYPE = 0x0204, RES_TABLE_OVERLAYABLE_POLICY_TYPE = 0x0205, RES_TABLE_STAGED_ALIAS_TYPE = 0x0206, }; /** Loading Loading @@ -1638,6 +1640,29 @@ struct ResTable_lib_entry uint16_t packageName[128]; }; /** * A map that allows rewriting staged (non-finalized) resource ids to their finalized counterparts. */ struct ResTable_staged_alias_header { struct ResChunk_header header; // The number of ResTable_staged_alias_entry that follow this header. uint32_t count; }; /** * Maps the staged (non-finalized) resource id to its finalized resource id. */ struct ResTable_staged_alias_entry { // The compile-time staged resource id to rewrite. uint32_t stagedResId; // The compile-time finalized resource id to which the staged resource id should be rewritten. uint32_t finalizedResId; }; /** * Specifies the set of resources that are explicitly allowed to be overlaid by RROs. */ Loading Loading @@ -1751,6 +1776,8 @@ public: void addMapping(uint8_t buildPackageId, uint8_t runtimePackageId); void addAlias(uint32_t stagedId, uint32_t finalizedId); // Returns whether or not the value must be looked up. bool requiresLookup(const Res_value* value) const; Loading @@ -1768,6 +1795,7 @@ private: uint8_t mLookupTable[256]; KeyedVector<String16, uint8_t> mEntries; bool mAppAsLib; std::map<uint32_t, uint32_t> mAliasId; }; bool U16StringToInt(const char16_t* s, size_t len, Res_value* outValue); Loading Loading
libs/androidfw/AssetManager2.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,16 @@ void AssetManager2::BuildDynamicRefTable() { for (auto iter2 = package_groups_.begin(); iter2 != package_groups_end; ++iter2) { iter2->dynamic_ref_table->addMapping(String16(package_name.c_str(), package_name.size()), iter->dynamic_ref_table->mAssignedPackageId); // Add the alias resources to the dynamic reference table of every package group. Since // staging aliases can only be defined by the framework package (which is not a shared // library), the compile-time package id of the framework is the same across all packages // that compile against the framework. for (const auto& package : iter2->packages_) { for (const auto& entry : package.loaded_package_->GetAliasResourceIdMap()) { iter->dynamic_ref_table->addAlias(entry.first, entry.second); } } } } } Loading
libs/androidfw/LoadedArsc.cpp +37 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ using android::base::StringPrintf; namespace android { constexpr const static int kFrameworkPackageId = 0x01; constexpr const static int kAppPackageId = 0x7f; namespace { Loading Loading @@ -675,6 +676,42 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, } } break; case RES_TABLE_STAGED_ALIAS_TYPE: { if (loaded_package->package_id_ != kFrameworkPackageId) { LOG(WARNING) << "Alias chunk ignored for non-framework package '" << loaded_package->package_name_ << "'"; break; } std::unordered_set<uint32_t> finalized_ids; const auto lib_alias = child_chunk.header<ResTable_staged_alias_header>(); if (!lib_alias) { return {}; } const auto entry_begin = child_chunk.data_ptr().convert<ResTable_staged_alias_entry>(); const auto entry_end = entry_begin + dtohl(lib_alias->count); for (auto entry_iter = entry_begin; entry_iter != entry_end; ++entry_iter) { if (!entry_iter) { return {}; } auto finalized_id = dtohl(entry_iter->finalizedResId); if (!finalized_ids.insert(finalized_id).second) { LOG(ERROR) << StringPrintf("Repeated finalized resource id '%08x' in staged aliases.", finalized_id); return {}; } auto staged_id = dtohl(entry_iter->stagedResId); auto [_, success] = loaded_package->alias_id_map_.insert(std::make_pair(staged_id, finalized_id)); if (!success) { LOG(ERROR) << StringPrintf("Repeated staged resource id '%08x' in staged aliases.", staged_id); return {}; } } } break; default: LOG(WARNING) << StringPrintf("Unknown chunk type '%02x'.", chunk.type()); break; Loading
libs/androidfw/ResourceTypes.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -7079,6 +7079,10 @@ void DynamicRefTable::addMapping(uint8_t buildPackageId, uint8_t runtimePackageI mLookupTable[buildPackageId] = runtimePackageId; } void DynamicRefTable::addAlias(uint32_t stagedId, uint32_t finalizedId) { mAliasId[stagedId] = finalizedId; } status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const { uint32_t res = *resId; size_t packageId = Res_GETPACKAGE(res) + 1; Loading @@ -7088,8 +7092,16 @@ status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const { return NO_ERROR; } if (packageId == APP_PACKAGE_ID && !mAppAsLib) { // No lookup needs to be done, app package IDs are absolute. auto alias_id = mAliasId.find(res); if (alias_id != mAliasId.end()) { // Rewrite the resource id to its alias resource id. Since the alias resource id is a // compile-time id, it still needs to be resolved further. res = alias_id->second; } if (packageId == SYS_PACKAGE_ID || (packageId == APP_PACKAGE_ID && !mAppAsLib)) { // No lookup needs to be done, app and framework package IDs are absolute. *resId = res; return NO_ERROR; } Loading
libs/androidfw/include/androidfw/LoadedArsc.h +16 −10 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #ifndef LOADEDARSC_H_ #define LOADEDARSC_H_ #include <map> #include <memory> #include <set> #include <vector> Loading Loading @@ -171,51 +172,51 @@ class LoadedPackage { incfs::verified_map_ptr<ResTable_type> type_chunk, uint32_t offset); // Returns the string pool where type names are stored. inline const ResStringPool* GetTypeStringPool() const { const ResStringPool* GetTypeStringPool() const { return &type_string_pool_; } // Returns the string pool where the names of resource entries are stored. inline const ResStringPool* GetKeyStringPool() const { const ResStringPool* GetKeyStringPool() const { return &key_string_pool_; } inline const std::string& GetPackageName() const { const std::string& GetPackageName() const { return package_name_; } inline int GetPackageId() const { int GetPackageId() const { return package_id_; } // Returns true if this package is dynamic (shared library) and needs to have an ID assigned. inline bool IsDynamic() const { bool IsDynamic() const { return (property_flags_ & PROPERTY_DYNAMIC) != 0; } // Returns true if this package is a Runtime Resource Overlay. inline bool IsOverlay() const { bool IsOverlay() const { return (property_flags_ & PROPERTY_OVERLAY) != 0; } // Returns true if this package originates from a system provided resource. inline bool IsSystem() const { bool IsSystem() const { return (property_flags_ & PROPERTY_SYSTEM) != 0; } // Returns true if this package is a custom loader and should behave like an overlay. inline bool IsCustomLoader() const { bool IsCustomLoader() const { return (property_flags_ & PROPERTY_LOADER) != 0; } inline package_property_t GetPropertyFlags() const { package_property_t GetPropertyFlags() const { return property_flags_; } // Returns the map of package name to package ID used in this LoadedPackage. At runtime, a // package could have been assigned a different package ID than what this LoadedPackage was // compiled with. AssetManager rewrites the package IDs so that they are compatible at runtime. inline const std::vector<DynamicPackageEntry>& GetDynamicPackageMap() const { const std::vector<DynamicPackageEntry>& GetDynamicPackageMap() const { return dynamic_package_map_; } Loading Loading @@ -270,6 +271,10 @@ class LoadedPackage { return overlayable_map_; } const std::map<uint32_t, uint32_t>& GetAliasResourceIdMap() const { return alias_id_map_; } private: DISALLOW_COPY_AND_ASSIGN(LoadedPackage); Loading @@ -287,6 +292,7 @@ class LoadedPackage { ByteBucketArray<uint32_t> resource_ids_; std::vector<DynamicPackageEntry> dynamic_package_map_; std::vector<const std::pair<OverlayableInfo, std::unordered_set<uint32_t>>> overlayable_infos_; std::map<uint32_t, uint32_t> alias_id_map_; // A map of overlayable name to actor std::unordered_map<std::string, std::string> overlayable_map_; Loading
libs/androidfw/include/androidfw/ResourceTypes.h +45 −17 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <android/configuration.h> #include <array> #include <map> #include <memory> namespace android { Loading Loading @@ -253,6 +254,7 @@ enum { RES_TABLE_LIBRARY_TYPE = 0x0203, RES_TABLE_OVERLAYABLE_TYPE = 0x0204, RES_TABLE_OVERLAYABLE_POLICY_TYPE = 0x0205, RES_TABLE_STAGED_ALIAS_TYPE = 0x0206, }; /** Loading Loading @@ -1638,6 +1640,29 @@ struct ResTable_lib_entry uint16_t packageName[128]; }; /** * A map that allows rewriting staged (non-finalized) resource ids to their finalized counterparts. */ struct ResTable_staged_alias_header { struct ResChunk_header header; // The number of ResTable_staged_alias_entry that follow this header. uint32_t count; }; /** * Maps the staged (non-finalized) resource id to its finalized resource id. */ struct ResTable_staged_alias_entry { // The compile-time staged resource id to rewrite. uint32_t stagedResId; // The compile-time finalized resource id to which the staged resource id should be rewritten. uint32_t finalizedResId; }; /** * Specifies the set of resources that are explicitly allowed to be overlaid by RROs. */ Loading Loading @@ -1751,6 +1776,8 @@ public: void addMapping(uint8_t buildPackageId, uint8_t runtimePackageId); void addAlias(uint32_t stagedId, uint32_t finalizedId); // Returns whether or not the value must be looked up. bool requiresLookup(const Res_value* value) const; Loading @@ -1768,6 +1795,7 @@ private: uint8_t mLookupTable[256]; KeyedVector<String16, uint8_t> mEntries; bool mAppAsLib; std::map<uint32_t, uint32_t> mAliasId; }; bool U16StringToInt(const char16_t* s, size_t len, Res_value* outValue); Loading