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

Commit c91290a6 authored by Phil Weaver's avatar Phil Weaver Committed by Android (Google) Code Review
Browse files

Merge "Separate a11y and autofill view ids" into oc-dev

parents 4ab690a5 846cda93
Loading
Loading
Loading
Loading
+17 −18
Original line number Diff line number Diff line
@@ -719,7 +719,7 @@ public class Activity extends ContextThemeWrapper
    public static final int FINISH_TASK_WITH_ACTIVITY = 2;

    static final String FRAGMENTS_TAG = "android:fragments";
    private static final String LAST_ACCESSIBILITY_ID = "android:lastAccessibilityId";
    private static final String LAST_AUTOFILL_ID = "android:lastAutofillId";

    private static final String AUTOFILL_RESET_NEEDED = "@android:autofillResetNeeded";
    private static final String WINDOW_HIERARCHY_TAG = "android:viewHierarchyState";
@@ -853,8 +853,8 @@ public class Activity extends ContextThemeWrapper

    private boolean mAutoFillResetNeeded;

    /** The last accessibility id that was returned from {@link #getNextAccessibilityId()} */
    private int mLastAccessibilityId = View.LAST_APP_ACCESSIBILITY_ID;
    /** The last autofill id that was returned from {@link #getNextAutofillId()} */
    private int mLastAutofillId = View.LAST_APP_AUTOFILL_ID;

    private AutofillPopupWindow mAutofillPopupWindow;

@@ -999,7 +999,7 @@ public class Activity extends ContextThemeWrapper
        }
        if (savedInstanceState != null) {
            mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
            mLastAccessibilityId = savedInstanceState.getInt(LAST_ACCESSIBILITY_ID, View.NO_ID);
            mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID, View.NO_ID);

            if (mAutoFillResetNeeded) {
                getAutofillManager().onCreate(savedInstanceState);
@@ -1348,24 +1348,23 @@ public class Activity extends ContextThemeWrapper
    }

    /**
     * Gets the next accessibility ID.
     * Gets the next autofill ID.
     *
     * <p>All IDs will be bigger than {@link View#LAST_APP_ACCESSIBILITY_ID}. All IDs returned
     * <p>All IDs will be bigger than {@link View#LAST_APP_AUTOFILL_ID}. All IDs returned
     * will be unique.
     *
     * @return A ID that is unique in the activity
     *
     * {@hide}
     */
    @Override
    public int getNextAccessibilityId() {
        if (mLastAccessibilityId == Integer.MAX_VALUE - 1) {
            mLastAccessibilityId = View.LAST_APP_ACCESSIBILITY_ID;
    public int getNextAutofillId() {
        if (mLastAutofillId == Integer.MAX_VALUE - 1) {
            mLastAutofillId = View.LAST_APP_AUTOFILL_ID;
        }

        mLastAccessibilityId++;
        mLastAutofillId++;

        return mLastAccessibilityId;
        return mLastAutofillId;
    }

    /**
@@ -1563,7 +1562,7 @@ public class Activity extends ContextThemeWrapper
    protected void onSaveInstanceState(Bundle outState) {
        outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());

        outState.putInt(LAST_ACCESSIBILITY_ID, mLastAccessibilityId);
        outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);
        Parcelable p = mFragments.saveAllState();
        if (p != null) {
            outState.putParcelable(FRAGMENTS_TAG, p);
@@ -7455,7 +7454,7 @@ public class Activity extends ContextThemeWrapper

    /** @hide */
    @Override
    @NonNull public View[] findViewsByAccessibilityIdTraversal(@NonNull int[] viewIds) {
    @NonNull public View[] findViewsByAutofillIdTraversal(@NonNull int[] viewIds) {
        final View[] views = new View[viewIds.length];
        final ArrayList<ViewRootImpl> roots =
                WindowManagerGlobal.getInstance().getRootViews(getActivityToken());
@@ -7466,7 +7465,7 @@ public class Activity extends ContextThemeWrapper
            if (rootView != null) {
                for (int viewNum = 0; viewNum < viewIds.length; viewNum++) {
                    if (views[viewNum] == null) {
                        views[viewNum] = rootView.findViewByAccessibilityIdTraversal(
                        views[viewNum] = rootView.findViewByAutofillIdTraversal(
                                viewIds[viewNum]);
                    }
                }
@@ -7478,14 +7477,14 @@ public class Activity extends ContextThemeWrapper

    /** @hide */
    @Override
    @Nullable public View findViewByAccessibilityIdTraversal(int viewId) {
    @Nullable public View findViewByAutofillIdTraversal(int viewId) {
        final ArrayList<ViewRootImpl> roots =
                WindowManagerGlobal.getInstance().getRootViews(getActivityToken());
        for (int rootNum = 0; rootNum < roots.size(); rootNum++) {
            final View rootView = roots.get(rootNum).getView();

            if (rootView != null) {
                final View view = rootView.findViewByAccessibilityIdTraversal(viewId);
                final View view = rootView.findViewByAutofillIdTraversal(viewId);
                if (view != null) {
                    return view;
                }
@@ -7499,7 +7498,7 @@ public class Activity extends ContextThemeWrapper
    @Override
    @NonNull public boolean[] getViewVisibility(@NonNull int[] viewIds) {
        final boolean[] isVisible = new boolean[viewIds.length];
        final View views[] = findViewsByAccessibilityIdTraversal(viewIds);
        final View views[] = findViewsByAutofillIdTraversal(viewIds);

        for (int i = 0; i < viewIds.length; i++) {
            View view = views[i];
+9 −9
Original line number Diff line number Diff line
@@ -488,27 +488,27 @@ public abstract class Context {
     */
    public abstract Context getApplicationContext();

    /** Non-activity related accessibility ids are unique in the app */
    private static int sLastAccessibilityId = View.NO_ID;
    /** Non-activity related autofill ids are unique in the app */
    private static int sLastAutofillId = View.NO_ID;

    /**
     * Gets the next accessibility ID.
     * Gets the next autofill ID.
     *
     * <p>All IDs will be smaller or the same as {@link View#LAST_APP_ACCESSIBILITY_ID}. All IDs
     * <p>All IDs will be smaller or the same as {@link View#LAST_APP_AUTOFILL_ID}. All IDs
     * returned will be unique.
     *
     * @return A ID that is unique in the process
     *
     * {@hide}
     */
    public int getNextAccessibilityId() {
        if (sLastAccessibilityId == View.LAST_APP_ACCESSIBILITY_ID - 1) {
            sLastAccessibilityId = View.NO_ID;
    public int getNextAutofillId() {
        if (sLastAutofillId == View.LAST_APP_AUTOFILL_ID - 1) {
            sLastAutofillId = View.NO_ID;
        }

        sLastAccessibilityId++;
        sLastAutofillId++;

        return sLastAccessibilityId;
        return sLastAutofillId;
    }

    /**
+2 −3
Original line number Diff line number Diff line
@@ -956,8 +956,7 @@ public class ContextWrapper extends Context {
    /**
     * @hide
     */
    @Override
    public int getNextAccessibilityId() {
        return mBase.getNextAccessibilityId();
    public int getNextAutofillId() {
        return mBase.getNextAutofillId();
    }
}
+63 −24
Original line number Diff line number Diff line
@@ -802,7 +802,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     *
     * {@hide}
     */
    public static final int LAST_APP_ACCESSIBILITY_ID = Integer.MAX_VALUE / 2;
    public static final int LAST_APP_AUTOFILL_ID = Integer.MAX_VALUE / 2;
    /**
     * Attribute to find the autofilled highlight
@@ -2044,6 +2044,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    private SparseArray<Object> mKeyedTags;
    /**
     * The next available accessibility id.
     */
    private static int sNextAccessibilityViewId;
    /**
     * The animation currently associated with this view.
     * @hide
@@ -2086,16 +2091,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    @ViewDebug.ExportedProperty(resolveId = true)
    int mID = NO_ID;
    /** The ID of this view for accessibility and autofill purposes.
    /** The ID of this view for autofill purposes.
     * <ul>
     *     <li>== {@link #NO_ID}: ID has not been assigned yet
     *     <li>&le; {@link #LAST_APP_ACCESSIBILITY_ID}: View is not part of a activity. The ID is
     *     <li>&le; {@link #LAST_APP_AUTOFILL_ID}: View is not part of a activity. The ID is
     *                                                  unique in the process. This might change
     *                                                  over activity lifecycle events.
     *     <li>&gt; {@link #LAST_APP_ACCESSIBILITY_ID}: View is part of a activity. The ID is
     *     <li>&gt; {@link #LAST_APP_AUTOFILL_ID}: View is part of a activity. The ID is
     *                                                  unique in the activity. This stays the same
     *                                                  over activity lifecycle events.
     */
    private int mAutofillViewId = NO_ID;
    // ID for accessibility purposes. This ID must be unique for every window
    private int mAccessibilityViewId = NO_ID;
    private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
@@ -7723,7 +7731,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (mAutofillId == null) {
            // The autofill id needs to be unique, but its value doesn't matter,
            // so it's better to reuse the accessibility id to save space.
            mAutofillId = new AutofillId(getAccessibilityViewId());
            mAutofillId = new AutofillId(getAutofillViewId());
        }
        return mAutofillId;
    }
@@ -7956,7 +7964,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    private boolean isAutofillable() {
        return getAutofillType() != AUTOFILL_TYPE_NONE && isImportantForAutofill()
                && getAccessibilityViewId() > LAST_APP_ACCESSIBILITY_ID;
                && getAutofillViewId() > LAST_APP_AUTOFILL_ID;
    }
    private void populateVirtualStructure(ViewStructure structure,
@@ -8474,11 +8482,25 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    public int getAccessibilityViewId() {
        if (mAccessibilityViewId == NO_ID) {
            mAccessibilityViewId = mContext.getNextAccessibilityId();
            mAccessibilityViewId = sNextAccessibilityViewId++;
        }
        return mAccessibilityViewId;
    }
    /**
     * Gets the unique identifier of this view on the screen for autofill purposes.
     *
     * @return The view autofill id.
     *
     * @hide
     */
    public int getAutofillViewId() {
        if (mAutofillViewId == NO_ID) {
            mAutofillViewId = mContext.getNextAutofillId();
        }
        return mAutofillViewId;
    }
    /**
     * Gets the unique identifier of the window in which this View reseides.
     *
@@ -12117,7 +12139,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (isAutofillable()) {
            AutofillManager afm = getAutofillManager();
            if (afm != null && getAccessibilityViewId() > LAST_APP_ACCESSIBILITY_ID) {
            if (afm != null && getAutofillViewId() > LAST_APP_AUTOFILL_ID) {
                if (mVisibilityChangeForAutofillHandler != null) {
                    mVisibilityChangeForAutofillHandler.removeMessages(0);
                }
@@ -17547,16 +17569,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     *
     * @return Returns a Parcelable object containing the view's current dynamic
     *         state, or null if there is nothing interesting to save.
     * @see #onRestoreInstanceState(android.os.Parcelable)
     * @see #saveHierarchyState(android.util.SparseArray)
     * @see #dispatchSaveInstanceState(android.util.SparseArray)
     * @see #onRestoreInstanceState(Parcelable)
     * @see #saveHierarchyState(SparseArray)
     * @see #dispatchSaveInstanceState(SparseArray)
     * @see #setSaveEnabled(boolean)
     */
    @CallSuper
    @Nullable protected Parcelable onSaveInstanceState() {
        mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
        if (mStartActivityRequestWho != null || isAutofilled()
                || mAccessibilityViewId > LAST_APP_ACCESSIBILITY_ID) {
                || mAutofillViewId > LAST_APP_AUTOFILL_ID) {
            BaseSavedState state = new BaseSavedState(AbsSavedState.EMPTY_STATE);
            if (mStartActivityRequestWho != null) {
@@ -17567,13 +17589,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                state.mSavedData |= BaseSavedState.IS_AUTOFILLED;
            }
            if (mAccessibilityViewId > LAST_APP_ACCESSIBILITY_ID) {
                state.mSavedData |= BaseSavedState.ACCESSIBILITY_ID;
            if (mAutofillViewId > LAST_APP_AUTOFILL_ID) {
                state.mSavedData |= BaseSavedState.AUTOFILL_ID;
            }
            state.mStartActivityRequestWhoSaved = mStartActivityRequestWho;
            state.mIsAutofilled = isAutofilled();
            state.mAccessibilityViewId = mAccessibilityViewId;
            state.mAutofillViewId = mAutofillViewId;
            return state;
        }
        return BaseSavedState.EMPTY_STATE;
@@ -17651,8 +17673,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            if ((baseState.mSavedData & BaseSavedState.IS_AUTOFILLED) != 0) {
                setAutofilled(baseState.mIsAutofilled);
            }
            if ((baseState.mSavedData & BaseSavedState.ACCESSIBILITY_ID) != 0) {
                mAccessibilityViewId = baseState.mAccessibilityViewId;
            if ((baseState.mSavedData & BaseSavedState.AUTOFILL_ID) != 0) {
                mAutofillViewId = baseState.mAutofillViewId;
            }
        }
    }
@@ -21488,11 +21510,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    }
    /**
     * Performs the traversal to find a view by its unuque and stable accessibility id.
     * Performs the traversal to find a view by its unique and stable accessibility id.
     *
     * <strong>Note:</strong>This method does not stop at the root namespace
     * boundary since the user can touch the screen at an arbitrary location
     * potentially crossing the root namespace bounday which will send an
     * potentially crossing the root namespace boundary which will send an
     * accessibility event to accessibility services and they should be able
     * to obtain the event source. Also accessibility ids are guaranteed to be
     * unique in the window.
@@ -21508,6 +21530,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        return null;
    }
    /**
     * Performs the traversal to find a view by its autofill id.
     *
     * <strong>Note:</strong>This method does not stop at the root namespace
     * boundary.
     *
     * @param autofillId The autofill id.
     * @return The found view.
     * @hide
     */
    public <T extends View> T findViewByAutofillIdTraversal(int autofillId) {
        if (getAutofillViewId() == autofillId) {
            return (T) this;
        }
        return null;
    }
    /**
     * Look for a child view with the given tag.  If this view has the given
     * tag, return this view.
@@ -24974,13 +25013,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    public static class BaseSavedState extends AbsSavedState {
        static final int START_ACTIVITY_REQUESTED_WHO_SAVED = 0b1;
        static final int IS_AUTOFILLED = 0b10;
        static final int ACCESSIBILITY_ID = 0b100;
        static final int AUTOFILL_ID = 0b100;
        // Flags that describe what data in this state is valid
        int mSavedData;
        String mStartActivityRequestWhoSaved;
        boolean mIsAutofilled;
        int mAccessibilityViewId;
        int mAutofillViewId;
        /**
         * Constructor used when reading from a parcel. Reads the state of the superclass.
@@ -25003,7 +25042,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            mSavedData = source.readInt();
            mStartActivityRequestWhoSaved = source.readString();
            mIsAutofilled = source.readBoolean();
            mAccessibilityViewId = source.readInt();
            mAutofillViewId = source.readInt();
        }
        /**
@@ -25022,7 +25061,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            out.writeInt(mSavedData);
            out.writeString(mStartActivityRequestWhoSaved);
            out.writeBoolean(mIsAutofilled);
            out.writeInt(mAccessibilityViewId);
            out.writeInt(mAutofillViewId);
        }
        public static final Parcelable.Creator<BaseSavedState> CREATOR
+21 −0
Original line number Diff line number Diff line
@@ -1361,6 +1361,27 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        return null;
    }

    /** @hide */
    @Override
    public View findViewByAutofillIdTraversal(int autofillId) {
        View foundView = super.findViewByAutofillIdTraversal(autofillId);
        if (foundView != null) {
            return foundView;
        }

        final int childrenCount = mChildrenCount;
        final View[] children = mChildren;
        for (int i = 0; i < childrenCount; i++) {
            View child = children[i];
            foundView = child.findViewByAutofillIdTraversal(autofillId);
            if (foundView != null) {
                return foundView;
            }
        }

        return null;
    }

    @Override
    public void dispatchWindowFocusChanged(boolean hasFocus) {
        super.dispatchWindowFocusChanged(hasFocus);
Loading