Merge "Block visible background user unallowed key event gestures" into main
diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java
index cb1e016..290f526 100644
--- a/core/java/android/hardware/input/KeyGestureEvent.java
+++ b/core/java/android/hardware/input/KeyGestureEvent.java
@@ -232,6 +232,26 @@
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;
}
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index 5f7ad27..db6d772 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -18,6 +18,8 @@
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;
@@ -55,7 +57,6 @@
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;
@@ -64,6 +65,8 @@
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;
@@ -159,6 +162,10 @@
/** 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);
@@ -180,6 +187,7 @@
mAppLaunchShortcutManager = new AppLaunchShortcutManager(mContext);
mInputGestureManager = new InputGestureManager(mContext);
mInputDataStore = inputDataStore;
+ mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
initBehaviors();
initKeyCombinationRules();
}
@@ -449,6 +457,9 @@
}
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) {
@@ -457,6 +468,24 @@
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
@@ -895,7 +924,7 @@
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);
}
@@ -903,7 +932,7 @@
@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
@@ -915,6 +944,11 @@
}
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)) {
@@ -927,6 +961,24 @@
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()) {
@@ -943,7 +995,7 @@
// 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();
}
@@ -951,7 +1003,7 @@
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*/);
}