Loading core/java/android/content/res/AssetManager.java +1 −0 Original line number Diff line number Diff line Loading @@ -773,6 +773,7 @@ public final class AssetManager implements AutoCloseable { private native final String[] getArrayStringResource(int arrayRes); private native final int[] getArrayStringInfo(int arrayRes); /*package*/ native final int[] getArrayIntResource(int arrayRes); /*package*/ native final int[] getStyleAttributes(int themeRes); private native final void init(boolean isSystem); private native final void destroy(); Loading core/java/android/content/res/Resources.java +10 −0 Original line number Diff line number Diff line Loading @@ -1571,6 +1571,16 @@ public class Resources { return got; } /** * Gets all of the attribute ids associated with this {@link Theme}. For debugging only. * * @return The int array containing attribute ids associated with this {@link Theme}. * @hide */ public int[] getAllAttributes() { return mAssets.getStyleAttributes(getAppliedStyleResId()); } /** * Returns the resources to which this theme belongs. * Loading core/java/android/view/ViewDebug.java +62 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.os.Handler; import android.os.RemoteException; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; import java.io.BufferedOutputStream; import java.io.BufferedWriter; Loading Loading @@ -315,6 +316,7 @@ public class ViewDebug { private static final String REMOTE_COMMAND_CAPTURE = "CAPTURE"; private static final String REMOTE_COMMAND_DUMP = "DUMP"; private static final String REMOTE_COMMAND_DUMP_THEME = "DUMP_THEME"; private static final String REMOTE_COMMAND_INVALIDATE = "INVALIDATE"; private static final String REMOTE_COMMAND_REQUEST_LAYOUT = "REQUEST_LAYOUT"; private static final String REMOTE_PROFILE = "PROFILE"; Loading Loading @@ -430,6 +432,8 @@ public class ViewDebug { if (REMOTE_COMMAND_DUMP.equalsIgnoreCase(command)) { dump(view, false, true, clientStream); } else if (REMOTE_COMMAND_DUMP_THEME.equalsIgnoreCase(command)) { dumpTheme(view, clientStream); } else if (REMOTE_COMMAND_CAPTURE_LAYERS.equalsIgnoreCase(command)) { captureLayers(view, new DataOutputStream(clientStream)); } else { Loading Loading @@ -820,6 +824,64 @@ public class ViewDebug { } } /** * Dumps the theme attributes from the given View. * @hide */ public static void dumpTheme(View view, OutputStream clientStream) throws IOException { BufferedWriter out = null; try { out = new BufferedWriter(new OutputStreamWriter(clientStream, "utf-8"), 32 * 1024); String[] attributes = getStyleAttributesDump(view.getContext().getResources(), view.getContext().getTheme()); if (attributes != null) { for (int i = 0; i < attributes.length; i += 2) { if (attributes[i] != null) { out.write(attributes[i] + "\n"); out.write(attributes[i + 1] + "\n"); } } } out.write("DONE."); out.newLine(); } catch (Exception e) { android.util.Log.w("View", "Problem dumping View Theme:", e); } finally { if (out != null) { out.close(); } } } /** * Gets the style attributes from the {@link Resources.Theme}. For debugging only. * * @param resources Resources to resolve attributes from. * @param theme Theme to dump. * @return a String array containing pairs of adjacent Theme attribute data: name followed by * its value. * * @hide */ private static String[] getStyleAttributesDump(Resources resources, Resources.Theme theme) { TypedValue outValue = new TypedValue(); String nullString = "null"; int i = 0; int[] attributes = theme.getAllAttributes(); String[] data = new String[attributes.length * 2]; for (int attributeId : attributes) { try { data[i] = resources.getResourceName(attributeId); data[i + 1] = theme.resolveAttribute(attributeId, outValue, true) ? outValue.coerceToString().toString() : nullString; i += 2; } catch (Resources.NotFoundException e) { // ignore resources we can't resolve } } return data; } private static View findView(ViewGroup group, String className, int hashCode) { if (isRequestedView(group, className, hashCode)) { return group; Loading core/jni/android_util_AssetManager.cpp +33 −0 Original line number Diff line number Diff line Loading @@ -1888,6 +1888,37 @@ static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, j return array; } static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jobject clazz, jint styleId) { AssetManager* am = assetManagerForJavaObject(env, clazz); if (am == NULL) { return NULL; } const ResTable& res(am->getResources()); const ResTable::bag_entry* startOfBag; const ssize_t N = res.lockBag(styleId, &startOfBag); if (N < 0) { return NULL; } jintArray array = env->NewIntArray(N); if (array == NULL) { res.unlockBag(startOfBag); return NULL; } Res_value value; const ResTable::bag_entry* bag = startOfBag; for (size_t i=0; ((ssize_t)i)<N; i++, bag++) { int resourceId = bag->map.name.ident; env->SetIntArrayRegion(array, i, 1, &resourceId); } res.unlockBag(startOfBag); return array; } static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem) { if (isSystem) { Loading Loading @@ -2038,6 +2069,8 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_getArrayStringInfo }, { "getArrayIntResource","(I)[I", (void*) android_content_AssetManager_getArrayIntResource }, { "getStyleAttributes","(I)[I", (void*) android_content_AssetManager_getStyleAttributes }, // Bookkeeping. { "init", "(Z)V", Loading Loading
core/java/android/content/res/AssetManager.java +1 −0 Original line number Diff line number Diff line Loading @@ -773,6 +773,7 @@ public final class AssetManager implements AutoCloseable { private native final String[] getArrayStringResource(int arrayRes); private native final int[] getArrayStringInfo(int arrayRes); /*package*/ native final int[] getArrayIntResource(int arrayRes); /*package*/ native final int[] getStyleAttributes(int themeRes); private native final void init(boolean isSystem); private native final void destroy(); Loading
core/java/android/content/res/Resources.java +10 −0 Original line number Diff line number Diff line Loading @@ -1571,6 +1571,16 @@ public class Resources { return got; } /** * Gets all of the attribute ids associated with this {@link Theme}. For debugging only. * * @return The int array containing attribute ids associated with this {@link Theme}. * @hide */ public int[] getAllAttributes() { return mAssets.getStyleAttributes(getAppliedStyleResId()); } /** * Returns the resources to which this theme belongs. * Loading
core/java/android/view/ViewDebug.java +62 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.os.Handler; import android.os.RemoteException; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; import java.io.BufferedOutputStream; import java.io.BufferedWriter; Loading Loading @@ -315,6 +316,7 @@ public class ViewDebug { private static final String REMOTE_COMMAND_CAPTURE = "CAPTURE"; private static final String REMOTE_COMMAND_DUMP = "DUMP"; private static final String REMOTE_COMMAND_DUMP_THEME = "DUMP_THEME"; private static final String REMOTE_COMMAND_INVALIDATE = "INVALIDATE"; private static final String REMOTE_COMMAND_REQUEST_LAYOUT = "REQUEST_LAYOUT"; private static final String REMOTE_PROFILE = "PROFILE"; Loading Loading @@ -430,6 +432,8 @@ public class ViewDebug { if (REMOTE_COMMAND_DUMP.equalsIgnoreCase(command)) { dump(view, false, true, clientStream); } else if (REMOTE_COMMAND_DUMP_THEME.equalsIgnoreCase(command)) { dumpTheme(view, clientStream); } else if (REMOTE_COMMAND_CAPTURE_LAYERS.equalsIgnoreCase(command)) { captureLayers(view, new DataOutputStream(clientStream)); } else { Loading Loading @@ -820,6 +824,64 @@ public class ViewDebug { } } /** * Dumps the theme attributes from the given View. * @hide */ public static void dumpTheme(View view, OutputStream clientStream) throws IOException { BufferedWriter out = null; try { out = new BufferedWriter(new OutputStreamWriter(clientStream, "utf-8"), 32 * 1024); String[] attributes = getStyleAttributesDump(view.getContext().getResources(), view.getContext().getTheme()); if (attributes != null) { for (int i = 0; i < attributes.length; i += 2) { if (attributes[i] != null) { out.write(attributes[i] + "\n"); out.write(attributes[i + 1] + "\n"); } } } out.write("DONE."); out.newLine(); } catch (Exception e) { android.util.Log.w("View", "Problem dumping View Theme:", e); } finally { if (out != null) { out.close(); } } } /** * Gets the style attributes from the {@link Resources.Theme}. For debugging only. * * @param resources Resources to resolve attributes from. * @param theme Theme to dump. * @return a String array containing pairs of adjacent Theme attribute data: name followed by * its value. * * @hide */ private static String[] getStyleAttributesDump(Resources resources, Resources.Theme theme) { TypedValue outValue = new TypedValue(); String nullString = "null"; int i = 0; int[] attributes = theme.getAllAttributes(); String[] data = new String[attributes.length * 2]; for (int attributeId : attributes) { try { data[i] = resources.getResourceName(attributeId); data[i + 1] = theme.resolveAttribute(attributeId, outValue, true) ? outValue.coerceToString().toString() : nullString; i += 2; } catch (Resources.NotFoundException e) { // ignore resources we can't resolve } } return data; } private static View findView(ViewGroup group, String className, int hashCode) { if (isRequestedView(group, className, hashCode)) { return group; Loading
core/jni/android_util_AssetManager.cpp +33 −0 Original line number Diff line number Diff line Loading @@ -1888,6 +1888,37 @@ static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, j return array; } static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jobject clazz, jint styleId) { AssetManager* am = assetManagerForJavaObject(env, clazz); if (am == NULL) { return NULL; } const ResTable& res(am->getResources()); const ResTable::bag_entry* startOfBag; const ssize_t N = res.lockBag(styleId, &startOfBag); if (N < 0) { return NULL; } jintArray array = env->NewIntArray(N); if (array == NULL) { res.unlockBag(startOfBag); return NULL; } Res_value value; const ResTable::bag_entry* bag = startOfBag; for (size_t i=0; ((ssize_t)i)<N; i++, bag++) { int resourceId = bag->map.name.ident; env->SetIntArrayRegion(array, i, 1, &resourceId); } res.unlockBag(startOfBag); return array; } static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem) { if (isSystem) { Loading Loading @@ -2038,6 +2069,8 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_getArrayStringInfo }, { "getArrayIntResource","(I)[I", (void*) android_content_AssetManager_getArrayIntResource }, { "getStyleAttributes","(I)[I", (void*) android_content_AssetManager_getStyleAttributes }, // Bookkeeping. { "init", "(Z)V", Loading