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

Commit 9de69ec8 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari
Browse files

A11y Key interceptor should use IMS for key policy calls

A11y input filter consumes key before IMS processes key
combinations. So, if for certain keys, A11y input filter needs to
let the default shourtcut handling to occur, allow it to directly
call into IMS instead of WM policy which no longer handles all key
shortcuts.

Test: atest KeyInterceptorTest
Bug: 358569822
Flag: com.android.hardware.input.fix_keyboard_interceptor_policy_call
Change-Id: Ib798045616fa7cc989ba3aca4fff32222d53b4a9
parent 68cb0d5f
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -205,3 +205,13 @@ flag {
    description: "Adds support for creating a virtual keyboard API"
    bug: "416054433"
}

flag {
    name: "fix_keyboard_interceptor_policy_call"
    namespace: "input"
    description: "Fixes keyboard interceptor calls to the policy"
    bug: "358569822"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -766,7 +766,7 @@ public class AccessibilityInputFilter extends InputFilter implements EventStream
            // mKeyboardInterceptor does not forward KeyEvents to other EventStreamTransformations,
            // so it must be the last EventStreamTransformation for key events in the list.
            mKeyboardInterceptor = new KeyboardInterceptor(mAms,
                    LocalServices.getService(WindowManagerPolicy.class));
                    LocalServices.getService(InputManagerInternal.class));
            // Since the display id of KeyEvent always would be -1 and it would be dispatched to
            // the display with input focus directly, we only need one KeyboardInterceptor for
            // default display.
+11 −10
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ import android.util.Pools;
import android.util.Slog;
import android.view.KeyEvent;

import com.android.server.policy.WindowManagerPolicy;
import com.android.server.input.InputManagerInternal;

/**
 * Intercepts key events and forwards them to accessibility manager service.
@@ -35,7 +35,7 @@ public class KeyboardInterceptor extends BaseEventStreamTransformation implement
    private static final String LOG_TAG = "KeyboardInterceptor";

    private final AccessibilityManagerService mAms;
    private final WindowManagerPolicy mPolicy;
    private final InputManagerInternal mInputManagerInternal;
    private final Handler mHandler;

    private KeyEventHolder mEventQueueStart;
@@ -43,24 +43,25 @@ public class KeyboardInterceptor extends BaseEventStreamTransformation implement

    /**
     * @param service The service to notify of key events
     * @param policy The policy to check for keys that may affect a11y
     * @param inputManager The input manager to check for keys that may affect a11y
     */
    public KeyboardInterceptor(AccessibilityManagerService service, WindowManagerPolicy policy) {
    public KeyboardInterceptor(AccessibilityManagerService service,
            InputManagerInternal inputManager) {
        mAms = service;
        mPolicy = policy;
        mInputManagerInternal = inputManager;
        mHandler = new Handler(this);
    }

    /**
     * @param service The service to notify of key events
     * @param policy The policy to check for keys that may affect a11y
     * @param inputManager The input manager to check for keys that may affect a11y
     * @param handler The handler to use. Only used for testing.
     */
    public KeyboardInterceptor(AccessibilityManagerService service, WindowManagerPolicy policy,
            Handler handler) {
    public KeyboardInterceptor(AccessibilityManagerService service,
            InputManagerInternal inputManager, Handler handler) {
        // Can't combine the constructors without making at least mHandler non-final.
        mAms = service;
        mPolicy = policy;
        mInputManagerInternal = inputManager;
        mHandler = handler;
    }

@@ -148,7 +149,7 @@ public class KeyboardInterceptor extends BaseEventStreamTransformation implement
    private long getEventDelay(KeyEvent event, int policyFlags) {
        int keyCode = event.getKeyCode();
        if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) || (keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
            return mPolicy.interceptKeyBeforeDispatching(null, event, policyFlags);
            return mInputManagerInternal.interceptKeyCombinationBeforeAccessibility(event);
        }
        return 0;
    }
+13 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.SparseBooleanArray;
import android.view.InputChannel;
import android.view.KeyEvent;
import android.view.inputmethod.InputMethodSubtype;

import com.android.internal.inputmethod.InputMethodSubtypeHandle;
@@ -350,4 +351,16 @@ public abstract class InputManagerInternal {
     */
    public abstract void registerAccessibilityPointerMotionFilter(
            @Nullable AccessibilityPointerMotionFilter filter);

    /**
     * Allows A11y input filter to allow processing of key combinations (or wait for key
     * combination processing).
     *
     * @param event key to intercept
     * @return 0 if the key is not consumed and can be immediately forwarded to respective A11y
     * service, -1 if the key is consumed and should not be sent forward, or a positive value
     * indicating the number of milliseconds by which the key forwarding should be delayed before
     * trying again.
     */
    public abstract long interceptKeyCombinationBeforeAccessibility(@NonNull KeyEvent event);
}
+12 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.view.KeyEvent.KEYCODE_UNKNOWN;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;

import static com.android.hardware.input.Flags.enableCustomizableInputGestures;
import static com.android.hardware.input.Flags.fixKeyboardInterceptorPolicyCall;
import static com.android.hardware.input.Flags.fixSearchModifierFallbacks;
import static com.android.hardware.input.Flags.keyEventActivityDetection;
import static com.android.hardware.input.Flags.touchpadVisualizer;
@@ -3870,6 +3871,17 @@ public class InputManagerService extends IInputManager.Stub
                AccessibilityPointerMotionFilter filter) {
            InputManagerService.this.registerAccessibilityPointerMotionFilter(filter);
        }

        @Override
        public long interceptKeyCombinationBeforeAccessibility(@NonNull KeyEvent event) {
            if (fixKeyboardInterceptorPolicyCall()) {
                return mKeyGestureController.interceptKeyBeforeDispatching(/* focusedToken= */null,
                        event, /* policyFlags= */0);
            } else {
                return mWindowManagerCallbacks.interceptKeyBeforeDispatching(
                        /* focusedToken= */null, event, /* policyFlags= */0);
            }
        }
    }

    @Override
Loading