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
This commit is contained in:
Winson
2019-01-11 11:28:34 -08:00
parent 0c891e8f4e
commit 2f3669b767
9 changed files with 471 additions and 86 deletions

View File

@@ -48,4 +48,65 @@ bool ExtractResourceName(const StringPiece& str, StringPiece* out_package, Strin
!(has_type_separator && out_type->empty());
}
bool ToResourceName(StringPoolRef& type_string_ref,
StringPoolRef& entry_string_ref,
const LoadedPackage* package,
AssetManager2::ResourceName* out_name) {
out_name->package = package->GetPackageName().data();
out_name->package_len = package->GetPackageName().size();
out_name->type = type_string_ref.string8(&out_name->type_len);
out_name->type16 = nullptr;
if (out_name->type == nullptr) {
out_name->type16 = type_string_ref.string16(&out_name->type_len);
if (out_name->type16 == nullptr) {
return false;
}
}
out_name->entry = entry_string_ref.string8(&out_name->entry_len);
out_name->entry16 = nullptr;
if (out_name->entry == nullptr) {
out_name->entry16 = entry_string_ref.string16(&out_name->entry_len);
if (out_name->entry16 == nullptr) {
return false;
}
}
return true;
}
std::string ToFormattedResourceString(AssetManager2::ResourceName* resource_name) {
std::string result;
if (resource_name->package != nullptr) {
result.append(resource_name->package, resource_name->package_len);
}
if (resource_name->type != nullptr || resource_name->type16 != nullptr) {
if (!result.empty()) {
result += ":";
}
if (resource_name->type != nullptr) {
result.append(resource_name->type, resource_name->type_len);
} else {
result += util::Utf16ToUtf8(StringPiece16(resource_name->type16, resource_name->type_len));
}
}
if (resource_name->entry != nullptr || resource_name->entry16 != nullptr) {
if (!result.empty()) {
result += "/";
}
if (resource_name->entry != nullptr) {
result.append(resource_name->entry, resource_name->entry_len);
} else {
result += util::Utf16ToUtf8(StringPiece16(resource_name->entry16, resource_name->entry_len));
}
}
return result;
}
} // namespace android