1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 package com.android.systemui.power.domain.interactor 19 20 import android.os.PowerManager 21 import androidx.test.ext.junit.runners.AndroidJUnit4 22 import androidx.test.filters.SmallTest 23 import com.android.systemui.SysuiTestCase 24 import com.android.systemui.classifier.FalsingCollector 25 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository 26 import com.android.systemui.power.shared.model.WakeSleepReason 27 import com.android.systemui.power.shared.model.WakefulnessState 28 import com.android.systemui.plugins.statusbar.StatusBarStateController 29 import com.android.systemui.power.data.repository.FakePowerRepository 30 import com.android.systemui.statusbar.phone.ScreenOffAnimationController 31 import com.android.systemui.util.mockito.whenever 32 import com.google.common.truth.Truth.assertThat 33 import junit.framework.Assert.assertFalse 34 import junit.framework.Assert.assertTrue 35 import kotlin.test.assertEquals 36 import kotlinx.coroutines.Dispatchers 37 import kotlinx.coroutines.flow.launchIn 38 import kotlinx.coroutines.flow.onEach 39 import kotlinx.coroutines.runBlocking 40 import org.junit.Before 41 import org.junit.Test 42 import org.junit.runner.RunWith 43 import org.mockito.Mock 44 import org.mockito.Mockito.verify 45 import org.mockito.MockitoAnnotations 46 47 @SmallTest 48 @RunWith(AndroidJUnit4::class) 49 class PowerInteractorTest : SysuiTestCase() { 50 51 private lateinit var underTest: PowerInteractor 52 private lateinit var repository: FakePowerRepository 53 private val keyguardRepository = FakeKeyguardRepository() 54 @Mock private lateinit var falsingCollector: FalsingCollector 55 @Mock private lateinit var screenOffAnimationController: ScreenOffAnimationController 56 @Mock private lateinit var statusBarStateController: StatusBarStateController 57 58 @Before setUpnull59 fun setUp() { 60 MockitoAnnotations.initMocks(this) 61 62 repository = FakePowerRepository() 63 underTest = 64 PowerInteractor( 65 repository, 66 falsingCollector, 67 screenOffAnimationController, 68 statusBarStateController, 69 ) 70 } 71 72 @Test isInteractive_screenTurnsOffnull73 fun isInteractive_screenTurnsOff() = 74 runBlocking(IMMEDIATE) { 75 repository.setInteractive(true) 76 var value: Boolean? = null 77 val job = underTest.isInteractive.onEach { value = it }.launchIn(this) 78 79 repository.setInteractive(false) 80 81 assertThat(value).isFalse() 82 job.cancel() 83 } 84 85 @Test isInteractive_becomesInteractivenull86 fun isInteractive_becomesInteractive() = 87 runBlocking(IMMEDIATE) { 88 repository.setInteractive(false) 89 var value: Boolean? = null 90 val job = underTest.isInteractive.onEach { value = it }.launchIn(this) 91 92 repository.setInteractive(true) 93 94 assertThat(value).isTrue() 95 job.cancel() 96 } 97 98 @Test wakeUpIfDozing_notDozing_notWokennull99 fun wakeUpIfDozing_notDozing_notWoken() { 100 whenever(statusBarStateController.isDozing).thenReturn(false) 101 whenever(screenOffAnimationController.allowWakeUpIfDozing()).thenReturn(true) 102 103 underTest.wakeUpIfDozing("why", PowerManager.WAKE_REASON_TAP) 104 105 assertThat(repository.lastWakeWhy).isNull() 106 assertThat(repository.lastWakeReason).isNull() 107 } 108 109 @Test wakeUpIfDozing_notAllowed_notWokennull110 fun wakeUpIfDozing_notAllowed_notWoken() { 111 whenever(screenOffAnimationController.allowWakeUpIfDozing()).thenReturn(false) 112 whenever(statusBarStateController.isDozing).thenReturn(true) 113 114 underTest.wakeUpIfDozing("why", PowerManager.WAKE_REASON_TAP) 115 116 assertThat(repository.lastWakeWhy).isNull() 117 assertThat(repository.lastWakeReason).isNull() 118 } 119 120 @Test wakeUpIfDozing_dozingAndAllowed_wokenAndFalsingNotifiednull121 fun wakeUpIfDozing_dozingAndAllowed_wokenAndFalsingNotified() { 122 whenever(statusBarStateController.isDozing).thenReturn(true) 123 whenever(screenOffAnimationController.allowWakeUpIfDozing()).thenReturn(true) 124 125 underTest.wakeUpIfDozing("testReason", PowerManager.WAKE_REASON_GESTURE) 126 127 assertThat(repository.lastWakeWhy).isEqualTo("testReason") 128 assertThat(repository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_GESTURE) 129 verify(falsingCollector).onScreenOnFromTouch() 130 } 131 132 @Test wakeUpForFullScreenIntent_notGoingToSleepAndNotDozing_notWokennull133 fun wakeUpForFullScreenIntent_notGoingToSleepAndNotDozing_notWoken() { 134 underTest.onFinishedWakingUp() 135 whenever(statusBarStateController.isDozing).thenReturn(false) 136 137 underTest.wakeUpForFullScreenIntent() 138 139 assertThat(repository.lastWakeWhy).isNull() 140 assertThat(repository.lastWakeReason).isNull() 141 } 142 143 @Test wakeUpForFullScreenIntent_startingToSleep_wokennull144 fun wakeUpForFullScreenIntent_startingToSleep_woken() { 145 underTest.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_MIN) 146 whenever(statusBarStateController.isDozing).thenReturn(false) 147 148 underTest.wakeUpForFullScreenIntent() 149 150 assertThat(repository.lastWakeWhy).isNotNull() 151 assertThat(repository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_APPLICATION) 152 } 153 154 @Test wakeUpForFullScreenIntent_dozing_wokennull155 fun wakeUpForFullScreenIntent_dozing_woken() { 156 whenever(statusBarStateController.isDozing).thenReturn(true) 157 underTest.onFinishedWakingUp() 158 underTest.wakeUpForFullScreenIntent() 159 160 assertThat(repository.lastWakeWhy).isNotNull() 161 assertThat(repository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_APPLICATION) 162 } 163 164 @Test wakeUpIfDreaming_dreaming_wokennull165 fun wakeUpIfDreaming_dreaming_woken() { 166 // GIVEN device is dreaming 167 whenever(statusBarStateController.isDreaming).thenReturn(true) 168 169 // WHEN wakeUpIfDreaming is called 170 underTest.wakeUpIfDreaming("testReason", PowerManager.WAKE_REASON_GESTURE) 171 172 // THEN device is woken up 173 assertThat(repository.lastWakeWhy).isEqualTo("testReason") 174 assertThat(repository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_GESTURE) 175 } 176 177 @Test wakeUpIfDreaming_notDreaming_notWokennull178 fun wakeUpIfDreaming_notDreaming_notWoken() { 179 // GIVEN device is not dreaming 180 whenever(statusBarStateController.isDreaming).thenReturn(false) 181 182 // WHEN wakeUpIfDreaming is called 183 underTest.wakeUpIfDreaming("why", PowerManager.WAKE_REASON_TAP) 184 185 // THEN device is not woken 186 assertThat(repository.lastWakeWhy).isNull() 187 assertThat(repository.lastWakeReason).isNull() 188 } 189 190 @Test onStartedGoingToSleep_clearsPowerButtonLaunchGestureTriggerednull191 fun onStartedGoingToSleep_clearsPowerButtonLaunchGestureTriggered() { 192 underTest.onStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON, true) 193 194 assertTrue(repository.wakefulness.value.powerButtonLaunchGestureTriggered) 195 196 underTest.onFinishedWakingUp() 197 198 assertTrue(repository.wakefulness.value.powerButtonLaunchGestureTriggered) 199 200 underTest.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON) 201 202 assertFalse(repository.wakefulness.value.powerButtonLaunchGestureTriggered) 203 } 204 205 @Test onCameraLaunchGestureDetected_maintainsAllOtherStatenull206 fun onCameraLaunchGestureDetected_maintainsAllOtherState() { 207 underTest.onStartedWakingUp( 208 PowerManager.WAKE_REASON_POWER_BUTTON, 209 /*powerButtonLaunchGestureTriggeredDuringSleep= */ false 210 ) 211 underTest.onFinishedWakingUp() 212 underTest.onCameraLaunchGestureDetected() 213 214 assertEquals(WakefulnessState.AWAKE, repository.wakefulness.value.internalWakefulnessState) 215 assertEquals(WakeSleepReason.POWER_BUTTON, repository.wakefulness.value.lastWakeReason) 216 assertTrue(repository.wakefulness.value.powerButtonLaunchGestureTriggered) 217 } 218 219 @Test onCameraLaunchGestureDetected_stillTrue_ifGestureNotDetectedOnWakingUpnull220 fun onCameraLaunchGestureDetected_stillTrue_ifGestureNotDetectedOnWakingUp() { 221 underTest.onCameraLaunchGestureDetected() 222 // Ensure that the 'false' here does not clear the direct launch detection call earlier. 223 // This state should only be reset onStartedGoingToSleep. 224 underTest.onFinishedGoingToSleep(/*powerButtonLaunchGestureTriggeredDuringSleep= */ false) 225 underTest.onStartedWakingUp( 226 PowerManager.WAKE_REASON_POWER_BUTTON, 227 /*powerButtonLaunchGestureTriggeredDuringSleep= */ false 228 ) 229 underTest.onFinishedWakingUp() 230 231 assertEquals(WakefulnessState.AWAKE, repository.wakefulness.value.internalWakefulnessState) 232 assertEquals(WakeSleepReason.POWER_BUTTON, repository.wakefulness.value.lastWakeReason) 233 assertTrue(repository.wakefulness.value.powerButtonLaunchGestureTriggered) 234 } 235 236 @Test cameraLaunchDetectedOnGoingToSleep_stillTrue_ifGestureNotDetectedOnWakingUpnull237 fun cameraLaunchDetectedOnGoingToSleep_stillTrue_ifGestureNotDetectedOnWakingUp() { 238 underTest.onFinishedGoingToSleep(/*powerButtonLaunchGestureTriggeredDuringSleep= */ true) 239 // Ensure that the 'false' here does not clear the direct launch detection call earlier. 240 // This state should only be reset onStartedGoingToSleep. 241 underTest.onStartedWakingUp( 242 PowerManager.WAKE_REASON_POWER_BUTTON, 243 /*powerButtonLaunchGestureTriggeredDuringSleep= */ false 244 ) 245 underTest.onFinishedWakingUp() 246 247 assertEquals(WakefulnessState.AWAKE, repository.wakefulness.value.internalWakefulnessState) 248 assertEquals(WakeSleepReason.POWER_BUTTON, repository.wakefulness.value.lastWakeReason) 249 assertTrue(repository.wakefulness.value.powerButtonLaunchGestureTriggered) 250 } 251 252 companion object { 253 private val IMMEDIATE = Dispatchers.Main.immediate 254 } 255 } 256