summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jon Miranda <jonmiranda@google.com> 2014-09-03 17:57:35 -0700
committer Jon Miranda <jonmiranda@google.com> 2014-09-05 16:19:08 -0700
commit042ad633bc68bdda2bb0c50216706d73575a5992 (patch)
tree5de05effd4cff0e0dcaad51a17d7a870067c3635
parent836c0a8b949d71293c996761691e065f0651acef (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.java1
-rw-r--r--core/java/android/content/res/Resources.java10
-rw-r--r--core/java/android/view/ViewDebug.java62
-rw-r--r--core/jni/android_util_AssetManager.cpp33
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",