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

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

Merge "Optimizing AccessibilityNodeInfo caching."

parents fd6f77dc 6254f480
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -27314,6 +27314,7 @@ package android.view.accessibility {
    method public int describeContents();
    method public static java.lang.String eventTypeToString(int);
    method public int getAction();
    method public int getContentChangeType();
    method public long getEventTime();
    method public int getEventType();
    method public int getMovementGranularity();
@@ -27325,11 +27326,14 @@ package android.view.accessibility {
    method public static android.view.accessibility.AccessibilityEvent obtain(android.view.accessibility.AccessibilityEvent);
    method public static android.view.accessibility.AccessibilityEvent obtain();
    method public void setAction(int);
    method public void setContentChangeType(int);
    method public void setEventTime(long);
    method public void setEventType(int);
    method public void setMovementGranularity(int);
    method public void setPackageName(java.lang.CharSequence);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final int CONTENT_CHANGE_TYPE_NODE = 1; // 0x1
    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 0; // 0x0
    field public static final android.os.Parcelable.Creator CREATOR;
    field public static final int INVALID_POSITION = -1; // 0xffffffff
    field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4
@@ -27391,10 +27395,12 @@ package android.view.accessibility {
    method public int getActions();
    method public void getBoundsInParent(android.graphics.Rect);
    method public void getBoundsInScreen(android.graphics.Rect);
    method public android.os.Bundle getBundle();
    method public android.view.accessibility.AccessibilityNodeInfo getChild(int);
    method public int getChildCount();
    method public java.lang.CharSequence getClassName();
    method public java.lang.CharSequence getContentDescription();
    method public int getInputType();
    method public android.view.accessibility.AccessibilityNodeInfo getLabelFor();
    method public android.view.accessibility.AccessibilityNodeInfo getLabeledBy();
    method public int getMovementGranularities();
@@ -27438,6 +27444,7 @@ package android.view.accessibility {
    method public void setEnabled(boolean);
    method public void setFocusable(boolean);
    method public void setFocused(boolean);
    method public void setInputType(int);
    method public void setLabelFor(android.view.View);
    method public void setLabelFor(android.view.View, int);
    method public void setLabeledBy(android.view.View);
+4 −0
Original line number Diff line number Diff line
@@ -406,6 +406,10 @@ final class AccessibilityInteractionController {
                        if (host == null || !ViewRootImpl.isViewDescendantOf(host, root)) {
                            break;
                        }
                        // The focused view not shown, we failed.
                        if (!isShown(host)) {
                            break;
                        }
                        // If the host has a provider ask this provider to search for the
                        // focus instead fetching all provider nodes to do the search here.
                        AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
+110 −54
Original line number Diff line number Diff line
@@ -1564,6 +1564,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
    SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
    /**
     * The view's tag.
     * {@hide}
@@ -2136,13 +2138,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    /**
     * Flag indicating whether a view has accessibility focus.
     */
    static final int PFLAG2_ACCESSIBILITY_FOCUSED = 0x00000040 << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
    static final int PFLAG2_ACCESSIBILITY_FOCUSED = 0x04000000;
    /**
     * Flag indicating whether a view state for accessibility has changed.
     * Flag whether the accessibility state of the subtree rooted at this view changed.
     */
    static final int PFLAG2_ACCESSIBILITY_STATE_CHANGED = 0x00000080
            << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
    static final int PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED = 0x08000000;
    /**
     * Flag indicating whether a view failed the quickReject() check in draw(). This condition
@@ -4454,10 +4455,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            onFocusChanged(true, direction, previouslyFocusedRect);
            refreshDrawableState();
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                notifyAccessibilityStateChanged();
            }
        }
    }
@@ -4561,10 +4558,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            if (!rootViewRequestFocus()) {
                notifyGlobalFocusCleared(this);
            }
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                notifyAccessibilityStateChanged();
            }
        }
    }
@@ -4593,10 +4586,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            onFocusChanged(false, 0, null);
            refreshDrawableState();
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                notifyAccessibilityStateChanged();
            }
        }
    }
@@ -4647,9 +4636,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
        if (gainFocus) {
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
            }
        } else {
            notifyViewAccessibilityStateChangedIfNeeded();
        }
        InputMethodManager imm = InputMethodManager.peekInstance();
@@ -4706,6 +4695,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * @see AccessibilityDelegate
     */
    public void sendAccessibilityEvent(int eventType) {
        // Excluded views do not send accessibility events.
        if (!includeForAccessibility()) {
            return;
        }
        if (mAccessibilityDelegate != null) {
            mAccessibilityDelegate.sendAccessibilityEvent(this, eventType);
        } else {
@@ -5365,8 +5358,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        final boolean nonEmptyDesc = contentDescription != null && contentDescription.length() > 0;
        if (nonEmptyDesc && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
            setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
            notifySubtreeAccessibilityStateChangedIfNeeded();
        } else {
            notifyViewAccessibilityStateChangedIfNeeded();
        }
        notifyAccessibilityStateChanged();
    }
    /**
@@ -6646,7 +6641,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            }
            invalidate();
            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
            notifyAccessibilityStateChanged();
            return true;
        }
        return false;
@@ -6709,7 +6703,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED;
            invalidate();
            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
            notifyAccessibilityStateChanged();
        }
    }
@@ -6883,11 +6876,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
     */
    public void setImportantForAccessibility(int mode) {
        final boolean oldIncludeForAccessibility = includeForAccessibility();
        if (mode != getImportantForAccessibility()) {
            mPrivateFlags2 &= ~PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
            mPrivateFlags2 |= (mode << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT)
                    & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
            notifyAccessibilityStateChanged();
            if (oldIncludeForAccessibility != includeForAccessibility()) {
                notifySubtreeAccessibilityStateChangedIfNeeded();
            } else {
                notifyViewAccessibilityStateChangedIfNeeded();
            }
        }
    }
@@ -6994,25 +6992,44 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    }
    /**
     * Notifies accessibility services that some view's important for
     * accessibility state has changed. Note that such notifications
     * are made at most once every
     * Notifies that the accessibility state of this view changed. The change
     * is local to this view and does not represent structural changes such
     * as children and parent. For example, the view became focusable. The
     * notification is at at most once every
     * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
     * to avoid unnecessary load to the system. Also once a view has
     * made a notifucation this method is a NOP until the notification has
     * been sent to clients.
     * to avoid unnecessary load to the system. Also once a view has a pending
     * notifucation this method is a NOP until the notification has been sent.
     *
     * @hide
     */
    public void notifyViewAccessibilityStateChangedIfNeeded() {
        if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
            return;
        }
        if (mSendViewStateChangedAccessibilityEvent == null) {
            mSendViewStateChangedAccessibilityEvent =
                    new SendViewStateChangedAccessibilityEvent();
        }
        mSendViewStateChangedAccessibilityEvent.runOrPost();
    }
    /**
     * Notifies that the accessibility state of this view changed. The change
     * is *not* local to this view and does represent structural changes such
     * as children and parent. For example, the view size changed. The
     * notification is at at most once every
     * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
     * to avoid unnecessary load to the system. Also once a view has a pending
     * notifucation this method is a NOP until the notification has been sent.
     *
     * TODO: Makse sure this method is called for any view state change
     *       that is interesting for accessilility purposes.
     * @hide
     */
    public void notifyAccessibilityStateChanged() {
    private void notifySubtreeAccessibilityStateChangedIfNeeded() {
        if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
            return;
        }
        if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_STATE_CHANGED) == 0) {
            mPrivateFlags2 |= PFLAG2_ACCESSIBILITY_STATE_CHANGED;
        if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
            mPrivateFlags2 |= PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
            if (mParent != null) {
                mParent.childAccessibilityStateChanged(this);
            }
@@ -7020,13 +7037,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    }
    /**
     * Reset the state indicating the this view has requested clients
     * interested in its accessibility state to be notified.
     *
     * @hide
     * Reset the flag indicating the accessibility state of the subtree rooted
     * at this view changed.
     */
    public void resetAccessibilityStateChanged() {
        mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_STATE_CHANGED;
    void resetSubtreeAccessibilityStateChanged() {
        mPrivateFlags2 &= ~PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
    }
    /**
@@ -7139,7 +7154,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                        || getAccessibilitySelectionEnd() != end)
                        && (start == end)) {
                    setAccessibilitySelection(start, end);
                    notifyAccessibilityStateChanged();
                    notifyViewAccessibilityStateChangedIfNeeded();
                    return true;
                }
            } break;
@@ -8560,6 +8575,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * @param mask Constant indicating the bit range that should be changed
     */
    void setFlags(int flags, int mask) {
        final boolean accessibilityEnabled =
                AccessibilityManager.getInstance(mContext).isEnabled();
        final boolean oldIncludeForAccessibility = accessibilityEnabled
                ? includeForAccessibility() : false;
        int old = mViewFlags;
        mViewFlags = (mViewFlags & ~mask) | (flags & mask);
@@ -8584,9 +8604,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                 */
                if (mParent != null) mParent.focusableViewAvailable(this);
            }
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                notifyAccessibilityStateChanged();
            }
        }
        final int newVisibility = flags & VISIBILITY_MASK;
@@ -8707,10 +8724,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            }
        }
        if (AccessibilityManager.getInstance(mContext).isEnabled()
                && ((changed & FOCUSABLE) != 0 || (changed & CLICKABLE) != 0
                        || (changed & LONG_CLICKABLE) != 0 || (changed & ENABLED) != 0)) {
            notifyAccessibilityStateChanged();
        if (accessibilityEnabled) {
            if ((changed & FOCUSABLE_MASK) != 0 || (changed & VISIBILITY_MASK) != 0
                    || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0) {
                if (oldIncludeForAccessibility != includeForAccessibility()) {
                    notifySubtreeAccessibilityStateChangedIfNeeded();
                } else {
                    notifyViewAccessibilityStateChangedIfNeeded();
                }
            }
            if ((changed & ENABLED_MASK) != 0) {
                notifyViewAccessibilityStateChangedIfNeeded();
            }
        }
    }
@@ -11757,6 +11782,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        jumpDrawablesToCurrentState();
        clearAccessibilityFocus();
        resetSubtreeAccessibilityStateChanged();
        if (isFocused()) {
            InputMethodManager imm = InputMethodManager.peekInstance();
            imm.focusIn(this);
@@ -12052,8 +12079,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        mCurrentAnimation = null;
        mCurrentScene = null;
        resetAccessibilityStateChanged();
    }
    private void cleanupDraw() {
@@ -14438,6 +14463,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            mPrivateFlags |= drawn;
            mBackgroundSizeChanged = true;
            notifySubtreeAccessibilityStateChangedIfNeeded();
        }
        return changed;
    }
@@ -15202,9 +15229,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            invalidate(true);
            refreshDrawableState();
            dispatchSetSelected(selected);
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                notifyAccessibilityStateChanged();
            }
            notifyViewAccessibilityStateChangedIfNeeded();
        }
    }
@@ -18819,6 +18844,37 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    private class SendViewStateChangedAccessibilityEvent implements Runnable {
        private boolean mPosted;
        private long mLastEventTimeMillis;
        public void run() {
            mPosted = false;
            mLastEventTimeMillis = SystemClock.uptimeMillis();
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                AccessibilityEvent event = AccessibilityEvent.obtain();
                event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
                event.setContentChangeType(AccessibilityEvent.CONTENT_CHANGE_TYPE_NODE);
                sendAccessibilityEventUnchecked(event);
            }
        }
        public void runOrPost() {
            if (mPosted) {
                return;
            }
            final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
            final long minEventIntevalMillis =
                    ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
            if (timeSinceLastMillis >= minEventIntevalMillis) {
                run();
            } else {
                postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
                mPosted = true;
            }
        }
    }
    /**
     * Dump all private flags in readable format, useful for documentation and
     * sanity checking.
+21 −17
Original line number Diff line number Diff line
@@ -1697,16 +1697,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        }
    }

    /**
     * @hide
     */
    @Override
    public void childAccessibilityStateChanged(View child) {
        if (mParent != null) {
            mParent.childAccessibilityStateChanged(child);
        }
    }

    /**
     * Implement this method to intercept hover events before they are handled
     * by child views.
@@ -2534,13 +2524,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     * @hide
     */
    @Override
    public void resetAccessibilityStateChanged() {
        super.resetAccessibilityStateChanged();
    public void childAccessibilityStateChanged(View root) {
        if (mParent != null) {
            mParent.childAccessibilityStateChanged(root);
        }
    }

    @Override
    void resetSubtreeAccessibilityStateChanged() {
        super.resetSubtreeAccessibilityStateChanged();
        View[] children = mChildren;
        final int childCount = mChildrenCount;
        for (int i = 0; i < childCount; i++) {
            View child = children[i];
            child.resetAccessibilityStateChanged();
            children[i].resetSubtreeAccessibilityStateChanged();
        }
    }

@@ -3466,7 +3462,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    }

    private void clearCachedLayoutMode() {
        if (!getBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) {
        if (!hasBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) {
           mLayoutMode = LAYOUT_MODE_UNDEFINED;
        }
    }
@@ -3597,6 +3593,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        if (child.hasTransientState()) {
            childHasTransientStateChanged(child, true);
        }

        if (child.isImportantForAccessibility() && child.getVisibility() != View.GONE) {
            childAccessibilityStateChanged(child);
        }
    }

    private void addInArray(View child, int index) {
@@ -3836,6 +3836,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        }

        onViewRemoved(view);

        if (view.isImportantForAccessibility() && view.getVisibility() != View.GONE) {
            childAccessibilityStateChanged(view);
        }
    }

    /**
@@ -4786,7 +4790,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        setBooleanFlag(FLAG_USE_CHILD_DRAWING_ORDER, enabled);
    }

    private boolean getBooleanFlag(int flag) {
    private boolean hasBooleanFlag(int flag) {
        return (mGroupFlags & flag) == flag;
    }

@@ -4854,7 +4858,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    void invalidateInheritedLayoutMode(int layoutModeOfRoot) {
        if (mLayoutMode == LAYOUT_MODE_UNDEFINED ||
            mLayoutMode == layoutModeOfRoot ||
            getBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) {
            hasBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) {
            return;
        }
        setLayoutMode(LAYOUT_MODE_UNDEFINED, false);
+5 −4
Original line number Diff line number Diff line
@@ -292,13 +292,14 @@ public interface ViewParent {
    public ViewParent getParentForAccessibility();

    /**
     * A child notifies its parent that its state for accessibility has changed.
     * That is some of the child properties reported to accessibility services has
     * changed, hence the interested services have to be notified for the new state.
     * A child notifies its parent that the accessibility state of a subtree rooted
     * at a given node changed. That is the structure of the subtree is different.
     *
     * @param The root of the changed subtree.
     *
     * @hide
     */
    public void childAccessibilityStateChanged(View child);
    public void childAccessibilityStateChanged(View root);

    /**
     * Tells if this view parent can resolve the layout direction.
Loading