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

Commit e4d31b3c authored by Eugene Susla's avatar Eugene Susla
Browse files

Move A11y events throttling away from View(RootImpl)

..and also extract common code into a common superclass

This also preserves the order of the throttled events
(TYPE_VIEW_SCROLLED & TYPE_WINDOW_CONTENT_CHANGED) with regards to the rest
of events by flushing any pending throttled events immediately if another
event is requested to be sent.

Test: ensure no new a11y CTS failures
Change-Id: I948a16716521974393aaa1cf822d0a0324e9ce3a
parent dd312aba
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.accessibilityservice.IAccessibilityServiceConnection;
import android.annotation.NonNull;
import android.annotation.TestApi;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
@@ -47,10 +46,14 @@ import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;

import com.android.internal.util.CollectionUtils;

import libcore.io.IoUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeoutException;

@@ -580,6 +583,8 @@ public final class UiAutomation {
        // Execute the command *without* the lock being held.
        command.run();

        List<AccessibilityEvent> eventsReceived = Collections.emptyList();

        // Acquire the lock and wait for the event.
        try {
            // Wait for the event.
@@ -600,14 +605,14 @@ public final class UiAutomation {
                    if (filter.accept(event)) {
                        return event;
                    }
                    event.recycle();
                    eventsReceived = CollectionUtils.add(eventsReceived, event);
                }
                // Check if timed out and if not wait.
                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                final long remainingTimeMillis = timeoutMillis - elapsedTimeMillis;
                if (remainingTimeMillis <= 0) {
                    throw new TimeoutException("Expected event not received within: "
                            + timeoutMillis + " ms.");
                            + timeoutMillis + " ms, among " + eventsReceived);
                }
                synchronized (mLock) {
                    if (mEventQueue.isEmpty()) {
@@ -620,6 +625,10 @@ public final class UiAutomation {
                }
            }
        } finally {
            for (int i = 0; i < CollectionUtils.size(eventsReceived); i++) {
                AccessibilityEvent event = eventsReceived.get(i);
                event.recycle();
            }
            synchronized (mLock) {
                mWaitingForEventDelivery = false;
                mEventQueue.clear();
+60 −124
Original line number Diff line number Diff line
@@ -4407,7 +4407,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    private CheckForLongPress mPendingCheckForLongPress;
    private CheckForTap mPendingCheckForTap = null;
    private PerformClick mPerformClick;
    private SendViewScrolledAccessibilityEvent mSendViewScrolledAccessibilityEvent;
    private UnsetPressedState mUnsetPressedState;
@@ -7156,7 +7155,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (gainFocus) {
            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
        } else {
            notifyViewAccessibilityStateChangedIfNeeded(
            notifyAccessibilityStateChanged(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
        }
@@ -8826,9 +8825,9 @@ 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();
            notifyAccessibilitySubtreeChanged();
        } else {
            notifyViewAccessibilityStateChangedIfNeeded(
            notifyAccessibilityStateChanged(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
        }
    }
@@ -8861,7 +8860,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            return;
        }
        mAccessibilityTraversalBeforeId = beforeId;
        notifyViewAccessibilityStateChangedIfNeeded(
        notifyAccessibilityStateChanged(
                AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
    }
@@ -8905,7 +8904,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            return;
        }
        mAccessibilityTraversalAfterId = afterId;
        notifyViewAccessibilityStateChangedIfNeeded(
        notifyAccessibilityStateChanged(
                AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
    }
@@ -8948,7 +8947,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                && mID == View.NO_ID) {
            mID = generateViewId();
        }
        notifyViewAccessibilityStateChangedIfNeeded(
        notifyAccessibilityStateChanged(
                AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
    }
@@ -10442,8 +10441,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (pflags3 != mPrivateFlags3) {
            mPrivateFlags3 = pflags3;
            notifyViewAccessibilityStateChangedIfNeeded(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
            notifyAccessibilityStateChanged(AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
        }
    }
@@ -11261,7 +11259,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
            mPrivateFlags2 |= (mode << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT)
                    & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
            notifyViewAccessibilityStateChangedIfNeeded(
            notifyAccessibilityStateChanged(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
        }
    }
@@ -11319,9 +11317,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            mPrivateFlags2 |= (mode << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT)
                    & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
            if (!maySkipNotify || oldIncludeForAccessibility != includeForAccessibility()) {
                notifySubtreeAccessibilityStateChangedIfNeeded();
                notifyAccessibilitySubtreeChanged();
            } else {
                notifyViewAccessibilityStateChangedIfNeeded(
                notifyAccessibilityStateChanged(
                        AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
            }
        }
@@ -11496,25 +11494,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     *
     * @hide
     */
    public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) {
        if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
            return;
        }
        // If this is a live region, we should send a subtree change event
        // from this view immediately. Otherwise, we can let it propagate up.
        if (getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE) {
            final AccessibilityEvent event = AccessibilityEvent.obtain();
            event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
            event.setContentChangeTypes(changeType);
            sendAccessibilityEventUnchecked(event);
        } else if (mParent != null) {
            try {
                mParent.notifySubtreeAccessibilityStateChanged(this, this, changeType);
            } catch (AbstractMethodError e) {
                Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
                        " does not fully implement ViewParent", e);
            }
        }
    public void notifyAccessibilityStateChanged(int changeType) {
        notifyAccessibilityStateChanged(this, changeType);
    }
    /**
@@ -11528,20 +11509,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     *
     * @hide
     */
    public void notifySubtreeAccessibilityStateChangedIfNeeded() {
    public void notifyAccessibilitySubtreeChanged() {
        if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
            mPrivateFlags2 |= PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
            notifyAccessibilityStateChanged(AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
        }
    }
    void notifyAccessibilityStateChanged(View source, int changeType) {
        if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
            return;
        }
        if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
            mPrivateFlags2 |= PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
        if (mParent != null) {
            try {
                    mParent.notifySubtreeAccessibilityStateChanged(
                            this, this, AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
                mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);
            } catch (AbstractMethodError e) {
                    Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
                            " does not fully implement ViewParent", e);
                }
                Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName()
                        + " does not fully implement ViewParent", e);
            }
        }
    }
@@ -11563,8 +11547,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    /**
     * Reset the flag indicating the accessibility state of the subtree rooted
     * at this view changed.
     *
     * @hide
     */
    void resetSubtreeAccessibilityStateChanged() {
    public void resetSubtreeAccessibilityStateChanged() {
        mPrivateFlags2 &= ~PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
    }
@@ -11725,7 +11711,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                        || getAccessibilitySelectionEnd() != end)
                        && (start == end)) {
                    setAccessibilitySelection(start, end);
                    notifyViewAccessibilityStateChangedIfNeeded(
                    notifyAccessibilityStateChanged(
                            AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
                    return true;
                }
@@ -13713,7 +13699,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                        ((!(mParent instanceof ViewGroup)) || ((ViewGroup) mParent).isShown())) {
                    dispatchVisibilityAggregated(newVisibility == VISIBLE);
                }
                notifySubtreeAccessibilityStateChangedIfNeeded();
                notifyAccessibilitySubtreeChanged();
            }
        }
@@ -13759,13 +13745,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                    || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0
                    || (changed & CONTEXT_CLICKABLE) != 0) {
                if (oldIncludeForAccessibility != includeForAccessibility()) {
                    notifySubtreeAccessibilityStateChangedIfNeeded();
                    notifyAccessibilitySubtreeChanged();
                } else {
                    notifyViewAccessibilityStateChangedIfNeeded(
                    notifyAccessibilityStateChanged(
                            AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
                }
            } else if ((changed & ENABLED_MASK) != 0) {
                notifyViewAccessibilityStateChangedIfNeeded(
                notifyAccessibilityStateChanged(
                        AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
            }
        }
@@ -13800,10 +13786,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * @param oldt Previous vertical scroll origin.
     */
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        notifySubtreeAccessibilityStateChangedIfNeeded();
        notifyAccessibilitySubtreeChanged();
        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
            postSendViewScrolledAccessibilityEventCallback(l - oldl, t - oldt);
        ViewRootImpl root = getViewRootImpl();
        if (root != null) {
            root.getAccessibilityState()
                    .getSendViewScrolledAccessibilityEvent()
                    .post(this, /* dx */ l - oldl, /* dy */ t - oldt);
        }
        mBackgroundSizeChanged = true;
@@ -14199,7 +14188,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            invalidateViewProperty(false, true);
            invalidateParentIfNeededAndWasQuickRejected();
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }
    }
@@ -14243,7 +14232,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            invalidateViewProperty(false, true);
            invalidateParentIfNeededAndWasQuickRejected();
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }
    }
@@ -14287,7 +14276,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            invalidateViewProperty(false, true);
            invalidateParentIfNeededAndWasQuickRejected();
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }
    }
@@ -14324,7 +14313,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            invalidateViewProperty(false, true);
            invalidateParentIfNeededAndWasQuickRejected();
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }
    }
@@ -14361,7 +14350,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            invalidateViewProperty(false, true);
            invalidateParentIfNeededAndWasQuickRejected();
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }
    }
@@ -14564,7 +14553,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (mTransformationInfo.mAlpha != alpha) {
            // Report visibility changes, which can affect children, to accessibility
            if ((alpha == 0) ^ (mTransformationInfo.mAlpha == 0)) {
                notifySubtreeAccessibilityStateChangedIfNeeded();
                notifyAccessibilitySubtreeChanged();
            }
            mTransformationInfo.mAlpha = alpha;
            if (onSetAlpha((int) (alpha * 255))) {
@@ -15066,7 +15055,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            invalidateViewProperty(false, true);
            invalidateParentIfNeededAndWasQuickRejected();
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }
    }
@@ -15100,7 +15089,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            invalidateViewProperty(false, true);
            invalidateParentIfNeededAndWasQuickRejected();
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }
    }
@@ -15270,7 +15259,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    public void invalidateOutline() {
        rebuildOutline();
        notifySubtreeAccessibilityStateChangedIfNeeded();
        notifyAccessibilitySubtreeChanged();
        invalidateViewProperty(false, false);
    }
@@ -15465,7 +15454,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                }
                invalidateParentIfNeeded();
            }
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }
    }
@@ -15513,7 +15502,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                }
                invalidateParentIfNeeded();
            }
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }
    }
@@ -16390,18 +16379,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    /**
     * Post a callback to send a {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} event.
     * This event is sent at most once every
     * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}.
     */
    private void postSendViewScrolledAccessibilityEventCallback(int dx, int dy) {
        if (mSendViewScrolledAccessibilityEvent == null) {
            mSendViewScrolledAccessibilityEvent = new SendViewScrolledAccessibilityEvent();
        }
        mSendViewScrolledAccessibilityEvent.post(dx, dy);
    }
    /**
     * Called by a parent to request that a child update its values for mScrollX
     * and mScrollY if necessary. This will typically be done if the child is
@@ -17657,7 +17634,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        removeUnsetPressCallback();
        removeLongPressCallback();
        removePerformClickCallback();
        cancel(mSendViewScrolledAccessibilityEvent);
        if (mAttachInfo != null
                && mAttachInfo.mViewRootImpl.mAccessibilityState != null
                && mAttachInfo.mViewRootImpl.mAccessibilityState.isScrollEventSenderInitialized()) {
            mAttachInfo.mViewRootImpl.mAccessibilityState
                    .getSendViewScrolledAccessibilityEvent()
                    .cancelIfPendingFor(this);
        }
        stopNestedScroll();
        // Anything that started animating right before detach should already
@@ -20256,7 +20239,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                mForegroundInfo.mBoundsChanged = true;
            }
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }
        return changed;
    }
@@ -21683,7 +21666,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            if (selected) {
                sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
            } else {
                notifyViewAccessibilityStateChangedIfNeeded(
                notifyAccessibilityStateChanged(
                        AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
            }
        }
@@ -26239,53 +26222,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    /**
     * Resuable callback for sending
     * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
     */
    private class SendViewScrolledAccessibilityEvent implements Runnable {
        public volatile boolean mIsPending;
        public int mDeltaX;
        public int mDeltaY;
        public void post(int dx, int dy) {
            mDeltaX += dx;
            mDeltaY += dy;
            if (!mIsPending) {
                mIsPending = true;
                postDelayed(this, ViewConfiguration.getSendRecurringAccessibilityEventsInterval());
            }
        }
        @Override
        public void run() {
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                AccessibilityEvent event = AccessibilityEvent.obtain(
                        AccessibilityEvent.TYPE_VIEW_SCROLLED);
                event.setScrollDeltaX(mDeltaX);
                event.setScrollDeltaY(mDeltaY);
                sendAccessibilityEventUnchecked(event);
            }
            reset();
        }
        private void reset() {
            mIsPending = false;
            mDeltaX = 0;
            mDeltaY = 0;
        }
    }
    /**
     * Remove the pending callback for sending a
     * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} accessibility event.
     */
    private void cancel(@Nullable SendViewScrolledAccessibilityEvent callback) {
        if (callback == null || !callback.mIsPending) return;
        removeCallbacks(callback);
        callback.reset();
    }
    /**
     * <p>
     * This class represents a delegate that can be registered in a {@link View}
+16 −26
Original line number Diff line number Diff line
@@ -3637,44 +3637,34 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        return ViewGroup.class.getName();
    }

    @Override
    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(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
        } else if (mParent != null) {
            try {
                mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);
            } catch (AbstractMethodError e) {
                Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
                        " does not fully implement ViewParent", e);
            }
        }
    }

    /** @hide */
    @Override
    public void notifySubtreeAccessibilityStateChangedIfNeeded() {
    public void notifyAccessibilitySubtreeChanged() {
        if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
            return;
        }
        // If something important for a11y is happening in this subtree, make sure it's dispatched
        // from a view that is important for a11y so it doesn't get lost.
        if ((getImportantForAccessibility() != IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS)
                && !isImportantForAccessibility() && (getChildCount() > 0)) {
        if (getImportantForAccessibility() != IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
                && !isImportantForAccessibility()
                && getChildCount() > 0) {
            ViewParent a11yParent = getParentForAccessibility();
            if (a11yParent instanceof View) {
                ((View) a11yParent).notifySubtreeAccessibilityStateChangedIfNeeded();
                ((View) a11yParent).notifyAccessibilitySubtreeChanged();
                return;
            }
        }
        super.notifySubtreeAccessibilityStateChangedIfNeeded();
        super.notifyAccessibilitySubtreeChanged();
    }

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

    /** @hide */
    @Override
    public void resetSubtreeAccessibilityStateChanged() {
        super.resetSubtreeAccessibilityStateChanged();
        View[] children = mChildren;
        final int childCount = mChildrenCount;
@@ -5086,7 +5076,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        }

        if (child.getVisibility() != View.GONE) {
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }

        if (mTransientIndices != null) {
@@ -5356,7 +5346,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        dispatchViewRemoved(view);

        if (view.getVisibility() != View.GONE) {
            notifySubtreeAccessibilityStateChangedIfNeeded();
            notifyAccessibilitySubtreeChanged();
        }

        int transientCount = mTransientIndices == null ? 0 : mTransientIndices.size();
@@ -6075,7 +6065,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        if (invalidate) {
            invalidateViewProperty(false, false);
        }
        notifySubtreeAccessibilityStateChangedIfNeeded();
        notifyAccessibilitySubtreeChanged();
    }

    @Override
+33 −125

File changed.

Preview size limit exceeded, changes collapsed.

+61 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view.accessibility;

import android.annotation.NonNull;
import android.annotation.Nullable;

/**
 * Accessibility-related state of a {@link android.view.ViewRootImpl}
 *
 * @hide
 */
public class AccessibilityViewHierarchyState {
    private @Nullable SendViewScrolledAccessibilityEvent mSendViewScrolledAccessibilityEvent;
    private @Nullable SendWindowContentChangedAccessibilityEvent
            mSendWindowContentChangedAccessibilityEvent;

    /**
     * @return a {@link SendViewScrolledAccessibilityEvent}, creating one if needed
     */
    public @NonNull SendViewScrolledAccessibilityEvent getSendViewScrolledAccessibilityEvent() {
        if (mSendViewScrolledAccessibilityEvent == null) {
            mSendViewScrolledAccessibilityEvent = new SendViewScrolledAccessibilityEvent();
        }
        return mSendViewScrolledAccessibilityEvent;
    }

    public boolean isScrollEventSenderInitialized() {
        return mSendViewScrolledAccessibilityEvent != null;
    }

    /**
     * @return a {@link SendWindowContentChangedAccessibilityEvent}, creating one if needed
     */
    public @NonNull SendWindowContentChangedAccessibilityEvent
            getSendWindowContentChangedAccessibilityEvent() {
        if (mSendWindowContentChangedAccessibilityEvent == null) {
            mSendWindowContentChangedAccessibilityEvent =
                    new SendWindowContentChangedAccessibilityEvent();
        }
        return mSendWindowContentChangedAccessibilityEvent;
    }

    public boolean isWindowContentChangedEventSenderInitialized() {
        return mSendWindowContentChangedAccessibilityEvent != null;
    }
}
Loading