summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Lucas Silva <lusilva@google.com> 2025-02-19 10:15:44 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-02-19 10:15:44 -0800
commit1cdb234491b8b5776a51007db426da59cda9c9ae (patch)
tree4d81b309e97efbd5e5b688495097e23b6abf297a
parent1088bc431e850290c7a45ad1f678f5c556901b75 (diff)
parent2c5aff23e492e31c0365f9a589dfcd48f1e15430 (diff)
Merge "Reland "Support transitioning from doze to dream from button press."" into main
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModelTest.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt2
-rw-r--r--services/core/java/com/android/server/dreams/DreamManagerService.java3
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java44
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java18
8 files changed, 125 insertions, 9 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModelTest.kt
new file mode 100644
index 000000000000..052dfd52887f
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModelTest.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.kosmos.collectValues
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DozingToDreamingTransitionViewModelTest : SysuiTestCase() {
+ val kosmos = testKosmos()
+
+ val underTest by lazy { kosmos.dozingToDreamingTransitionViewModel }
+
+ @Test
+ fun notificationShadeAlpha() =
+ kosmos.runTest {
+ val values by collectValues(underTest.notificationAlpha)
+ assertThat(values).isEmpty()
+
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.DREAMING,
+ testScope,
+ )
+
+ assertThat(values).isNotEmpty()
+ values.forEach { assertThat(it).isEqualTo(0) }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index 6f5f662d6fa3..0700ec639153 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -159,6 +159,7 @@ constructor(
val isKeyguardOccludedLegacy = keyguardInteractor.isKeyguardOccluded.value
val primaryBouncerShowing = keyguardInteractor.primaryBouncerShowing.value
val isKeyguardGoingAway = keyguardInteractor.isKeyguardGoingAway.value
+ val canStartDreaming = dreamManager.canStartDreaming(false)
if (!deviceEntryInteractor.isLockscreenEnabled()) {
if (!SceneContainerFlag.isEnabled) {
@@ -191,6 +192,13 @@ constructor(
if (!SceneContainerFlag.isEnabled) {
transitionToGlanceableHub()
}
+ } else if (canStartDreaming) {
+ // If we're waking up to dream, transition directly to dreaming without
+ // showing the lockscreen.
+ startTransitionTo(
+ KeyguardState.DREAMING,
+ ownerReason = "moving from doze to dream",
+ )
} else {
startTransitionTo(KeyguardState.LOCKSCREEN)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModel.kt
index e6a85c6860c5..9018c58a7e36 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToDreamingTransitionViewModel.kt
@@ -39,4 +39,6 @@ constructor(animationFlow: KeyguardTransitionAnimationFlow) {
)
val lockscreenAlpha: Flow<Float> = transitionAnimation.immediatelyTransitionTo(0f)
+ // Notifications should not be shown while transitioning to dream.
+ val notificationAlpha = transitionAnimation.immediatelyTransitionTo(0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index c0ebe7dd7023..5c81c8e22bfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -49,6 +49,7 @@ import com.android.systemui.keyguard.ui.viewmodel.AodToGoneTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToOccludedTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToPrimaryBouncerTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.DozingToDreamingTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DozingToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DozingToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DozingToOccludedTransitionViewModel
@@ -139,6 +140,7 @@ constructor(
private val aodToOccludedTransitionViewModel: AodToOccludedTransitionViewModel,
private val aodToGlanceableHubTransitionViewModel: AodToGlanceableHubTransitionViewModel,
private val aodToPrimaryBouncerTransitionViewModel: AodToPrimaryBouncerTransitionViewModel,
+ private val dozingToDreamingTransitionViewModel: DozingToDreamingTransitionViewModel,
dozingToGlanceableHubTransitionViewModel: DozingToGlanceableHubTransitionViewModel,
private val dozingToLockscreenTransitionViewModel: DozingToLockscreenTransitionViewModel,
private val dozingToOccludedTransitionViewModel: DozingToOccludedTransitionViewModel,
@@ -577,6 +579,7 @@ constructor(
aodToOccludedTransitionViewModel.lockscreenAlpha(viewState),
aodToGlanceableHubTransitionViewModel.lockscreenAlpha(viewState),
aodToPrimaryBouncerTransitionViewModel.notificationAlpha,
+ dozingToDreamingTransitionViewModel.notificationAlpha,
dozingToLockscreenTransitionViewModel.lockscreenAlpha,
dozingToOccludedTransitionViewModel.lockscreenAlpha(viewState),
dozingToPrimaryBouncerTransitionViewModel.notificationAlpha,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
index 17ef208fe12e..51bb94fd2ab9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
@@ -30,6 +30,7 @@ import com.android.systemui.keyguard.ui.viewmodel.aodToGoneTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.aodToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.aodToOccludedTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.aodToPrimaryBouncerTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.dozingToDreamingTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.dozingToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.dozingToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.dozingToOccludedTransitionViewModel
@@ -83,6 +84,7 @@ val Kosmos.sharedNotificationContainerViewModel by Fixture {
aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
aodToOccludedTransitionViewModel = aodToOccludedTransitionViewModel,
aodToPrimaryBouncerTransitionViewModel = aodToPrimaryBouncerTransitionViewModel,
+ dozingToDreamingTransitionViewModel = dozingToDreamingTransitionViewModel,
dozingToGlanceableHubTransitionViewModel = dozingToGlanceableHubTransitionViewModel,
dozingToLockscreenTransitionViewModel = dozingToLockscreenTransitionViewModel,
dozingToOccludedTransitionViewModel = dozingToOccludedTransitionViewModel,
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 7e8bb28b6a37..2af74f620c95 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -569,7 +569,8 @@ public final class DreamManagerService extends SystemService {
}
private void requestDreamInternal() {
- if (isDreamingInternal() && !dreamIsFrontmost() && mController.bringDreamToFront()) {
+ if (isDreamingInternal() && !dreamIsFrontmost() && mController.bringDreamToFront()
+ && !isDozingInternal()) {
return;
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 76c5240ab623..95ac908efcf0 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1163,6 +1163,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ private boolean shouldShowHub() {
+ final boolean hubEnabled = Settings.Secure.getIntForUser(
+ mContext.getContentResolver(), Settings.Secure.GLANCEABLE_HUB_ENABLED,
+ 1, mCurrentUserId) == 1;
+
+ return mUserManagerInternal != null && mUserManagerInternal.isUserUnlocked(mCurrentUserId)
+ && hubEnabled && mDreamManagerInternal.dreamConditionActive();
+ }
+
@VisibleForTesting
void powerPress(long eventTime, int count, int displayId) {
// SideFPS still needs to know about suppressed power buttons, in case it needs to block
@@ -1251,7 +1260,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mContext.getContentResolver(), Settings.Secure.GLANCEABLE_HUB_ENABLED,
1, mCurrentUserId) == 1;
- if (mDreamManagerInternal.isDreaming() || isKeyguardShowing()) {
+ if ((mDreamManagerInternal != null && mDreamManagerInternal.isDreaming())
+ || isKeyguardShowing()) {
// If the device is already dreaming or on keyguard, go to sleep.
sleepDefaultDisplayFromPowerButton(eventTime, 0);
break;
@@ -1261,9 +1271,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// show hub.
boolean keyguardAvailable = !mLockPatternUtils.isLockScreenDisabled(
mCurrentUserId);
- if (mUserManagerInternal.isUserUnlocked(mCurrentUserId) && hubEnabled
- && keyguardAvailable && mDreamManagerInternal.dreamConditionActive()) {
- // If the hub can be launched, send a message to keyguard.
+ if (shouldShowHub() && keyguardAvailable) {
+ // If the hub can be launched, send a message to keyguard. We do not know if
+ // the hub is already running or not, keyguard handles turning screen off if
+ // it is.
Bundle options = new Bundle();
options.putBoolean(EXTRA_TRIGGER_HUB, true);
lockNow(options);
@@ -1324,14 +1335,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
* @param isScreenOn Whether the screen is currently on.
* @param noDreamAction The action to perform if dreaming is not possible.
*/
- private void attemptToDreamFromShortPowerButtonPress(
+ private boolean attemptToDreamFromShortPowerButtonPress(
boolean isScreenOn, Runnable noDreamAction) {
if (mShortPressOnPowerBehavior != SHORT_PRESS_POWER_DREAM_OR_SLEEP
&& mShortPressOnPowerBehavior != SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP) {
// If the power button behavior isn't one that should be able to trigger the dream, give
// up.
noDreamAction.run();
- return;
+ return false;
}
final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
@@ -1339,7 +1350,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Slog.d(TAG, "Can't start dreaming when attempting to dream from short power"
+ " press (isScreenOn=" + isScreenOn + ")");
noDreamAction.run();
- return;
+ return false;
}
synchronized (mLock) {
@@ -1350,6 +1361,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
dreamManagerInternal.requestDream();
+
+ return true;
}
/**
@@ -2327,6 +2340,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowWakeUpPolicy getWindowWakeUpPolicy() {
return new WindowWakeUpPolicy(mContext);
}
+
+ DreamManagerInternal getDreamManagerInternal() {
+ return LocalServices.getService(DreamManagerInternal.class);
+ }
}
/** {@inheritDoc} */
@@ -2345,7 +2362,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
mInputManager = mContext.getSystemService(InputManager.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
- mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
+ mDreamManagerInternal = injector.getDreamManagerInternal();
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
mSensorPrivacyManager = mContext.getSystemService(SensorPrivacyManager.class);
@@ -6398,6 +6415,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
event.getDisplayId(), event.getKeyCode(), "wakeUpFromWakeKey")) {
return;
}
+
+ if (!shouldShowHub()
+ && mShortPressOnPowerBehavior == SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP
+ && event.getKeyCode() == KEYCODE_POWER
+ && attemptToDreamFromShortPowerButtonPress(false, () -> {})) {
+ // In the case that we should wake to dream and successfully initiate dreaming, do not
+ // continue waking up. Doing so will exit the dream state and cause UI to react
+ // accordingly.
+ return;
+ }
+
wakeUpFromWakeKey(
event.getEventTime(),
event.getKeyCode(),
diff --git a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
index 32a3b7f2c9cc..22c86eb3a9b8 100644
--- a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
@@ -272,6 +272,19 @@ public class PhoneWindowManagerTests {
}
@Test
+ public void powerPress_withoutDreamManagerInternal_doesNotCrash() {
+ when(mDisplayPolicy.isAwake()).thenReturn(true);
+ mDreamManagerInternal = null;
+ initPhoneWindowManager();
+
+ // Power button pressed.
+ int eventTime = 0;
+ mPhoneWindowManager.powerPress(eventTime, 1, 0);
+
+ // verify no crash
+ }
+
+ @Test
public void powerPress_hubOrDreamOrSleep_hubAvailableLocks() {
when(mDisplayPolicy.isAwake()).thenReturn(true);
mContext.getTestablePermissions().setPermission(android.Manifest.permission.DEVICE_POWER,
@@ -352,5 +365,10 @@ public class PhoneWindowManagerTests {
WindowWakeUpPolicy getWindowWakeUpPolicy() {
return mock(WindowWakeUpPolicy.class);
}
+
+ @Override
+ DreamManagerInternal getDreamManagerInternal() {
+ return mDreamManagerInternal;
+ }
}
}