Loading libs/androidfw/AssetManager2.cpp +38 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "android-base/logging.h" #include "android-base/stringprintf.h" #include "androidfw/ResourceTypes.h" #include "androidfw/ResourceUtils.h" #include "androidfw/Util.h" #include "utils/ByteOrder.h" Loading Loading @@ -600,6 +601,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( return base::unexpected(result.error()); } bool overlaid = false; if (!stop_at_first_match && !ignore_configuration && !apk_assets_[result->cookie]->IsLoader()) { for (const auto& id_map : package_group.overlays_) { auto overlay_entry = id_map.overlay_res_maps_.Lookup(resid); Loading @@ -616,6 +618,27 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( if (UNLIKELY(logging_enabled)) { last_resolution_.steps.push_back( Resolution::Step{Resolution::Step::Type::OVERLAID_INLINE, String8(), result->cookie}); if (auto path = apk_assets_[result->cookie]->GetPath()) { const std::string overlay_path = path->data(); if (IsFabricatedOverlay(overlay_path)) { // FRRO don't have package name so we use the creating package here. String8 frro_name = String8("FRRO"); // Get the first part of it since the expected one should be like // {overlayPackageName}-{overlayName}-{4 alphanumeric chars}.frro // under /data/resource-cache/. const std::string name = overlay_path.substr(overlay_path.rfind('/') + 1); const size_t end = name.find('-'); if (frro_name.size() != overlay_path.size() && end != std::string::npos) { frro_name.append(base::StringPrintf(" created by %s", name.substr(0 /* pos */, end).c_str()).c_str()); } last_resolution_.best_package_name = frro_name; } else { last_resolution_.best_package_name = result->package_name->c_str(); } } overlaid = true; } continue; } Loading Loading @@ -646,6 +669,9 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( last_resolution_.steps.push_back( Resolution::Step{Resolution::Step::Type::OVERLAID, overlay_result->config.toString(), overlay_result->cookie}); last_resolution_.best_package_name = overlay_result->package_name->c_str(); overlaid = true; } } } Loading @@ -654,6 +680,10 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( last_resolution_.cookie = result->cookie; last_resolution_.type_string_ref = result->type_string_ref; last_resolution_.entry_string_ref = result->entry_string_ref; last_resolution_.best_config_name = result->config.toString(); if (!overlaid) { last_resolution_.best_package_name = result->package_name->c_str(); } } return result; Loading @@ -671,8 +701,6 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( uint32_t best_offset = 0U; uint32_t type_flags = 0U; std::vector<Resolution::Step> resolution_steps; // If `desired_config` is not the same as the set configuration or the caller will accept a value // from any configuration, then we cannot use our filtered list of types since it only it contains // types matched to the set configuration. Loading Loading @@ -725,7 +753,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( resolution_type = Resolution::Step::Type::OVERLAID; } else { if (UNLIKELY(logging_enabled)) { resolution_steps.push_back(Resolution::Step{Resolution::Step::Type::SKIPPED, last_resolution_.steps.push_back(Resolution::Step{Resolution::Step::Type::SKIPPED, this_config.toString(), cookie}); } Loading @@ -742,7 +770,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( if (!offset.has_value()) { if (UNLIKELY(logging_enabled)) { resolution_steps.push_back(Resolution::Step{Resolution::Step::Type::NO_ENTRY, last_resolution_.steps.push_back(Resolution::Step{Resolution::Step::Type::NO_ENTRY, this_config.toString(), cookie}); } Loading Loading @@ -806,6 +834,8 @@ void AssetManager2::ResetResourceResolution() const { last_resolution_.steps.clear(); last_resolution_.type_string_ref = StringPoolRef(); last_resolution_.entry_string_ref = StringPoolRef(); last_resolution_.best_config_name.clear(); last_resolution_.best_package_name.clear(); } void AssetManager2::SetResourceResolutionLoggingEnabled(bool enabled) { Loading Loading @@ -865,6 +895,10 @@ std::string AssetManager2::GetLastResourceResolution() const { } } log_stream << "\nBest matching is from " << (last_resolution_.best_config_name.isEmpty() ? "default" : last_resolution_.best_config_name) << " configuration of " << last_resolution_.best_package_name; return log_stream.str(); } Loading libs/androidfw/include/androidfw/AssetManager2.h +6 −0 Original line number Diff line number Diff line Loading @@ -486,6 +486,12 @@ class AssetManager2 { // Steps taken to resolve last resource. std::vector<Step> steps; // The configuration name of the best resource found. String8 best_config_name; // The package name of the best resource found. String8 best_package_name; }; // Record of the last resolved resource's resolution path. Loading libs/androidfw/tests/AssetManager2_test.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -766,7 +766,9 @@ TEST_F(AssetManager2Test, GetLastPathWithSingleApkAssets) { auto result = assetmanager.GetLastResourceResolution(); EXPECT_EQ("Resolution for 0x7f030000 com.android.basic:string/test1\n" "\tFor config - de\n" "\tFound initial: basic/basic.apk", result); "\tFound initial: basic/basic.apk\n" "Best matching is from default configuration of com.android.basic", result); } TEST_F(AssetManager2Test, GetLastPathWithMultipleApkAssets) { Loading @@ -787,7 +789,9 @@ TEST_F(AssetManager2Test, GetLastPathWithMultipleApkAssets) { EXPECT_EQ("Resolution for 0x7f030000 com.android.basic:string/test1\n" "\tFor config - de\n" "\tFound initial: basic/basic.apk\n" "\tFound better: basic/basic_de_fr.apk - de", result); "\tFound better: basic/basic_de_fr.apk - de\n" "Best matching is from de configuration of com.android.basic", result); } TEST_F(AssetManager2Test, GetLastPathAfterDisablingReturnsEmpty) { Loading Loading
libs/androidfw/AssetManager2.cpp +38 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "android-base/logging.h" #include "android-base/stringprintf.h" #include "androidfw/ResourceTypes.h" #include "androidfw/ResourceUtils.h" #include "androidfw/Util.h" #include "utils/ByteOrder.h" Loading Loading @@ -600,6 +601,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( return base::unexpected(result.error()); } bool overlaid = false; if (!stop_at_first_match && !ignore_configuration && !apk_assets_[result->cookie]->IsLoader()) { for (const auto& id_map : package_group.overlays_) { auto overlay_entry = id_map.overlay_res_maps_.Lookup(resid); Loading @@ -616,6 +618,27 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( if (UNLIKELY(logging_enabled)) { last_resolution_.steps.push_back( Resolution::Step{Resolution::Step::Type::OVERLAID_INLINE, String8(), result->cookie}); if (auto path = apk_assets_[result->cookie]->GetPath()) { const std::string overlay_path = path->data(); if (IsFabricatedOverlay(overlay_path)) { // FRRO don't have package name so we use the creating package here. String8 frro_name = String8("FRRO"); // Get the first part of it since the expected one should be like // {overlayPackageName}-{overlayName}-{4 alphanumeric chars}.frro // under /data/resource-cache/. const std::string name = overlay_path.substr(overlay_path.rfind('/') + 1); const size_t end = name.find('-'); if (frro_name.size() != overlay_path.size() && end != std::string::npos) { frro_name.append(base::StringPrintf(" created by %s", name.substr(0 /* pos */, end).c_str()).c_str()); } last_resolution_.best_package_name = frro_name; } else { last_resolution_.best_package_name = result->package_name->c_str(); } } overlaid = true; } continue; } Loading Loading @@ -646,6 +669,9 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( last_resolution_.steps.push_back( Resolution::Step{Resolution::Step::Type::OVERLAID, overlay_result->config.toString(), overlay_result->cookie}); last_resolution_.best_package_name = overlay_result->package_name->c_str(); overlaid = true; } } } Loading @@ -654,6 +680,10 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( last_resolution_.cookie = result->cookie; last_resolution_.type_string_ref = result->type_string_ref; last_resolution_.entry_string_ref = result->entry_string_ref; last_resolution_.best_config_name = result->config.toString(); if (!overlaid) { last_resolution_.best_package_name = result->package_name->c_str(); } } return result; Loading @@ -671,8 +701,6 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( uint32_t best_offset = 0U; uint32_t type_flags = 0U; std::vector<Resolution::Step> resolution_steps; // If `desired_config` is not the same as the set configuration or the caller will accept a value // from any configuration, then we cannot use our filtered list of types since it only it contains // types matched to the set configuration. Loading Loading @@ -725,7 +753,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( resolution_type = Resolution::Step::Type::OVERLAID; } else { if (UNLIKELY(logging_enabled)) { resolution_steps.push_back(Resolution::Step{Resolution::Step::Type::SKIPPED, last_resolution_.steps.push_back(Resolution::Step{Resolution::Step::Type::SKIPPED, this_config.toString(), cookie}); } Loading @@ -742,7 +770,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( if (!offset.has_value()) { if (UNLIKELY(logging_enabled)) { resolution_steps.push_back(Resolution::Step{Resolution::Step::Type::NO_ENTRY, last_resolution_.steps.push_back(Resolution::Step{Resolution::Step::Type::NO_ENTRY, this_config.toString(), cookie}); } Loading Loading @@ -806,6 +834,8 @@ void AssetManager2::ResetResourceResolution() const { last_resolution_.steps.clear(); last_resolution_.type_string_ref = StringPoolRef(); last_resolution_.entry_string_ref = StringPoolRef(); last_resolution_.best_config_name.clear(); last_resolution_.best_package_name.clear(); } void AssetManager2::SetResourceResolutionLoggingEnabled(bool enabled) { Loading Loading @@ -865,6 +895,10 @@ std::string AssetManager2::GetLastResourceResolution() const { } } log_stream << "\nBest matching is from " << (last_resolution_.best_config_name.isEmpty() ? "default" : last_resolution_.best_config_name) << " configuration of " << last_resolution_.best_package_name; return log_stream.str(); } Loading
libs/androidfw/include/androidfw/AssetManager2.h +6 −0 Original line number Diff line number Diff line Loading @@ -486,6 +486,12 @@ class AssetManager2 { // Steps taken to resolve last resource. std::vector<Step> steps; // The configuration name of the best resource found. String8 best_config_name; // The package name of the best resource found. String8 best_package_name; }; // Record of the last resolved resource's resolution path. Loading
libs/androidfw/tests/AssetManager2_test.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -766,7 +766,9 @@ TEST_F(AssetManager2Test, GetLastPathWithSingleApkAssets) { auto result = assetmanager.GetLastResourceResolution(); EXPECT_EQ("Resolution for 0x7f030000 com.android.basic:string/test1\n" "\tFor config - de\n" "\tFound initial: basic/basic.apk", result); "\tFound initial: basic/basic.apk\n" "Best matching is from default configuration of com.android.basic", result); } TEST_F(AssetManager2Test, GetLastPathWithMultipleApkAssets) { Loading @@ -787,7 +789,9 @@ TEST_F(AssetManager2Test, GetLastPathWithMultipleApkAssets) { EXPECT_EQ("Resolution for 0x7f030000 com.android.basic:string/test1\n" "\tFor config - de\n" "\tFound initial: basic/basic.apk\n" "\tFound better: basic/basic_de_fr.apk - de", result); "\tFound better: basic/basic_de_fr.apk - de\n" "Best matching is from de configuration of com.android.basic", result); } TEST_F(AssetManager2Test, GetLastPathAfterDisablingReturnsEmpty) { Loading