Loading libs/androidfw/ApkAssets.cpp +11 −8 Original line number Diff line number Diff line Loading @@ -27,15 +27,16 @@ namespace android { std::unique_ptr<ApkAssets> ApkAssets::Load(const std::string& path) { return ApkAssets::LoadImpl(path, false /*load_as_shared_library*/); std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) { return ApkAssets::LoadImpl(path, system, false /*load_as_shared_library*/); } std::unique_ptr<ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path) { return ApkAssets::LoadImpl(path, true /*load_as_shared_library*/); std::unique_ptr<const ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path, bool system) { return ApkAssets::LoadImpl(path, system, true /*load_as_shared_library*/); } std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(const std::string& path, std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(const std::string& path, bool system, bool load_as_shared_library) { ATRACE_CALL(); ::ZipArchiveHandle unmanaged_handle; Loading Loading @@ -70,11 +71,13 @@ std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(const std::string& path, loaded_apk->path_ = path; loaded_apk->loaded_arsc_ = LoadedArsc::Load(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/), loaded_apk->resources_asset_->getLength(), load_as_shared_library); loaded_apk->resources_asset_->getLength(), system, load_as_shared_library); if (loaded_apk->loaded_arsc_ == nullptr) { return {}; } return loaded_apk; // Need to force a move for mingw32. return std::move(loaded_apk); } std::unique_ptr<Asset> ApkAssets::Open(const std::string& path, Asset::AccessMode /*mode*/) const { Loading libs/androidfw/AssetManager2.cpp +80 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ #include "androidfw/AssetManager2.h" #include <set> #include "android-base/logging.h" #include "android-base/stringprintf.h" #include "utils/ByteOrder.h" Loading Loading @@ -143,6 +145,36 @@ void AssetManager2::SetConfiguration(const ResTable_config& configuration) { } } std::set<ResTable_config> AssetManager2::GetResourceConfigurations(bool exclude_system, bool exclude_mipmap) { ATRACE_CALL(); std::set<ResTable_config> configurations; for (const PackageGroup& package_group : package_groups_) { for (const LoadedPackage* package : package_group.packages_) { if (exclude_system && package->IsSystem()) { continue; } package->CollectConfigurations(exclude_mipmap, &configurations); } } return configurations; } std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system, bool merge_equivalent_languages) { ATRACE_CALL(); std::set<std::string> locales; for (const PackageGroup& package_group : package_groups_) { for (const LoadedPackage* package : package_group.packages_) { if (exclude_system && package->IsSystem()) { continue; } package->CollectLocales(merge_equivalent_languages, &locales); } } return locales; } std::unique_ptr<Asset> AssetManager2::Open(const std::string& filename, Asset::AccessMode mode) { const std::string new_path = "assets/" + filename; return OpenNonAsset(new_path, mode); Loading Loading @@ -325,10 +357,17 @@ ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag, if (dtohl(entry.entry->flags) & ResTable_entry::FLAG_COMPLEX) { if (!may_be_bag) { LOG(ERROR) << base::StringPrintf("Resource %08x is a complex map type.", resid); } return kInvalidCookie; } // Create a reference since we can't represent this complex type as a Res_value. out_value->dataType = Res_value::TYPE_REFERENCE; out_value->data = resid; *out_selected_config = config; *out_flags = flags; return cookie; } const Res_value* device_value = reinterpret_cast<const Res_value*>( reinterpret_cast<const uint8_t*>(entry.entry) + dtohs(entry.entry->size)); out_value->copyFrom_dtoh(*device_value); Loading @@ -341,6 +380,37 @@ ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag, return cookie; } ApkAssetsCookie AssetManager2::ResolveReference(ApkAssetsCookie cookie, Res_value* in_out_value, ResTable_config* in_out_selected_config, uint32_t* in_out_flags, ResTable_ref* out_last_reference) { ATRACE_CALL(); constexpr const int kMaxIterations = 20; out_last_reference->ident = 0u; for (size_t iteration = 0u; in_out_value->dataType == Res_value::TYPE_REFERENCE && in_out_value->data != 0u && iteration < kMaxIterations; iteration++) { if (out_last_reference != nullptr) { out_last_reference->ident = in_out_value->data; } uint32_t new_flags = 0u; cookie = GetResource(in_out_value->data, true /*may_be_bag*/, 0u /*density_override*/, in_out_value, in_out_selected_config, &new_flags); if (cookie == kInvalidCookie) { return kInvalidCookie; } if (in_out_flags != nullptr) { *in_out_flags |= new_flags; } if (out_last_reference->ident == in_out_value->data) { // This reference can't be resolved, so exit now and let the caller deal with it. return cookie; } } return cookie; } const ResolvedBag* AssetManager2::GetBag(uint32_t resid) { ATRACE_CALL(); Loading Loading @@ -501,6 +571,15 @@ const ResolvedBag* AssetManager2::GetBag(uint32_t resid) { return result; } uint32_t AssetManager2::GetResourceId(const std::string& resource_name, const std::string& fallback_type, const std::string& fallback_package) { (void)resource_name; (void)fallback_type; (void)fallback_package; return 0u; } void AssetManager2::InvalidateCaches(uint32_t diff) { if (diff == 0xffffffffu) { // Everything must go. Loading libs/androidfw/LoadedArsc.cpp +58 −3 Original line number Diff line number Diff line Loading @@ -321,6 +321,57 @@ static bool VerifyType(const Chunk& chunk) { return true; } void LoadedPackage::CollectConfigurations(bool exclude_mipmap, std::set<ResTable_config>* out_configs) const { const static std::u16string kMipMap = u"mipmap"; const size_t type_count = type_specs_.size(); for (size_t i = 0; i < type_count; i++) { const util::unique_cptr<TypeSpec>& type_spec = type_specs_[i]; if (type_spec != nullptr) { if (exclude_mipmap) { const int type_idx = type_spec->type_spec->id - 1; size_t type_name_len; const char16_t* type_name16 = type_string_pool_.stringAt(type_idx, &type_name_len); if (type_name16 != nullptr) { if (kMipMap.compare(0, std::u16string::npos, type_name16, type_name_len) == 0) { // This is a mipmap type, skip collection. continue; } } const char* type_name = type_string_pool_.string8At(type_idx, &type_name_len); if (type_name != nullptr) { if (strncmp(type_name, "mipmap", type_name_len) == 0) { // This is a mipmap type, skip collection. continue; } } } for (size_t j = 0; j < type_spec->type_count; j++) { out_configs->insert(type_spec->types[j].configuration); } } } } void LoadedPackage::CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const { char temp_locale[RESTABLE_MAX_LOCALE_LEN]; const size_t type_count = type_specs_.size(); for (size_t i = 0; i < type_count; i++) { const util::unique_cptr<TypeSpec>& type_spec = type_specs_[i]; if (type_spec != nullptr) { for (size_t j = 0; j < type_spec->type_count; j++) { const ResTable_config& configuration = type_spec->types[j].configuration; if (configuration.locale != 0) { configuration.getBcp47Locale(temp_locale, canonicalize); std::string locale(temp_locale); out_locales->insert(std::move(locale)); } } } } } std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk) { ATRACE_CALL(); std::unique_ptr<LoadedPackage> loaded_package{new LoadedPackage()}; Loading Loading @@ -574,6 +625,7 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, bool load_as_shared_library) { if (loaded_package->package_id_ == kAppPackageId) { loaded_package->dynamic_ = load_as_shared_library; } loaded_package->system_ = system_; packages_.push_back(std::move(loaded_package)); } break; Loading @@ -590,12 +642,13 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, bool load_as_shared_library) { return true; } std::unique_ptr<LoadedArsc> LoadedArsc::Load(const void* data, size_t len, std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const void* data, size_t len, bool system, bool load_as_shared_library) { ATRACE_CALL(); // Not using make_unique because the constructor is private. std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc()); loaded_arsc->system_ = system; ChunkIterator iter(data, len); while (iter.HasNext()) { Loading @@ -617,7 +670,9 @@ std::unique_ptr<LoadedArsc> LoadedArsc::Load(const void* data, size_t len, LOG(ERROR) << iter.GetLastError(); return {}; } return loaded_arsc; // Need to force a move for mingw32. return std::move(loaded_arsc); } } // namespace android libs/androidfw/include/androidfw/ApkAssets.h +6 −4 Original line number Diff line number Diff line Loading @@ -31,8 +31,9 @@ namespace android { // Holds an APK. class ApkAssets { public: static std::unique_ptr<ApkAssets> Load(const std::string& path); static std::unique_ptr<ApkAssets> LoadAsSharedLibrary(const std::string& path); static std::unique_ptr<const ApkAssets> Load(const std::string& path, bool system = false); static std::unique_ptr<const ApkAssets> LoadAsSharedLibrary(const std::string& path, bool system = false); std::unique_ptr<Asset> Open(const std::string& path, Asset::AccessMode mode = Asset::AccessMode::ACCESS_RANDOM) const; Loading @@ -44,7 +45,8 @@ class ApkAssets { private: DISALLOW_COPY_AND_ASSIGN(ApkAssets); static std::unique_ptr<ApkAssets> LoadImpl(const std::string& path, bool load_as_shared_library); static std::unique_ptr<const ApkAssets> LoadImpl(const std::string& path, bool system, bool load_as_shared_library); ApkAssets() = default; Loading @@ -57,7 +59,7 @@ class ApkAssets { ZipArchivePtr zip_handle_; std::string path_; std::unique_ptr<Asset> resources_asset_; std::unique_ptr<LoadedArsc> loaded_arsc_; std::unique_ptr<const LoadedArsc> loaded_arsc_; }; } // namespace android Loading libs/androidfw/include/androidfw/AssetManager2.h +43 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <array> #include <limits> #include <set> #include <unordered_map> #include "androidfw/ApkAssets.h" Loading Loading @@ -112,6 +113,24 @@ class AssetManager2 : public ::AAssetManager { inline const ResTable_config& GetConfiguration() const { return configuration_; } // Returns all configurations for which there are resources defined. This includes resource // configurations in all the ApkAssets set for this AssetManager. // If `exclude_system` is set to true, resource configurations from system APKs // ('android' package, other libraries) will be excluded from the list. // If `exclude_mipmap` is set to true, resource configurations defined for resource type 'mipmap' // will be excluded from the list. std::set<ResTable_config> GetResourceConfigurations(bool exclude_system = false, bool exclude_mipmap = false); // Returns all the locales for which there are resources defined. This includes resource // locales in all the ApkAssets set for this AssetManager. // If `exclude_system` is set to true, resource locales from system APKs // ('android' package, other libraries) will be excluded from the list. // If `merge_equivalent_languages` is set to true, resource locales will be canonicalized // and de-duped in the resulting list. std::set<std::string> GetResourceLocales(bool exclude_system = false, bool merge_equivalent_languages = false); // Searches the set of APKs loaded by this AssetManager and opens the first one found located // in the assets/ directory. // `mode` controls how the file is opened. Loading Loading @@ -149,6 +168,14 @@ class AssetManager2 : public ::AAssetManager { // Returns false if the resource was not found. bool GetResourceFlags(uint32_t resid, uint32_t* out_flags); // Finds the resource ID assigned to `resource_name`. // `resource_name` must be of the form '[package:][type/]entry'. // If no package is specified in `resource_name`, then `fallback_package` is used as the package. // If no type is specified in `resource_name`, then `fallback_type` is used as the type. // Returns 0x0 if no resource by that name was found. uint32_t GetResourceId(const std::string& resource_name, const std::string& fallback_type = {}, const std::string& fallback_package = {}); // Retrieves the best matching resource with ID `resid`. The resource value is filled into // `out_value` and the configuration for the selected value is populated in `out_selected_config`. // `out_flags` holds the same flags as retrieved with GetResourceFlags(). Loading @@ -162,6 +189,22 @@ class AssetManager2 : public ::AAssetManager { Res_value* out_value, ResTable_config* out_selected_config, uint32_t* out_flags); // Resolves the resource reference in `in_out_value` if the data type is // Res_value::TYPE_REFERENCE. // `cookie` is the ApkAssetsCookie of the reference in `in_out_value`. // `in_out_value` is the reference to resolve. The result is placed back into this object. // `in_out_flags` is the type spec flags returned from calls to GetResource() or // GetResourceFlags(). Configuration flags of the values pointed to by the reference // are OR'd together with `in_out_flags`. // `in_out_config` is populated with the configuration for which the resolved value was defined. // `out_last_reference` is populated with the last reference ID before resolving to an actual // value. // Returns the cookie of the APK the resolved resource was defined in, or kInvalidCookie if // it was not found. ApkAssetsCookie ResolveReference(ApkAssetsCookie cookie, Res_value* in_out_value, ResTable_config* in_out_selected_config, uint32_t* in_out_flags, ResTable_ref* out_last_reference); // Retrieves the best matching bag/map resource with ID `resid`. // This method will resolve all parent references for this bag and merge keys with the child. // To iterate over the keys, use the following idiom: Loading Loading
libs/androidfw/ApkAssets.cpp +11 −8 Original line number Diff line number Diff line Loading @@ -27,15 +27,16 @@ namespace android { std::unique_ptr<ApkAssets> ApkAssets::Load(const std::string& path) { return ApkAssets::LoadImpl(path, false /*load_as_shared_library*/); std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) { return ApkAssets::LoadImpl(path, system, false /*load_as_shared_library*/); } std::unique_ptr<ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path) { return ApkAssets::LoadImpl(path, true /*load_as_shared_library*/); std::unique_ptr<const ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path, bool system) { return ApkAssets::LoadImpl(path, system, true /*load_as_shared_library*/); } std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(const std::string& path, std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(const std::string& path, bool system, bool load_as_shared_library) { ATRACE_CALL(); ::ZipArchiveHandle unmanaged_handle; Loading Loading @@ -70,11 +71,13 @@ std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(const std::string& path, loaded_apk->path_ = path; loaded_apk->loaded_arsc_ = LoadedArsc::Load(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/), loaded_apk->resources_asset_->getLength(), load_as_shared_library); loaded_apk->resources_asset_->getLength(), system, load_as_shared_library); if (loaded_apk->loaded_arsc_ == nullptr) { return {}; } return loaded_apk; // Need to force a move for mingw32. return std::move(loaded_apk); } std::unique_ptr<Asset> ApkAssets::Open(const std::string& path, Asset::AccessMode /*mode*/) const { Loading
libs/androidfw/AssetManager2.cpp +80 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ #include "androidfw/AssetManager2.h" #include <set> #include "android-base/logging.h" #include "android-base/stringprintf.h" #include "utils/ByteOrder.h" Loading Loading @@ -143,6 +145,36 @@ void AssetManager2::SetConfiguration(const ResTable_config& configuration) { } } std::set<ResTable_config> AssetManager2::GetResourceConfigurations(bool exclude_system, bool exclude_mipmap) { ATRACE_CALL(); std::set<ResTable_config> configurations; for (const PackageGroup& package_group : package_groups_) { for (const LoadedPackage* package : package_group.packages_) { if (exclude_system && package->IsSystem()) { continue; } package->CollectConfigurations(exclude_mipmap, &configurations); } } return configurations; } std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system, bool merge_equivalent_languages) { ATRACE_CALL(); std::set<std::string> locales; for (const PackageGroup& package_group : package_groups_) { for (const LoadedPackage* package : package_group.packages_) { if (exclude_system && package->IsSystem()) { continue; } package->CollectLocales(merge_equivalent_languages, &locales); } } return locales; } std::unique_ptr<Asset> AssetManager2::Open(const std::string& filename, Asset::AccessMode mode) { const std::string new_path = "assets/" + filename; return OpenNonAsset(new_path, mode); Loading Loading @@ -325,10 +357,17 @@ ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag, if (dtohl(entry.entry->flags) & ResTable_entry::FLAG_COMPLEX) { if (!may_be_bag) { LOG(ERROR) << base::StringPrintf("Resource %08x is a complex map type.", resid); } return kInvalidCookie; } // Create a reference since we can't represent this complex type as a Res_value. out_value->dataType = Res_value::TYPE_REFERENCE; out_value->data = resid; *out_selected_config = config; *out_flags = flags; return cookie; } const Res_value* device_value = reinterpret_cast<const Res_value*>( reinterpret_cast<const uint8_t*>(entry.entry) + dtohs(entry.entry->size)); out_value->copyFrom_dtoh(*device_value); Loading @@ -341,6 +380,37 @@ ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag, return cookie; } ApkAssetsCookie AssetManager2::ResolveReference(ApkAssetsCookie cookie, Res_value* in_out_value, ResTable_config* in_out_selected_config, uint32_t* in_out_flags, ResTable_ref* out_last_reference) { ATRACE_CALL(); constexpr const int kMaxIterations = 20; out_last_reference->ident = 0u; for (size_t iteration = 0u; in_out_value->dataType == Res_value::TYPE_REFERENCE && in_out_value->data != 0u && iteration < kMaxIterations; iteration++) { if (out_last_reference != nullptr) { out_last_reference->ident = in_out_value->data; } uint32_t new_flags = 0u; cookie = GetResource(in_out_value->data, true /*may_be_bag*/, 0u /*density_override*/, in_out_value, in_out_selected_config, &new_flags); if (cookie == kInvalidCookie) { return kInvalidCookie; } if (in_out_flags != nullptr) { *in_out_flags |= new_flags; } if (out_last_reference->ident == in_out_value->data) { // This reference can't be resolved, so exit now and let the caller deal with it. return cookie; } } return cookie; } const ResolvedBag* AssetManager2::GetBag(uint32_t resid) { ATRACE_CALL(); Loading Loading @@ -501,6 +571,15 @@ const ResolvedBag* AssetManager2::GetBag(uint32_t resid) { return result; } uint32_t AssetManager2::GetResourceId(const std::string& resource_name, const std::string& fallback_type, const std::string& fallback_package) { (void)resource_name; (void)fallback_type; (void)fallback_package; return 0u; } void AssetManager2::InvalidateCaches(uint32_t diff) { if (diff == 0xffffffffu) { // Everything must go. Loading
libs/androidfw/LoadedArsc.cpp +58 −3 Original line number Diff line number Diff line Loading @@ -321,6 +321,57 @@ static bool VerifyType(const Chunk& chunk) { return true; } void LoadedPackage::CollectConfigurations(bool exclude_mipmap, std::set<ResTable_config>* out_configs) const { const static std::u16string kMipMap = u"mipmap"; const size_t type_count = type_specs_.size(); for (size_t i = 0; i < type_count; i++) { const util::unique_cptr<TypeSpec>& type_spec = type_specs_[i]; if (type_spec != nullptr) { if (exclude_mipmap) { const int type_idx = type_spec->type_spec->id - 1; size_t type_name_len; const char16_t* type_name16 = type_string_pool_.stringAt(type_idx, &type_name_len); if (type_name16 != nullptr) { if (kMipMap.compare(0, std::u16string::npos, type_name16, type_name_len) == 0) { // This is a mipmap type, skip collection. continue; } } const char* type_name = type_string_pool_.string8At(type_idx, &type_name_len); if (type_name != nullptr) { if (strncmp(type_name, "mipmap", type_name_len) == 0) { // This is a mipmap type, skip collection. continue; } } } for (size_t j = 0; j < type_spec->type_count; j++) { out_configs->insert(type_spec->types[j].configuration); } } } } void LoadedPackage::CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const { char temp_locale[RESTABLE_MAX_LOCALE_LEN]; const size_t type_count = type_specs_.size(); for (size_t i = 0; i < type_count; i++) { const util::unique_cptr<TypeSpec>& type_spec = type_specs_[i]; if (type_spec != nullptr) { for (size_t j = 0; j < type_spec->type_count; j++) { const ResTable_config& configuration = type_spec->types[j].configuration; if (configuration.locale != 0) { configuration.getBcp47Locale(temp_locale, canonicalize); std::string locale(temp_locale); out_locales->insert(std::move(locale)); } } } } } std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk) { ATRACE_CALL(); std::unique_ptr<LoadedPackage> loaded_package{new LoadedPackage()}; Loading Loading @@ -574,6 +625,7 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, bool load_as_shared_library) { if (loaded_package->package_id_ == kAppPackageId) { loaded_package->dynamic_ = load_as_shared_library; } loaded_package->system_ = system_; packages_.push_back(std::move(loaded_package)); } break; Loading @@ -590,12 +642,13 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, bool load_as_shared_library) { return true; } std::unique_ptr<LoadedArsc> LoadedArsc::Load(const void* data, size_t len, std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const void* data, size_t len, bool system, bool load_as_shared_library) { ATRACE_CALL(); // Not using make_unique because the constructor is private. std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc()); loaded_arsc->system_ = system; ChunkIterator iter(data, len); while (iter.HasNext()) { Loading @@ -617,7 +670,9 @@ std::unique_ptr<LoadedArsc> LoadedArsc::Load(const void* data, size_t len, LOG(ERROR) << iter.GetLastError(); return {}; } return loaded_arsc; // Need to force a move for mingw32. return std::move(loaded_arsc); } } // namespace android
libs/androidfw/include/androidfw/ApkAssets.h +6 −4 Original line number Diff line number Diff line Loading @@ -31,8 +31,9 @@ namespace android { // Holds an APK. class ApkAssets { public: static std::unique_ptr<ApkAssets> Load(const std::string& path); static std::unique_ptr<ApkAssets> LoadAsSharedLibrary(const std::string& path); static std::unique_ptr<const ApkAssets> Load(const std::string& path, bool system = false); static std::unique_ptr<const ApkAssets> LoadAsSharedLibrary(const std::string& path, bool system = false); std::unique_ptr<Asset> Open(const std::string& path, Asset::AccessMode mode = Asset::AccessMode::ACCESS_RANDOM) const; Loading @@ -44,7 +45,8 @@ class ApkAssets { private: DISALLOW_COPY_AND_ASSIGN(ApkAssets); static std::unique_ptr<ApkAssets> LoadImpl(const std::string& path, bool load_as_shared_library); static std::unique_ptr<const ApkAssets> LoadImpl(const std::string& path, bool system, bool load_as_shared_library); ApkAssets() = default; Loading @@ -57,7 +59,7 @@ class ApkAssets { ZipArchivePtr zip_handle_; std::string path_; std::unique_ptr<Asset> resources_asset_; std::unique_ptr<LoadedArsc> loaded_arsc_; std::unique_ptr<const LoadedArsc> loaded_arsc_; }; } // namespace android Loading
libs/androidfw/include/androidfw/AssetManager2.h +43 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <array> #include <limits> #include <set> #include <unordered_map> #include "androidfw/ApkAssets.h" Loading Loading @@ -112,6 +113,24 @@ class AssetManager2 : public ::AAssetManager { inline const ResTable_config& GetConfiguration() const { return configuration_; } // Returns all configurations for which there are resources defined. This includes resource // configurations in all the ApkAssets set for this AssetManager. // If `exclude_system` is set to true, resource configurations from system APKs // ('android' package, other libraries) will be excluded from the list. // If `exclude_mipmap` is set to true, resource configurations defined for resource type 'mipmap' // will be excluded from the list. std::set<ResTable_config> GetResourceConfigurations(bool exclude_system = false, bool exclude_mipmap = false); // Returns all the locales for which there are resources defined. This includes resource // locales in all the ApkAssets set for this AssetManager. // If `exclude_system` is set to true, resource locales from system APKs // ('android' package, other libraries) will be excluded from the list. // If `merge_equivalent_languages` is set to true, resource locales will be canonicalized // and de-duped in the resulting list. std::set<std::string> GetResourceLocales(bool exclude_system = false, bool merge_equivalent_languages = false); // Searches the set of APKs loaded by this AssetManager and opens the first one found located // in the assets/ directory. // `mode` controls how the file is opened. Loading Loading @@ -149,6 +168,14 @@ class AssetManager2 : public ::AAssetManager { // Returns false if the resource was not found. bool GetResourceFlags(uint32_t resid, uint32_t* out_flags); // Finds the resource ID assigned to `resource_name`. // `resource_name` must be of the form '[package:][type/]entry'. // If no package is specified in `resource_name`, then `fallback_package` is used as the package. // If no type is specified in `resource_name`, then `fallback_type` is used as the type. // Returns 0x0 if no resource by that name was found. uint32_t GetResourceId(const std::string& resource_name, const std::string& fallback_type = {}, const std::string& fallback_package = {}); // Retrieves the best matching resource with ID `resid`. The resource value is filled into // `out_value` and the configuration for the selected value is populated in `out_selected_config`. // `out_flags` holds the same flags as retrieved with GetResourceFlags(). Loading @@ -162,6 +189,22 @@ class AssetManager2 : public ::AAssetManager { Res_value* out_value, ResTable_config* out_selected_config, uint32_t* out_flags); // Resolves the resource reference in `in_out_value` if the data type is // Res_value::TYPE_REFERENCE. // `cookie` is the ApkAssetsCookie of the reference in `in_out_value`. // `in_out_value` is the reference to resolve. The result is placed back into this object. // `in_out_flags` is the type spec flags returned from calls to GetResource() or // GetResourceFlags(). Configuration flags of the values pointed to by the reference // are OR'd together with `in_out_flags`. // `in_out_config` is populated with the configuration for which the resolved value was defined. // `out_last_reference` is populated with the last reference ID before resolving to an actual // value. // Returns the cookie of the APK the resolved resource was defined in, or kInvalidCookie if // it was not found. ApkAssetsCookie ResolveReference(ApkAssetsCookie cookie, Res_value* in_out_value, ResTable_config* in_out_selected_config, uint32_t* in_out_flags, ResTable_ref* out_last_reference); // Retrieves the best matching bag/map resource with ID `resid`. // This method will resolve all parent references for this bag and merge keys with the child. // To iterate over the keys, use the following idiom: Loading