Loading core/java/android/hardware/input/KeyGestureEvent.java +20 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,26 @@ public final class KeyGestureEvent { public @interface KeyGestureType { } /** * Returns whether the key gesture type passed as argument is allowed for visible background * users. * * @hide */ public static boolean isVisibleBackgrounduserAllowedGesture(int keyGestureType) { switch (keyGestureType) { case KEY_GESTURE_TYPE_SLEEP: case KEY_GESTURE_TYPE_WAKEUP: case KEY_GESTURE_TYPE_LAUNCH_ASSISTANT: case KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT: case KEY_GESTURE_TYPE_VOLUME_MUTE: case KEY_GESTURE_TYPE_RECENT_APPS: case KEY_GESTURE_TYPE_APP_SWITCH: return false; } return true; } public KeyGestureEvent(@NonNull AidlKeyGestureEvent keyGestureEvent) { this.mKeyGestureEvent = keyGestureEvent; } Loading services/core/java/com/android/server/input/KeyGestureController.java +57 −5 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.server.input; import static android.content.pm.PackageManager.FEATURE_LEANBACK; import static android.content.pm.PackageManager.FEATURE_WATCH; import static android.os.UserManager.isVisibleBackgroundUsersEnabled; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManagerPolicyConstants.FLAG_INTERACTIVE; import static com.android.hardware.input.Flags.enableNew25q2Keycodes; Loading Loading @@ -55,7 +57,6 @@ 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; Loading @@ -64,6 +65,8 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.IShortcutService; import com.android.server.LocalServices; import com.android.server.pm.UserManagerInternal; import com.android.server.policy.KeyCombinationManager; import java.util.ArrayDeque; Loading Loading @@ -159,6 +162,10 @@ final class KeyGestureController { /** Currently fully consumed key codes per device */ private final SparseArray<Set<Integer>> mConsumedKeysForDevice = new SparseArray<>(); private final UserManagerInternal mUserManagerInternal; private final boolean mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled(); KeyGestureController(Context context, Looper looper, InputDataStore inputDataStore) { mContext = context; mHandler = new Handler(looper, this::handleMessage); Loading @@ -180,6 +187,7 @@ final class KeyGestureController { mAppLaunchShortcutManager = new AppLaunchShortcutManager(mContext); mInputGestureManager = new InputGestureManager(mContext); mInputDataStore = inputDataStore; mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); initBehaviors(); initKeyCombinationRules(); } Loading Loading @@ -449,6 +457,9 @@ final class KeyGestureController { } public boolean interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { if (mVisibleBackgroundUsersEnabled && shouldIgnoreKeyEventForVisibleBackgroundUser(event)) { return false; } final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; if (InputSettings.doesKeyGestureEventHandlerSupportMultiKeyGestures() && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { Loading @@ -457,6 +468,24 @@ final class KeyGestureController { return false; } private boolean shouldIgnoreKeyEventForVisibleBackgroundUser(KeyEvent event) { final int displayAssignedUserId = mUserManagerInternal.getUserAssignedToDisplay( event.getDisplayId()); final int currentUserId; synchronized (mUserLock) { currentUserId = mCurrentUserId; } if (currentUserId != displayAssignedUserId && !KeyEvent.isVisibleBackgroundUserAllowedKey(event.getKeyCode())) { if (DEBUG) { Slog.w(TAG, "Ignored key event [" + event + "] for visible background user [" + displayAssignedUserId + "]"); } return true; } return false; } public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event, int policyFlags) { // TODO(b/358569822): Handle shortcuts trigger logic here and pass it to appropriate Loading Loading @@ -895,7 +924,7 @@ final class KeyGestureController { private void handleMultiKeyGesture(int[] keycodes, @KeyGestureEvent.KeyGestureType int gestureType, int action, int flags) { handleKeyGesture(KeyCharacterMap.VIRTUAL_KEYBOARD, keycodes, /* modifierState= */0, gestureType, action, Display.DEFAULT_DISPLAY, /* focusedToken = */null, flags, gestureType, action, DEFAULT_DISPLAY, /* focusedToken = */null, flags, /* appLaunchData = */null); } Loading @@ -903,7 +932,7 @@ final class KeyGestureController { @Nullable AppLaunchData appLaunchData) { handleKeyGesture(KeyCharacterMap.VIRTUAL_KEYBOARD, new int[0], /* modifierState= */0, keyGestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, Display.DEFAULT_DISPLAY, /* focusedToken = */null, /* flags = */0, appLaunchData); DEFAULT_DISPLAY, /* focusedToken = */null, /* flags = */0, appLaunchData); } @VisibleForTesting Loading @@ -915,6 +944,11 @@ final class KeyGestureController { } private boolean handleKeyGesture(AidlKeyGestureEvent event, @Nullable IBinder focusedToken) { if (mVisibleBackgroundUsersEnabled && event.displayId != DEFAULT_DISPLAY && shouldIgnoreGestureEventForVisibleBackgroundUser(event.gestureType, event.displayId)) { return false; } synchronized (mKeyGestureHandlerRecords) { for (KeyGestureHandlerRecord handler : mKeyGestureHandlerRecords.values()) { if (handler.handleKeyGesture(event, focusedToken)) { Loading @@ -927,6 +961,24 @@ final class KeyGestureController { return false; } private boolean shouldIgnoreGestureEventForVisibleBackgroundUser( @KeyGestureEvent.KeyGestureType int gestureType, int displayId) { final int displayAssignedUserId = mUserManagerInternal.getUserAssignedToDisplay(displayId); final int currentUserId; synchronized (mUserLock) { currentUserId = mCurrentUserId; } if (currentUserId != displayAssignedUserId && !KeyGestureEvent.isVisibleBackgrounduserAllowedGesture(gestureType)) { if (DEBUG) { Slog.w(TAG, "Ignored gesture event [" + gestureType + "] for visible background user [" + displayAssignedUserId + "]"); } return true; } return false; } private boolean isKeyGestureSupported(@KeyGestureEvent.KeyGestureType int gestureType) { synchronized (mKeyGestureHandlerRecords) { for (KeyGestureHandlerRecord handler : mKeyGestureHandlerRecords.values()) { Loading @@ -943,7 +995,7 @@ final class KeyGestureController { // TODO(b/358569822): Once we move the gesture detection logic to IMS, we ideally // should not rely on PWM to tell us about the gesture start and end. AidlKeyGestureEvent event = createKeyGestureEvent(deviceId, keycodes, modifierState, gestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, Display.DEFAULT_DISPLAY, gestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, DEFAULT_DISPLAY, /* flags = */0, /* appLaunchData = */null); mHandler.obtainMessage(MSG_NOTIFY_KEY_GESTURE_EVENT, event).sendToTarget(); } Loading @@ -951,7 +1003,7 @@ final class KeyGestureController { public void handleKeyGesture(int deviceId, int[] keycodes, int modifierState, @KeyGestureEvent.KeyGestureType int gestureType) { AidlKeyGestureEvent event = createKeyGestureEvent(deviceId, keycodes, modifierState, gestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, Display.DEFAULT_DISPLAY, gestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, DEFAULT_DISPLAY, /* flags = */0, /* appLaunchData = */null); handleKeyGesture(event, null /*focusedToken*/); } Loading Loading
core/java/android/hardware/input/KeyGestureEvent.java +20 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,26 @@ public final class KeyGestureEvent { public @interface KeyGestureType { } /** * Returns whether the key gesture type passed as argument is allowed for visible background * users. * * @hide */ public static boolean isVisibleBackgrounduserAllowedGesture(int keyGestureType) { switch (keyGestureType) { case KEY_GESTURE_TYPE_SLEEP: case KEY_GESTURE_TYPE_WAKEUP: case KEY_GESTURE_TYPE_LAUNCH_ASSISTANT: case KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT: case KEY_GESTURE_TYPE_VOLUME_MUTE: case KEY_GESTURE_TYPE_RECENT_APPS: case KEY_GESTURE_TYPE_APP_SWITCH: return false; } return true; } public KeyGestureEvent(@NonNull AidlKeyGestureEvent keyGestureEvent) { this.mKeyGestureEvent = keyGestureEvent; } Loading
services/core/java/com/android/server/input/KeyGestureController.java +57 −5 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.server.input; import static android.content.pm.PackageManager.FEATURE_LEANBACK; import static android.content.pm.PackageManager.FEATURE_WATCH; import static android.os.UserManager.isVisibleBackgroundUsersEnabled; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManagerPolicyConstants.FLAG_INTERACTIVE; import static com.android.hardware.input.Flags.enableNew25q2Keycodes; Loading Loading @@ -55,7 +57,6 @@ 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; Loading @@ -64,6 +65,8 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.IShortcutService; import com.android.server.LocalServices; import com.android.server.pm.UserManagerInternal; import com.android.server.policy.KeyCombinationManager; import java.util.ArrayDeque; Loading Loading @@ -159,6 +162,10 @@ final class KeyGestureController { /** Currently fully consumed key codes per device */ private final SparseArray<Set<Integer>> mConsumedKeysForDevice = new SparseArray<>(); private final UserManagerInternal mUserManagerInternal; private final boolean mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled(); KeyGestureController(Context context, Looper looper, InputDataStore inputDataStore) { mContext = context; mHandler = new Handler(looper, this::handleMessage); Loading @@ -180,6 +187,7 @@ final class KeyGestureController { mAppLaunchShortcutManager = new AppLaunchShortcutManager(mContext); mInputGestureManager = new InputGestureManager(mContext); mInputDataStore = inputDataStore; mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); initBehaviors(); initKeyCombinationRules(); } Loading Loading @@ -449,6 +457,9 @@ final class KeyGestureController { } public boolean interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { if (mVisibleBackgroundUsersEnabled && shouldIgnoreKeyEventForVisibleBackgroundUser(event)) { return false; } final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; if (InputSettings.doesKeyGestureEventHandlerSupportMultiKeyGestures() && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { Loading @@ -457,6 +468,24 @@ final class KeyGestureController { return false; } private boolean shouldIgnoreKeyEventForVisibleBackgroundUser(KeyEvent event) { final int displayAssignedUserId = mUserManagerInternal.getUserAssignedToDisplay( event.getDisplayId()); final int currentUserId; synchronized (mUserLock) { currentUserId = mCurrentUserId; } if (currentUserId != displayAssignedUserId && !KeyEvent.isVisibleBackgroundUserAllowedKey(event.getKeyCode())) { if (DEBUG) { Slog.w(TAG, "Ignored key event [" + event + "] for visible background user [" + displayAssignedUserId + "]"); } return true; } return false; } public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event, int policyFlags) { // TODO(b/358569822): Handle shortcuts trigger logic here and pass it to appropriate Loading Loading @@ -895,7 +924,7 @@ final class KeyGestureController { private void handleMultiKeyGesture(int[] keycodes, @KeyGestureEvent.KeyGestureType int gestureType, int action, int flags) { handleKeyGesture(KeyCharacterMap.VIRTUAL_KEYBOARD, keycodes, /* modifierState= */0, gestureType, action, Display.DEFAULT_DISPLAY, /* focusedToken = */null, flags, gestureType, action, DEFAULT_DISPLAY, /* focusedToken = */null, flags, /* appLaunchData = */null); } Loading @@ -903,7 +932,7 @@ final class KeyGestureController { @Nullable AppLaunchData appLaunchData) { handleKeyGesture(KeyCharacterMap.VIRTUAL_KEYBOARD, new int[0], /* modifierState= */0, keyGestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, Display.DEFAULT_DISPLAY, /* focusedToken = */null, /* flags = */0, appLaunchData); DEFAULT_DISPLAY, /* focusedToken = */null, /* flags = */0, appLaunchData); } @VisibleForTesting Loading @@ -915,6 +944,11 @@ final class KeyGestureController { } private boolean handleKeyGesture(AidlKeyGestureEvent event, @Nullable IBinder focusedToken) { if (mVisibleBackgroundUsersEnabled && event.displayId != DEFAULT_DISPLAY && shouldIgnoreGestureEventForVisibleBackgroundUser(event.gestureType, event.displayId)) { return false; } synchronized (mKeyGestureHandlerRecords) { for (KeyGestureHandlerRecord handler : mKeyGestureHandlerRecords.values()) { if (handler.handleKeyGesture(event, focusedToken)) { Loading @@ -927,6 +961,24 @@ final class KeyGestureController { return false; } private boolean shouldIgnoreGestureEventForVisibleBackgroundUser( @KeyGestureEvent.KeyGestureType int gestureType, int displayId) { final int displayAssignedUserId = mUserManagerInternal.getUserAssignedToDisplay(displayId); final int currentUserId; synchronized (mUserLock) { currentUserId = mCurrentUserId; } if (currentUserId != displayAssignedUserId && !KeyGestureEvent.isVisibleBackgrounduserAllowedGesture(gestureType)) { if (DEBUG) { Slog.w(TAG, "Ignored gesture event [" + gestureType + "] for visible background user [" + displayAssignedUserId + "]"); } return true; } return false; } private boolean isKeyGestureSupported(@KeyGestureEvent.KeyGestureType int gestureType) { synchronized (mKeyGestureHandlerRecords) { for (KeyGestureHandlerRecord handler : mKeyGestureHandlerRecords.values()) { Loading @@ -943,7 +995,7 @@ final class KeyGestureController { // TODO(b/358569822): Once we move the gesture detection logic to IMS, we ideally // should not rely on PWM to tell us about the gesture start and end. AidlKeyGestureEvent event = createKeyGestureEvent(deviceId, keycodes, modifierState, gestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, Display.DEFAULT_DISPLAY, gestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, DEFAULT_DISPLAY, /* flags = */0, /* appLaunchData = */null); mHandler.obtainMessage(MSG_NOTIFY_KEY_GESTURE_EVENT, event).sendToTarget(); } Loading @@ -951,7 +1003,7 @@ final class KeyGestureController { public void handleKeyGesture(int deviceId, int[] keycodes, int modifierState, @KeyGestureEvent.KeyGestureType int gestureType) { AidlKeyGestureEvent event = createKeyGestureEvent(deviceId, keycodes, modifierState, gestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, Display.DEFAULT_DISPLAY, gestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, DEFAULT_DISPLAY, /* flags = */0, /* appLaunchData = */null); handleKeyGesture(event, null /*focusedToken*/); } Loading