diff options
9 files changed, 111 insertions, 13 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeScreenStateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeScreenStateTest.java index bbd78b317560..4f2c1ed6c778 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeScreenStateTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeScreenStateTest.java @@ -50,6 +50,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.biometrics.UdfpsController; +import com.android.systemui.keyguard.domain.interactor.DozeInteractor; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.user.domain.interactor.SelectedUserInteractor; import com.android.systemui.util.wakelock.WakeLockFake; @@ -87,6 +88,8 @@ public class DozeScreenStateTest extends SysuiTestCase { @Mock private DozeScreenBrightness mDozeScreenBrightness; @Mock + private DozeInteractor mDozeInteractor; + @Mock private SelectedUserInteractor mSelectedUserInteractor; @Before @@ -103,7 +106,7 @@ public class DozeScreenStateTest extends SysuiTestCase { mWakeLock = new WakeLockFake(); mScreen = new DozeScreenState(mServiceFake, mHandlerFake, mDozeHost, mDozeParameters, mWakeLock, mAuthController, mUdfpsControllerProvider, mDozeLog, - mDozeScreenBrightness, mSelectedUserInteractor); + mDozeScreenBrightness, mDozeInteractor, mSelectedUserInteractor); } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/power/domain/interactor/PowerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/power/domain/interactor/PowerInteractorTest.kt index 53dec696004d..f725e06fd0e1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/power/domain/interactor/PowerInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/power/domain/interactor/PowerInteractorTest.kt @@ -18,6 +18,7 @@ package com.android.systemui.power.domain.interactor import android.os.PowerManager +import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase @@ -25,9 +26,12 @@ import com.android.systemui.camera.cameraGestureHelper import com.android.systemui.classifier.FalsingCollector import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.keyguard.domain.interactor.dozeInteractor import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.power.data.repository.FakePowerRepository +import com.android.systemui.power.data.repository.fakePowerRepository +import com.android.systemui.power.shared.model.DozeScreenStateModel import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.power.shared.model.WakefulnessState import com.android.systemui.statusbar.phone.ScreenOffAnimationController @@ -51,9 +55,9 @@ class PowerInteractorTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private val cameraGestureHelper = kosmos.cameraGestureHelper + private val repository: FakePowerRepository = kosmos.fakePowerRepository private lateinit var underTest: PowerInteractor - private lateinit var repository: FakePowerRepository private val keyguardRepository = FakeKeyguardRepository() @Mock private lateinit var falsingCollector: FalsingCollector @Mock private lateinit var screenOffAnimationController: ScreenOffAnimationController @@ -63,7 +67,6 @@ class PowerInteractorTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) - repository = FakePowerRepository() underTest = PowerInteractor( repository, @@ -208,7 +211,7 @@ class PowerInteractorTest : SysuiTestCase() { whenever(cameraGestureHelper.canCameraGestureBeLaunched(any())).thenReturn(false) underTest.onStartedWakingUp( PowerManager.WAKE_REASON_POWER_BUTTON, - /*powerButtonLaunchGestureTriggeredDuringSleep= */ false + /*powerButtonLaunchGestureTriggeredDuringSleep= */ false, ) underTest.onFinishedWakingUp() underTest.onCameraLaunchGestureDetected() @@ -224,7 +227,7 @@ class PowerInteractorTest : SysuiTestCase() { fun onCameraLaunchGestureDetected_maintainsAllOtherState() { underTest.onStartedWakingUp( PowerManager.WAKE_REASON_POWER_BUTTON, - /*powerButtonLaunchGestureTriggeredDuringSleep= */ false + /*powerButtonLaunchGestureTriggeredDuringSleep= */ false, ) underTest.onFinishedWakingUp() underTest.onCameraLaunchGestureDetected() @@ -244,7 +247,7 @@ class PowerInteractorTest : SysuiTestCase() { underTest.onFinishedGoingToSleep(/* powerButtonLaunchGestureTriggeredDuringSleep= */ false) underTest.onStartedWakingUp( PowerManager.WAKE_REASON_POWER_BUTTON, - /*powerButtonLaunchGestureTriggeredDuringSleep= */ false + /*powerButtonLaunchGestureTriggeredDuringSleep= */ false, ) underTest.onFinishedWakingUp() @@ -262,7 +265,7 @@ class PowerInteractorTest : SysuiTestCase() { // This state should only be reset onStartedGoingToSleep. underTest.onStartedWakingUp( PowerManager.WAKE_REASON_POWER_BUTTON, - /*powerButtonLaunchGestureTriggeredDuringSleep= */ false + /*powerButtonLaunchGestureTriggeredDuringSleep= */ false, ) underTest.onFinishedWakingUp() @@ -272,4 +275,26 @@ class PowerInteractorTest : SysuiTestCase() { .isEqualTo(WakeSleepReason.POWER_BUTTON) assertTrue(repository.wakefulness.value.powerButtonLaunchGestureTriggered) } + + @Test + fun dozeScreenState() = + testScope.runTest { + val dozeScreenState by collectLastValue(underTest.dozeScreenState) + assertThat(dozeScreenState).isEqualTo(DozeScreenStateModel.UNKNOWN) + + kosmos.dozeInteractor.setDozeScreenState(Display.STATE_OFF) + assertThat(dozeScreenState).isEqualTo(DozeScreenStateModel.OFF) + + kosmos.dozeInteractor.setDozeScreenState(Display.STATE_ON) + assertThat(dozeScreenState).isEqualTo(DozeScreenStateModel.ON) + + kosmos.dozeInteractor.setDozeScreenState(Display.STATE_DOZE) + assertThat(dozeScreenState).isEqualTo(DozeScreenStateModel.DOZE) + + kosmos.dozeInteractor.setDozeScreenState(Display.STATE_DOZE_SUSPEND) + assertThat(dozeScreenState).isEqualTo(DozeScreenStateModel.DOZE_SUSPEND) + + kosmos.dozeInteractor.setDozeScreenState(Display.STATE_ON_SUSPEND) + assertThat(dozeScreenState).isEqualTo(DozeScreenStateModel.ON_SUSPEND) + } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java index ba579188a8c9..673ee6dda259 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java @@ -37,6 +37,7 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.doze.dagger.DozeScope; import com.android.systemui.doze.dagger.WrappedService; import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.keyguard.domain.interactor.DozeInteractor; import com.android.systemui.user.domain.interactor.SelectedUserInteractor; import com.android.systemui.util.wakelock.SettableWakeLock; import com.android.systemui.util.wakelock.WakeLock; @@ -82,6 +83,7 @@ public class DozeScreenState implements DozeMachine.Part { private final DozeLog mDozeLog; private final DozeScreenBrightness mDozeScreenBrightness; private final SelectedUserInteractor mSelectedUserInteractor; + private final DozeInteractor mDozeInteractor; private int mPendingScreenState = Display.STATE_UNKNOWN; private SettableWakeLock mWakeLock; @@ -97,6 +99,7 @@ public class DozeScreenState implements DozeMachine.Part { Provider<UdfpsController> udfpsControllerProvider, DozeLog dozeLog, DozeScreenBrightness dozeScreenBrightness, + DozeInteractor dozeInteractor, SelectedUserInteractor selectedUserInteractor) { mDozeService = service; mHandler = handler; @@ -108,6 +111,7 @@ public class DozeScreenState implements DozeMachine.Part { mDozeLog = dozeLog; mDozeScreenBrightness = dozeScreenBrightness; mSelectedUserInteractor = selectedUserInteractor; + mDozeInteractor = dozeInteractor; updateUdfpsController(); if (mUdfpsController == null) { @@ -225,6 +229,7 @@ public class DozeScreenState implements DozeMachine.Part { if (screenState != Display.STATE_UNKNOWN) { if (DEBUG) Log.d(TAG, "setDozeScreenState(" + screenState + ")"); mDozeService.setDozeScreenState(screenState); + mDozeInteractor.setDozeScreenState(screenState); if (screenState == Display.STATE_DOZE) { // If we're entering doze, update the doze screen brightness. We might have been // clamping it to the dim brightness during the screen off animation, and we should diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DozeInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DozeInteractor.kt index d04e4f1171a0..7c8bca8d9eb1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DozeInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DozeInteractor.kt @@ -17,8 +17,11 @@ package com.android.systemui.keyguard.domain.interactor import android.graphics.Point +import android.view.Display import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.data.repository.KeyguardRepository +import com.android.systemui.power.data.repository.PowerRepository +import com.android.systemui.power.shared.model.DozeScreenStateModel import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Scenes @@ -30,6 +33,7 @@ class DozeInteractor @Inject constructor( private val keyguardRepository: KeyguardRepository, + private val powerRepository: PowerRepository, // TODO(b/336364825) Remove Lazy when SceneContainerFlag is released - // while the flag is off, creating this object too early results in a crash private val sceneInteractor: Lazy<SceneInteractor>, @@ -41,6 +45,20 @@ constructor( return sceneInteractor.get().currentScene.value == Scenes.Lockscreen } + fun setDozeScreenState(state: Int) { + powerRepository.dozeScreenState.value = + when (state) { + Display.STATE_UNKNOWN -> DozeScreenStateModel.UNKNOWN + Display.STATE_OFF -> DozeScreenStateModel.OFF + Display.STATE_ON -> DozeScreenStateModel.ON + Display.STATE_DOZE -> DozeScreenStateModel.DOZE + Display.STATE_DOZE_SUSPEND -> DozeScreenStateModel.DOZE_SUSPEND + Display.STATE_VR -> DozeScreenStateModel.VR + Display.STATE_ON_SUSPEND -> DozeScreenStateModel.ON_SUSPEND + else -> throw IllegalArgumentException("Invalid DozeScreenState: $state") + } + } + fun setAodAvailable(value: Boolean) { keyguardRepository.setAodAvailable(value) } diff --git a/packages/SystemUI/src/com/android/systemui/power/data/repository/PowerRepository.kt b/packages/SystemUI/src/com/android/systemui/power/data/repository/PowerRepository.kt index 82420875e0de..43bd6aa37b5a 100644 --- a/packages/SystemUI/src/com/android/systemui/power/data/repository/PowerRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/power/data/repository/PowerRepository.kt @@ -27,6 +27,7 @@ import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLoggin import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.power.shared.model.DozeScreenStateModel import com.android.systemui.power.shared.model.ScreenPowerState import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.power.shared.model.WakefulnessModel @@ -64,6 +65,9 @@ interface PowerRepository { */ val screenPowerState: StateFlow<ScreenPowerState> + /** More granular display states, mainly for use in dozing. */ + val dozeScreenState: MutableStateFlow<DozeScreenStateModel> + /** Wakes up the device. */ fun wakeUp(why: String, @PowerManager.WakeReason wakeReason: Int) @@ -100,6 +104,8 @@ constructor( dispatcher: BroadcastDispatcher, ) : PowerRepository { + override val dozeScreenState = MutableStateFlow(DozeScreenStateModel.UNKNOWN) + override val isInteractive: Flow<Boolean> = conflatedCallbackFlow { fun send() { trySendWithFailureLogging(manager.isInteractive, TAG) diff --git a/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt b/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt index 1cf4c23415da..8a3ee1248f57 100644 --- a/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt @@ -24,6 +24,7 @@ import com.android.systemui.classifier.FalsingCollectorActual import com.android.systemui.dagger.SysUISingleton import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.power.data.repository.PowerRepository +import com.android.systemui.power.shared.model.DozeScreenStateModel import com.android.systemui.power.shared.model.ScreenPowerState import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.power.shared.model.WakefulnessModel @@ -33,6 +34,7 @@ import javax.inject.Inject import javax.inject.Provider import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map @@ -72,7 +74,11 @@ constructor( /** Helper flow in case "isAsleep" reads better than "!isAwake". */ val isAsleep = isAwake.map { !it } - val screenPowerState = repository.screenPowerState + /** The physical on/off state of the display. */ + val screenPowerState: StateFlow<ScreenPowerState> = repository.screenPowerState + + /** The screen state, related to power and controlled by [DozeScreenState] */ + val dozeScreenState: StateFlow<DozeScreenStateModel> = repository.dozeScreenState.asStateFlow() /** * Notifies the power interactor that a user touch happened. diff --git a/packages/SystemUI/src/com/android/systemui/power/shared/model/DozeScreenStateModel.kt b/packages/SystemUI/src/com/android/systemui/power/shared/model/DozeScreenStateModel.kt new file mode 100644 index 000000000000..510b90c071d8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/power/shared/model/DozeScreenStateModel.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 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.power.shared.model + +/** Model device doze screen states. */ +enum class DozeScreenStateModel { + /** Doze components are set up. Followed by transition to DOZE or DOZE_AOD. */ + UNKNOWN, + /** Regular doze. Device is asleep and listening for pulse triggers. */ + OFF, + /** Deep doze. Device is asleep and is not listening for pulse triggers. */ + ON, + /** Always-on doze. Device is asleep, showing UI and listening for pulse triggers. */ + DOZE, + /** Pulse has been requested. Device is awake and preparing UI */ + DOZE_SUSPEND, + /** Pulse is showing. Device is awake and showing UI. */ + VR, + /** Pulse is showing with bright wallpaper. Device is awake and showing UI. */ + ON_SUSPEND, +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DozeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DozeInteractorKosmos.kt index 3304d44db9b1..10ca84f579d1 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DozeInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DozeInteractorKosmos.kt @@ -19,11 +19,9 @@ package com.android.systemui.keyguard.domain.interactor import com.android.systemui.keyguard.data.repository.keyguardRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.power.data.repository.powerRepository import com.android.systemui.scene.domain.interactor.sceneInteractor val Kosmos.dozeInteractor: DozeInteractor by Fixture { - DozeInteractor( - keyguardRepository, - { sceneInteractor }, - ) + DozeInteractor(keyguardRepository, powerRepository, { sceneInteractor }) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/power/data/repository/FakePowerRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/power/data/repository/FakePowerRepository.kt index ace650020a9d..9dfbcfbbc407 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/power/data/repository/FakePowerRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/power/data/repository/FakePowerRepository.kt @@ -19,6 +19,7 @@ package com.android.systemui.power.data.repository import android.os.PowerManager import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.power.shared.model.DozeScreenStateModel import com.android.systemui.power.shared.model.ScreenPowerState import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.power.shared.model.WakefulnessModel @@ -41,6 +42,8 @@ class FakePowerRepository @Inject constructor() : PowerRepository { private val _screenPowerState = MutableStateFlow(ScreenPowerState.SCREEN_OFF) override val screenPowerState = _screenPowerState.asStateFlow() + override val dozeScreenState = MutableStateFlow(DozeScreenStateModel.UNKNOWN) + var lastWakeWhy: String? = null var lastWakeReason: Int? = null @@ -63,7 +66,7 @@ class FakePowerRepository @Inject constructor() : PowerRepository { rawState: WakefulnessState, lastWakeReason: WakeSleepReason, lastSleepReason: WakeSleepReason, - powerButtonLaunchGestureTriggered: Boolean + powerButtonLaunchGestureTriggered: Boolean, ) { _wakefulness.value = WakefulnessModel( |