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