Add function to return path for last resolved resource
After an AssetManager.FindEntry call is made, either directly or from any of the resource entry calls, a stack of the steps taken to resolve the resource is saved. Those steps can be retrieved as a log later on by calling AssetManager.GetLastResourceResolution, which returns a formatted string of the resource ID/name and path taken, including the configs and package names of each step.
Logging and the saving of the steps to memory can be enabled/disabled with the @hide .setResourceResolutionLoggingEnabled() method on AssetManager.
Bug: 122374289
Test: cases for single and multi ApkAssets loaded
Test: case for no resolution made
Test: made test app to display log on device
Test: added debugging call to source and ran through on-device apps
Change-Id: I6a32b8d4020c3f8510032ff7f431510089fff43f
diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp
index 5449a54..105dcd2 100644
--- a/libs/androidfw/tests/AssetManager2_test.cpp
+++ b/libs/androidfw/tests/AssetManager2_test.cpp
@@ -586,4 +586,111 @@
EXPECT_THAT(asset_dir->getFileType(2), Eq(FileType::kFileTypeDirectory));
}
+TEST_F(AssetManager2Test, GetLastPathWithoutEnablingReturnsEmpty) {
+ ResTable_config desired_config;
+
+ AssetManager2 assetmanager;
+ assetmanager.SetConfiguration(desired_config);
+ assetmanager.SetApkAssets({basic_assets_.get()});
+ assetmanager.SetResourceResolutionLoggingEnabled(false);
+
+ Res_value value;
+ ResTable_config selected_config;
+ uint32_t flags;
+
+ ApkAssetsCookie cookie =
+ assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
+ 0 /*density_override*/, &value, &selected_config, &flags);
+ ASSERT_NE(kInvalidCookie, cookie);
+
+ auto result = assetmanager.GetLastResourceResolution();
+ EXPECT_EQ("", result);
+}
+
+TEST_F(AssetManager2Test, GetLastPathWithoutResolutionReturnsEmpty) {
+ ResTable_config desired_config;
+
+ AssetManager2 assetmanager;
+ assetmanager.SetConfiguration(desired_config);
+ assetmanager.SetApkAssets({basic_assets_.get()});
+
+ auto result = assetmanager.GetLastResourceResolution();
+ EXPECT_EQ("", result);
+}
+
+TEST_F(AssetManager2Test, GetLastPathWithSingleApkAssets) {
+ ResTable_config desired_config;
+ memset(&desired_config, 0, sizeof(desired_config));
+ desired_config.language[0] = 'd';
+ desired_config.language[1] = 'e';
+
+ AssetManager2 assetmanager;
+ assetmanager.SetResourceResolutionLoggingEnabled(true);
+ assetmanager.SetConfiguration(desired_config);
+ assetmanager.SetApkAssets({basic_assets_.get()});
+
+ Res_value value;
+ ResTable_config selected_config;
+ uint32_t flags;
+
+ ApkAssetsCookie cookie =
+ assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
+ 0 /*density_override*/, &value, &selected_config, &flags);
+ ASSERT_NE(kInvalidCookie, cookie);
+
+ auto result = assetmanager.GetLastResourceResolution();
+ EXPECT_EQ("Resolution for 0x7f030000 com.android.basic:string/test1\n\tFor config -de\n\tFound initial: com.android.basic", result);
+}
+
+TEST_F(AssetManager2Test, GetLastPathWithMultipleApkAssets) {
+ ResTable_config desired_config;
+ memset(&desired_config, 0, sizeof(desired_config));
+ desired_config.language[0] = 'd';
+ desired_config.language[1] = 'e';
+
+ AssetManager2 assetmanager;
+ assetmanager.SetResourceResolutionLoggingEnabled(true);
+ assetmanager.SetConfiguration(desired_config);
+ assetmanager.SetApkAssets({basic_assets_.get(), basic_de_fr_assets_.get()});
+
+ Res_value value = Res_value();
+ ResTable_config selected_config;
+ uint32_t flags;
+
+ ApkAssetsCookie cookie =
+ assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
+ 0 /*density_override*/, &value, &selected_config, &flags);
+ ASSERT_NE(kInvalidCookie, cookie);
+
+ auto result = assetmanager.GetLastResourceResolution();
+ EXPECT_EQ("Resolution for 0x7f030000 com.android.basic:string/test1\n\tFor config -de\n\tFound initial: com.android.basic\n\tFound better: com.android.basic -de", result);
+}
+
+TEST_F(AssetManager2Test, GetLastPathAfterDisablingReturnsEmpty) {
+ ResTable_config desired_config;
+ memset(&desired_config, 0, sizeof(desired_config));
+
+ AssetManager2 assetmanager;
+ assetmanager.SetResourceResolutionLoggingEnabled(true);
+ assetmanager.SetConfiguration(desired_config);
+ assetmanager.SetApkAssets({basic_assets_.get()});
+
+ Res_value value = Res_value();
+ ResTable_config selected_config;
+ uint32_t flags;
+
+ ApkAssetsCookie cookie =
+ assetmanager.GetResource(basic::R::string::test1, false /*may_be_bag*/,
+ 0 /*density_override*/, &value, &selected_config, &flags);
+ ASSERT_NE(kInvalidCookie, cookie);
+
+ auto resultEnabled = assetmanager.GetLastResourceResolution();
+ ASSERT_NE("", resultEnabled);
+
+ assetmanager.SetResourceResolutionLoggingEnabled(false);
+
+ auto resultDisabled = assetmanager.GetLastResourceResolution();
+ EXPECT_EQ("", resultDisabled);
+}
+
} // namespace android