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

Commit 10e340cb authored by Phil Weaver's avatar Phil Weaver
Browse files

Throttle app a11y events in one place.

We were throttling content changed a11y events both in View
and in ViewRootImpl. This change eliminates the throttling
in View, so events can be consolidated to reduce the number
of IPCs.

Change-Id: I1e1ecf1afc399e4103da82e6ed1779abfd3ec955
parent 863b7fea
Loading
Loading
Loading
Loading
+14 −79
Original line number Diff line number Diff line
@@ -2032,8 +2032,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
    SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
    /**
     * The view's tag.
     * {@hide}
@@ -10901,11 +10899,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
            return;
        }
        if (mSendViewStateChangedAccessibilityEvent == null) {
            mSendViewStateChangedAccessibilityEvent =
                    new SendViewStateChangedAccessibilityEvent();
        // 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);
            }
        }
        mSendViewStateChangedAccessibilityEvent.runOrPost(changeType);
    }
    /**
@@ -25720,79 +25728,6 @@ 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()) {
                final AccessibilityEvent event = AccessibilityEvent.obtain();
                event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
                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;
            }
            if (mPosted) {
                return;
            }
            final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
            final long minEventIntevalMillis =
                    ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
            if (timeSinceLastMillis >= minEventIntevalMillis) {
                removeCallbacks(this);
                run();
            } else {
                postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
                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;
    }
    /**
     * Dump all private flags in readable format, useful for documentation and
     * sanity checking.
+2 −1
Original line number Diff line number Diff line
@@ -3535,7 +3535,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        // 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);
            notifyViewAccessibilityStateChangedIfNeeded(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
        } else if (mParent != null) {
            try {
                mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);