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

Commit 0a332b80 authored by Yabin Huang's avatar Yabin Huang
Browse files

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
parent 20792fe6
Loading
Loading
Loading
Loading
+77 −4
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
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.dreams.IDreamManager;
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.FileNotFoundException;
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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    // 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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    event.recycle();
                    break;
                case MSG_HANDLE_ALL_APPS:
                    KeyEvent keyEvent = (KeyEvent) msg.obj;
                    if (isKeyEventForCurrentUser(keyEvent.getDisplayId(), keyEvent.getKeyCode(),
                            "launchAllAppsViaA11y")) {
                        launchAllAppsAction();
                    }
                    break;
                case MSG_RINGER_TOGGLE_CHORD:
                    handleRingerChordGesture();
@@ -2081,7 +2104,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            switch (mLongPressOnHomeBehavior) {
                case LONG_PRESS_HOME_ALL_APPS:
                    notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
                    if (isKeyEventForCurrentUser(event.getDisplayId(), event.getKeyCode(),
                            "launchAllAppsViaA11y")) {
                        launchAllAppsAction();
                    }
                    break;
                case LONG_PRESS_HOME_ASSIST:
                    notifyKeyGestureCompleted(event,
@@ -3724,7 +3750,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                                KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK);
                    } else if (mPendingMetaAction) {
                        if (!canceled) {
                            if (isKeyEventForCurrentUser(event.getDisplayId(), event.getKeyCode(),
                                    "launchAllAppsViaA11y")) {
                                launchAllAppsAction();
                            }
                            notifyKeyGestureCompleted(event,
                                    KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
                        }
@@ -3995,7 +4024,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    }

    private void wakeUpFromWakeKey(KeyEvent event) {
        if (!isKeyEventForCurrentUser(
                event.getDisplayId(), event.getKeyCode(), "wakeUpFromWakeKey")) {
            return;
        }
        wakeUpFromWakeKey(
                event.getEventTime(),
                event.getKeyCode(),
@@ -6429,6 +6471,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    // 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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
        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;
    }
}