Modify PhoneWindowManager to avoid interfering with current user's experience
- There are several code locations that assume the operations are for
the current user.
- However, these operations could be executed in reponse to requests
for visible background users in MUMD environment.
- We should handle them to avoid interfering with current user's
experience.
Bug: 358267540
Test: atest WmTests:PhoneWindowManagerTests
Flag: EXEMPT bugfix
(cherry picked from https://partner-android-review.googlesource.com/q/commit:bd7104e0e1abe78201a4adcf6ce3bbc1abc0b93f)
Change-Id: I21cff2407937d9de87108529a74d0e9e3f4ca4e8
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index ef37464..9ed3c96 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -37,6 +37,7 @@
import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.O;
import static android.os.IInputConstants.INVALID_INPUT_DEVICE_ID;
+import static android.os.UserManager.isVisibleBackgroundUsersEnabled;
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -183,6 +184,7 @@
import android.service.vr.IPersistentVrStateCallbacks;
import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
+import android.util.ArraySet;
import android.util.Log;
import android.util.MathUtils;
import android.util.MutableBoolean;
@@ -255,6 +257,7 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -717,6 +720,22 @@
// Timeout for showing the keyguard after the screen is on, in case no "ready" is received.
private int mKeyguardDrawnTimeout = 1000;
+ private final boolean mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled();
+
+ // Key codes that should be ignored for visible background users in MUMD environment.
+ private static final Set<Integer> KEY_CODES_IGNORED_FOR_VISIBLE_BACKGROUND_USERS =
+ new ArraySet<>(Arrays.asList(
+ KeyEvent.KEYCODE_POWER,
+ KeyEvent.KEYCODE_SLEEP,
+ KeyEvent.KEYCODE_WAKEUP,
+ KeyEvent.KEYCODE_CALL,
+ KeyEvent.KEYCODE_ENDCALL,
+ KeyEvent.KEYCODE_ASSIST,
+ KeyEvent.KEYCODE_VOICE_ASSIST,
+ KeyEvent.KEYCODE_MUTE,
+ KeyEvent.KEYCODE_VOLUME_MUTE
+ ));
+
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
@@ -810,7 +829,11 @@
event.recycle();
break;
case MSG_HANDLE_ALL_APPS:
- launchAllAppsAction();
+ KeyEvent keyEvent = (KeyEvent) msg.obj;
+ if (isKeyEventForCurrentUser(keyEvent.getDisplayId(), keyEvent.getKeyCode(),
+ "launchAllAppsViaA11y")) {
+ launchAllAppsAction();
+ }
break;
case MSG_RINGER_TOGGLE_CHORD:
handleRingerChordGesture();
@@ -2081,7 +2104,10 @@
switch (mLongPressOnHomeBehavior) {
case LONG_PRESS_HOME_ALL_APPS:
notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
- launchAllAppsAction();
+ if (isKeyEventForCurrentUser(event.getDisplayId(), event.getKeyCode(),
+ "launchAllAppsViaA11y")) {
+ launchAllAppsAction();
+ }
break;
case LONG_PRESS_HOME_ASSIST:
notifyKeyGestureCompleted(event,
@@ -3724,7 +3750,10 @@
KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK);
} else if (mPendingMetaAction) {
if (!canceled) {
- launchAllAppsAction();
+ if (isKeyEventForCurrentUser(event.getDisplayId(), event.getKeyCode(),
+ "launchAllAppsViaA11y")) {
+ launchAllAppsAction();
+ }
notifyKeyGestureCompleted(event,
KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
}
@@ -3995,7 +4024,8 @@
return true;
case KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS:
case KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS:
- if (complete) {
+ if (complete && isKeyEventForCurrentUser(event.getDisplayId(),
+ event.getKeycodes()[0], "launchAllAppsViaA11y")) {
launchAllAppsAction();
}
return true;
@@ -4843,6 +4873,14 @@
boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
|| event.isWakeKey();
+ // There are key events that perform the operation as the current user,
+ // and these should be ignored for visible background users.
+ if (mVisibleBackgroundUsersEnabled
+ && KEY_CODES_IGNORED_FOR_VISIBLE_BACKGROUND_USERS.contains(keyCode)
+ && !isKeyEventForCurrentUser(event.getDisplayId(), keyCode, null)) {
+ return 0;
+ }
+
if (!mSystemBooted) {
// If we have not yet booted, don't let key events do anything.
// Exception: Wake and power key events are forwarded to PowerManager to allow it to
@@ -5850,6 +5888,10 @@
}
private void wakeUpFromWakeKey(KeyEvent event) {
+ if (!isKeyEventForCurrentUser(
+ event.getDisplayId(), event.getKeyCode(), "wakeUpFromWakeKey")) {
+ return;
+ }
wakeUpFromWakeKey(
event.getEventTime(),
event.getKeyCode(),
@@ -6429,6 +6471,12 @@
// TODO (b/113840485): Move this logic to DisplayPolicy when lockscreen supports multi-display.
@Override
public void setAllowLockscreenWhenOn(int displayId, boolean allow) {
+ // We should ignore this operation for visible background users
+ // until lockscreen supports multi-display.
+ if (mVisibleBackgroundUsersEnabled
+ && mUserManagerInternal.getUserAssignedToDisplay(displayId) != mCurrentUserId) {
+ return;
+ }
if (allow) {
mAllowLockscreenWhenOnDisplays.add(displayId);
} else {
@@ -7237,4 +7285,29 @@
}
return DEFAULT_DISPLAY;
}
+
+ /**
+ * This method is intended to prevent key events for visible background users
+ * from interfering with the current user's experience in MUMD environment.
+ *
+ * @param displayId the displayId of the key event.
+ * @param keyCode the key code of the event.
+ *
+ * @return false if the key event is for a visible background user.
+ */
+ private boolean isKeyEventForCurrentUser(int displayId, int keyCode, @Nullable String purpose) {
+ if (!mVisibleBackgroundUsersEnabled) {
+ return true;
+ }
+ int assignedUser = mUserManagerInternal.getUserAssignedToDisplay(displayId);
+ if (assignedUser == mCurrentUserId) {
+ return true;
+ }
+ if (DEBUG_INPUT) {
+ Slog.w(TAG, "Cannot handle " + KeyEvent.keyCodeToString(keyCode)
+ + (purpose != null ? " to " + purpose : "")
+ + " for visible background user(u" + assignedUser + ")");
+ }
+ return false;
+ }
}