1 /* 2 * Copyright (C) 2020 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.util.sensors; 18 19 import static android.hardware.Sensor.TYPE_ALL; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertTrue; 24 import static org.mockito.Mockito.mock; 25 import static org.mockito.Mockito.when; 26 27 import android.hardware.Sensor; 28 import android.testing.AndroidTestingRunner; 29 30 import androidx.test.filters.SmallTest; 31 32 import com.android.systemui.SysuiTestCase; 33 import com.android.systemui.util.concurrency.FakeExecution; 34 import com.android.systemui.util.concurrency.FakeExecutor; 35 import com.android.systemui.util.concurrency.FakeThreadFactory; 36 import com.android.systemui.util.time.FakeSystemClock; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.util.List; 43 44 @SmallTest 45 @RunWith(AndroidTestingRunner.class) 46 public class ThresholdSensorImplTest extends SysuiTestCase { 47 48 private ThresholdSensorImpl mThresholdSensor; 49 private FakeSensorManager mSensorManager; 50 private AsyncSensorManager mAsyncSensorManager; 51 private FakeSensorManager.FakeProximitySensor mFakeProximitySensor; 52 private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); 53 54 @Before setUp()55 public void setUp() throws Exception { 56 mSensorManager = new FakeSensorManager(getContext()); 57 58 mAsyncSensorManager = new AsyncSensorManager( 59 mSensorManager, new FakeThreadFactory(mFakeExecutor), null); 60 61 mFakeProximitySensor = mSensorManager.getFakeProximitySensor(); 62 ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( 63 null, mAsyncSensorManager, new FakeExecution()); 64 mThresholdSensor = (ThresholdSensorImpl) thresholdSensorBuilder 65 .setSensor(mFakeProximitySensor.getSensor()) 66 .setThresholdValue(mFakeProximitySensor.getSensor().getMaximumRange()) 67 .build(); 68 } 69 70 @Test testRegistersWakeUpProxSensor_givenWakeUpExistsAfterNonWakeup()71 public void testRegistersWakeUpProxSensor_givenWakeUpExistsAfterNonWakeup() { 72 // GIVEN sensor manager with two prox sensors (one non-wakeup, one wakeup) 73 final String sensorTypeProx = "prox"; 74 AsyncSensorManager mockSensorManager = mock(AsyncSensorManager.class); 75 76 Sensor mockNonWakeupProx = mock(Sensor.class); 77 when(mockNonWakeupProx.isWakeUpSensor()).thenReturn(false); 78 when(mockNonWakeupProx.getStringType()).thenReturn(sensorTypeProx); 79 80 Sensor mockWakeupProx = mock(Sensor.class); 81 when(mockWakeupProx.isWakeUpSensor()).thenReturn(true); 82 when(mockWakeupProx.getStringType()).thenReturn(sensorTypeProx); 83 84 when(mockSensorManager.getSensorList(TYPE_ALL)).thenReturn( 85 List.of(mockNonWakeupProx, mockWakeupProx)); 86 87 // WHEN we build a threshold sensor by type 88 ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( 89 null, mockSensorManager, new FakeExecution()); 90 Sensor proxSensor = thresholdSensorBuilder.findSensorByType(sensorTypeProx, true); 91 92 // THEN the prox sensor used is the wakeup sensor 93 assertEquals(mockWakeupProx, proxSensor); 94 } 95 96 @Test testRegistersWakeUpProxSensor_givenNonWakeUpExistsAfterWakeup()97 public void testRegistersWakeUpProxSensor_givenNonWakeUpExistsAfterWakeup() { 98 // GIVEN sensor manager with two prox sensors (one wakeup, one non-wakeup) 99 final String sensorTypeProx = "prox"; 100 AsyncSensorManager mockSensorManager = mock(AsyncSensorManager.class); 101 102 Sensor mockNonWakeupProx = mock(Sensor.class); 103 when(mockNonWakeupProx.isWakeUpSensor()).thenReturn(false); 104 when(mockNonWakeupProx.getStringType()).thenReturn(sensorTypeProx); 105 106 Sensor mockWakeupProx = mock(Sensor.class); 107 when(mockWakeupProx.isWakeUpSensor()).thenReturn(true); 108 when(mockWakeupProx.getStringType()).thenReturn(sensorTypeProx); 109 110 when(mockSensorManager.getSensorList(TYPE_ALL)).thenReturn( 111 List.of(mockWakeupProx, mockNonWakeupProx)); 112 113 // WHEN we build a threshold sensor by type 114 ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( 115 null, mockSensorManager, new FakeExecution()); 116 Sensor proxSensor = thresholdSensorBuilder.findSensorByType(sensorTypeProx, true); 117 118 // THEN the prox sensor used is the wakeup sensor 119 assertEquals(mockWakeupProx, proxSensor); 120 } 121 122 @Test testRegistersNonWakeUpProxSensor_givenNonWakeUpOnly()123 public void testRegistersNonWakeUpProxSensor_givenNonWakeUpOnly() { 124 // GIVEN sensor manager with one non-wakeup prox sensor 125 final String sensorTypeProx = "prox"; 126 AsyncSensorManager mockSensorManager = mock(AsyncSensorManager.class); 127 128 Sensor mockNonWakeupProx = mock(Sensor.class); 129 when(mockNonWakeupProx.isWakeUpSensor()).thenReturn(false); 130 when(mockNonWakeupProx.getStringType()).thenReturn(sensorTypeProx); 131 132 when(mockSensorManager.getSensorList(TYPE_ALL)).thenReturn(List.of(mockNonWakeupProx)); 133 134 // WHEN we build a threshold sensor by type 135 ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( 136 null, mockSensorManager, new FakeExecution()); 137 Sensor proxSensor = thresholdSensorBuilder.findSensorByType(sensorTypeProx, true); 138 139 // THEN the prox sensor used is the one available (non-wakeup) 140 assertEquals(mockNonWakeupProx, proxSensor); 141 } 142 143 @Test testSingleListener()144 public void testSingleListener() { 145 TestableListener listener = new TestableListener(); 146 147 assertFalse(mThresholdSensor.isRegistered()); 148 mThresholdSensor.register(listener); 149 waitForSensorManager(); 150 assertTrue(mThresholdSensor.isRegistered()); 151 assertEquals(0, listener.mCallCount); 152 153 mFakeProximitySensor.sendProximityResult(true); 154 assertFalse(listener.mBelow); 155 assertEquals(1, listener.mCallCount); 156 mFakeProximitySensor.sendProximityResult(false); 157 assertTrue(listener.mBelow); 158 assertEquals(2, listener.mCallCount); 159 160 mThresholdSensor.unregister(listener); 161 waitForSensorManager(); 162 } 163 164 @Test testMultiListener()165 public void testMultiListener() { 166 TestableListener listenerA = new TestableListener(); 167 TestableListener listenerB = new TestableListener(); 168 169 assertFalse(mThresholdSensor.isRegistered()); 170 171 mThresholdSensor.register(listenerA); 172 waitForSensorManager(); 173 assertTrue(mThresholdSensor.isRegistered()); 174 mThresholdSensor.register(listenerB); 175 waitForSensorManager(); 176 assertTrue(mThresholdSensor.isRegistered()); 177 assertEquals(0, listenerA.mCallCount); 178 assertEquals(0, listenerB.mCallCount); 179 180 181 mFakeProximitySensor.sendProximityResult(true); 182 assertFalse(listenerA.mBelow); 183 assertFalse(listenerB.mBelow); 184 assertEquals(1, listenerA.mCallCount); 185 assertEquals(1, listenerB.mCallCount); 186 mFakeProximitySensor.sendProximityResult(false); 187 assertTrue(listenerA.mBelow); 188 assertTrue(listenerB.mBelow); 189 assertEquals(2, listenerA.mCallCount); 190 assertEquals(2, listenerB.mCallCount); 191 192 mThresholdSensor.unregister(listenerA); 193 mThresholdSensor.unregister(listenerB); 194 waitForSensorManager(); 195 } 196 197 @Test testDuplicateListener()198 public void testDuplicateListener() { 199 TestableListener listenerA = new TestableListener(); 200 201 assertFalse(mThresholdSensor.isRegistered()); 202 203 mThresholdSensor.register(listenerA); 204 waitForSensorManager(); 205 assertTrue(mThresholdSensor.isRegistered()); 206 mThresholdSensor.register(listenerA); 207 waitForSensorManager(); 208 assertTrue(mThresholdSensor.isRegistered()); 209 assertEquals(0, listenerA.mCallCount); 210 211 mFakeProximitySensor.sendProximityResult(true); 212 assertFalse(listenerA.mBelow); 213 assertEquals(1, listenerA.mCallCount); 214 mFakeProximitySensor.sendProximityResult(false); 215 assertTrue(listenerA.mBelow); 216 assertEquals(2, listenerA.mCallCount); 217 218 mThresholdSensor.unregister(listenerA); 219 waitForSensorManager(); 220 } 221 @Test testUnregister()222 public void testUnregister() { 223 TestableListener listener = new TestableListener(); 224 225 assertFalse(mThresholdSensor.isRegistered()); 226 mThresholdSensor.register(listener); 227 waitForSensorManager(); 228 assertTrue(mThresholdSensor.isRegistered()); 229 assertEquals(0, listener.mCallCount); 230 231 mFakeProximitySensor.sendProximityResult(true); 232 assertFalse(listener.mBelow); 233 assertEquals(1, listener.mCallCount); 234 235 mThresholdSensor.unregister(listener); 236 waitForSensorManager(); 237 assertFalse(mThresholdSensor.isRegistered()); 238 } 239 240 @Test testPauseAndResume()241 public void testPauseAndResume() { 242 TestableListener listener = new TestableListener(); 243 244 assertFalse(mThresholdSensor.isRegistered()); 245 mThresholdSensor.register(listener); 246 waitForSensorManager(); 247 assertTrue(mThresholdSensor.isRegistered()); 248 assertEquals(0, listener.mCallCount); 249 250 mFakeProximitySensor.sendProximityResult(true); 251 assertFalse(listener.mBelow); 252 assertEquals(1, listener.mCallCount); 253 254 mThresholdSensor.pause(); 255 waitForSensorManager(); 256 assertFalse(mThresholdSensor.isRegistered()); 257 258 // More events do nothing when paused. 259 mFakeProximitySensor.sendProximityResult(true); 260 assertFalse(listener.mBelow); 261 assertEquals(1, listener.mCallCount); 262 mFakeProximitySensor.sendProximityResult(false); 263 assertFalse(listener.mBelow); 264 assertEquals(1, listener.mCallCount); 265 266 mThresholdSensor.resume(); 267 waitForSensorManager(); 268 assertTrue(mThresholdSensor.isRegistered()); 269 // Still matches our previous call 270 assertFalse(listener.mBelow); 271 assertEquals(1, listener.mCallCount); 272 273 mFakeProximitySensor.sendProximityResult(false); 274 assertTrue(listener.mBelow); 275 assertEquals(2, listener.mCallCount); 276 277 mThresholdSensor.unregister(listener); 278 waitForSensorManager(); 279 assertFalse(mThresholdSensor.isRegistered()); 280 } 281 282 @Test testAlertListeners()283 public void testAlertListeners() { 284 TestableListener listenerA = new TestableListener(); 285 TestableListener listenerB = new TestableListener(); 286 287 assertFalse(mThresholdSensor.isRegistered()); 288 289 mThresholdSensor.register(listenerA); 290 mThresholdSensor.register(listenerB); 291 waitForSensorManager(); 292 assertTrue(mThresholdSensor.isRegistered()); 293 assertEquals(0, listenerA.mCallCount); 294 assertEquals(0, listenerB.mCallCount); 295 296 mFakeProximitySensor.sendProximityResult(true); 297 assertFalse(listenerA.mBelow); 298 assertEquals(1, listenerA.mCallCount); 299 assertFalse(listenerB.mBelow); 300 assertEquals(1, listenerB.mCallCount); 301 302 mFakeProximitySensor.sendProximityResult(false); 303 assertTrue(listenerA.mBelow); 304 assertEquals(2, listenerA.mCallCount); 305 assertTrue(listenerB.mBelow); 306 assertEquals(2, listenerB.mCallCount); 307 308 mThresholdSensor.unregister(listenerA); 309 mThresholdSensor.unregister(listenerB); 310 waitForSensorManager(); 311 } 312 313 @Test testHysteresis()314 public void testHysteresis() { 315 float lowValue = 10f; 316 float highValue = 100f; 317 FakeSensorManager.FakeGenericSensor sensor = mSensorManager.getFakeLightSensor(); 318 ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( 319 null, mAsyncSensorManager, new FakeExecution()); 320 ThresholdSensorImpl thresholdSensor = (ThresholdSensorImpl) thresholdSensorBuilder 321 .setSensor(sensor.getSensor()) 322 .setThresholdValue(lowValue) 323 .setThresholdLatchValue(highValue) 324 .build(); 325 326 TestableListener listener = new TestableListener(); 327 328 assertFalse(thresholdSensor.isRegistered()); 329 thresholdSensor.register(listener); 330 waitForSensorManager(); 331 assertTrue(thresholdSensor.isRegistered()); 332 assertEquals(0, listener.mCallCount); 333 334 sensor.sendSensorEvent(lowValue - 1); 335 336 assertTrue(listener.mBelow); 337 assertEquals(1, listener.mCallCount); 338 339 sensor.sendSensorEvent(lowValue + 1); 340 341 assertTrue(listener.mBelow); 342 assertEquals(1, listener.mCallCount); 343 344 sensor.sendSensorEvent(highValue); 345 346 assertFalse(listener.mBelow); 347 assertEquals(2, listener.mCallCount); 348 349 sensor.sendSensorEvent(highValue - 1); 350 351 assertFalse(listener.mBelow); 352 assertEquals(2, listener.mCallCount); 353 354 355 sensor.sendSensorEvent(lowValue - 1); 356 357 assertTrue(listener.mBelow); 358 assertEquals(3, listener.mCallCount); 359 } 360 361 @Test testAlertAfterPause()362 public void testAlertAfterPause() { 363 TestableListener listener = new TestableListener(); 364 365 mThresholdSensor.register(listener); 366 waitForSensorManager(); 367 mFakeProximitySensor.sendProximityResult(false); 368 assertTrue(listener.mBelow); 369 assertEquals(1, listener.mCallCount); 370 371 mThresholdSensor.pause(); 372 373 mFakeProximitySensor.sendProximityResult(false); 374 assertTrue(listener.mBelow); 375 assertEquals(1, listener.mCallCount); 376 } 377 378 static class TestableListener implements ThresholdSensor.Listener { 379 boolean mBelow; 380 long mTimestampNs; 381 int mCallCount; 382 383 @Override onThresholdCrossed(ThresholdSensorEvent event)384 public void onThresholdCrossed(ThresholdSensorEvent event) { 385 mBelow = event.getBelow(); 386 mTimestampNs = event.getTimestampNs(); 387 mCallCount++; 388 } 389 } 390 waitForSensorManager()391 private void waitForSensorManager() { 392 mFakeExecutor.runAllReady(); 393 } 394 395 } 396