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

am: c91290a6e9

Change-Id: Ib4566c2f0e32477d5f9eb6510edc140c2b66e0a4
This commit is contained in:
Phil Weaver
2017-06-17 00:56:19 +00:00
committed by android-build-merger
6 changed files with 120 additions and 62 deletions

View File

@@ -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];

View File

@@ -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;
}
/**

View File

@@ -956,8 +956,7 @@ public class ContextWrapper extends Context {
/**
* @hide
*/
@Override
public int getNextAccessibilityId() {
return mBase.getNextAccessibilityId();
public int getNextAutofillId() {
return mBase.getNextAutofillId();
}
}

View File

@@ -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;
}
}
}
@@ -21476,7 +21498,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param accessibilityId The searched accessibility id.
* @return The found view.
*/
final <T extends View> T findViewByAccessibilityId(int accessibilityId) {
final <T extends View> T findViewByAccessibilityId(int accessibilityId) {
if (accessibilityId < 0) {
return null;
}
@@ -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

View File

@@ -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);

View File

@@ -246,20 +246,20 @@ public final class AutofillManager {
/**
* Finds views by traversing the hierarchies of the client.
*
* @param viewIds The accessibility ids of the views to find
* @param viewIds The autofill ids of the views to find
*
* @return And array containing the views (empty if no views found).
*/
@NonNull View[] findViewsByAccessibilityIdTraversal(@NonNull int[] viewIds);
@NonNull View[] findViewsByAutofillIdTraversal(@NonNull int[] viewIds);
/**
* Finds a view by traversing the hierarchies of the client.
*
* @param viewId The accessibility id of the views to find
* @param viewId The autofill id of the views to find
*
* @return The view, or {@code null} if not found
*/
@Nullable View findViewByAccessibilityIdTraversal(int viewId);
@Nullable View findViewByAutofillIdTraversal(int viewId);
/**
* Runs the specified action on the UI thread.
@@ -795,11 +795,11 @@ public final class AutofillManager {
}
private static AutofillId getAutofillId(View view) {
return new AutofillId(view.getAccessibilityViewId());
return new AutofillId(view.getAutofillViewId());
}
private static AutofillId getAutofillId(View parent, int virtualId) {
return new AutofillId(parent.getAccessibilityViewId(), virtualId);
return new AutofillId(parent.getAutofillViewId(), virtualId);
}
private void startSessionLocked(@NonNull AutofillId id, @NonNull Rect bounds,
@@ -1039,7 +1039,7 @@ public final class AutofillManager {
final int itemCount = ids.size();
int numApplied = 0;
ArrayMap<View, SparseArray<AutofillValue>> virtualValues = null;
final View[] views = client.findViewsByAccessibilityIdTraversal(getViewIds(ids));
final View[] views = client.findViewsByAutofillIdTraversal(getViewIds(ids));
for (int i = 0; i < itemCount; i++) {
final AutofillId id = ids.get(i);
@@ -1232,7 +1232,7 @@ public final class AutofillManager {
return null;
}
return client.findViewByAccessibilityIdTraversal(autofillId.getViewId());
return client.findViewByAutofillIdTraversal(autofillId.getViewId());
}
/** @hide */