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/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 7b564ae..4101c04 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -44,6 +44,8 @@
#include "androidfw/MutexGuard.h"
#include "androidfw/PosixUtils.h"
#include "androidfw/ResourceTypes.h"
+#include "androidfw/ResourceUtils.h"
+
#include "core_jni_helpers.h"
#include "jni.h"
#include "nativehelper/JNIHelp.h"
@@ -975,34 +977,7 @@
return nullptr;
}
- std::string result;
- if (name.package != nullptr) {
- result.append(name.package, name.package_len);
- }
-
- if (name.type != nullptr || name.type16 != nullptr) {
- if (!result.empty()) {
- result += ":";
- }
-
- if (name.type != nullptr) {
- result.append(name.type, name.type_len);
- } else {
- result += util::Utf16ToUtf8(StringPiece16(name.type16, name.type_len));
- }
- }
-
- if (name.entry != nullptr || name.entry16 != nullptr) {
- if (!result.empty()) {
- result += "/";
- }
-
- if (name.entry != nullptr) {
- result.append(name.entry, name.entry_len);
- } else {
- result += util::Utf16ToUtf8(StringPiece16(name.entry16, name.entry_len));
- }
- }
+ std::string result = ToFormattedResourceString(&name);
return env->NewStringUTF(result.c_str());
}
@@ -1049,6 +1024,26 @@
return nullptr;
}
+static void NativeSetResourceResolutionLoggingEnabled(JNIEnv* /*env*/,
+ jclass /*clazz*/,
+ jlong ptr,
+ jboolean enabled) {
+ ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+ assetmanager->SetResourceResolutionLoggingEnabled(enabled);
+}
+
+static jstring NativeGetLastResourceResolution(JNIEnv* env,
+ jclass /*clazz*/,
+ jlong ptr) {
+ ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+ std::string resolution = assetmanager->GetLastResourceResolution();
+ if (resolution.empty()) {
+ return nullptr;
+ } else {
+ return env->NewStringUTF(resolution.c_str());
+ }
+}
+
static jobjectArray NativeGetLocales(JNIEnv* env, jclass /*class*/, jlong ptr,
jboolean exclude_system) {
ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
@@ -1452,6 +1447,10 @@
{"nativeGetResourcePackageName", "(JI)Ljava/lang/String;", (void*)NativeGetResourcePackageName},
{"nativeGetResourceTypeName", "(JI)Ljava/lang/String;", (void*)NativeGetResourceTypeName},
{"nativeGetResourceEntryName", "(JI)Ljava/lang/String;", (void*)NativeGetResourceEntryName},
+ {"nativeSetResourceResolutionLoggingEnabled", "(JZ)V",
+ (void*) NativeSetResourceResolutionLoggingEnabled},
+ {"nativeGetLastResourceResolution", "(J)Ljava/lang/String;",
+ (void*) NativeGetLastResourceResolution},
{"nativeGetLocales", "(JZ)[Ljava/lang/String;", (void*)NativeGetLocales},
{"nativeGetSizeConfigurations", "(J)[Landroid/content/res/Configuration;",
(void*)NativeGetSizeConfigurations},