diff options
| author | 2014-09-03 17:57:35 -0700 | |
|---|---|---|
| committer | 2014-09-05 16:19:08 -0700 | |
| commit | 042ad633bc68bdda2bb0c50216706d73575a5992 (patch) | |
| tree | 5de05effd4cff0e0dcaad51a17d7a870067c3635 | |
| parent | 836c0a8b949d71293c996761691e065f0651acef (diff) | |
Added getStyleAttributes to access all Theme attributes.
ViewDebug uses getStyleAttributes to get the attributes, and then gets the
attribute name and value so that Hierarchy Viewer can display it.
Bug: 17407087
Change-Id: I3577e32ae99668383701dc908bb46db14a75c3c4
| -rw-r--r-- | core/java/android/content/res/AssetManager.java | 1 | ||||
| -rw-r--r-- | core/java/android/content/res/Resources.java | 10 | ||||
| -rw-r--r-- | core/java/android/view/ViewDebug.java | 62 | ||||
| -rw-r--r-- | core/jni/android_util_AssetManager.cpp | 33 |
4 files changed, 106 insertions, 0 deletions
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 2684e6c62af7..e57882240e56 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -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(); diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 31813c102dac..cabe228817b2 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -1572,6 +1572,16 @@ public class Resources { } /** + * 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. * * @return Resources to which this theme belongs. diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index 6c66eb0e001e..a94f9732a4bd 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -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; @@ -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"; @@ -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 { @@ -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; diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 5faf03d5aae6..396f3ec7a176 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -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) { @@ -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", |