Loading core/jni/android_util_AssetManager.cpp +5 −2 Original line number Diff line number Diff line Loading @@ -343,7 +343,9 @@ static jobject NativeGetOverlayableMap(JNIEnv* env, jclass /*clazz*/, jlong ptr, assetmanager->ForEachPackage([&](const std::string& this_package_name, uint8_t package_id) { if (this_package_name == std_package_name) { map = assetmanager->GetOverlayableMapForPackage(package_id); return false; } return true; }); if (map == nullptr) { Loading Loading @@ -521,15 +523,16 @@ static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/ return nullptr; } assetmanager->ForEachPackage([&](const std::string& package_name, uint8_t package_id) { assetmanager->ForEachPackage([&](const std::string& package_name, uint8_t package_id) -> bool { jstring jpackage_name = env->NewStringUTF(package_name.c_str()); if (jpackage_name == nullptr) { // An exception is pending. return; return false; } env->CallVoidMethod(sparse_array, gSparseArrayOffsets.put, static_cast<jint>(package_id), jpackage_name); return true; }); return sparse_array; } Loading libs/androidfw/AssetManager2.cpp +39 −25 Original line number Diff line number Diff line Loading @@ -356,6 +356,7 @@ std::unique_ptr<Asset> AssetManager2::OpenNonAsset(const std::string& filename, ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_override, bool /*stop_at_first_match*/, bool ignore_configuration, FindEntryResult* out_entry) const { // Might use this if density_override != 0. ResTable_config density_override_config; Loading Loading @@ -399,7 +400,7 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri // If desired_config is the same as the set configuration, then we can use our filtered list // and we don't need to match the configurations, since they already matched. const bool use_fast_path = desired_config == &configuration_; const bool use_fast_path = !ignore_configuration && desired_config == &configuration_; for (size_t pi = 0; pi < package_count; pi++) { const ConfiguredPackage& loaded_package_impl = package_group.packages_[pi]; Loading Loading @@ -475,9 +476,10 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri // ResTable_config, we must copy it. const auto iter_end = type_spec->types + type_spec->type_count; for (auto iter = type_spec->types; iter != iter_end; ++iter) { ResTable_config this_config; this_config.copyFromDtoH((*iter)->config); ResTable_config this_config{}; if (!ignore_configuration) { this_config.copyFromDtoH((*iter)->config); if (!this_config.match(*desired_config)) { continue; } Loading @@ -491,6 +493,7 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri } else { continue; } } // The configuration matches and is better than the previous selection. // Find the entry value if it exists for this configuration. Loading @@ -506,6 +509,11 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri best_config = &best_config_copy; best_offset = offset; if (ignore_configuration) { // Any configuration will suffice, so break. break; } if (resource_resolution_logging_enabled_) { resolution_steps.push_back(Resolution::Step{resolution_type, this_config.toString(), Loading Loading @@ -622,8 +630,9 @@ std::string AssetManager2::GetLastResourceResolution() const { bool AssetManager2::GetResourceName(uint32_t resid, ResourceName* out_name) const { FindEntryResult entry; ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, true /* stop_at_first_match */, &entry); ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, true /* stop_at_first_match */, true /* ignore_configuration */, &entry); if (cookie == kInvalidCookie) { return false; } Loading Loading @@ -652,13 +661,14 @@ bool AssetManager2::GetResourceName(uint32_t resid, ResourceName* out_name) cons bool AssetManager2::GetResourceFlags(uint32_t resid, uint32_t* out_flags) const { FindEntryResult entry; ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, false /* stop_at_first_match */, &entry); ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, false /* stop_at_first_match */, true /* ignore_configuration */, &entry); if (cookie != kInvalidCookie) { *out_flags = entry.type_flags; return cookie; return true; } return kInvalidCookie; return false; } ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag, Loading @@ -666,8 +676,8 @@ ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag, ResTable_config* out_selected_config, uint32_t* out_flags) const { FindEntryResult entry; ApkAssetsCookie cookie = FindEntry(resid, density_override, false /* stop_at_first_match */, &entry); ApkAssetsCookie cookie = FindEntry(resid, density_override, false /* stop_at_first_match */, false /* ignore_configuration */, &entry); if (cookie == kInvalidCookie) { return kInvalidCookie; } Loading Loading @@ -759,8 +769,10 @@ const ResolvedBag* AssetManager2::GetBag(uint32_t resid, std::vector<uint32_t>& } FindEntryResult entry; ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, false /* stop_at_first_match */, &entry); ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, false /* stop_at_first_match */, false /* ignore_configuration */, &entry); if (cookie == kInvalidCookie) { return nullptr; } Loading Loading @@ -1387,7 +1399,9 @@ void Theme::SetTo(const Theme& o) { // Find the cookie of the attribute resource id FindEntryResult attribute_entry_result; ApkAssetsCookie attribute_cookie = o.asset_manager_->FindEntry(make_resid(p, t, e), 0 /* density_override */ , false, o.asset_manager_->FindEntry(make_resid(p, t, e), 0 /* density_override */ , true /* stop_at_first_match */, true /* ignore_configuration */, &attribute_entry_result); // Determine the package id of the attribute in the destination AssetManager Loading libs/androidfw/include/androidfw/AssetManager2.h +9 −5 Original line number Diff line number Diff line Loading @@ -257,11 +257,12 @@ class AssetManager2 { // Creates a new Theme from this AssetManager. std::unique_ptr<Theme> NewTheme(); template <typename Func> void ForEachPackage(Func func) const { void ForEachPackage(const std::function<bool(const std::string&, uint8_t)> func) const { for (const PackageGroup& package_group : package_groups_) { func(package_group.packages_.front().loaded_package_->GetPackageName(), package_group.dynamic_ref_table.mAssignedPackageId); if (!func(package_group.packages_.front().loaded_package_->GetPackageName(), package_group.dynamic_ref_table.mAssignedPackageId)) { return; } } } Loading @@ -282,10 +283,13 @@ class AssetManager2 { // care about the value. In this case, the value of `FindEntryResult::type_flags` is incomplete // and should not be used. // // When `ignore_configuration` is true, FindEntry will return always select the first entry in // for the type seen regardless of its configuration. // // NOTE: FindEntry takes care of ensuring that structs within FindEntryResult have been properly // bounds-checked. Callers of FindEntry are free to trust the data if this method succeeds. ApkAssetsCookie FindEntry(uint32_t resid, uint16_t density_override, bool stop_at_first_match, FindEntryResult* out_entry) const; bool ignore_configuration, FindEntryResult* out_entry) const; // Assigns package IDs to all shared library ApkAssets. // Should be called whenever the ApkAssets are changed. Loading tools/aapt2/ResourceUtils.cpp +36 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ constexpr int32_t kNonBreakingSpace = 0xa0; Maybe<ResourceName> ToResourceName( const android::ResTable::resource_name& name_in) { // TODO: Remove this when ResTable and AssetManager(1) are removed from AAPT2 ResourceName name_out; if (!name_in.package) { return {}; Loading Loading @@ -79,6 +80,41 @@ Maybe<ResourceName> ToResourceName( return name_out; } Maybe<ResourceName> ToResourceName(const android::AssetManager2::ResourceName& name_in) { ResourceName name_out; if (!name_in.package) { return {}; } name_out.package = std::string(name_in.package, name_in.package_len); const ResourceType* type; if (name_in.type16) { type = ParseResourceType( util::Utf16ToUtf8(StringPiece16(name_in.type16, name_in.type_len))); } else if (name_in.type) { type = ParseResourceType(StringPiece(name_in.type, name_in.type_len)); } else { return {}; } if (!type) { return {}; } name_out.type = *type; if (name_in.entry16) { name_out.entry = util::Utf16ToUtf8(StringPiece16(name_in.entry16, name_in.entry_len)); } else if (name_in.entry) { name_out.entry = std::string(name_in.entry, name_in.entry_len); } else { return {}; } return name_out; } bool ParseResourceName(const StringPiece& str, ResourceNameRef* out_ref, bool* out_private) { if (str.empty()) { Loading tools/aapt2/ResourceUtils.h +7 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <functional> #include <memory> #include "androidfw/AssetManager2.h" #include "androidfw/ConfigDescription.h" #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" Loading Loading @@ -77,6 +78,12 @@ bool IsAttributeReference(const android::StringPiece& str); Maybe<ResourceName> ToResourceName( const android::ResTable::resource_name& name); /** * Convert an android::AssetManager2::ResourceName to an aapt::ResourceName struct. */ Maybe<ResourceName> ToResourceName( const android::AssetManager2::ResourceName& name_in); /** * Returns a boolean value if the string is equal to TRUE, true, True, FALSE, * false, or False. Loading Loading
core/jni/android_util_AssetManager.cpp +5 −2 Original line number Diff line number Diff line Loading @@ -343,7 +343,9 @@ static jobject NativeGetOverlayableMap(JNIEnv* env, jclass /*clazz*/, jlong ptr, assetmanager->ForEachPackage([&](const std::string& this_package_name, uint8_t package_id) { if (this_package_name == std_package_name) { map = assetmanager->GetOverlayableMapForPackage(package_id); return false; } return true; }); if (map == nullptr) { Loading Loading @@ -521,15 +523,16 @@ static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/ return nullptr; } assetmanager->ForEachPackage([&](const std::string& package_name, uint8_t package_id) { assetmanager->ForEachPackage([&](const std::string& package_name, uint8_t package_id) -> bool { jstring jpackage_name = env->NewStringUTF(package_name.c_str()); if (jpackage_name == nullptr) { // An exception is pending. return; return false; } env->CallVoidMethod(sparse_array, gSparseArrayOffsets.put, static_cast<jint>(package_id), jpackage_name); return true; }); return sparse_array; } Loading
libs/androidfw/AssetManager2.cpp +39 −25 Original line number Diff line number Diff line Loading @@ -356,6 +356,7 @@ std::unique_ptr<Asset> AssetManager2::OpenNonAsset(const std::string& filename, ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_override, bool /*stop_at_first_match*/, bool ignore_configuration, FindEntryResult* out_entry) const { // Might use this if density_override != 0. ResTable_config density_override_config; Loading Loading @@ -399,7 +400,7 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri // If desired_config is the same as the set configuration, then we can use our filtered list // and we don't need to match the configurations, since they already matched. const bool use_fast_path = desired_config == &configuration_; const bool use_fast_path = !ignore_configuration && desired_config == &configuration_; for (size_t pi = 0; pi < package_count; pi++) { const ConfiguredPackage& loaded_package_impl = package_group.packages_[pi]; Loading Loading @@ -475,9 +476,10 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri // ResTable_config, we must copy it. const auto iter_end = type_spec->types + type_spec->type_count; for (auto iter = type_spec->types; iter != iter_end; ++iter) { ResTable_config this_config; this_config.copyFromDtoH((*iter)->config); ResTable_config this_config{}; if (!ignore_configuration) { this_config.copyFromDtoH((*iter)->config); if (!this_config.match(*desired_config)) { continue; } Loading @@ -491,6 +493,7 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri } else { continue; } } // The configuration matches and is better than the previous selection. // Find the entry value if it exists for this configuration. Loading @@ -506,6 +509,11 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri best_config = &best_config_copy; best_offset = offset; if (ignore_configuration) { // Any configuration will suffice, so break. break; } if (resource_resolution_logging_enabled_) { resolution_steps.push_back(Resolution::Step{resolution_type, this_config.toString(), Loading Loading @@ -622,8 +630,9 @@ std::string AssetManager2::GetLastResourceResolution() const { bool AssetManager2::GetResourceName(uint32_t resid, ResourceName* out_name) const { FindEntryResult entry; ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, true /* stop_at_first_match */, &entry); ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, true /* stop_at_first_match */, true /* ignore_configuration */, &entry); if (cookie == kInvalidCookie) { return false; } Loading Loading @@ -652,13 +661,14 @@ bool AssetManager2::GetResourceName(uint32_t resid, ResourceName* out_name) cons bool AssetManager2::GetResourceFlags(uint32_t resid, uint32_t* out_flags) const { FindEntryResult entry; ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, false /* stop_at_first_match */, &entry); ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, false /* stop_at_first_match */, true /* ignore_configuration */, &entry); if (cookie != kInvalidCookie) { *out_flags = entry.type_flags; return cookie; return true; } return kInvalidCookie; return false; } ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag, Loading @@ -666,8 +676,8 @@ ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag, ResTable_config* out_selected_config, uint32_t* out_flags) const { FindEntryResult entry; ApkAssetsCookie cookie = FindEntry(resid, density_override, false /* stop_at_first_match */, &entry); ApkAssetsCookie cookie = FindEntry(resid, density_override, false /* stop_at_first_match */, false /* ignore_configuration */, &entry); if (cookie == kInvalidCookie) { return kInvalidCookie; } Loading Loading @@ -759,8 +769,10 @@ const ResolvedBag* AssetManager2::GetBag(uint32_t resid, std::vector<uint32_t>& } FindEntryResult entry; ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, false /* stop_at_first_match */, &entry); ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */, false /* stop_at_first_match */, false /* ignore_configuration */, &entry); if (cookie == kInvalidCookie) { return nullptr; } Loading Loading @@ -1387,7 +1399,9 @@ void Theme::SetTo(const Theme& o) { // Find the cookie of the attribute resource id FindEntryResult attribute_entry_result; ApkAssetsCookie attribute_cookie = o.asset_manager_->FindEntry(make_resid(p, t, e), 0 /* density_override */ , false, o.asset_manager_->FindEntry(make_resid(p, t, e), 0 /* density_override */ , true /* stop_at_first_match */, true /* ignore_configuration */, &attribute_entry_result); // Determine the package id of the attribute in the destination AssetManager Loading
libs/androidfw/include/androidfw/AssetManager2.h +9 −5 Original line number Diff line number Diff line Loading @@ -257,11 +257,12 @@ class AssetManager2 { // Creates a new Theme from this AssetManager. std::unique_ptr<Theme> NewTheme(); template <typename Func> void ForEachPackage(Func func) const { void ForEachPackage(const std::function<bool(const std::string&, uint8_t)> func) const { for (const PackageGroup& package_group : package_groups_) { func(package_group.packages_.front().loaded_package_->GetPackageName(), package_group.dynamic_ref_table.mAssignedPackageId); if (!func(package_group.packages_.front().loaded_package_->GetPackageName(), package_group.dynamic_ref_table.mAssignedPackageId)) { return; } } } Loading @@ -282,10 +283,13 @@ class AssetManager2 { // care about the value. In this case, the value of `FindEntryResult::type_flags` is incomplete // and should not be used. // // When `ignore_configuration` is true, FindEntry will return always select the first entry in // for the type seen regardless of its configuration. // // NOTE: FindEntry takes care of ensuring that structs within FindEntryResult have been properly // bounds-checked. Callers of FindEntry are free to trust the data if this method succeeds. ApkAssetsCookie FindEntry(uint32_t resid, uint16_t density_override, bool stop_at_first_match, FindEntryResult* out_entry) const; bool ignore_configuration, FindEntryResult* out_entry) const; // Assigns package IDs to all shared library ApkAssets. // Should be called whenever the ApkAssets are changed. Loading
tools/aapt2/ResourceUtils.cpp +36 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ constexpr int32_t kNonBreakingSpace = 0xa0; Maybe<ResourceName> ToResourceName( const android::ResTable::resource_name& name_in) { // TODO: Remove this when ResTable and AssetManager(1) are removed from AAPT2 ResourceName name_out; if (!name_in.package) { return {}; Loading Loading @@ -79,6 +80,41 @@ Maybe<ResourceName> ToResourceName( return name_out; } Maybe<ResourceName> ToResourceName(const android::AssetManager2::ResourceName& name_in) { ResourceName name_out; if (!name_in.package) { return {}; } name_out.package = std::string(name_in.package, name_in.package_len); const ResourceType* type; if (name_in.type16) { type = ParseResourceType( util::Utf16ToUtf8(StringPiece16(name_in.type16, name_in.type_len))); } else if (name_in.type) { type = ParseResourceType(StringPiece(name_in.type, name_in.type_len)); } else { return {}; } if (!type) { return {}; } name_out.type = *type; if (name_in.entry16) { name_out.entry = util::Utf16ToUtf8(StringPiece16(name_in.entry16, name_in.entry_len)); } else if (name_in.entry) { name_out.entry = std::string(name_in.entry, name_in.entry_len); } else { return {}; } return name_out; } bool ParseResourceName(const StringPiece& str, ResourceNameRef* out_ref, bool* out_private) { if (str.empty()) { Loading
tools/aapt2/ResourceUtils.h +7 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <functional> #include <memory> #include "androidfw/AssetManager2.h" #include "androidfw/ConfigDescription.h" #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" Loading Loading @@ -77,6 +78,12 @@ bool IsAttributeReference(const android::StringPiece& str); Maybe<ResourceName> ToResourceName( const android::ResTable::resource_name& name); /** * Convert an android::AssetManager2::ResourceName to an aapt::ResourceName struct. */ Maybe<ResourceName> ToResourceName( const android::AssetManager2::ResourceName& name_in); /** * Returns a boolean value if the string is equal to TRUE, true, True, FALSE, * false, or False. Loading