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

Commit 8f004c85 authored by Aurimas Liutikas's avatar Aurimas Liutikas
Browse files

Add helper methods for View attribute debugging

Adding abilities to debug:
- Attribute resolution stack (which resources are looked
  at when resolving an attribute)
- Attribute value source (where did each attribute value
  get defined)
- Get explicit style id (if a view had it set via style="...")

This feature will be behind Settings.Global flag that Android
Studio will set to the debugged application package ID.

Bug: 111439551
Test: atest CtsViewTestCases:android.view.cts.ViewStyleTest
Change-Id: Ib6f9fc81000bb867b5b94a68953c99b0bc802d6c
parent abb20beb
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -12355,8 +12355,10 @@ package android.content.res {
  public final class Resources.Theme {
    method public void applyStyle(int, boolean);
    method public void dump(int, String, String);
    method public int[] getAttributeResolutionStack(@AttrRes int, @StyleRes int, @StyleRes int);
    method public int getChangingConfigurations();
    method public android.graphics.drawable.Drawable getDrawable(@DrawableRes int) throws android.content.res.Resources.NotFoundException;
    method @StyleRes public int getExplicitStyle(@Nullable android.util.AttributeSet);
    method public android.content.res.Resources getResources();
    method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[]);
    method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@StyleRes int, @NonNull @StyleableRes int[]) throws android.content.res.Resources.NotFoundException;
@@ -50326,6 +50328,8 @@ package android.view {
    method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getAlpha();
    method public android.view.animation.Animation getAnimation();
    method public android.os.IBinder getApplicationWindowToken();
    method @NonNull public java.util.List<java.lang.Integer> getAttributeResolutionStack();
    method @NonNull public java.util.Map<java.lang.Integer,java.lang.Integer> getAttributeSourceResourceMap();
    method @android.view.ViewDebug.ExportedProperty @Nullable public String[] getAutofillHints();
    method public final android.view.autofill.AutofillId getAutofillId();
    method public int getAutofillType();
@@ -50356,6 +50360,7 @@ package android.view {
    method public void getDrawingRect(android.graphics.Rect);
    method public long getDrawingTime();
    method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getElevation();
    method @StyleRes public int getExplicitStyle();
    method @android.view.ViewDebug.ExportedProperty public boolean getFilterTouchesWhenObscured();
    method @android.view.ViewDebug.ExportedProperty public boolean getFitsSystemWindows();
    method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.NOT_FOCUSABLE, to="NOT_FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE, to="FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE_AUTO, to="FOCUSABLE_AUTO")}, category="focus") public int getFocusable();
@@ -50650,6 +50655,7 @@ package android.view {
    method public static int resolveSizeAndState(int, int, int);
    method public boolean restoreDefaultFocus();
    method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>);
    method public final void saveAttributeDataForStyleable(@NonNull android.content.Context, @NonNull int[], @Nullable android.util.AttributeSet, @NonNull android.content.res.TypedArray, int, int);
    method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>);
    method public void scheduleDrawable(@NonNull android.graphics.drawable.Drawable, @NonNull Runnable, long);
    method public void scrollBy(int, int);
+15 −7
Original line number Diff line number Diff line
@@ -4565,16 +4565,25 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

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

        if (updateDebugViewAttributeState()) {
            // request all activities to relaunch for the changes to take place
            relaunchAllActivities();
        }
    }

    private boolean updateDebugViewAttributeState() {
        boolean previousState = View.sDebugViewAttributes;

        View.sDebugViewAttributesApplicationPackage = mCoreSettings.getString(
                Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, "");
        String currentPackage = (mBoundApplication != null && mBoundApplication.appInfo != null)
                ? mBoundApplication.appInfo.packageName : "";
        View.sDebugViewAttributes =
                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0
                        || View.sDebugViewAttributesApplicationPackage.equals(currentPackage);
        return previousState != View.sDebugViewAttributes;
    }

    private void relaunchAllActivities() {
        for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
            final Activity activity = entry.getValue().activity;
@@ -5950,8 +5959,7 @@ public final class ActivityThread extends ClientTransactionHandler {
        // true : use 24 hour format.
        DateFormat.set24HourTimePref(is24Hr);

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

        StrictMode.initThreadDefaults(data.appInfo);
        StrictMode.initVmDefaults(data.appInfo);
+10 −0
Original line number Diff line number Diff line
@@ -1051,6 +1051,14 @@ public final class AssetManager implements AutoCloseable {
        }
    }

    int[] getAttributeResolutionStack(long themePtr, @AttrRes int defStyleAttr,
            @StyleRes int defStyleRes, @StyleRes int xmlStyle) {
        synchronized (this) {
            return nativeAttributeResolutionStack(
                    mObject, themePtr, xmlStyle, defStyleAttr, defStyleRes);
        }
    }

    @UnsupportedAppUsage
    boolean resolveAttrs(long themePtr, @AttrRes int defStyleAttr, @StyleRes int defStyleRes,
            @Nullable int[] inValues, @NonNull int[] inAttrs, @NonNull int[] outValues,
@@ -1419,6 +1427,8 @@ public final class AssetManager implements AutoCloseable {
    private static native @Nullable String nativeGetLastResourceResolution(long ptr);

    // Style attribute retrieval native methods.
    private static native int[] nativeAttributeResolutionStack(long ptr, long themePtr,
            @StyleRes int xmlStyleRes, @AttrRes int defStyleAttr, @StyleRes int defStyleRes);
    private static native void nativeApplyStyle(long ptr, long themePtr, @AttrRes int defStyleAttr,
            @StyleRes int defStyleRes, long xmlParserPtr, @NonNull int[] inAttrs,
            long outValuesAddress, long outIndicesAddress);
+62 −0
Original line number Diff line number Diff line
@@ -1725,6 +1725,68 @@ public class Resources {
        public void rebase() {
            mThemeImpl.rebase();
        }

        /**
         * Returns the resource ID for the style specified using {@code style="..."} in the
         * {@link AttributeSet}'s backing XML element or {@link Resources#ID_NULL} otherwise if not
         * specified or otherwise not applicable.
         * <p>
         * Each {@link android.view.View} can have an explicit style specified in the layout file.
         * This style is used first during the {@link android.view.View} attribute resolution, then
         * if an attribute is not defined there the resource system looks at default style and theme
         * as fallbacks.
         *
         * @param set The base set of attribute values.
         *
         * @return The resource ID for the style specified using {@code style="..."} in the
         *      {@link AttributeSet}'s backing XML element or {@link Resources#ID_NULL} otherwise
         *      if not specified or otherwise not applicable.
         */
        @StyleRes
        public int getExplicitStyle(@Nullable AttributeSet set) {
            if (set == null) {
                return ID_NULL;
            }
            int styleAttr = set.getStyleAttribute();
            if (styleAttr == ID_NULL) {
                return ID_NULL;
            }
            String styleAttrType = getResources().getResourceTypeName(styleAttr);
            if ("attr".equals(styleAttrType)) {
                TypedValue explicitStyle = new TypedValue();
                boolean resolved = resolveAttribute(styleAttr, explicitStyle, true);
                if (resolved) {
                    return explicitStyle.resourceId;
                }
            } else if ("style".equals(styleAttrType)) {
                return styleAttr;
            }
            return ID_NULL;
        }

        /**
         * Returns the ordered list of resource ID that are considered when resolving attribute
         * values when making an equivalent call to
         * {@link #obtainStyledAttributes(AttributeSet, int[], int, int)} . The list will include
         * a set of explicit styles ({@code explicitStyleRes} and it will include the default styles
         * ({@code defStyleAttr} and {@code defStyleRes}).
         *
         * @param defStyleAttr An attribute in the current theme that contains a
         *                     reference to a style resource that supplies
         *                     defaults values for the TypedArray.  Can be
         *                     0 to not look for defaults.
         * @param defStyleRes A resource identifier of a style resource that
         *                    supplies default values for the TypedArray,
         *                    used only if defStyleAttr is 0 or can not be found
         *                    in the theme.  Can be 0 to not look for defaults.
         * @param explicitStyleRes A resource identifier of an explicit style resource.
         * @return ordered list of resource ID that are considered when resolving attribute values.
         */
        public int[] getAttributeResolutionStack(@AttrRes int defStyleAttr,
                @StyleRes int defStyleRes, @StyleRes int explicitStyleRes) {
            return mThemeImpl.getAttributeResolutionStack(
                    defStyleAttr, defStyleRes, explicitStyleRes);
        }
    }

    static class ThemeKey implements Cloneable {
+26 −0
Original line number Diff line number Diff line
@@ -1488,6 +1488,32 @@ public class ResourcesImpl {
                }
            }
        }

        /**
         * Returns the ordered list of resource ID that are considered when resolving attribute
         * values when making an equivalent call to
         * {@link #obtainStyledAttributes(Resources.Theme, AttributeSet, int[], int, int)}. The list
         * will include a set of explicit styles ({@code explicitStyleRes} and it will include the
         * default styles ({@code defStyleAttr} and {@code defStyleRes}).
         *
         * @param defStyleAttr An attribute in the current theme that contains a
         *                     reference to a style resource that supplies
         *                     defaults values for the TypedArray.  Can be
         *                     0 to not look for defaults.
         * @param defStyleRes A resource identifier of a style resource that
         *                    supplies default values for the TypedArray,
         *                    used only if defStyleAttr is 0 or can not be found
         *                    in the theme.  Can be 0 to not look for defaults.
         * @param explicitStyleRes A resource identifier of an explicit style resource.
         * @return ordered list of resource ID that are considered when resolving attribute values.
         */
        public int[] getAttributeResolutionStack(@AttrRes int defStyleAttr,
                @StyleRes int defStyleRes, @StyleRes int explicitStyleRes) {
            synchronized (mKey) {
                return mAssets.getAttributeResolutionStack(
                        mTheme, defStyleAttr, defStyleRes, explicitStyleRes);
            }
        }
    }

    private static class LookupStack {
Loading