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

Commit aca95ca0 authored by Alan Viverette's avatar Alan Viverette Committed by Android Git Automerger
Browse files

am 2a65a283: Merge "Add live region politeness to View, AccessibilityNodeInfo" into klp-dev

* commit '2a65a283':
  Add live region politeness to View, AccessibilityNodeInfo
parents 9282b9ac 2a65a283
Loading
Loading
Loading
Loading
+16 −12
Original line number Diff line number Diff line
@@ -228,6 +228,7 @@ package android {
    field public static final int accessibilityEventTypes = 16843648; // 0x1010380
    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 accountPreferences = 16843423; // 0x101029f
    field public static final int accountType = 16843407; // 0x101028f
    field public static final int action = 16842797; // 0x101002d
@@ -27481,6 +27482,7 @@ package android.view {
    method public android.view.View focusSearch(int);
    method public void forceLayout();
    method public static int generateViewId();
    method public int getAccessibilityLiveRegion();
    method public android.view.accessibility.AccessibilityNodeProvider getAccessibilityNodeProvider();
    method public float getAlpha();
    method public android.view.animation.Animation getAnimation();
@@ -27742,6 +27744,7 @@ package android.view {
    method public void sendAccessibilityEvent(int);
    method public void sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent);
    method public void setAccessibilityDelegate(android.view.View.AccessibilityDelegate);
    method public void setAccessibilityLiveRegion(int);
    method public void setActivated(boolean);
    method public void setAlpha(float);
    method public void setAnimation(android.view.animation.Animation);
@@ -27847,6 +27850,9 @@ package android.view {
    method protected boolean verifyDrawable(android.graphics.drawable.Drawable);
    method public boolean willNotCacheDrawing();
    method public boolean willNotDraw();
    field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
    field public static final android.util.Property ALPHA;
    field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
    field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
@@ -28155,7 +28161,6 @@ package android.view {
    method public void bringChildToFront(android.view.View);
    method protected boolean canAnimate();
    method protected boolean checkLayoutParams(android.view.ViewGroup.LayoutParams);
    method public void childAccessibilityStateChanged(android.view.View);
    method public void childDrawableStateChanged(android.view.View);
    method public void childHasTransientStateChanged(android.view.View, boolean);
    method protected void cleanupLayoutState(android.view.View);
@@ -28204,6 +28209,7 @@ package android.view {
    method protected void measureChild(android.view.View, int, int);
    method protected void measureChildWithMargins(android.view.View, int, int, int, int);
    method protected void measureChildren(int, int);
    method public void notifySubtreeAccessibilityStateChanged(android.view.View, android.view.View, int);
    method public final void offsetDescendantRectToMyCoords(android.view.View, android.graphics.Rect);
    method public final void offsetRectIntoDescendantCoords(android.view.View, android.graphics.Rect);
    method public boolean onInterceptHoverEvent(android.view.MotionEvent);
@@ -28321,7 +28327,6 @@ package android.view {
    method public abstract boolean canResolveLayoutDirection();
    method public abstract boolean canResolveTextAlignment();
    method public abstract boolean canResolveTextDirection();
    method public abstract void childAccessibilityStateChanged(android.view.View);
    method public abstract void childDrawableStateChanged(android.view.View);
    method public abstract void childHasTransientStateChanged(android.view.View, boolean);
    method public abstract void clearChildFocus(android.view.View);
@@ -28340,6 +28345,7 @@ package android.view {
    method public abstract boolean isLayoutRequested();
    method public abstract boolean isTextAlignmentResolved();
    method public abstract boolean isTextDirectionResolved();
    method public abstract void notifySubtreeAccessibilityStateChanged(android.view.View, android.view.View, int);
    method public abstract void recomputeViewAttributes(android.view.View);
    method public abstract void requestChildFocus(android.view.View, android.view.View);
    method public abstract boolean requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean);
@@ -28765,7 +28771,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 int getContentChangeTypes();
    method public long getEventTime();
    method public int getEventType();
    method public int getMovementGranularity();
@@ -28777,14 +28783,16 @@ 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 setContentChangeTypes(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 int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
    field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
    field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 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
@@ -28857,6 +28865,7 @@ package android.view.accessibility {
    method public int getInputType();
    method public android.view.accessibility.AccessibilityNodeInfo getLabelFor();
    method public android.view.accessibility.AccessibilityNodeInfo getLabeledBy();
    method public int getLiveRegion();
    method public int getMovementGranularities();
    method public java.lang.CharSequence getPackageName();
    method public android.view.accessibility.AccessibilityNodeInfo getParent();
@@ -28874,11 +28883,8 @@ package android.view.accessibility {
    method public boolean isDismissable();
    method public boolean isEditable();
    method public boolean isEnabled();
    method public boolean isExpandable();
    method public boolean isExpanded();
    method public boolean isFocusable();
    method public boolean isFocused();
    method public boolean isLiveRegion();
    method public boolean isLongClickable();
    method public boolean isMultiLine();
    method public boolean isPassword();
@@ -28908,8 +28914,6 @@ package android.view.accessibility {
    method public void setDismissable(boolean);
    method public void setEditable(boolean);
    method public void setEnabled(boolean);
    method public void setExpandable(boolean);
    method public void setExpanded(boolean);
    method public void setFocusable(boolean);
    method public void setFocused(boolean);
    method public void setInputType(int);
@@ -28917,7 +28921,7 @@ package android.view.accessibility {
    method public void setLabelFor(android.view.View, int);
    method public void setLabeledBy(android.view.View);
    method public void setLabeledBy(android.view.View, int);
    method public void setLiveRegion(boolean);
    method public void setLiveRegion(int);
    method public void setLongClickable(boolean);
    method public void setMovementGranularities(int);
    method public void setMultiLine(boolean);
+164 −16
Original line number Diff line number Diff line
@@ -2133,6 +2133,50 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        | IMPORTANT_FOR_ACCESSIBILITY_YES | IMPORTANT_FOR_ACCESSIBILITY_NO)
        << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
    /**
     * Shift for the bits in {@link #mPrivateFlags2} related to the
     * "accessibilityLiveRegion" attribute.
     */
    static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT = 22;
    /**
     * Live region mode specifying that accessibility services should not
     * automatically announce changes to this view. This is the default live
     * region mode for most views.
     * <p>
     * Use with {@link #setAccessibilityLiveRegion(int)}.
     */
    public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000;
    /**
     * Live region mode specifying that accessibility services should announce
     * changes to this view.
     * <p>
     * Use with {@link #setAccessibilityLiveRegion(int)}.
     */
    public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001;
    /**
     * Live region mode specifying that accessibility services should interrupt
     * ongoing speech to immediately announce changes to this view.
     * <p>
     * Use with {@link #setAccessibilityLiveRegion(int)}.
     */
    public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002;
    /**
     * The default whether the view is important for accessibility.
     */
    static final int ACCESSIBILITY_LIVE_REGION_DEFAULT = ACCESSIBILITY_LIVE_REGION_NONE;
    /**
     * Mask for obtaining the bits which specify a view's accessibility live
     * region mode.
     */
    static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK = (ACCESSIBILITY_LIVE_REGION_NONE
            | ACCESSIBILITY_LIVE_REGION_POLITE | ACCESSIBILITY_LIVE_REGION_ASSERTIVE)
            << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
    /**
     * Flag indicating whether a view has accessibility focus.
     */
@@ -3763,6 +3807,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                    setImportantForAccessibility(a.getInt(attr,
                            IMPORTANT_FOR_ACCESSIBILITY_DEFAULT));
                    break;
                case R.styleable.View_accessibilityLiveRegion:
                    setAccessibilityLiveRegion(a.getInt(attr, ACCESSIBILITY_LIVE_REGION_DEFAULT));
                    break;
            }
        }
@@ -4710,7 +4757,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (gainFocus) {
            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
        } else {
            notifyViewAccessibilityStateChangedIfNeeded();
            notifyViewAccessibilityStateChangedIfNeeded(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
        }
        InputMethodManager imm = InputMethodManager.peekInstance();
@@ -5431,7 +5479,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
            notifySubtreeAccessibilityStateChangedIfNeeded();
        } else {
            notifyViewAccessibilityStateChangedIfNeeded();
            notifyViewAccessibilityStateChangedIfNeeded(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
        }
    }
@@ -6953,6 +7002,58 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
    }
    /**
     * Sets the live region mode for this view. This indicates to accessibility
     * services whether they should automatically notify the user about changes
     * to the view's content description or text, or to the content descriptions
     * or text of the view's children (where applicable).
     * <p>
     * For example, in a login screen with a TextView that displays an "incorrect
     * password" notification, that view should be marked as a live region with
     * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
     * <p>
     * To disable change notifications for this view, use
     * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region
     * mode for most views.
     * <p>
     * To indicate that the user should be notified of changes, use
     * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
     * <p>
     * If the view's changes should interrupt ongoing speech and notify the user
     * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}.
     *
     * @param mode The live region mode for this view, one of:
     *        <ul>
     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE}
     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE}
     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}
     *        </ul>
     * @attr ref android.R.styleable#View_accessibilityLiveRegion
     */
    public void setAccessibilityLiveRegion(int mode) {
        if (mode != getAccessibilityLiveRegion()) {
            mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
            mPrivateFlags2 |= (mode << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT)
                    & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
            notifyViewAccessibilityStateChangedIfNeeded(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
        }
    }
    /**
     * Gets the live region mode for this View.
     *
     * @return The live region mode for the view.
     *
     * @attr ref android.R.styleable#View_accessibilityLiveRegion
     *
     * @see #setAccessibilityLiveRegion(int)
     */
    public int getAccessibilityLiveRegion() {
        return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK)
                >> PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
    }
    /**
     * Sets how to determine whether this view is important for accessibility
     * which is if it fires accessibility events and if it is reported to
@@ -6975,7 +7076,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            if (oldIncludeForAccessibility != includeForAccessibility()) {
                notifySubtreeAccessibilityStateChangedIfNeeded();
            } else {
                notifyViewAccessibilityStateChangedIfNeeded();
                notifyViewAccessibilityStateChangedIfNeeded(
                        AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
            }
        }
    }
@@ -6997,7 +7099,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                return false;
            case IMPORTANT_FOR_ACCESSIBILITY_AUTO:
                return isActionableForAccessibility() || hasListenersForAccessibility()
                        || getAccessibilityNodeProvider() != null;
                        || getAccessibilityNodeProvider() != null
                        || getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE;
            default:
                throw new IllegalArgumentException("Unknow important for accessibility mode: "
                        + mode);
@@ -7094,7 +7197,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     *
     * @hide
     */
    public void notifyViewAccessibilityStateChangedIfNeeded() {
    public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) {
        if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
            return;
        }
@@ -7102,7 +7205,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            mSendViewStateChangedAccessibilityEvent =
                    new SendViewStateChangedAccessibilityEvent();
        }
        mSendViewStateChangedAccessibilityEvent.runOrPost();
        mSendViewStateChangedAccessibilityEvent.runOrPost(changeType);
    }
    /**
@@ -7124,7 +7227,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            mPrivateFlags2 |= PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
            if (mParent != null) {
                try {
                    mParent.childAccessibilityStateChanged(this);
                    mParent.notifySubtreeAccessibilityStateChanged(
                            this, this, AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
                } catch (AbstractMethodError e) {
                    Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
                            " does not fully implement ViewParent", e);
@@ -7251,7 +7355,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                        || getAccessibilitySelectionEnd() != end)
                        && (start == end)) {
                    setAccessibilitySelection(start, end);
                    notifyViewAccessibilityStateChangedIfNeeded();
                    notifyViewAccessibilityStateChangedIfNeeded(
                            AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
                    return true;
                }
            } break;
@@ -8825,11 +8930,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                if (oldIncludeForAccessibility != includeForAccessibility()) {
                    notifySubtreeAccessibilityStateChangedIfNeeded();
                } else {
                    notifyViewAccessibilityStateChangedIfNeeded();
                    notifyViewAccessibilityStateChangedIfNeeded(
                            AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
                }
            }
            if ((changed & ENABLED_MASK) != 0) {
                notifyViewAccessibilityStateChangedIfNeeded();
            } else if ((changed & ENABLED_MASK) != 0) {
                notifyViewAccessibilityStateChangedIfNeeded(
                        AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
            }
        }
    }
@@ -15430,7 +15536,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            invalidate(true);
            refreshDrawableState();
            dispatchSetSelected(selected);
            notifyViewAccessibilityStateChangedIfNeeded();
            notifyViewAccessibilityStateChangedIfNeeded(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
        }
    }
@@ -19172,21 +19279,44 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    }
    private class SendViewStateChangedAccessibilityEvent implements Runnable {
        private int mChangeTypes = 0;
        private boolean mPosted;
        private boolean mPostedWithDelay;
        private long mLastEventTimeMillis;
        @Override
        public void run() {
            mPosted = false;
            mPostedWithDelay = false;
            mLastEventTimeMillis = SystemClock.uptimeMillis();
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                AccessibilityEvent event = AccessibilityEvent.obtain();
                final AccessibilityEvent event = AccessibilityEvent.obtain();
                event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
                event.setContentChangeType(AccessibilityEvent.CONTENT_CHANGE_TYPE_NODE);
                event.setContentChangeTypes(mChangeTypes);
                sendAccessibilityEventUnchecked(event);
            }
            mChangeTypes = 0;
        }
        public void runOrPost(int changeType) {
            mChangeTypes |= changeType;
            // If this is a live region or the child of a live region, collect
            // all events from this frame and send them on the next frame.
            if (inLiveRegion()) {
                // If we're already posted with a delay, remove that.
                if (mPostedWithDelay) {
                    removeCallbacks(this);
                    mPostedWithDelay = false;
                }
                // Only post if we're not already posted.
                if (!mPosted) {
                    post(this);
                    mPosted = true;
                }
                return;
            }
        public void runOrPost() {
            if (mPosted) {
                return;
            }
@@ -19199,8 +19329,26 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            } else {
                postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
                mPosted = true;
                mPostedWithDelay = true;
            }
        }
    }
    private boolean inLiveRegion() {
        if (getAccessibilityLiveRegion() != View.ACCESSIBILITY_LIVE_REGION_NONE) {
            return true;
        }
        ViewParent parent = getParent();
        while (parent instanceof View) {
            if (((View) parent).getAccessibilityLiveRegion()
                    != View.ACCESSIBILITY_LIVE_REGION_NONE) {
                return true;
            }
            parent = parent.getParent();
        }
        return false;
    }
    /**
+8 −3
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.util.Log;
import android.util.Pools.SynchronizedPool;
import android.util.SparseArray;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -2528,10 +2529,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    }

    @Override
    public void childAccessibilityStateChanged(View root) {
        if (mParent != null) {
    public void notifySubtreeAccessibilityStateChanged(View child, View source, int changeType) {
        // If this is a live region, we should send a subtree change event
        // from this view. Otherwise, we can let it propagate up.
        if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) {
            notifyViewAccessibilityStateChangedIfNeeded(changeType);
        } else if (mParent != null) {
            try {
                mParent.childAccessibilityStateChanged(root);
                mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);
            } catch (AbstractMethodError e) {
                Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
                        " does not fully implement ViewParent", e);
+15 −6
Original line number Diff line number Diff line
@@ -309,12 +309,21 @@ public interface ViewParent {
    public ViewParent getParentForAccessibility();

    /**
     * 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 root The root of the changed subtree.
     * Notifies a view parent that the accessibility state of one of its
     * descendants has changed and that the structure of the subtree is
     * different.
     * @param child The direct child whose subtree has changed.
     * @param source The descendant view that changed.
     * @param changeType A bit mask of the types of changes that occurred. One
     *            or more of:
     *            <ul>
     *            <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION}
     *            <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_SUBTREE}
     *            <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_TEXT}
     *            <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_UNDEFINED}
     *            </ul>
     */
    public void childAccessibilityStateChanged(View root);
    public void notifySubtreeAccessibilityStateChanged(View child, View source, int changeType);

    /**
     * Tells if this view parent can resolve the layout direction.
+11 −6
Original line number Diff line number Diff line
@@ -5807,12 +5807,12 @@ public final class ViewRootImpl implements ViewParent,
     * This event is send at most once every
     * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}.
     */
    private void postSendWindowContentChangedCallback(View source) {
    private void postSendWindowContentChangedCallback(View source, int changeType) {
        if (mSendWindowContentChangedAccessibilityEvent == null) {
            mSendWindowContentChangedAccessibilityEvent =
                new SendWindowContentChangedAccessibilityEvent();
        }
        mSendWindowContentChangedAccessibilityEvent.runOrPost(source);
        mSendWindowContentChangedAccessibilityEvent.runOrPost(source, changeType);
    }

    /**
@@ -5884,8 +5884,8 @@ public final class ViewRootImpl implements ViewParent,
    }

    @Override
    public void childAccessibilityStateChanged(View child) {
        postSendWindowContentChangedCallback(child);
    public void notifySubtreeAccessibilityStateChanged(View child, View source, int changeType) {
        postSendWindowContentChangedCallback(source, changeType);
    }

    @Override
@@ -6538,6 +6538,8 @@ public final class ViewRootImpl implements ViewParent,
    }

    private class SendWindowContentChangedAccessibilityEvent implements Runnable {
        private int mChangeTypes = 0;

        public View mSource;
        public long mLastEventTimeMillis;

@@ -6548,7 +6550,7 @@ public final class ViewRootImpl implements ViewParent,
                mLastEventTimeMillis = SystemClock.uptimeMillis();
                AccessibilityEvent event = AccessibilityEvent.obtain();
                event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
                event.setContentChangeType(AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
                event.setContentChangeTypes(mChangeTypes);
                mSource.sendAccessibilityEventUnchecked(event);
            } else {
                mLastEventTimeMillis = 0;
@@ -6556,17 +6558,20 @@ public final class ViewRootImpl implements ViewParent,
            // In any case reset to initial state.
            mSource.resetSubtreeAccessibilityStateChanged();
            mSource = null;
            mChangeTypes = 0;
        }

        public void runOrPost(View source) {
        public void runOrPost(View source, int changeType) {
            if (mSource != null) {
                // If there is no common predecessor, then mSource points to
                // a removed view, hence in this case always prefer the source.
                View predecessor = getCommonPredecessor(mSource, source);
                mSource = (predecessor != null) ? predecessor : source;
                mChangeTypes |= changeType;
                return;
            }
            mSource = source;
            mChangeTypes = changeType;
            final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
            final long minEventIntevalMillis =
                    ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
Loading