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

Commit 19c468c8 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari
Browse files

(1/n) Remove usage of isKeyGestureSupported() from KeyGestureController

isKeyGestureSupported is synchronous API that makes system server
dependent on handler and can cause ANR if handlers misbehave.
It was added as a stop gap for multi-key gestures that require
some SysUI info like keyguard state, display state, etc, to decide
if the key needs to be consumed or not at the start of the gesture.

With this refactor:
- Use Display state for Default display as a replacement for
mDefaultDisplayPolicy.isAwake() which was added initially to ensure
the shortcut chords are only trigerred if default display is on.

In subsequent CLs:
- WM policy added an API to check isKeyguardLocked() and we will
use that for checking keyguard status
- Move A11yShortcutController to KGC to circumvent the need of the
isShortcutAvailable() API

Test: atest KeyGestureControllerTests
Bug: 358569822
Bug: 383602794
Flag: EXEMPT refactor
Change-Id: I000c6a46ae0e17495db5fa5f0f039940549bc243
parent 30ca69ca
Loading
Loading
Loading
Loading
+15 −23
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.display.DisplayManager;
import android.hardware.input.AidlInputGestureData;
import android.hardware.input.AidlKeyGestureEvent;
import android.hardware.input.AppLaunchData;
@@ -57,6 +58,7 @@ import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -127,6 +129,7 @@ final class KeyGestureController {
    private final SettingsObserver mSettingsObserver;
    private final AppLaunchShortcutManager mAppLaunchShortcutManager;
    private final InputGestureManager mInputGestureManager;
    private final DisplayManager mDisplayManager;
    @GuardedBy("mInputDataStore")
    private final InputDataStore mInputDataStore;
    private static final Object mUserLock = new Object();
@@ -194,6 +197,7 @@ final class KeyGestureController {
        mSettingsObserver = new SettingsObserver(mHandler);
        mAppLaunchShortcutManager = new AppLaunchShortcutManager(mContext);
        mInputGestureManager = new InputGestureManager(mContext);
        mDisplayManager = Objects.requireNonNull(mContext.getSystemService(DisplayManager.class));
        mInputDataStore = inputDataStore;
        mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
        initBehaviors();
@@ -245,12 +249,6 @@ final class KeyGestureController {
            mKeyCombinationManager.addRule(
                    new KeyCombinationManager.TwoKeysCombinationRule(KeyEvent.KEYCODE_VOLUME_DOWN,
                            KeyEvent.KEYCODE_POWER) {
                        @Override
                        public boolean preCondition() {
                            return isKeyGestureSupported(
                                    KeyGestureEvent.KEY_GESTURE_TYPE_SCREENSHOT_CHORD);
                        }

                        @Override
                        public void execute() {
                            handleMultiKeyGesture(
@@ -273,12 +271,6 @@ final class KeyGestureController {
                mKeyCombinationManager.addRule(
                        new KeyCombinationManager.TwoKeysCombinationRule(KeyEvent.KEYCODE_POWER,
                                KeyEvent.KEYCODE_STEM_PRIMARY) {
                            @Override
                            public boolean preCondition() {
                                return isKeyGestureSupported(
                                        KeyGestureEvent.KEY_GESTURE_TYPE_SCREENSHOT_CHORD);
                            }

                            @Override
                            public void execute() {
                                handleMultiKeyGesture(new int[]{KeyEvent.KEYCODE_POWER,
@@ -333,9 +325,6 @@ final class KeyGestureController {
                        KeyEvent.KEYCODE_POWER) {
                    @Override
                    public boolean preCondition() {
                        if (!isKeyGestureSupported(getGestureType())) {
                            return false;
                        }
                        switch (mPowerVolUpBehavior) {
                            case POWER_VOLUME_UP_BEHAVIOR_MUTE:
                                return mRingerToggleChord != Settings.Secure.VOLUME_HUSH_OFF;
@@ -422,12 +411,6 @@ final class KeyGestureController {
            mKeyCombinationManager.addRule(
                    new KeyCombinationManager.TwoKeysCombinationRule(KeyEvent.KEYCODE_BACK,
                            KeyEvent.KEYCODE_DPAD_CENTER) {
                        @Override
                        public boolean preCondition() {
                            return isKeyGestureSupported(
                                    KeyGestureEvent.KEY_GESTURE_TYPE_TV_TRIGGER_BUG_REPORT);
                        }

                        @Override
                        public void execute() {
                            handleMultiKeyGesture(
@@ -468,10 +451,11 @@ final class KeyGestureController {
        if (mVisibleBackgroundUsersEnabled && shouldIgnoreKeyEventForVisibleBackgroundUser(event)) {
            return false;
        }
        final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0;
        if (InputSettings.doesKeyGestureEventHandlerSupportMultiKeyGestures()
                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
            return mKeyCombinationManager.interceptKey(event, interactive);
            final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0;
            final boolean isDefaultDisplayOn = isDefaultDisplayOn();
            return mKeyCombinationManager.interceptKey(event, interactive && isDefaultDisplayOn);
        }
        return false;
    }
@@ -1038,6 +1022,14 @@ final class KeyGestureController {
        mIoHandler.obtainMessage(MSG_LOAD_CUSTOM_GESTURES, userId).sendToTarget();
    }

    private boolean isDefaultDisplayOn() {
        Display defaultDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
        if (defaultDisplay == null) {
            return false;
        }
        return Display.isOnState(defaultDisplay.getState());
    }

    @MainThread
    private void notifyKeyGestureEvent(AidlKeyGestureEvent event) {
        InputDevice device = getInputDevice(event.deviceId);
+4 −4
Original line number Diff line number Diff line
@@ -148,19 +148,19 @@ public class KeyCombinationManager {
     * to a window.
     * Return true if any active rule could be triggered by the key event, otherwise false.
     */
    public boolean interceptKey(KeyEvent event, boolean interactive) {
    public boolean interceptKey(KeyEvent event, boolean isDefaultDisplayInteractive) {
        synchronized (mLock) {
            return interceptKeyLocked(event, interactive);
            return interceptKeyLocked(event, isDefaultDisplayInteractive);
        }
    }

    private boolean interceptKeyLocked(KeyEvent event, boolean interactive) {
    private boolean interceptKeyLocked(KeyEvent event, boolean isDefaultDisplayInteractive) {
        final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
        final int keyCode = event.getKeyCode();
        final int count = mActiveRules.size();
        final long eventTime = event.getEventTime();

        if (interactive && down) {
        if (isDefaultDisplayInteractive && down) {
            if (mDownTimes.size() > 0) {
                if (count > 0
                        && eventTime > mDownTimes.valueAt(0) + COMBINE_KEY_DELAY_MILLIS) {
+7 −10
Original line number Diff line number Diff line
@@ -4300,22 +4300,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    case KeyGestureEvent.KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS:
                    case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION:
                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB:
                        return true;
                    case KeyGestureEvent.KEY_GESTURE_TYPE_SCREENSHOT_CHORD:
                    case KeyGestureEvent.KEY_GESTURE_TYPE_RINGER_TOGGLE_CHORD:
                    case KeyGestureEvent.KEY_GESTURE_TYPE_GLOBAL_ACTIONS:
                    case KeyGestureEvent.KEY_GESTURE_TYPE_TV_TRIGGER_BUG_REPORT:
                        return mDefaultDisplayPolicy.isAwake();
                    case KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT_CHORD:
                        return mDefaultDisplayPolicy.isAwake() && mAccessibilityShortcutController
                                .isAccessibilityShortcutAvailable(isKeyguardLocked());
                    case KeyGestureEvent.KEY_GESTURE_TYPE_TV_ACCESSIBILITY_SHORTCUT_CHORD:
                        return mDefaultDisplayPolicy.isAwake() && mAccessibilityShortcutController
                                .isAccessibilityShortcutAvailable(false);
                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
                        return enableTalkbackAndMagnifierKeyGestures();
                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS:
                        return enableVoiceAccessKeyGestures();
                        return true;
                    case KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT_CHORD:
                        return mAccessibilityShortcutController.isAccessibilityShortcutAvailable(
                                isKeyguardLocked());
                    case KeyGestureEvent.KEY_GESTURE_TYPE_TV_ACCESSIBILITY_SHORTCUT_CHORD:
                        return mAccessibilityShortcutController.isAccessibilityShortcutAvailable(
                                false);
                    default:
                        return false;
                }