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

Commit b1ecf0d7 authored by Svetoslav's avatar Svetoslav Committed by Android (Google) Code Review
Browse files

Merge "Adding APIs to enable apps to influence accessibility traversal." into lmp-mr1-dev

parents b9144cea 6c70290f
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -239,6 +239,8 @@ package android {
    field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
    field public static final int accessibilityFlags = 16843652; // 0x1010384
    field public static final int accessibilityLiveRegion = 16843758; // 0x10103ee
    field public static final int accessibilityTraversalAfter = 16844036; // 0x1010504
    field public static final int accessibilityTraversalBefore = 16844035; // 0x1010503
    field public static final int accountPreferences = 16843423; // 0x101029f
    field public static final int accountType = 16843407; // 0x101028f
    field public static final int action = 16842797; // 0x101002d
@@ -33610,6 +33612,8 @@ package android.view {
    method public static int generateViewId();
    method public int getAccessibilityLiveRegion();
    method public android.view.accessibility.AccessibilityNodeProvider getAccessibilityNodeProvider();
    method public int getAccessibilityTraversalAfter();
    method public int getAccessibilityTraversalBefore();
    method public float getAlpha();
    method public android.view.animation.Animation getAnimation();
    method public android.os.IBinder getApplicationWindowToken();
@@ -33886,6 +33890,8 @@ package android.view {
    method public void sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent);
    method public void setAccessibilityDelegate(android.view.View.AccessibilityDelegate);
    method public void setAccessibilityLiveRegion(int);
    method public void setAccessibilityTraversalAfter(int);
    method public void setAccessibilityTraversalBefore(int);
    method public void setActivated(boolean);
    method public void setAlpha(float);
    method public void setAnimation(android.view.animation.Animation);
@@ -35165,6 +35171,8 @@ package android.view.accessibility {
    method public java.lang.CharSequence getText();
    method public int getTextSelectionEnd();
    method public int getTextSelectionStart();
    method public android.view.accessibility.AccessibilityNodeInfo getTraversalAfter();
    method public android.view.accessibility.AccessibilityNodeInfo getTraversalBefore();
    method public java.lang.String getViewIdResourceName();
    method public android.view.accessibility.AccessibilityWindowInfo getWindow();
    method public int getWindowId();
@@ -35235,6 +35243,10 @@ package android.view.accessibility {
    method public void setSource(android.view.View, int);
    method public void setText(java.lang.CharSequence);
    method public void setTextSelection(int, int);
    method public void setTraversalAfter(android.view.View);
    method public void setTraversalAfter(android.view.View, int);
    method public void setTraversalBefore(android.view.View);
    method public void setTraversalBefore(android.view.View, int);
    method public void setViewIdResourceName(java.lang.String);
    method public void setVisibleToUser(boolean);
    method public void writeToParcel(android.os.Parcel, int);
@@ -38432,6 +38444,8 @@ package android.widget {
    method public boolean onLoadClass(java.lang.Class);
    method public void reapply(android.content.Context, android.view.View);
    method public void removeAllViews(int);
    method public void setAccessibilityTraversalAfter(int, int);
    method public void setAccessibilityTraversalBefore(int, int);
    method public void setBitmap(int, java.lang.String, android.graphics.Bitmap);
    method public void setBoolean(int, java.lang.String, boolean);
    method public void setBundle(int, java.lang.String, android.os.Bundle);
+134 −0
Original line number Diff line number Diff line
@@ -3108,6 +3108,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    private MatchLabelForPredicate mMatchLabelForPredicate;
    /**
     * Specifies a view before which this one is visited in accessibility traversal.
     */
    private int mAccessibilityTraversalBeforeId = NO_ID;
    /**
     * Specifies a view after which this one is visited in accessibility traversal.
     */
    private int mAccessibilityTraversalAfterId = NO_ID;
    /**
     * Predicate for matching a view by its id.
     */
@@ -3888,6 +3898,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                case com.android.internal.R.styleable.View_contentDescription:
                    setContentDescription(a.getString(attr));
                    break;
                case com.android.internal.R.styleable.View_accessibilityTraversalBefore:
                    setAccessibilityTraversalBefore(a.getResourceId(attr, NO_ID));
                    break;
                case com.android.internal.R.styleable.View_accessibilityTraversalAfter:
                    setAccessibilityTraversalAfter(a.getResourceId(attr, NO_ID));
                    break;
                case com.android.internal.R.styleable.View_labelFor:
                    setLabelFor(a.getResourceId(attr, NO_ID));
                    break;
@@ -5611,6 +5627,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            if (rootView == null) {
                rootView = this;
            }
            View label = rootView.findLabelForView(this, mID);
            if (label != null) {
                info.setLabeledBy(label);
@@ -5639,6 +5656,30 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            }
        }
        if (mAccessibilityTraversalBeforeId != View.NO_ID) {
            View rootView = getRootView();
            if (rootView == null) {
                rootView = this;
            }
            View next = rootView.findViewInsideOutShouldExist(this,
                    mAccessibilityTraversalBeforeId);
            if (next != null) {
                info.setTraversalBefore(next);
            }
        }
        if (mAccessibilityTraversalAfterId != View.NO_ID) {
            View rootView = getRootView();
            if (rootView == null) {
                rootView = this;
            }
            View next = rootView.findViewInsideOutShouldExist(this,
                    mAccessibilityTraversalAfterId);
            if (next != null) {
                info.setTraversalAfter(next);
            }
        }
        info.setVisibleToUser(isVisibleToUser());
        info.setPackageName(mContext.getPackageName());
@@ -6042,6 +6083,94 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    /**
     * Sets the id of a view before which this one is visited in accessibility traversal.
     * A screen-reader must visit the content of this view before the content of the one
     * it precedes. For example, if view B is set to be before view A, then a screen-reader
     * will traverse the entire content of B before traversing the entire content of A,
     * regardles of what traversal strategy it is using.
     * <p>
     * Views that do not have specified before/after relationships are traversed in order
     * determined by the screen-reader.
     * </p>
     * <p>
     * Setting that this view is before a view that is not important for accessibility
     * or if this view is not important for accessibility will have no effect as the
     * screen-reader is not aware of unimportant views.
     * </p>
     *
     * @param beforeId The id of a view this one precedes in accessibility traversal.
     *
     * @attr ref android.R.styleable#View_accessibilityTraversalBefore
     *
     * @see #setImportantForAccessibility(int)
     */
    @RemotableViewMethod
    public void setAccessibilityTraversalBefore(int beforeId) {
        if (mAccessibilityTraversalBeforeId == beforeId) {
            return;
        }
        mAccessibilityTraversalBeforeId = beforeId;
        notifyViewAccessibilityStateChangedIfNeeded(
                AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
    }
    /**
     * Gets the id of a view before which this one is visited in accessibility traversal.
     *
     * @return The id of a view this one precedes in accessibility traversal if
     *         specified, otherwise {@link #NO_ID}.
     *
     * @see #setAccessibilityTraversalBefore(int)
     */
    public int getAccessibilityTraversalBefore() {
        return mAccessibilityTraversalBeforeId;
    }
    /**
     * Sets the id of a view after which this one is visited in accessibility traversal.
     * A screen-reader must visit the content of the other view before the content of this
     * one. For example, if view B is set to be after view A, then a screen-reader
     * will traverse the entire content of A before traversing the entire content of B,
     * regardles of what traversal strategy it is using.
     * <p>
     * Views that do not have specified before/after relationships are traversed in order
     * determined by the screen-reader.
     * </p>
     * <p>
     * Setting that this view is after a view that is not important for accessibility
     * or if this view is not important for accessibility will have no effect as the
     * screen-reader is not aware of unimportant views.
     * </p>
     *
     * @param afterId The id of a view this one succedees in accessibility traversal.
     *
     * @attr ref android.R.styleable#View_accessibilityTraversalAfter
     *
     * @see #setImportantForAccessibility(int)
     */
    @RemotableViewMethod
    public void setAccessibilityTraversalAfter(int afterId) {
        if (mAccessibilityTraversalAfterId == afterId) {
            return;
        }
        mAccessibilityTraversalAfterId = afterId;
        notifyViewAccessibilityStateChangedIfNeeded(
                AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
    }
    /**
     * Gets the id of a view after which this one is visited in accessibility traversal.
     *
     * @return The id of a view this one succeedes in accessibility traversal if
     *         specified, otherwise {@link #NO_ID}.
     *
     * @see #setAccessibilityTraversalAfter(int)
     */
    public int getAccessibilityTraversalAfter() {
        return mAccessibilityTraversalAfterId;
    }
    /**
     * Gets the id of a view for which this view serves as a label for
     * accessibility purposes.
@@ -6061,11 +6190,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    @RemotableViewMethod
    public void setLabelFor(int id) {
        if (mLabelForId == id) {
            return;
        }
        mLabelForId = id;
        if (mLabelForId != View.NO_ID
                && mID == View.NO_ID) {
            mID = generateViewId();
        }
        notifyViewAccessibilityStateChangedIfNeeded(
                AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
    }
    /**
+147 −21
Original line number Diff line number Diff line
@@ -547,6 +547,8 @@ public class AccessibilityNodeInfo implements Parcelable {
    private long mParentNodeId = ROOT_NODE_ID;
    private long mLabelForId = ROOT_NODE_ID;
    private long mLabeledById = ROOT_NODE_ID;
    private long mTraversalBefore = ROOT_NODE_ID;
    private long mTraversalAfter = ROOT_NODE_ID;

    private int mBooleanProperties;
    private final Rect mBoundsInParent = new Rect();
@@ -1045,6 +1047,126 @@ public class AccessibilityNodeInfo implements Parcelable {
        return mActions.remove(action);
    }

    /**
     * Gets the node before which this one is visited during traversal. A screen-reader
     * must visit the content of this node before the content of the one it precedes.
     *
     * @return The succeeding node if such or <code>null</code>.
     *
     * @see #setTraversalBefore(android.view.View)
     * @see #setTraversalBefore(android.view.View, int)
     */
    public AccessibilityNodeInfo getTraversalBefore() {
        enforceSealed();
        return getNodeForAccessibilityId(mTraversalBefore);
    }

    /**
     * Sets the view before whose node this one should be visited during traversal. A
     * screen-reader must visit the content of this node before the content of the one
     * it precedes.
     * <p>
     *   <strong>Note:</strong> Cannot be called from an
     *   {@link android.accessibilityservice.AccessibilityService}.
     *   This class is made immutable before being delivered to an AccessibilityService.
     * </p>
     *
     * @param view The view providing the preceding node.
     *
     * @see #getTraversalBefore()
     */
    public void setTraversalBefore(View view) {
        setTraversalBefore(view, UNDEFINED_ITEM_ID);
    }

    /**
     * Sets the node before which this one is visited during traversal. A screen-reader
     * must visit the content of this node before the content of the one it precedes.
     * The successor is a virtual descendant of the given <code>root</code>. If
     * <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root is set
     * as the successor.
     * <p>
     * A virtual descendant is an imaginary View that is reported as a part of the view
     * hierarchy for accessibility purposes. This enables custom views that draw complex
     * content to report them selves as a tree of virtual views, thus conveying their
     * logical structure.
     * </p>
     * <p>
     *   <strong>Note:</strong> Cannot be called from an
     *   {@link android.accessibilityservice.AccessibilityService}.
     *   This class is made immutable before being delivered to an AccessibilityService.
     * </p>
     *
     * @param root The root of the virtual subtree.
     * @param virtualDescendantId The id of the virtual descendant.
     */
    public void setTraversalBefore(View root, int virtualDescendantId) {
        enforceNotSealed();
        final int rootAccessibilityViewId = (root != null)
                ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID;
        mTraversalBefore = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
    }

    /**
     * Gets the node after which this one is visited in accessibility traversal.
     * A screen-reader must visit the content of the other node before the content
     * of this one.
     *
     * @return The succeeding node if such or <code>null</code>.
     *
     * @see #setTraversalAfter(android.view.View)
     * @see #setTraversalAfter(android.view.View, int)
     */
    public AccessibilityNodeInfo getTraversalAfter() {
        enforceSealed();
        return getNodeForAccessibilityId(mTraversalAfter);
    }

    /**
     * Sets the view whose node is visited after this one in accessibility traversal.
     * A screen-reader must visit the content of the other node before the content
     * of this one.
     * <p>
     *   <strong>Note:</strong> Cannot be called from an
     *   {@link android.accessibilityservice.AccessibilityService}.
     *   This class is made immutable before being delivered to an AccessibilityService.
     * </p>
     *
     * @param view The previous view.
     *
     * @see #getTraversalAfter()
     */
    public void setTraversalAfter(View view) {
        setTraversalAfter(view, UNDEFINED_ITEM_ID);
    }

    /**
     * Sets the node after which this one is visited in accessibility traversal.
     * A screen-reader must visit the content of the other node before the content
     * of this one. If <code>virtualDescendantId</code> equals to {@link View#NO_ID}
     * the root is set as the predecessor.
     * <p>
     * A virtual descendant is an imaginary View that is reported as a part of the view
     * hierarchy for accessibility purposes. This enables custom views that draw complex
     * content to report them selves as a tree of virtual views, thus conveying their
     * logical structure.
     * </p>
     * <p>
     *   <strong>Note:</strong> Cannot be called from an
     *   {@link android.accessibilityservice.AccessibilityService}.
     *   This class is made immutable before being delivered to an AccessibilityService.
     * </p>
     *
     * @param root The root of the virtual subtree.
     * @param virtualDescendantId The id of the virtual descendant.
     */
    public void setTraversalAfter(View root, int virtualDescendantId) {
        enforceNotSealed();
        final int rootAccessibilityViewId = (root != null)
                ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID;
        mTraversalAfter = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
    }

    /**
     * Sets the maximum text length, or -1 for no limit.
     * <p>
@@ -1229,13 +1351,7 @@ public class AccessibilityNodeInfo implements Parcelable {
     */
    public AccessibilityNodeInfo getParent() {
        enforceSealed();
        if (!canPerformRequestOverConnection(mParentNodeId)) {
            return null;
        }
        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
                mWindowId, mParentNodeId, false, FLAG_PREFETCH_PREDECESSORS
                        | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
        return getNodeForAccessibilityId(mParentNodeId);
    }

    /**
@@ -2055,13 +2171,7 @@ public class AccessibilityNodeInfo implements Parcelable {
     */
    public AccessibilityNodeInfo getLabelFor() {
        enforceSealed();
        if (!canPerformRequestOverConnection(mLabelForId)) {
            return null;
        }
        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
                mWindowId, mLabelForId, false, FLAG_PREFETCH_PREDECESSORS
                        | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
        return getNodeForAccessibilityId(mLabelForId);
    }

    /**
@@ -2113,13 +2223,7 @@ public class AccessibilityNodeInfo implements Parcelable {
     */
    public AccessibilityNodeInfo getLabeledBy() {
        enforceSealed();
        if (!canPerformRequestOverConnection(mLabeledById)) {
            return null;
        }
        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
                mWindowId, mLabeledById, false, FLAG_PREFETCH_PREDECESSORS
                        | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
        return getNodeForAccessibilityId(mLabeledById);
    }

    /**
@@ -2453,6 +2557,9 @@ public class AccessibilityNodeInfo implements Parcelable {
        parcel.writeLong(mParentNodeId);
        parcel.writeLong(mLabelForId);
        parcel.writeLong(mLabeledById);
        parcel.writeLong(mTraversalBefore);
        parcel.writeLong(mTraversalAfter);

        parcel.writeInt(mConnectionId);

        final LongArray childIds = mChildNodeIds;
@@ -2571,6 +2678,8 @@ public class AccessibilityNodeInfo implements Parcelable {
        mParentNodeId = other.mParentNodeId;
        mLabelForId = other.mLabelForId;
        mLabeledById = other.mLabeledById;
        mTraversalBefore = other.mTraversalBefore;
        mTraversalAfter = other.mTraversalAfter;
        mWindowId = other.mWindowId;
        mConnectionId = other.mConnectionId;
        mBoundsInParent.set(other.mBoundsInParent);
@@ -2633,6 +2742,9 @@ public class AccessibilityNodeInfo implements Parcelable {
        mParentNodeId = parcel.readLong();
        mLabelForId = parcel.readLong();
        mLabeledById = parcel.readLong();
        mTraversalBefore = parcel.readLong();
        mTraversalAfter = parcel.readLong();

        mConnectionId = parcel.readInt();

        final int childrenSize = parcel.readInt();
@@ -2725,6 +2837,8 @@ public class AccessibilityNodeInfo implements Parcelable {
        mParentNodeId = ROOT_NODE_ID;
        mLabelForId = ROOT_NODE_ID;
        mLabeledById = ROOT_NODE_ID;
        mTraversalBefore = ROOT_NODE_ID;
        mTraversalAfter = ROOT_NODE_ID;
        mWindowId = UNDEFINED_ITEM_ID;
        mConnectionId = UNDEFINED_CONNECTION_ID;
        mMaxTextLength = -1;
@@ -2911,6 +3025,8 @@ public class AccessibilityNodeInfo implements Parcelable {
            builder.append("; accessibilityViewId: " + getAccessibilityViewId(mSourceNodeId));
            builder.append("; virtualDescendantId: " + getVirtualDescendantId(mSourceNodeId));
            builder.append("; mParentNodeId: " + mParentNodeId);
            builder.append("; traversalBefore: ").append(mTraversalBefore);
            builder.append("; traversalAfter: ").append(mTraversalAfter);

            int granularities = mMovementGranularities;
            builder.append("; MovementGranularities: [");
@@ -2963,6 +3079,16 @@ public class AccessibilityNodeInfo implements Parcelable {
        return builder.toString();
    }

    private AccessibilityNodeInfo getNodeForAccessibilityId(long accessibilityId) {
        if (!canPerformRequestOverConnection(accessibilityId)) {
            return null;
        }
        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
                mWindowId, accessibilityId, false, FLAG_PREFETCH_PREDECESSORS
                        | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
    }

    /**
     * A class defining an action that can be performed on an {@link AccessibilityNodeInfo}.
     * Each action has a unique id that is mandatory and optional data.
+20 −0
Original line number Diff line number Diff line
@@ -2527,6 +2527,26 @@ public class RemoteViews implements Parcelable, Filter {
        setCharSequence(viewId, "setContentDescription", contentDescription);
    }

    /**
     * Equivalent to calling {@link android.view.View#setAccessibilityTraversalBefore(int)}.
     *
     * @param viewId The id of the view whose before view in accessibility traversal to set.
     * @param nextId The id of the next in the accessibility traversal.
     **/
    public void setAccessibilityTraversalBefore(int viewId, int nextId) {
        setInt(viewId, "setAccessibilityTraversalBefore", nextId);
    }

    /**
     * Equivalent to calling {@link android.view.View#setAccessibilityTraversalAfter(int)}.
     *
     * @param viewId The id of the view whose after view in accessibility traversal to set.
     * @param nextId The id of the next in the accessibility traversal.
     **/
    public void setAccessibilityTraversalAfter(int viewId, int nextId) {
        setInt(viewId, "setAccessibilityTraversalAfter", nextId);
    }

    /**
     * Equivalent to calling View.setLabelFor(int).
     *
+12 −0
Original line number Diff line number Diff line
@@ -2363,6 +2363,18 @@
             representation this attribute can be used for providing such. -->
        <attr name="contentDescription" format="string" localization="suggested" />

        <!-- Sets the id of a view before which this one is visited in accessibility traversal.
             A screen-reader must visit the content of this view before the content of the one
             it precedes.
             @see android.view.View#setAccessibilityTraversalBefore(int)} -->
        <attr name="accessibilityTraversalBefore" format="integer" />

        <!-- Sets the id of a view after which this one is visited in accessibility traversal.
             A screen-reader must visit the content of the other view before the content of
             this one.
             @see android.view.View#setAccessibilityTraversalAfter(int)} -->
        <attr name="accessibilityTraversalAfter" format="integer" />

        <!-- Name of the method in this View's context to invoke when the view is
             clicked. This name must correspond to a public method that takes
             exactly one parameter of type View. For instance, if you specify
Loading