Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 836c0a8b authored by Jon Miranda's avatar Jon Miranda
Browse files

Exposes style and theme data, adds developer option.

Adds support for a String[] return type in ViewDebug; and in addition to that,
the hasAdjacentMapping method can use the String array as means to map a key to
its value.

Adds DEBUG_VIEW_ATTRIBUTES to Settings so that the heavy per-view
computations only affect those who opt in. This setting is used in
CoreSettingsObserver to avoid impacting start time.

Change-Id: I8f507e4e5361414c30d247e8d9815205feb5e91f
parent f6040e9c
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -3494,6 +3494,20 @@ public final class ActivityThread {
        synchronized (mResourcesManager) {
            mCoreSettings = coreSettings;
        }
        onCoreSettingsChange();
    }

    private void onCoreSettingsChange() {
        boolean debugViewAttributes =
                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
        if (debugViewAttributes != View.mDebugViewAttributes) {
            View.mDebugViewAttributes = debugViewAttributes;

            // request all activities to relaunch for the changes to take place
            for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
                requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, false);
            }
        }
    }

    private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
@@ -4324,6 +4338,9 @@ public final class ActivityThread {
        final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
        DateFormat.set24HourTimePref(is24Hr);

        View.mDebugViewAttributes =
                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;

        /**
         * For system applications on userdebug/eng builds, log stack
         * traces of disk and network access to dropbox for analysis.
+2 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.provider.MediaStore;
import android.util.AttributeSet;
import android.view.DisplayAdjustments;
import android.view.Display;
import android.view.ViewDebug;
import android.view.WindowManager;

import java.io.File;
@@ -420,6 +421,7 @@ public abstract class Context {
    /**
     * Return the Theme object associated with this Context.
     */
    @ViewDebug.ExportedProperty(deepExport = true)
    public abstract Resources.Theme getTheme();

    /**
+32 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.content.res;

import android.view.ViewDebug;
import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParser;
@@ -1638,6 +1639,35 @@ public class Resources {
        /*package*/ String getKey() {
            return mKey;
        }

        private String getResourceNameFromHexString(String hexString) {
            return getResourceName(Integer.parseInt(hexString, 16));
        }

        /**
         * Parses {@link #mKey} and returns a String array that holds pairs of adjacent Theme data:
         * resource name followed by whether or not it was forced, as specified by
         * {@link #applyStyle(int, boolean)}.
         *
         * @hide
         */
        @ViewDebug.ExportedProperty(category = "theme", hasAdjacentMapping = true)
        public String[] getTheme() {
            String[] themeData = mKey.split(" ");
            String[] themes = new String[themeData.length * 2];
            String theme;
            boolean forced;

            for (int i = 0, j = themeData.length - 1; i < themes.length; i += 2, --j) {
                theme = themeData[j];
                forced = theme.endsWith("!");
                themes[i] = forced ?
                        getResourceNameFromHexString(theme.substring(0, theme.length() - 1)) :
                        getResourceNameFromHexString(theme);
                themes[i + 1] = forced ? "forced" : "not forced";
            }
            return themes;
        }
    }

    /**
+6 −0
Original line number Diff line number Diff line
@@ -5182,6 +5182,12 @@ public final class Settings {
         */
        public static final String ADB_ENABLED = "adb_enabled";

        /**
         * Whether Views are allowed to save their attribute data.
         * @hide
         */
        public static final String DEBUG_VIEW_ATTRIBUTES = "debug_view_attributes";

        /**
         * Whether assisted GPS should be enabled or not.
         * @hide
+69 −0
Original line number Diff line number Diff line
@@ -699,6 +699,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    public static final String DEBUG_LAYOUT_PROPERTY = "debug.layout";
    /**
     * When set to true, this view will save its attribute data.
     *
     * @hide
     */
    public static boolean mDebugViewAttributes = false;
    /**
     * Used to mark a View that has no ID.
     */
@@ -3254,6 +3261,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * This field should be made private, so it is hidden from the SDK.
     * {@hide}
     */
    @ViewDebug.ExportedProperty(deepExport = true)
    protected Context mContext;
    private final Resources mResources;
@@ -3523,6 +3531,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    GhostView mGhostView;
    /**
     * Holds pairs of adjacent attribute data: attribute name followed by its value.
     * @hide
     */
    @ViewDebug.ExportedProperty(category = "attributes", hasAdjacentMapping = true)
    public String[] mAttributes;
    /**
     * Maps a Resource id to its name.
     */
    private static SparseArray<String> mAttributeMap;
    /**
     * Simple constructor to use when creating a view from code.
     *
@@ -3641,6 +3661,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        final TypedArray a = context.obtainStyledAttributes(
                attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
        if (mDebugViewAttributes) {
            saveAttributeData(attrs, a);
        }
        Drawable background = null;
        int leftPadding = -1;
@@ -4136,6 +4160,51 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        mRenderNode = RenderNode.create(getClass().getName());
    }
    private static SparseArray<String> getAttributeMap() {
        if (mAttributeMap == null) {
            mAttributeMap = new SparseArray<String>();
        }
        return mAttributeMap;
    }
    private void saveAttributeData(AttributeSet attrs, TypedArray a) {
        int length = ((attrs == null ? 0 : attrs.getAttributeCount()) + a.getIndexCount()) * 2;
        mAttributes = new String[length];
        int i = 0;
        if (attrs != null) {
            for (i = 0; i < attrs.getAttributeCount(); i += 2) {
                mAttributes[i] = attrs.getAttributeName(i);
                mAttributes[i + 1] = attrs.getAttributeValue(i);
            }
        }
        SparseArray<String> attributeMap = getAttributeMap();
        for (int j = 0; j < a.length(); ++j) {
            if (a.hasValue(j)) {
                try {
                    int resourceId = a.getResourceId(j, 0);
                    if (resourceId == 0) {
                        continue;
                    }
                    String resourceName = attributeMap.get(resourceId);
                    if (resourceName == null) {
                        resourceName = a.getResources().getResourceName(resourceId);
                        attributeMap.put(resourceId, resourceName);
                    }
                    mAttributes[i] = resourceName;
                    mAttributes[i + 1] = a.getText(j).toString();
                    i += 2;
                } catch (Resources.NotFoundException e) {
                    // if we can't get the resource name, we just ignore it
                }
            }
        }
    }
    public String toString() {
        StringBuilder out = new StringBuilder(128);
        out.append(getClass().getName());
Loading