From 2f3669b767129bc8739bb03e80abc65eb54a3471 Mon Sep 17 00:00:00 2001 From: Winson Date: Fri, 11 Jan 2019 11:28:34 -0800 Subject: 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 --- libs/androidfw/include/androidfw/AssetManager2.h | 50 ++++++++++++++++++++++++ libs/androidfw/include/androidfw/ResourceUtils.h | 12 ++++++ 2 files changed, 62 insertions(+) (limited to 'libs/androidfw/include') diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h index 0d492984d41d..f29769b834d1 100644 --- a/libs/androidfw/include/androidfw/AssetManager2.h +++ b/libs/androidfw/include/androidfw/AssetManager2.h @@ -229,6 +229,14 @@ class AssetManager2 { ResTable_config* in_out_selected_config, uint32_t* in_out_flags, uint32_t* out_last_reference) const; + // Enables or disables resource resolution logging. Clears stored steps when + // disabled. + void SetResourceResolutionLoggingEnabled(bool enabled); + + // Returns formatted log of last resource resolution path, or empty if no + // resource has been resolved yet. + std::string GetLastResourceResolution() const; + // Retrieves the best matching bag/map resource with ID `resid`. // This method will resolve all parent references for this bag and merge keys with the child. // To iterate over the keys, use the following idiom: @@ -346,6 +354,48 @@ class AssetManager2 { // Cached set of bags. These are cached because they can inherit keys from parent bags, // which involves some calculation. std::unordered_map> cached_bags_; + + // Whether or not to save resource resolution steps + bool resource_resolution_logging_enabled_ = false; + + struct Resolution { + + struct Step { + + enum class Type { + INITIAL, + BETTER_MATCH, + OVERLAID + }; + + // Marks what kind of override this step was. + Type type; + + // Built name of configuration for this step. + String8 config_name; + + // Marks the package name of the better resource found in this step. + const std::string* package_name; + }; + + // Last resolved resource ID. + uint32_t resid; + + // Last resolved resource result cookie. + ApkAssetsCookie cookie = kInvalidCookie; + + // Last resolved resource type. + StringPoolRef type_string_ref; + + // Last resolved resource entry. + StringPoolRef entry_string_ref; + + // Steps taken to resolve last resource. + std::vector steps; + }; + + // Record of the last resolved resource's resolution path. + mutable Resolution last_resolution; }; class Theme { diff --git a/libs/androidfw/include/androidfw/ResourceUtils.h b/libs/androidfw/include/androidfw/ResourceUtils.h index d94779bf5225..eb6eb8e66175 100644 --- a/libs/androidfw/include/androidfw/ResourceUtils.h +++ b/libs/androidfw/include/androidfw/ResourceUtils.h @@ -17,6 +17,7 @@ #ifndef ANDROIDFW_RESOURCEUTILS_H #define ANDROIDFW_RESOURCEUTILS_H +#include "androidfw/AssetManager2.h" #include "androidfw/StringPiece.h" namespace android { @@ -27,6 +28,17 @@ namespace android { bool ExtractResourceName(const StringPiece& str, StringPiece* out_package, StringPiece* out_type, StringPiece* out_entry); +// Convert a type_string_ref, entry_string_ref, and package +// to AssetManager2::ResourceName. Useful for getting +// resource name without re-running AssetManager2::FindEntry searches. +bool ToResourceName(StringPoolRef& type_string_ref, + StringPoolRef& entry_string_ref, + const LoadedPackage* package, + AssetManager2::ResourceName* out_name); + +// Formats a ResourceName to "package:type/entry_name". +std::string ToFormattedResourceString(AssetManager2::ResourceName* resource_name); + inline uint32_t fix_package_id(uint32_t resid, uint8_t package_id) { return (resid & 0x00ffffffu) | (static_cast(package_id) << 24); } -- cgit v1.2.3-59-g8ed1b