From 6a7cdb09e6d9a55f111657a1f36c7ac2bc5467ab Mon Sep 17 00:00:00 2001 From: Coco Duan Date: Fri, 2 Jun 2023 02:12:47 +0000 Subject: [PATCH] Allow non-doze dreams to be windowless Support wallpaper dream to be windowless and use keyguard as the view. Transitions look alike AOD. Add the logic to stop dreaming after unlocking via bouncer. Allow SystemUI dreams to be windowless. Bug: b/285059232 Test: atest KeyguardViewMediatorTest; on device Change-Id: I3348a7d9c8c437c87a8049d879209e620c80771d --- .../android/service/dreams/DreamService.java | 17 ++++++++++---- .../keyguard/KeyguardViewMediator.java | 2 +- .../keyguard/KeyguardViewMediatorTest.java | 22 +++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index cd57de5649da2..5e7f5d62e256f 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -16,6 +16,8 @@ package android.service.dreams; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + import android.annotation.IdRes; import android.annotation.LayoutRes; import android.annotation.NonNull; @@ -630,7 +632,7 @@ public class DreamService extends Service implements Window.Callback { } /** - * Marks this dream as windowless. Only available to doze dreams. + * Marks this dream as windowless. It should be called in {@link #onCreate} method. * * @hide * @@ -640,7 +642,7 @@ public class DreamService extends Service implements Window.Callback { } /** - * Returns whether this dream is windowless. Only available to doze dreams. + * Returns whether this dream is windowless. * * @hide */ @@ -1230,8 +1232,10 @@ public class DreamService extends Service implements Window.Callback { mDreamToken = dreamToken; mCanDoze = canDoze; - if (mWindowless && !mCanDoze) { - throw new IllegalStateException("Only doze dreams can be windowless"); + // This is not a security check to prevent malicious dreams but a guard rail to stop + // third-party dreams from being windowless and not working well as a result. + if (mWindowless && !mCanDoze && !isCallerSystemUi()) { + throw new IllegalStateException("Only doze or SystemUI dreams can be windowless."); } mDispatchAfterOnAttachedToWindow = () -> { @@ -1366,6 +1370,11 @@ public class DreamService extends Service implements Window.Callback { } } + private boolean isCallerSystemUi() { + return checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE) + == PERMISSION_GRANTED; + } + private int applyFlags(int oldFlags, int flags, int mask) { return (oldFlags&~mask) | (flags&mask); } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index a5d209680a797..c629ebf9496f1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -2764,7 +2764,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, // It's possible that the device was unlocked (via BOUNCER or Fingerprint) while // dreaming. It's time to wake up. - if (mDreamOverlayShowing) { + if (mDreamOverlayShowing || mUpdateMonitor.isDreaming()) { mPM.wakeUp(mSystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:UNLOCK_DREAMING"); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index 60b1567c8044d..12a9f942fcc8d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -36,6 +36,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; @@ -318,6 +319,27 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { assertFalse(mViewMediator.isAnimatingScreenOff()); } + @Test + @TestableLooper.RunWithLooper(setAsMainLooper = true) + public void wakeupFromDreamingWhenKeyguardHides() { + mViewMediator.onSystemReady(); + TestableLooper.get(this).processAllMessages(); + + // Given device is dreaming + when(mUpdateMonitor.isDreaming()).thenReturn(true); + + // When keyguard is going away + mKeyguardStateController.notifyKeyguardGoingAway(true); + + // And keyguard is disabled which will call #handleHide + mViewMediator.setKeyguardEnabled(false); + TestableLooper.get(this).processAllMessages(); + + // Then dream should wake up + verify(mPowerManager).wakeUp(anyLong(), anyInt(), + eq("com.android.systemui:UNLOCK_DREAMING")); + } + @Test @TestableLooper.RunWithLooper(setAsMainLooper = true) public void restoreBouncerWhenSimLockedAndKeyguardIsGoingAway() {