Merge "Dump theme inheritance information in UnsupportedOperationException"
This commit is contained in:
committed by
Android (Google) Code Review
commit
a76a6cc3bc
@@ -791,6 +791,21 @@ public final class AssetManager implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To get the parent theme resource id according to the parameter theme resource id.
|
||||
* @param resId theme resource id.
|
||||
* @return the parent theme resource id.
|
||||
* @hide
|
||||
*/
|
||||
@StyleRes
|
||||
int getParentThemeIdentifier(@StyleRes int resId) {
|
||||
synchronized (this) {
|
||||
ensureValidLocked();
|
||||
// name is checked in JNI.
|
||||
return nativeGetParentThemeIdentifier(mObject, resId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable resource resolution logging to track the steps taken to resolve the last resource
|
||||
* entry retrieved. Stores the configuration and package names for each step.
|
||||
@@ -1600,6 +1615,8 @@ public final class AssetManager implements AutoCloseable {
|
||||
private static native void nativeThemeDump(long ptr, long themePtr, int priority, String tag,
|
||||
String prefix);
|
||||
static native @NativeConfig int nativeThemeGetChangingConfigurations(long themePtr);
|
||||
@StyleRes
|
||||
private static native int nativeGetParentThemeIdentifier(long ptr, @StyleRes int styleId);
|
||||
|
||||
// AssetInputStream related native methods.
|
||||
private static native void nativeAssetDestroy(long assetPtr);
|
||||
|
||||
@@ -1508,6 +1508,12 @@ public class Resources {
|
||||
* retrieve XML attributes with style and theme information applied.
|
||||
*/
|
||||
public final class Theme {
|
||||
/**
|
||||
* To trace parent themes needs to prevent a cycle situation.
|
||||
* e.x. A's parent is B, B's parent is C, and C's parent is A.
|
||||
*/
|
||||
private static final int MAX_NUMBER_OF_TRACING_PARENT_THEME = 100;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@@ -1801,6 +1807,13 @@ public class Resources {
|
||||
}
|
||||
}
|
||||
|
||||
@StyleRes
|
||||
/*package*/ int getParentThemeIdentifier(@StyleRes int resId) {
|
||||
synchronized (mLock) {
|
||||
return mThemeImpl.getParentThemeIdentifier(resId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -1948,8 +1961,27 @@ public class Resources {
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append('{');
|
||||
sb.append("id=0x").append(Integer.toHexString(getAppliedStyleResId())).append(", ");
|
||||
sb.append("themes=").append(Arrays.deepToString(getTheme()));
|
||||
int themeResId = getAppliedStyleResId();
|
||||
int i = 0;
|
||||
sb.append("InheritanceMap=[");
|
||||
while (themeResId > 0) {
|
||||
if (i > MAX_NUMBER_OF_TRACING_PARENT_THEME) {
|
||||
sb.append(",...");
|
||||
break;
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append("id=0x").append(Integer.toHexString(themeResId));
|
||||
sb.append(getResourcePackageName(themeResId))
|
||||
.append(":").append(getResourceTypeName(themeResId))
|
||||
.append("/").append(getResourceEntryName(themeResId));
|
||||
|
||||
i++;
|
||||
themeResId = getParentThemeIdentifier(themeResId);
|
||||
}
|
||||
sb.append("], Themes=").append(Arrays.deepToString(getTheme()));
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -1310,6 +1310,14 @@ public class ResourcesImpl {
|
||||
return mThemeResId;
|
||||
}
|
||||
|
||||
@StyleRes
|
||||
/*package*/ int getParentThemeIdentifier(@StyleRes int resId) {
|
||||
if (resId > 0) {
|
||||
return mAssets.getParentThemeIdentifier(resId);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void applyStyle(int resId, boolean force) {
|
||||
mAssets.applyStyleToTheme(mTheme, resId, force);
|
||||
mThemeResId = resId;
|
||||
|
||||
@@ -881,6 +881,12 @@ static jint NativeGetResourceArray(JNIEnv* env, jclass /*clazz*/, jlong ptr, jin
|
||||
return static_cast<jint>(bag->entry_count);
|
||||
}
|
||||
|
||||
static jint NativeGetParentThemeIdentifier(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid) {
|
||||
ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
|
||||
const auto parentThemeResId = assetmanager->GetParentThemeResourceId(resid);
|
||||
return parentThemeResId.value_or(0);
|
||||
}
|
||||
|
||||
static jint NativeGetResourceIdentifier(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring name,
|
||||
jstring def_type, jstring def_package) {
|
||||
ScopedUtfChars name_utf8(env, name);
|
||||
@@ -1464,6 +1470,8 @@ static const JNINativeMethod gAssetManagerMethods[] = {
|
||||
{"nativeGetResourceIntArray", "(JI)[I", (void*)NativeGetResourceIntArray},
|
||||
{"nativeGetResourceArraySize", "(JI)I", (void*)NativeGetResourceArraySize},
|
||||
{"nativeGetResourceArray", "(JI[I)I", (void*)NativeGetResourceArray},
|
||||
{"nativeGetParentThemeIdentifier", "(JI)I",
|
||||
(void*)NativeGetParentThemeIdentifier},
|
||||
|
||||
// AssetManager resource name/ID methods.
|
||||
{"nativeGetResourceIdentifier", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
|
||||
|
||||
@@ -902,6 +902,27 @@ std::string AssetManager2::GetLastResourceResolution() const {
|
||||
return log_stream.str();
|
||||
}
|
||||
|
||||
base::expected<uint32_t, NullOrIOError> AssetManager2::GetParentThemeResourceId(uint32_t resid)
|
||||
const {
|
||||
auto entry = FindEntry(resid, 0u /* density_override */,
|
||||
false /* stop_at_first_match */,
|
||||
false /* ignore_configuration */);
|
||||
if (!entry.has_value()) {
|
||||
return base::unexpected(entry.error());
|
||||
}
|
||||
|
||||
auto entry_map = std::get_if<incfs::verified_map_ptr<ResTable_map_entry>>(&entry->entry);
|
||||
if (entry_map == nullptr) {
|
||||
// Not a bag, nothing to do.
|
||||
return base::unexpected(std::nullopt);
|
||||
}
|
||||
|
||||
auto map = *entry_map;
|
||||
const uint32_t parent_resid = dtohl(map->parent.ident);
|
||||
|
||||
return parent_resid;
|
||||
}
|
||||
|
||||
base::expected<AssetManager2::ResourceName, NullOrIOError> AssetManager2::GetResourceName(
|
||||
uint32_t resid) const {
|
||||
auto result = FindEntry(resid, 0u /* density_override */, true /* stop_at_first_match */,
|
||||
|
||||
@@ -192,6 +192,12 @@ class AssetManager2 {
|
||||
std::unique_ptr<Asset> OpenNonAsset(const std::string& filename, ApkAssetsCookie cookie,
|
||||
Asset::AccessMode mode) const;
|
||||
|
||||
// Returns the resource id of parent style of the specified theme.
|
||||
//
|
||||
// Returns a null error if the name is missing/corrupt, or an I/O error if reading resource data
|
||||
// failed.
|
||||
base::expected<uint32_t, NullOrIOError> GetParentThemeResourceId(uint32_t resid) const;
|
||||
|
||||
// Returns the resource name of the specified resource ID.
|
||||
//
|
||||
// Utf8 strings are preferred, and only if they are unavailable are the Utf16 variants populated.
|
||||
|
||||
Reference in New Issue
Block a user