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

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

Merge "Adding accessibility focusable attribute (hidden for now)." into jb-dev

parents 82b3b1bc f9817f7a
Loading
Loading
Loading
Loading
+149 −11
Original line number Diff line number Diff line
@@ -2086,7 +2086,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
    // Accessiblity constants for mPrivateFlags2
    /**
     * Shift for accessibility related bits in {@link #mPrivateFlags2}.
     * Shift for the bits in {@link #mPrivateFlags2} related to the
     * "importantForAccessibility" attribute.
     */
    static final int IMPORTANT_FOR_ACCESSIBILITY_SHIFT = 20;
@@ -2142,6 +2143,72 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
     */
    static final int VIEW_QUICK_REJECTED = 0x20000000;
    // Accessiblity constants for mPrivateFlags2
    /**
     * Shift for the bits in {@link #mPrivateFlags2} related to the
     * "accessibilityFocusable" attribute.
     */
    static final int ACCESSIBILITY_FOCUSABLE_SHIFT = 30;
    /**
     * The system determines whether the view can take accessibility focus - default (recommended).
     * <p>
     * Such a view is consideted by the focus search if it is:
     * <ul>
     * <li>
     * Important for accessibility and actionable (clickable, long clickable, focusable)
     * </li>
     * <li>
     * Important for accessibility, not actionable (clickable, long clickable, focusable),
     * and does not have an actionable predecessor.
     * </li>
     * </ul>
     * An accessibility srvice can request putting accessibility focus on such a view.
     * </p>
     *
     * @hide
     */
    public static final int ACCESSIBILITY_FOCUSABLE_AUTO = 0x00000000;
    /**
     * The view can take accessibility focus.
     * <p>
     * A view that can take accessibility focus is always considered during focus
     * search and an accessibility service can request putting accessibility focus
     * on it.
     * </p>
     *
     * @hide
     */
    public static final int ACCESSIBILITY_FOCUSABLE_YES = 0x00000001;
    /**
     * The view can not take accessibility focus.
     * <p>
     * A view that can not take accessibility focus is never considered during focus
     * search and an accessibility service can not request putting accessibility focus
     * on it.
     * </p>
     *
     * @hide
     */
    public static final int ACCESSIBILITY_FOCUSABLE_NO = 0x00000002;
    /**
     * The default whether the view is accessiblity focusable.
     */
    static final int ACCESSIBILITY_FOCUSABLE_DEFAULT = ACCESSIBILITY_FOCUSABLE_AUTO;
    /**
     * Mask for obtainig the bits which specifies how to determine
     * whether a view is accessibility focusable.
     */
    static final int ACCESSIBILITY_FOCUSABLE_MASK = (ACCESSIBILITY_FOCUSABLE_AUTO
        | ACCESSIBILITY_FOCUSABLE_YES | ACCESSIBILITY_FOCUSABLE_NO)
        << ACCESSIBILITY_FOCUSABLE_SHIFT;
    /* End of masks for mPrivateFlags2 */
    static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED;
@@ -3132,7 +3199,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        mPrivateFlags2 = (LAYOUT_DIRECTION_DEFAULT << LAYOUT_DIRECTION_MASK_SHIFT) |
                (TEXT_DIRECTION_DEFAULT << TEXT_DIRECTION_MASK_SHIFT) |
                (TEXT_ALIGNMENT_DEFAULT << TEXT_ALIGNMENT_MASK_SHIFT) |
                (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << IMPORTANT_FOR_ACCESSIBILITY_SHIFT);
                (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << IMPORTANT_FOR_ACCESSIBILITY_SHIFT) |
                (ACCESSIBILITY_FOCUSABLE_DEFAULT << ACCESSIBILITY_FOCUSABLE_SHIFT);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
        mUserPaddingStart = -1;
@@ -4788,7 +4856,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        }
        if (!isAccessibilityFocused()) {
            final int mode = getAccessibilityFocusable();
            if (mode == ACCESSIBILITY_FOCUSABLE_YES || mode == ACCESSIBILITY_FOCUSABLE_AUTO) {
                info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
            }
        } else {
            info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
        }
@@ -6069,7 +6140,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
            return;
        }
        if ((focusableMode & FOCUSABLES_ACCESSIBILITY) == FOCUSABLES_ACCESSIBILITY) {
            if (canTakeAccessibilityFocusFromHover() || getAccessibilityNodeProvider() != null) {
            if (isAccessibilityFocusable()) {
                views.add(this);
                return;
            }
@@ -6403,12 +6474,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
     */
    @ViewDebug.ExportedProperty(category = "accessibility", mapping = {
            @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_AUTO,
                    to = "IMPORTANT_FOR_ACCESSIBILITY_AUTO"),
            @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_YES,
                    to = "IMPORTANT_FOR_ACCESSIBILITY_YES"),
            @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO,
                    to = "IMPORTANT_FOR_ACCESSIBILITY_NO")
            @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_AUTO, to = "auto"),
            @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_YES, to = "yes"),
            @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO, to = "no")
        })
    public int getImportantForAccessibility() {
        return (mPrivateFlags2 & IMPORTANT_FOR_ACCESSIBILITY_MASK)
@@ -6460,6 +6528,73 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        }
    }
    /**
     * Gets the mode for determining whether this View can take accessibility focus.
     *
     * @return The mode for determining whether a View can take accessibility focus.
     *
     * @attr ref android.R.styleable#View_accessibilityFocusable
     *
     * @see #ACCESSIBILITY_FOCUSABLE_YES
     * @see #ACCESSIBILITY_FOCUSABLE_NO
     * @see #ACCESSIBILITY_FOCUSABLE_AUTO
     *
     * @hide
     */
    @ViewDebug.ExportedProperty(category = "accessibility", mapping = {
            @ViewDebug.IntToString(from = ACCESSIBILITY_FOCUSABLE_AUTO, to = "auto"),
            @ViewDebug.IntToString(from = ACCESSIBILITY_FOCUSABLE_YES, to = "yes"),
            @ViewDebug.IntToString(from = ACCESSIBILITY_FOCUSABLE_NO, to = "no")
        })
    public int getAccessibilityFocusable() {
        return (mPrivateFlags2 & ACCESSIBILITY_FOCUSABLE_MASK) >>> ACCESSIBILITY_FOCUSABLE_SHIFT;
    }
    /**
     * Sets how to determine whether this view can take accessibility focus.
     *
     * @param mode How to determine whether this view can take accessibility focus.
     *
     * @attr ref android.R.styleable#View_accessibilityFocusable
     *
     * @see #ACCESSIBILITY_FOCUSABLE_YES
     * @see #ACCESSIBILITY_FOCUSABLE_NO
     * @see #ACCESSIBILITY_FOCUSABLE_AUTO
     *
     * @hide
     */
    public void setAccessibilityFocusable(int mode) {
        if (mode != getAccessibilityFocusable()) {
            mPrivateFlags2 &= ~ACCESSIBILITY_FOCUSABLE_MASK;
            mPrivateFlags2 |= (mode << ACCESSIBILITY_FOCUSABLE_SHIFT)
                    & ACCESSIBILITY_FOCUSABLE_MASK;
            notifyAccessibilityStateChanged();
        }
    }
    /**
     * Gets whether this view can take accessibility focus.
     *
     * @return Whether the view can take accessibility focus.
     *
     * @hide
     */
    public boolean isAccessibilityFocusable() {
        final int mode = (mPrivateFlags2 & ACCESSIBILITY_FOCUSABLE_MASK)
                >>> ACCESSIBILITY_FOCUSABLE_SHIFT;
        switch (mode) {
            case ACCESSIBILITY_FOCUSABLE_YES:
                return true;
            case ACCESSIBILITY_FOCUSABLE_NO:
                return false;
            case ACCESSIBILITY_FOCUSABLE_AUTO:
                return canTakeAccessibilityFocusFromHover()
                        || getAccessibilityNodeProvider() != null;
            default:
                throw new IllegalArgumentException("Unknow accessibility focusable mode: " + mode);
        }
    }
    /**
     * Gets the parent for accessibility purposes. Note that the parent for
     * accessibility is not necessary the immediate parent. It is the first
@@ -6641,7 +6776,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
                }
            } break;
            case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: {
                if (!isAccessibilityFocused()) {
                final int mode = getAccessibilityFocusable();
                if (!isAccessibilityFocused()
                        && (mode == ACCESSIBILITY_FOCUSABLE_YES
                                || mode == ACCESSIBILITY_FOCUSABLE_AUTO)) {
                    return requestAccessibilityFocus();
                }
            } break;
+36 −1
Original line number Diff line number Diff line
@@ -2136,7 +2136,8 @@
             query the screen. Note: While not recommended, an accessibility service may
             decide to ignore this attribute and operate on all views in the view tree. -->
        <attr name="importantForAccessibility" format="integer">
            <!-- The system determines whether the view is important for accessibility (recommended). -->
            <!-- The system determines whether the view is important for accessibility - default
                 (recommended). -->
            <enum name="auto" value="0" />
            <!-- The view is important for accessibility. -->
            <enum name="yes" value="1" />
@@ -2144,6 +2145,40 @@
            <enum name="no" value="2" />
        </attr>

        <!-- @hide Controls whether this view can take accessibility focus. -->
        <attr name="accessibilityFocusable" format="integer">
            <!-- The system determines whether the view can take accessibility focus - default
                 (recommended).
                 <p>
                 Such a view is consideted by the focus search if it is:
                 <ul>
                 <li>
                 Important for accessibility and actionable (clickable, long clickable, focusable)
                 </li>
                 <li>
                 Important for accessibility, not actionable (clickable, long clickable, focusable),
                 and does not have an actionable predecessor.
                 </li>
                 </ul>
                 An accessibility srvice can request putting accessibility focus on such a view.
                 </p> -->
            <enum name="auto" value="0" />
            <!-- The view can take accessibility focus.
                 <p>
                 A view that can take accessibility focus is always considered during focus
                 search and an accessibility service can request putting accessibility focus
                 on it.
                 </p> -->
            <enum name="yes" value="1" />
            <!-- The view can not take accessibility focus.
                 <p>
                 A view that can not take accessibility focus is never considered during focus
                 search and an accessibility service can not request putting accessibility focus
                 on it.
                 </p> -->
            <enum name="no" value="2" />
        </attr>

    </declare-styleable>

    <!-- Attributes that can be used with a {@link android.view.ViewGroup} or any