1 /* 2 * Copyright (C) 2017 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 package com.android.systemui.doze; 18 19 import static com.android.systemui.doze.DozeMachine.State.DOZE; 20 import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD; 21 import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_DOCKED; 22 import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED; 23 import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSING; 24 import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE; 25 import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING; 26 import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE; 27 import static com.android.systemui.doze.DozeMachine.State.FINISH; 28 import static com.android.systemui.doze.DozeMachine.State.INITIALIZED; 29 import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED; 30 import static com.android.systemui.utils.os.FakeHandler.Mode.QUEUEING; 31 32 import static org.hamcrest.Matchers.is; 33 import static org.junit.Assert.assertEquals; 34 import static org.junit.Assert.assertFalse; 35 import static org.junit.Assert.assertThat; 36 import static org.junit.Assert.assertTrue; 37 import static org.mockito.ArgumentMatchers.eq; 38 import static org.mockito.Matchers.anyObject; 39 import static org.mockito.Mockito.anyInt; 40 import static org.mockito.Mockito.doAnswer; 41 import static org.mockito.Mockito.verify; 42 import static org.mockito.Mockito.when; 43 44 import android.os.Looper; 45 import android.view.Display; 46 47 import androidx.test.filters.SmallTest; 48 import androidx.test.runner.AndroidJUnit4; 49 50 import com.android.systemui.SysuiTestCase; 51 import com.android.systemui.biometrics.AuthController; 52 import com.android.systemui.biometrics.UdfpsController; 53 import com.android.systemui.statusbar.phone.DozeParameters; 54 import com.android.systemui.user.domain.interactor.SelectedUserInteractor; 55 import com.android.systemui.util.wakelock.WakeLockFake; 56 import com.android.systemui.utils.os.FakeHandler; 57 58 import org.junit.Before; 59 import org.junit.Test; 60 import org.junit.runner.RunWith; 61 import org.mockito.ArgumentCaptor; 62 import org.mockito.Mock; 63 import org.mockito.MockitoAnnotations; 64 65 import javax.inject.Provider; 66 67 @RunWith(AndroidJUnit4.class) 68 @SmallTest 69 public class DozeScreenStateTest extends SysuiTestCase { 70 71 private DozeServiceFake mServiceFake; 72 private FakeHandler mHandlerFake; 73 @Mock 74 private DozeHost mDozeHost; 75 @Mock 76 private DozeParameters mDozeParameters; 77 private WakeLockFake mWakeLock; 78 private DozeScreenState mScreen; 79 @Mock 80 private Provider<UdfpsController> mUdfpsControllerProvider; 81 @Mock 82 private AuthController mAuthController; 83 @Mock 84 private UdfpsController mUdfpsController; 85 @Mock 86 private DozeLog mDozeLog; 87 @Mock 88 private DozeScreenBrightness mDozeScreenBrightness; 89 @Mock 90 private SelectedUserInteractor mSelectedUserInteractor; 91 92 @Before setUp()93 public void setUp() throws Exception { 94 MockitoAnnotations.initMocks(this); 95 when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(true); 96 when(mDozeParameters.getAlwaysOn()).thenReturn(true); 97 when(mUdfpsControllerProvider.get()).thenReturn(mUdfpsController); 98 when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(true); 99 when(mUdfpsController.isFingerDown()).thenReturn(false); 100 101 mServiceFake = new DozeServiceFake(); 102 mHandlerFake = new FakeHandler(Looper.getMainLooper()); 103 mWakeLock = new WakeLockFake(); 104 mScreen = new DozeScreenState(mServiceFake, mHandlerFake, mDozeHost, mDozeParameters, 105 mWakeLock, mAuthController, mUdfpsControllerProvider, mDozeLog, 106 mDozeScreenBrightness, mSelectedUserInteractor); 107 } 108 109 @Test testScreen_offInDoze()110 public void testScreen_offInDoze() { 111 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 112 mScreen.transitionTo(INITIALIZED, DOZE); 113 114 assertEquals(Display.STATE_OFF, mServiceFake.screenState); 115 } 116 117 @Test testScreen_onInAod()118 public void testScreen_onInAod() { 119 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 120 mScreen.transitionTo(INITIALIZED, DOZE_AOD); 121 122 assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState); 123 } 124 125 @Test testScreen_onInPulse()126 public void testScreen_onInPulse() { 127 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 128 mScreen.transitionTo(INITIALIZED, DOZE); 129 130 mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE); 131 mScreen.transitionTo(DOZE_REQUEST_PULSE, DOZE_PULSING); 132 133 assertEquals(Display.STATE_ON, mServiceFake.screenState); 134 } 135 136 @Test testScreen_offInRequestPulseWithoutAoD()137 public void testScreen_offInRequestPulseWithoutAoD() { 138 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 139 mScreen.transitionTo(INITIALIZED, DOZE); 140 141 mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE); 142 143 assertEquals(Display.STATE_OFF, mServiceFake.screenState); 144 } 145 146 @Test testScreen_offInRequestPulseWithAoD()147 public void testScreen_offInRequestPulseWithAoD() { 148 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 149 mScreen.transitionTo(INITIALIZED, DOZE_AOD); 150 151 mScreen.transitionTo(DOZE, DOZE_REQUEST_PULSE); 152 153 assertEquals(Display.STATE_OFF, mServiceFake.screenState); 154 } 155 156 @Test testScreen_onInDockedAod()157 public void testScreen_onInDockedAod() { 158 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 159 mScreen.transitionTo(INITIALIZED, DOZE_AOD_DOCKED); 160 161 assertEquals(Display.STATE_ON, mServiceFake.screenState); 162 } 163 164 @Test test_initialScreenStatePostedToHandler()165 public void test_initialScreenStatePostedToHandler() { 166 mHandlerFake.setMode(QUEUEING); 167 168 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 169 mServiceFake.screenStateSet = false; 170 mScreen.transitionTo(INITIALIZED, DOZE_AOD); 171 172 assertFalse(mServiceFake.screenStateSet); 173 174 mHandlerFake.dispatchQueuedMessages(); 175 176 assertTrue(mServiceFake.screenStateSet); 177 assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState); 178 } 179 180 @Test test_noScreenStateSetAfterFinish()181 public void test_noScreenStateSetAfterFinish() { 182 mHandlerFake.setMode(QUEUEING); 183 184 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 185 mScreen.transitionTo(INITIALIZED, DOZE_AOD); 186 mScreen.transitionTo(DOZE_AOD, FINISH); 187 188 mServiceFake.screenStateSet = false; 189 190 mHandlerFake.dispatchQueuedMessages(); 191 192 assertFalse(mServiceFake.screenStateSet); 193 } 194 195 @Test test_holdsWakeLockWhenGoingToLowPowerDelayed()196 public void test_holdsWakeLockWhenGoingToLowPowerDelayed() { 197 // Transition to low power mode will be delayed to let 198 // animations play at 60 fps. 199 when(mDozeParameters.shouldDelayDisplayDozeTransition()).thenReturn(true); 200 mHandlerFake.setMode(QUEUEING); 201 202 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 203 mHandlerFake.dispatchQueuedMessages(); 204 205 mScreen.transitionTo(INITIALIZED, DOZE_AOD); 206 assertThat(mWakeLock.isHeld(), is(true)); 207 208 mHandlerFake.dispatchQueuedMessages(); 209 assertThat(mWakeLock.isHeld(), is(false)); 210 } 211 212 @Test test_releasesWakeLock_abortingLowPowerDelayed()213 public void test_releasesWakeLock_abortingLowPowerDelayed() { 214 // Transition to low power mode will be delayed to let 215 // animations play at 60 fps. 216 when(mDozeParameters.shouldDelayDisplayDozeTransition()).thenReturn(true); 217 mHandlerFake.setMode(QUEUEING); 218 219 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 220 mHandlerFake.dispatchQueuedMessages(); 221 222 mScreen.transitionTo(INITIALIZED, DOZE_AOD); 223 assertThat(mWakeLock.isHeld(), is(true)); 224 mScreen.transitionTo(DOZE_AOD, FINISH); 225 226 assertThat(mWakeLock.isHeld(), is(false)); 227 } 228 229 @Test test_animatesPausing()230 public void test_animatesPausing() { 231 ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class); 232 doAnswer(invocation -> null).when(mDozeHost).prepareForGentleSleep(captor.capture()); 233 mHandlerFake.setMode(QUEUEING); 234 235 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 236 mScreen.transitionTo(INITIALIZED, DOZE_AOD_PAUSING); 237 mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED); 238 239 mHandlerFake.dispatchQueuedMessages(); 240 verify(mDozeHost).prepareForGentleSleep(eq(captor.getValue())); 241 captor.getValue().run(); 242 assertEquals(Display.STATE_OFF, mServiceFake.screenState); 243 } 244 245 @Test test_animatesOff()246 public void test_animatesOff() { 247 ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class); 248 doAnswer(invocation -> null).when(mDozeHost).prepareForGentleSleep(captor.capture()); 249 mHandlerFake.setMode(QUEUEING); 250 251 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 252 mScreen.transitionTo(INITIALIZED, DOZE_AOD); 253 mScreen.transitionTo(DOZE_AOD, DOZE); 254 255 mHandlerFake.dispatchQueuedMessages(); 256 verify(mDozeHost).prepareForGentleSleep(eq(captor.getValue())); 257 captor.getValue().run(); 258 assertEquals(Display.STATE_OFF, mServiceFake.screenState); 259 } 260 261 @Test testDelayEnterDozeScreenState_whenUdfpsFingerDown()262 public void testDelayEnterDozeScreenState_whenUdfpsFingerDown() { 263 // GIVEN AOD is initialized 264 when(mDozeParameters.shouldControlScreenOff()).thenReturn(true); 265 mHandlerFake.setMode(QUEUEING); 266 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 267 mHandlerFake.dispatchQueuedMessages(); 268 269 mScreen.transitionTo(INITIALIZED, DOZE_AOD); 270 271 // WHEN udfps is activated (fingerDown) 272 when(mUdfpsController.isFingerDown()).thenReturn(true); 273 mHandlerFake.dispatchQueuedMessages(); 274 275 // THEN the display screen state doesn't immediately change 276 assertEquals(Display.STATE_ON, mServiceFake.screenState); 277 278 // WHEN udfpsController finger is no longer down and the queued messages are run 279 when(mUdfpsController.isFingerDown()).thenReturn(false); 280 mHandlerFake.dispatchQueuedMessages(); 281 282 // THEN the display screen state will change 283 assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState); 284 } 285 286 @Test testDelayExitPulsingScreenState_whenUdfpsFingerDown()287 public void testDelayExitPulsingScreenState_whenUdfpsFingerDown() { 288 // GIVEN we're pulsing 289 when(mDozeParameters.shouldControlScreenOff()).thenReturn(true); 290 mHandlerFake.setMode(QUEUEING); 291 mScreen.transitionTo(UNINITIALIZED, INITIALIZED); 292 mScreen.transitionTo(INITIALIZED, DOZE_AOD); 293 mScreen.transitionTo(DOZE_AOD, DOZE_REQUEST_PULSE); 294 mScreen.transitionTo(DOZE_REQUEST_PULSE, DOZE_PULSING); 295 mScreen.transitionTo(DOZE_PULSING, DOZE_PULSE_DONE); 296 mHandlerFake.dispatchQueuedMessages(); 297 298 // WHEN udfps is activated while are transitioning back to DOZE_AOD 299 mScreen.transitionTo(DOZE_PULSE_DONE, DOZE_AOD); 300 when(mUdfpsController.isFingerDown()).thenReturn(true); 301 mHandlerFake.dispatchQueuedMessages(); 302 303 // THEN the display screen state doesn't immediately change 304 assertEquals(Display.STATE_ON, mServiceFake.screenState); 305 306 // WHEN udfpsController finger is no longer down and the queued messages are run 307 when(mUdfpsController.isFingerDown()).thenReturn(false); 308 mHandlerFake.dispatchQueuedMessages(); 309 310 // THEN the display screen state will change 311 assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState); 312 } 313 314 @Test authCallbackRemovedOnDestroy()315 public void authCallbackRemovedOnDestroy() { 316 mScreen.destroy(); 317 318 verify(mAuthController).removeCallback(anyObject()); 319 } 320 }