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

Commit ca523d6e authored by Svetoslav's avatar Svetoslav
Browse files

Deliver key events to the system if no accessibility service handles them.

We have APIs that allow an accessibility service to filter key events. The
service has to declare the capability to toggle event filtering in its
manifest and then it can set a flag to toggle the feature at runtime. The
problem was that even if no accessibility service was handling key events
these events were not fed back to the input system.

This change adds a new feature flag in the accessibility input filter that
is set only if at least one service can and wants to filter key events. If
the feature flag is set then the filter will deliver events to services and
,if they are not handled, to the system. This change also cleaned the logic
for updating the input filter.

bug:8713422

Change-Id: I4bc0c1348676569d1b76e9024708d1ed43ceb26a
parent 58665709
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -56,6 +56,13 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
     */
    static final int FLAG_FEATURE_TOUCH_EXPLORATION = 0x00000002;

    /**
     * Flag for enabling the filtering key events feature.
     *
     * @see #setEnabledFeatures(int)
     */
    static final int FLAG_FEATURE_FILTER_KEY_EVENTS = 0x00000004;

    private final Runnable mProcessBatchedEventsRunnable = new Runnable() {
        @Override
        public void run() {
@@ -101,6 +108,8 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo

    private boolean mKeyEventSequenceStarted;

    private boolean mFilterKeyEvents;

    AccessibilityInputFilter(Context context, AccessibilityManagerService service) {
        super(context.getMainLooper());
        mContext = context;
@@ -198,6 +207,10 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
    }

    private void onKeyEvent(KeyEvent event, int policyFlags) {
        if (!mFilterKeyEvents) {
            super.onInputEvent(event, policyFlags);
            return;
        }
        if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) {
            mKeyEventSequenceStarted = false;
            super.onInputEvent(event, policyFlags);
@@ -314,13 +327,6 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
        }
    }

    void reset() {
        setEnabledFeatures(0);
        mKeyEventSequenceStarted = false;
        mMotionEventSequenceStarted = false;
        mHoverEventSequenceStarted = false;
    }

    private void enableFeatures() {
        mMotionEventSequenceStarted = false;
        mHoverEventSequenceStarted = false;
@@ -338,6 +344,9 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
                mEventHandler = mTouchExplorer;
            }
        }
        if ((mEnabledFeatures & FLAG_FEATURE_FILTER_KEY_EVENTS) != 0) {
            mFilterKeyEvents = true;
        }
    }

    private void disableFeatures() {
@@ -352,6 +361,10 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
            mScreenMagnifier = null;
        }
        mEventHandler = null;
        mKeyEventSequenceStarted = false;
        mMotionEventSequenceStarted = false;
        mHoverEventSequenceStarted = false;
        mFilterKeyEvents = false;
    }

    @Override
+30 −12
Original line number Diff line number Diff line
@@ -1170,9 +1170,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
        boolean setInputFilter = false;
        AccessibilityInputFilter inputFilter = null;
        synchronized (mLock) {
            // Accessibility enabled means at least one service is enabled.
            if (userState.mIsAccessibilityEnabled
                    || userState.mIsDisplayMagnificationEnabled) {
            int flags = 0;
            if (userState.mIsDisplayMagnificationEnabled) {
                flags |= AccessibilityInputFilter.FLAG_FEATURE_SCREEN_MAGNIFIER;
            }
            // Touch exploration without accessibility makes no sense.
            if (userState.mIsAccessibilityEnabled && userState.mIsTouchExplorationEnabled) {
                flags |= AccessibilityInputFilter.FLAG_FEATURE_TOUCH_EXPLORATION;
            }
            if (userState.mIsFilterKeyEventsEnabled) {
                flags |= AccessibilityInputFilter.FLAG_FEATURE_FILTER_KEY_EVENTS;
            }
            if (flags != 0) {
                if (!mHasInputFilter) {
                    mHasInputFilter = true;
                    if (mInputFilter == null) {
@@ -1182,19 +1191,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
                    inputFilter = mInputFilter;
                    setInputFilter = true;
                }
                int flags = 0;
                if (userState.mIsDisplayMagnificationEnabled) {
                    flags |= AccessibilityInputFilter.FLAG_FEATURE_SCREEN_MAGNIFIER;
                }
                // Touch exploration without accessibility makes no sense.
                if (userState.mIsAccessibilityEnabled && userState.mIsTouchExplorationEnabled) {
                    flags |= AccessibilityInputFilter.FLAG_FEATURE_TOUCH_EXPLORATION;
                }
                mInputFilter.setEnabledFeatures(flags);
            } else {
                if (mHasInputFilter) {
                    mHasInputFilter = false;
                    mInputFilter.reset();
                    mInputFilter.disableFeatures();
                    inputFilter = null;
                    setInputFilter = true;
                }
@@ -1263,6 +1264,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
    private void onUserStateChangedLocked(UserState userState) {
        updateLegacyCapabilities(userState);
        updateServicesLocked(userState);
        updateFilterKeyEventsLocked(userState);
        updateTouchExplorationLocked(userState);
        updateEnhancedWebAccessibilityLocked(userState);
        scheduleUpdateInputFilter(userState);
@@ -1291,6 +1293,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
        }
    }

    private void updateFilterKeyEventsLocked(UserState userState) {
        final int serviceCount = userState.mBoundServices.size();
        for (int i = 0; i < serviceCount; i++) {
            Service service = userState.mBoundServices.get(i);
            if (service.mRequestFilterKeyEvents
                    && (service.mAccessibilityServiceInfo.getCapabilities()
                            & AccessibilityServiceInfo
                            .CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS) != 0) {
                userState.mIsFilterKeyEventsEnabled = true;
                return;
            }
        }
        userState.mIsFilterKeyEventsEnabled = false;
    }

    private void updateServicesLocked(UserState userState) {
        if (userState.mIsAccessibilityEnabled) {
            manageServicesLocked(userState);
@@ -2899,6 +2916,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
        public boolean mIsTouchExplorationEnabled;
        public boolean mIsEnhancedWebAccessibilityEnabled;
        public boolean mIsDisplayMagnificationEnabled;
        public boolean mIsFilterKeyEventsEnabled;

        private Service mUiAutomationService;
        private IAccessibilityServiceClient mUiAutomationServiceClient;