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

Commit a9eff611 authored by Hiroki Sato's avatar Hiroki Sato
Browse files

Populate a11y action in event throttle of ViewRootImpl

In ViewRootImpl#SendWindowContentChangedAccessibilityEvent throttles
a11y events of TYPE_WINDOW_CONTENT_CHANGED, and may merge multiple
events into one.

This changes adds merging logic of AccessibilityEvent#getAction.

Bug: 263246622
Test: CtsAccessibilityServiceTestCases
Change-Id: I3b80a26520f1ec6587deb7991b9d6287e3067131
parent 44fdc24a
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -228,6 +228,7 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.OptionalInt;
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -10833,6 +10834,12 @@ public final class ViewRootImpl implements ViewParent,

        public View mSource;
        public long mLastEventTimeMillis;
        /**
         * Keep track of action that caused the event.
         * This is empty if there's no performing actions for pending events.
         * This is zero if there're multiple events performed for pending events.
         */
        @NonNull public OptionalInt mAction = OptionalInt.empty();
        /**
         * Override for {@link AccessibilityEvent#originStackTrace} to provide the stack trace
         * of the original {@link #runOrPost} call instead of one for sending the delayed event
@@ -10856,6 +10863,7 @@ public final class ViewRootImpl implements ViewParent,
                AccessibilityEvent event = AccessibilityEvent.obtain();
                event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
                event.setContentChangeTypes(mChangeTypes);
                if (mAction.isPresent()) event.setAction(mAction.getAsInt());
                if (AccessibilityEvent.DEBUG_ORIGIN) event.originStackTrace = mOrigin;
                source.sendAccessibilityEventUnchecked(event);
            } else {
@@ -10864,6 +10872,7 @@ public final class ViewRootImpl implements ViewParent,
            // In any case reset to initial state.
            source.resetSubtreeAccessibilityStateChanged();
            mChangeTypes = 0;
            mAction = OptionalInt.empty();
            if (AccessibilityEvent.DEBUG_ORIGIN) mOrigin = null;
        }

@@ -10893,10 +10902,27 @@ public final class ViewRootImpl implements ViewParent,
                }
                mSource = (predecessor != null) ? predecessor : source;
                mChangeTypes |= changeType;

                final int performingAction = mAccessibilityManager.getPerformingAction();
                if (performingAction != 0) {
                    if (mAction.isEmpty()) {
                        mAction = OptionalInt.of(performingAction);
                    } else if (mAction.getAsInt() != performingAction) {
                        // Multiple actions are performed for pending events. We cannot decide one
                        // action here.
                        // We're doing best effort to set action value, and it's fine to set
                        // no action this case.
                        mAction = OptionalInt.of(0);
                    }
                }

                return;
            }
            mSource = source;
            mChangeTypes = changeType;
            if (mAccessibilityManager.getPerformingAction() != 0) {
                mAction = OptionalInt.of(mAccessibilityManager.getPerformingAction());
            }
            if (AccessibilityEvent.DEBUG_ORIGIN) {
                mOrigin = Thread.currentThread().getStackTrace();
            }
+9 −0
Original line number Diff line number Diff line
@@ -1274,6 +1274,15 @@ public final class AccessibilityManager {
        mPerformingAction = actionId;
    }

    /**
     * Get the id of {@link AccessibilityNodeInfo.AccessibilityAction} currently being performed.
     *
     * @hide
     */
    public int getPerformingAction() {
        return mPerformingAction;
    }

    /**
     * Registers a {@link HighTextContrastChangeListener} for changes in
     * the global high text contrast state of the system.