Loading core/java/android/service/dreams/DreamService.java +52 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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)); Loading @@ -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(); Loading core/java/android/service/dreams/flags.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -8,3 +8,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 } } services/core/java/com/android/server/wm/WindowManagerService.java +2 −1 Original line number Diff line number Diff line Loading @@ -49,6 +49,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; Loading Loading @@ -3427,7 +3428,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) { Loading services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +0 −9 Original line number Diff line number Diff line Loading @@ -244,15 +244,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( Loading Loading
core/java/android/service/dreams/DreamService.java +52 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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)); Loading @@ -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(); Loading
core/java/android/service/dreams/flags.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -8,3 +8,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 } }
services/core/java/com/android/server/wm/WindowManagerService.java +2 −1 Original line number Diff line number Diff line Loading @@ -49,6 +49,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; Loading Loading @@ -3427,7 +3428,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) { Loading
services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +0 −9 Original line number Diff line number Diff line Loading @@ -244,15 +244,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( Loading