17ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski/* 27ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * Copyright (C) 2016 The Android Open Source Project 37ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * 47ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 57ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * you may not use this file except in compliance with the License. 67ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * You may obtain a copy of the License at 77ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * 87ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 97ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * 107ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * Unless required by applicable law or agreed to in writing, software 117ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 127ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * See the License for the specific language governing permissions and 147ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski * limitations under the License. 157ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski */ 167ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 177ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#ifndef LOADEDARSC_H_ 187ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#define LOADEDARSC_H_ 197ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 207ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include <memory> 210c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski#include <set> 227ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include <vector> 237ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 247ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include "android-base/macros.h" 257ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 26da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski#include "androidfw/ByteBucketArray.h" 27da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski#include "androidfw/Chunk.h" 287ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#include "androidfw/ResourceTypes.h" 29da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski#include "androidfw/Util.h" 307ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 317ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinskinamespace android { 327ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 33da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinskiclass DynamicPackageEntry { 34da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski public: 35da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski DynamicPackageEntry() = default; 36da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski DynamicPackageEntry(std::string&& package_name, int package_id) 37da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski : package_name(std::move(package_name)), package_id(package_id) {} 38da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 39da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski std::string package_name; 40da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski int package_id = 0; 41da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski}; 42da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 43da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinskistruct LoadedArscEntry { 44da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski // A pointer to the resource table entry for this resource. 45da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski // If the size of the entry is > sizeof(ResTable_entry), it can be cast to 46da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski // a ResTable_map_entry and processed as a bag/map. 47da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski const ResTable_entry* entry = nullptr; 48da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 49da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski // The dynamic package ID map for the package from which this resource came from. 50da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski const DynamicRefTable* dynamic_ref_table = nullptr; 51da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 52da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski // The string pool reference to the type's name. This uses a different string pool than 53da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski // the global string pool, but this is hidden from the caller. 54da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski StringPoolRef type_string_ref; 55da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 56da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski // The string pool reference to the entry's name. This uses a different string pool than 57da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski // the global string pool, but this is hidden from the caller. 58da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski StringPoolRef entry_string_ref; 59da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski}; 60da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 61da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinskistruct TypeSpec; 62da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinskiclass LoadedArsc; 63da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 64da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinskiclass LoadedPackage { 65da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski friend class LoadedArsc; 66da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 67da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski public: 68da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski bool FindEntry(uint8_t type_idx, uint16_t entry_idx, const ResTable_config& config, 69da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski LoadedArscEntry* out_entry, ResTable_config* out_selected_config, 70da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski uint32_t* out_flags) const; 71da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 720c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // Returns the string pool where type names are stored. 73da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski inline const ResStringPool* GetTypeStringPool() const { return &type_string_pool_; } 74da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 750c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // Returns the string pool where the names of resource entries are stored. 76da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski inline const ResStringPool* GetKeyStringPool() const { return &key_string_pool_; } 77da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 78da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski inline const std::string& GetPackageName() const { return package_name_; } 79da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 80da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski inline int GetPackageId() const { return package_id_; } 81da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 820c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // Returns true if this package is dynamic (shared library) and needs to have an ID assigned. 83da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski inline bool IsDynamic() const { return dynamic_; } 84da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 850c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // Returns true if this package originates from a system provided resource. 860c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski inline bool IsSystem() const { return system_; } 870c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski 880c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // Returns the map of package name to package ID used in this LoadedPackage. At runtime, a 890c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // package could have been assigned a different package ID than what this LoadedPackage was 900c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // compiled with. AssetManager rewrites the package IDs so that they are compatible at runtime. 91da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski inline const std::vector<DynamicPackageEntry>& GetDynamicPackageMap() const { 92da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski return dynamic_package_map_; 93da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski } 94da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 950c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // Populates a set of ResTable_config structs, possibly excluding configurations defined for 960c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // the mipmap type. 970c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski void CollectConfigurations(bool exclude_mipmap, std::set<ResTable_config>* out_configs) const; 980c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski 990c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // Populates a set of strings representing locales. 1000c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // If `canonicalize` is set to true, each locale is transformed into its canonical format 1010c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // before being inserted into the set. This may cause some equivalent locales to de-dupe. 1020c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski void CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const; 1030c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski 104929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski // Finds the entry with the specified type name and entry name. The names are in UTF-16 because 105929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski // the underlying ResStringPool API expects this. For now this is acceptable, but since 106929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski // the default policy in AAPT2 is to build UTF-8 string pools, this needs to change. 107929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski // Returns a partial resource ID, with the package ID left as 0x00. The caller is responsible 108929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski // for patching the correct package ID to the resource ID. 109929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski uint32_t FindEntryByName(const std::u16string& type_name, const std::u16string& entry_name) const; 110929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski 111da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski private: 112da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski DISALLOW_COPY_AND_ASSIGN(LoadedPackage); 113da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 114da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski static std::unique_ptr<LoadedPackage> Load(const Chunk& chunk); 115da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 116da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski LoadedPackage() = default; 117da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 118da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski ResStringPool type_string_pool_; 119da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski ResStringPool key_string_pool_; 120da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski std::string package_name_; 121da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski int package_id_ = -1; 122c6aada9c5789b2777b19c522d3cd5052bbe784a4Adam Lesinski int type_id_offset_ = 0; 1230c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski bool dynamic_ = false; 1240c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski bool system_ = false; 125da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 126da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski ByteBucketArray<util::unique_cptr<TypeSpec>> type_specs_; 127da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski std::vector<DynamicPackageEntry> dynamic_package_map_; 128da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski}; 1297ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1307ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski// Read-only view into a resource table. This class validates all data 1317ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski// when loading, including offsets and lengths. 1327ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinskiclass LoadedArsc { 1337ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski public: 1340c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // Load a resource table from memory pointed to by `data` of size `len`. 1350c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // The lifetime of `data` must out-live the LoadedArsc returned from this method. 1360c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // If `system` is set to true, the LoadedArsc is considered as a system provided resource. 1370c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // If `load_as_shared_library` is set to true, the application package (0x7f) is treated 1380c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // as a shared library (0x00). When loaded into an AssetManager, the package will be assigned an 1390c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // ID. 1400c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski static std::unique_ptr<const LoadedArsc> Load(const void* data, size_t len, bool system = false, 1410c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski bool load_as_shared_library = false); 1427ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1437ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski ~LoadedArsc(); 1447ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1457ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski // Returns the string pool where all string resource values 1467ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski // (Res_value::dataType == Res_value::TYPE_STRING) are indexed. 1477ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski inline const ResStringPool* GetStringPool() const { return &global_string_pool_; } 1487ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1497ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski // Finds the resource with ID `resid` with the best value for configuration `config`. 1507ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski // The parameter `out_entry` will be filled with the resulting resource entry. 1517ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski // The resource entry can be a simple entry (ResTable_entry) or a complex bag 1527ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski // (ResTable_entry_map). 153da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski bool FindEntry(uint32_t resid, const ResTable_config& config, LoadedArscEntry* out_entry, 1547ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski ResTable_config* selected_config, uint32_t* out_flags) const; 1557ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1567ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski // Gets a pointer to the name of the package in `resid`, or nullptr if the package doesn't exist. 157da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski const LoadedPackage* GetPackageForId(uint32_t resid) const; 158da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski 1590c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // Returns true if this is a system provided resource. 1600c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski inline bool IsSystem() const { return system_; } 1610c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski 1620c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski // Returns a vector of LoadedPackage pointers, representing the packages in this LoadedArsc. 163da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski inline const std::vector<std::unique_ptr<const LoadedPackage>>& GetPackages() const { 164da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski return packages_; 165da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski } 1667ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1677ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski private: 1687ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski DISALLOW_COPY_AND_ASSIGN(LoadedArsc); 1697ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1707ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski LoadedArsc() = default; 171da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski bool LoadTable(const Chunk& chunk, bool load_as_shared_library); 1727ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1737ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski ResStringPool global_string_pool_; 174da431a22da38f9c4085b5d71ed9a9c6122c6a5a6Adam Lesinski std::vector<std::unique_ptr<const LoadedPackage>> packages_; 1750c40524953f3d36a880f91183302a2ea5c722930Adam Lesinski bool system_ = false; 1767ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski}; 1777ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1787ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski} // namespace android 1797ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski 1807ad1110ecd6a840fcd2895c62668828a1ca029c6Adam Lesinski#endif /* LOADEDARSC_H_ */ 181