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

Commit ac50ba45 authored by Bryce Lee's avatar Bryce Lee
Browse files

Handle confirm keys in Dreams.

This change adds handling confirm keys in Dreams to wake up and unlock
the device if the keyguard is insecure or bring up the bouncer prompt
on when the keyguard is secure. This change also removes logic to wakeup
from WindowManager when dismissing the keyguard while dreaming. This
logic is redundant as SystemUI already requests the device to wakeup
when unlocking while dreaming.

Fixes: 326975875
Flag: ACONFIG android.service.dreams.dream_handles_confirm_keys
Test: atest DreamServiceTest#testKeyHandling_InsecureKeyguardDismissesOnConfirmKey
Test: atest DreamServiceTest#testKeyHandling_SecureKeyguardConfirmKeyPromptsBouncer
Test: atest DreamServiceTest#testKeyHandling_InteractiveDreamConsumesConfirmNoWakeup
Test: atest DreamServiceTest#testKeyHandling_InteractiveDreamDoesNotConsumeConfirmPromptsBouncer
Change-Id: Ie080f694f87ae4bf26ebec09b333834da18e6d0c
parent aef03313
Loading
Loading
Loading
Loading
+52 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.service.dreams;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.service.dreams.Flags.dreamHandlesConfirmKeys;

import android.annotation.FlaggedApi;
import android.annotation.IdRes;
@@ -29,6 +30,7 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.TestApi;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.KeyguardManager;
import android.app.Service;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
@@ -280,6 +282,8 @@ public class DreamService extends Service implements Window.Callback {

    private IDreamOverlayCallback mOverlayCallback;

    private Integer mTrackingConfirmKey = null;


    public DreamService() {
        mDreamManager = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
@@ -296,7 +300,54 @@ public class DreamService extends Service implements Window.Callback {
    /** {@inheritDoc} */
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        // TODO: create more flexible version of mInteractive that allows use of KEYCODE_BACK
        if (dreamHandlesConfirmKeys()) {
            // In the case of an interactive dream that consumes the event, do not process further.
            if (mInteractive && mWindow.superDispatchKeyEvent(event)) {
                return true;
            }

            // If the key is a confirm key and on up, either unlock (no auth) or show bouncer.
            if (KeyEvent.isConfirmKey(event.getKeyCode())) {
                switch (event.getAction()) {
                    case KeyEvent.ACTION_DOWN -> {
                        if (mTrackingConfirmKey != null) {
                            return true;
                        }

                        mTrackingConfirmKey = event.getKeyCode();
                    }
                    case KeyEvent.ACTION_UP -> {
                        if (mTrackingConfirmKey != event.getKeyCode()) {
                            return true;
                        }

                        mTrackingConfirmKey = null;

                        final KeyguardManager keyguardManager =
                                getSystemService(KeyguardManager.class);

                        // Simply wake up in the case the device is not locked.
                        if (!keyguardManager.isKeyguardLocked()) {
                            wakeUp();
                            return true;
                        }

                        keyguardManager.requestDismissKeyguard(getActivity(),
                                new KeyguardManager.KeyguardDismissCallback() {
                                    @Override
                                    public void onDismissError() {
                                        Log.e(TAG, "Could not dismiss keyguard on confirm key");
                                    }
                                });
                    }
                }

                // All key events for matching key codes should be consumed to prevent other actions
                // from triggering.
                return true;
            }
        }

        if (!mInteractive) {
            if (mDebug) Slog.v(mTag, "Waking up on keyEvent");
            wakeUp();
+11 −0
Original line number Diff line number Diff line
@@ -7,3 +7,14 @@ flag {
      "relying on the dream's window"
  bug: "291990564"
}

flag {
  name: "dream_handles_confirm_keys"
  namespace: "dreams"
  description: "This flag enables dreams processing confirm keys to show the bouncer or dismiss "
       "the keyguard"
  bug: "326975875"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}
+2 −1
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
import static android.provider.Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH;
import static android.service.dreams.Flags.dreamHandlesConfirmKeys;
import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -3420,7 +3421,7 @@ public class WindowManagerService extends IWindowManager.Stub
        if (!checkCallingPermission(permission.CONTROL_KEYGUARD, "dismissKeyguard")) {
            throw new SecurityException("Requires CONTROL_KEYGUARD permission");
        }
        if (mAtmService.mKeyguardController.isShowingDream()) {
        if (!dreamHandlesConfirmKeys() && mAtmService.mKeyguardController.isShowingDream()) {
            mAtmService.mTaskSupervisor.wakeUp("leaveDream");
        }
        synchronized (mGlobalLock) {
+0 −9
Original line number Diff line number Diff line
@@ -242,15 +242,6 @@ public class WindowManagerServiceTests extends WindowTestsBase {
        verify(mWm.mAtmService).setFocusedTask(tappedTask.mTaskId, null);
    }

    @Test
    public void testDismissKeyguardCanWakeUp() {
        doReturn(true).when(mWm).checkCallingPermission(anyString(), anyString());
        doReturn(true).when(mWm.mAtmService.mKeyguardController).isShowingDream();
        doNothing().when(mWm.mAtmService.mTaskSupervisor).wakeUp(anyString());
        mWm.dismissKeyguard(null, "test-dismiss-keyguard");
        verify(mWm.mAtmService.mTaskSupervisor).wakeUp(anyString());
    }

    @Test
    public void testTrackOverlayWindow() {
        final WindowProcessController wpc = mSystemServicesTestRule.addProcess(