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(  |