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 package com.android.server.display; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertTrue; 22 import static org.mockito.Mockito.times; 23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.verifyZeroInteractions; 25 26 import android.hardware.display.DisplayManagerInternal; 27 28 import androidx.test.filters.SmallTest; 29 import androidx.test.runner.AndroidJUnit4; 30 31 import org.junit.Before; 32 import org.junit.Test; 33 import org.junit.runner.RunWith; 34 import org.mockito.Mock; 35 import org.mockito.MockitoAnnotations; 36 37 import java.util.concurrent.Callable; 38 39 @SmallTest 40 @RunWith(AndroidJUnit4.class) 41 public final class WakelockControllerTest { 42 private static final int DISPLAY_ID = 1; 43 44 @Mock 45 private DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks; 46 47 private WakelockController mWakelockController; 48 49 @Before before()50 public void before() { 51 MockitoAnnotations.initMocks(this); 52 mWakelockController = new WakelockController(DISPLAY_ID, mDisplayPowerCallbacks); 53 } 54 55 @Test validateSuspendBlockerIdsAreExpected()56 public void validateSuspendBlockerIdsAreExpected() { 57 assertEquals(mWakelockController.getSuspendBlockerUnfinishedBusinessId(), 58 "[" + DISPLAY_ID + "]unfinished business"); 59 assertEquals(mWakelockController.getSuspendBlockerOnStateChangedId(), 60 "[" + DISPLAY_ID + "]on state changed"); 61 assertEquals(mWakelockController.getSuspendBlockerProxPositiveId(), 62 "[" + DISPLAY_ID + "]prox positive"); 63 assertEquals(mWakelockController.getSuspendBlockerProxNegativeId(), 64 "[" + DISPLAY_ID + "]prox negative"); 65 assertEquals(mWakelockController.getSuspendBlockerProxDebounceId(), 66 "[" + DISPLAY_ID + "]prox debounce"); 67 } 68 69 @Test acquireStateChangedSuspendBlockerAcquiresIfNotAcquired()70 public void acquireStateChangedSuspendBlockerAcquiresIfNotAcquired() throws Exception { 71 // Acquire 72 verifyWakelockAcquisitionAndReaquisition(WakelockController.WAKE_LOCK_STATE_CHANGED, 73 () -> mWakelockController.isOnStateChangedPending()); 74 75 // Verify acquire happened only once 76 verify(mDisplayPowerCallbacks, times(1)) 77 .acquireSuspendBlocker(mWakelockController.getSuspendBlockerOnStateChangedId()); 78 79 // Release 80 verifyWakelockReleaseAndRerelease(WakelockController.WAKE_LOCK_STATE_CHANGED, 81 () -> mWakelockController.isOnStateChangedPending()); 82 83 // Verify release happened only once 84 verify(mDisplayPowerCallbacks, times(1)) 85 .releaseSuspendBlocker(mWakelockController.getSuspendBlockerOnStateChangedId()); 86 } 87 88 @Test acquireUnfinishedBusinessSuspendBlockerAcquiresIfNotAcquired()89 public void acquireUnfinishedBusinessSuspendBlockerAcquiresIfNotAcquired() throws Exception { 90 // Acquire 91 verifyWakelockAcquisitionAndReaquisition(WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS, 92 () -> mWakelockController.hasUnfinishedBusiness()); 93 94 // Verify acquire happened only once 95 verify(mDisplayPowerCallbacks, times(1)) 96 .acquireSuspendBlocker(mWakelockController.getSuspendBlockerUnfinishedBusinessId()); 97 98 // Release 99 verifyWakelockReleaseAndRerelease(WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS, 100 () -> mWakelockController.hasUnfinishedBusiness()); 101 102 // Verify release happened only once 103 verify(mDisplayPowerCallbacks, times(1)) 104 .releaseSuspendBlocker(mWakelockController.getSuspendBlockerUnfinishedBusinessId()); 105 } 106 107 @Test acquireProxPositiveSuspendBlockerAcquiresIfNotAcquired()108 public void acquireProxPositiveSuspendBlockerAcquiresIfNotAcquired() throws Exception { 109 // Acquire 110 verifyWakelockAcquisitionAndReaquisition(WakelockController.WAKE_LOCK_PROXIMITY_POSITIVE, 111 () -> mWakelockController.isProximityPositiveAcquired()); 112 113 // Verify acquire happened only once 114 verify(mDisplayPowerCallbacks, times(1)) 115 .acquireSuspendBlocker(mWakelockController.getSuspendBlockerProxPositiveId()); 116 117 // Release 118 verifyWakelockReleaseAndRerelease(WakelockController.WAKE_LOCK_PROXIMITY_POSITIVE, 119 () -> mWakelockController.isProximityPositiveAcquired()); 120 121 // Verify release happened only once 122 verify(mDisplayPowerCallbacks, times(1)) 123 .releaseSuspendBlocker(mWakelockController.getSuspendBlockerProxPositiveId()); 124 } 125 126 @Test acquireProxNegativeSuspendBlockerAcquiresIfNotAcquired()127 public void acquireProxNegativeSuspendBlockerAcquiresIfNotAcquired() throws Exception { 128 // Acquire 129 verifyWakelockAcquisitionAndReaquisition(WakelockController.WAKE_LOCK_PROXIMITY_NEGATIVE, 130 () -> mWakelockController.isProximityNegativeAcquired()); 131 132 // Verify acquire happened only once 133 verify(mDisplayPowerCallbacks, times(1)) 134 .acquireSuspendBlocker(mWakelockController.getSuspendBlockerProxNegativeId()); 135 136 // Release 137 verifyWakelockReleaseAndRerelease(WakelockController.WAKE_LOCK_PROXIMITY_NEGATIVE, 138 () -> mWakelockController.isProximityNegativeAcquired()); 139 140 // Verify release happened only once 141 verify(mDisplayPowerCallbacks, times(1)) 142 .releaseSuspendBlocker(mWakelockController.getSuspendBlockerProxNegativeId()); 143 } 144 145 @Test acquireProxDebounceSuspendBlockerAcquiresIfNotAcquired()146 public void acquireProxDebounceSuspendBlockerAcquiresIfNotAcquired() throws Exception { 147 // Acquire the suspend blocker 148 verifyWakelockAcquisitionAndReaquisition(WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE, 149 () -> mWakelockController.hasProximitySensorDebounced()); 150 151 // Verify acquire happened only once 152 verify(mDisplayPowerCallbacks, times(1)) 153 .acquireSuspendBlocker(mWakelockController.getSuspendBlockerProxDebounceId()); 154 155 // Release the suspend blocker 156 verifyWakelockReleaseAndRerelease(WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE, 157 () -> mWakelockController.hasProximitySensorDebounced()); 158 159 // Verify suspend blocker was released only once 160 verify(mDisplayPowerCallbacks, times(1)) 161 .releaseSuspendBlocker(mWakelockController.getSuspendBlockerProxDebounceId()); 162 } 163 164 @Test proximityPositiveRunnableWorksAsExpected()165 public void proximityPositiveRunnableWorksAsExpected() { 166 // Acquire the suspend blocker twice 167 assertTrue(mWakelockController.acquireWakelock( 168 WakelockController.WAKE_LOCK_PROXIMITY_POSITIVE)); 169 170 // Execute the runnable 171 Runnable proximityPositiveRunnable = mWakelockController.getOnProximityPositiveRunnable(); 172 proximityPositiveRunnable.run(); 173 174 // Validate one suspend blocker was released 175 assertFalse(mWakelockController.isProximityPositiveAcquired()); 176 verify(mDisplayPowerCallbacks).onProximityPositive(); 177 verify(mDisplayPowerCallbacks).releaseSuspendBlocker( 178 mWakelockController.getSuspendBlockerProxPositiveId()); 179 } 180 181 @Test proximityPositiveRunnableDoesNothingIfNotAcquired()182 public void proximityPositiveRunnableDoesNothingIfNotAcquired() { 183 // Execute the runnable 184 Runnable proximityPositiveRunnable = mWakelockController.getOnProximityPositiveRunnable(); 185 proximityPositiveRunnable.run(); 186 187 // Validate one suspend blocker was released 188 assertFalse(mWakelockController.isProximityPositiveAcquired()); 189 verifyZeroInteractions(mDisplayPowerCallbacks); 190 } 191 192 @Test proximityNegativeRunnableWorksAsExpected()193 public void proximityNegativeRunnableWorksAsExpected() { 194 // Acquire the suspend blocker twice 195 assertTrue(mWakelockController.acquireWakelock( 196 WakelockController.WAKE_LOCK_PROXIMITY_NEGATIVE)); 197 198 // Execute the runnable 199 Runnable proximityNegativeRunnable = mWakelockController.getOnProximityNegativeRunnable(); 200 proximityNegativeRunnable.run(); 201 202 // Validate one suspend blocker was released 203 assertFalse(mWakelockController.isProximityNegativeAcquired()); 204 verify(mDisplayPowerCallbacks).onProximityNegative(); 205 verify(mDisplayPowerCallbacks).releaseSuspendBlocker( 206 mWakelockController.getSuspendBlockerProxNegativeId()); 207 } 208 209 @Test proximityNegativeRunnableDoesNothingIfNotAcquired()210 public void proximityNegativeRunnableDoesNothingIfNotAcquired() { 211 // Execute the runnable 212 Runnable proximityNegativeRunnable = mWakelockController.getOnProximityNegativeRunnable(); 213 proximityNegativeRunnable.run(); 214 215 // Validate one suspend blocker was released 216 assertFalse(mWakelockController.isProximityNegativeAcquired()); 217 verifyZeroInteractions(mDisplayPowerCallbacks); 218 } 219 220 @Test onStateChangeRunnableWorksAsExpected()221 public void onStateChangeRunnableWorksAsExpected() { 222 // Acquire the suspend blocker twice 223 assertTrue(mWakelockController.acquireWakelock(WakelockController.WAKE_LOCK_STATE_CHANGED)); 224 225 // Execute the runnable 226 Runnable stateChangeRunnable = mWakelockController.getOnStateChangedRunnable(); 227 stateChangeRunnable.run(); 228 229 // Validate one suspend blocker was released 230 assertFalse(mWakelockController.isOnStateChangedPending()); 231 verify(mDisplayPowerCallbacks).onStateChanged(); 232 verify(mDisplayPowerCallbacks).releaseSuspendBlocker( 233 mWakelockController.getSuspendBlockerOnStateChangedId()); 234 } 235 236 @Test onStateChangeRunnableDoesNothingIfNotAcquired()237 public void onStateChangeRunnableDoesNothingIfNotAcquired() { 238 // Execute the runnable 239 Runnable stateChangeRunnable = mWakelockController.getOnStateChangedRunnable(); 240 stateChangeRunnable.run(); 241 242 // Validate one suspend blocker was released 243 assertFalse(mWakelockController.isOnStateChangedPending()); 244 verifyZeroInteractions(mDisplayPowerCallbacks); 245 } 246 247 @Test testReleaseAll()248 public void testReleaseAll() throws Exception { 249 // Use WAKE_LOCK_MAX to verify it has been correctly set and used in releaseAll(). 250 verifyWakelockAcquisition(WakelockController.WAKE_LOCK_MAX, 251 () -> mWakelockController.hasUnfinishedBusiness()); 252 mWakelockController.releaseAll(); 253 assertFalse(mWakelockController.hasUnfinishedBusiness()); 254 } 255 verifyWakelockAcquisitionAndReaquisition(int wakelockId, Callable<Boolean> isWakelockAcquiredCallable)256 private void verifyWakelockAcquisitionAndReaquisition(int wakelockId, 257 Callable<Boolean> isWakelockAcquiredCallable) 258 throws Exception { 259 verifyWakelockAcquisition(wakelockId, isWakelockAcquiredCallable); 260 verifyWakelockReacquisition(wakelockId, isWakelockAcquiredCallable); 261 } 262 verifyWakelockReleaseAndRerelease(int wakelockId, Callable<Boolean> isWakelockAcquiredCallable)263 private void verifyWakelockReleaseAndRerelease(int wakelockId, 264 Callable<Boolean> isWakelockAcquiredCallable) 265 throws Exception { 266 verifyWakelockRelease(wakelockId, isWakelockAcquiredCallable); 267 verifyWakelockRerelease(wakelockId, isWakelockAcquiredCallable); 268 } 269 verifyWakelockAcquisition(int wakelockId, Callable<Boolean> isWakelockAcquiredCallable)270 private void verifyWakelockAcquisition(int wakelockId, 271 Callable<Boolean> isWakelockAcquiredCallable) 272 throws Exception { 273 assertTrue(mWakelockController.acquireWakelock(wakelockId)); 274 assertTrue(isWakelockAcquiredCallable.call()); 275 } 276 verifyWakelockReacquisition(int wakelockId, Callable<Boolean> isWakelockAcquiredCallable)277 private void verifyWakelockReacquisition(int wakelockId, 278 Callable<Boolean> isWakelockAcquiredCallable) 279 throws Exception { 280 assertFalse(mWakelockController.acquireWakelock(wakelockId)); 281 assertTrue(isWakelockAcquiredCallable.call()); 282 } 283 verifyWakelockRelease(int wakelockId, Callable<Boolean> isWakelockAcquiredCallable)284 private void verifyWakelockRelease(int wakelockId, Callable<Boolean> isWakelockAcquiredCallable) 285 throws Exception { 286 assertTrue(mWakelockController.releaseWakelock(wakelockId)); 287 assertFalse(isWakelockAcquiredCallable.call()); 288 } 289 verifyWakelockRerelease(int wakelockId, Callable<Boolean> isWakelockAcquiredCallable)290 private void verifyWakelockRerelease(int wakelockId, 291 Callable<Boolean> isWakelockAcquiredCallable) 292 throws Exception { 293 assertFalse(mWakelockController.releaseWakelock(wakelockId)); 294 assertFalse(isWakelockAcquiredCallable.call()); 295 } 296 } 297