1 /* 2 * Copyright (C) 2019 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 android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; 20 21 import static com.android.systemui.doze.DozeLog.REASON_SENSOR_TAP; 22 import static com.android.systemui.doze.DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS; 23 import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN; 24 25 import static org.junit.Assert.assertEquals; 26 import static org.junit.Assert.assertFalse; 27 import static org.junit.Assert.assertTrue; 28 import static org.mockito.ArgumentMatchers.any; 29 import static org.mockito.ArgumentMatchers.anyFloat; 30 import static org.mockito.ArgumentMatchers.anyInt; 31 import static org.mockito.ArgumentMatchers.eq; 32 import static org.mockito.Mockito.doAnswer; 33 import static org.mockito.Mockito.mock; 34 import static org.mockito.Mockito.never; 35 import static org.mockito.Mockito.reset; 36 import static org.mockito.Mockito.times; 37 import static org.mockito.Mockito.verify; 38 import static org.mockito.Mockito.when; 39 40 import android.app.ActivityManager; 41 import android.content.res.Resources; 42 import android.database.ContentObserver; 43 import android.hardware.Sensor; 44 import android.hardware.display.AmbientDisplayConfiguration; 45 import android.testing.AndroidTestingRunner; 46 import android.testing.TestableLooper; 47 import android.testing.TestableLooper.RunWithLooper; 48 49 import androidx.test.filters.SmallTest; 50 51 import com.android.systemui.SysuiTestCase; 52 import com.android.systemui.biometrics.AuthController; 53 import com.android.systemui.doze.DozeSensors.TriggerSensor; 54 import com.android.systemui.plugins.SensorManagerPlugin; 55 import com.android.systemui.settings.UserTracker; 56 import com.android.systemui.statusbar.phone.DozeParameters; 57 import com.android.systemui.statusbar.policy.DevicePostureController; 58 import com.android.systemui.util.sensors.AsyncSensorManager; 59 import com.android.systemui.util.sensors.ProximitySensor; 60 import com.android.systemui.util.settings.FakeSettings; 61 import com.android.systemui.util.wakelock.WakeLock; 62 63 import org.junit.Before; 64 import org.junit.Test; 65 import org.junit.runner.RunWith; 66 import org.mockito.ArgumentCaptor; 67 import org.mockito.Captor; 68 import org.mockito.Mock; 69 import org.mockito.MockitoAnnotations; 70 71 import java.lang.reflect.Constructor; 72 import java.lang.reflect.Field; 73 import java.lang.reflect.Method; 74 import java.util.ArrayList; 75 import java.util.List; 76 import java.util.function.Consumer; 77 78 @RunWith(AndroidTestingRunner.class) 79 @RunWithLooper 80 @SmallTest 81 public class DozeSensorsTest extends SysuiTestCase { 82 @Mock 83 private Resources mResources; 84 @Mock 85 private AsyncSensorManager mSensorManager; 86 @Mock 87 private DozeParameters mDozeParameters; 88 @Mock 89 private AmbientDisplayConfiguration mAmbientDisplayConfiguration; 90 @Mock 91 private WakeLock mWakeLock; 92 @Mock 93 private DozeSensors.Callback mCallback; 94 @Mock 95 private Consumer<Boolean> mProxCallback; 96 @Mock 97 private TriggerSensor mTriggerSensor; 98 @Mock 99 private DozeLog mDozeLog; 100 @Mock 101 private AuthController mAuthController; 102 @Mock 103 private DevicePostureController mDevicePostureController; 104 @Mock 105 private UserTracker mUserTracker; 106 @Mock 107 private ProximitySensor mProximitySensor; 108 109 // Capture listeners so that they can be used to send events 110 @Captor 111 private ArgumentCaptor<AuthController.Callback> mAuthControllerCallbackCaptor = 112 ArgumentCaptor.forClass(AuthController.Callback.class); 113 private AuthController.Callback mAuthControllerCallback; 114 115 private FakeSettings mFakeSettings = new FakeSettings(); 116 private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener; 117 private TestableLooper mTestableLooper; 118 private TestableDozeSensors mDozeSensors; 119 private TriggerSensor mSensorTap; 120 121 @Before setUp()122 public void setUp() { 123 MockitoAnnotations.initMocks(this); 124 mTestableLooper = TestableLooper.get(this); 125 when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser()); 126 when(mAmbientDisplayConfiguration.tapSensorTypeMapping()) 127 .thenReturn(new String[]{"tapSensor"}); 128 when(mAmbientDisplayConfiguration.getWakeLockScreenDebounce()).thenReturn(5000L); 129 when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true); 130 when(mAmbientDisplayConfiguration.enabled(ActivityManager.getCurrentUser())).thenReturn( 131 true); 132 doAnswer(invocation -> { 133 ((Runnable) invocation.getArgument(0)).run(); 134 return null; 135 }).when(mWakeLock).wrap(any(Runnable.class)); 136 mDozeSensors = new TestableDozeSensors(); 137 138 verify(mAuthController).addCallback(mAuthControllerCallbackCaptor.capture()); 139 mAuthControllerCallback = mAuthControllerCallbackCaptor.getValue(); 140 } 141 142 @Test testRegisterProx()143 public void testRegisterProx() { 144 assertFalse(mProximitySensor.isRegistered()); 145 mDozeSensors.setProxListening(true); 146 verify(mProximitySensor).resume(); 147 } 148 149 @Test testSensorDebounce()150 public void testSensorDebounce() { 151 mDozeSensors.setListening(true, true, true); 152 153 mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class)); 154 mTestableLooper.processAllMessages(); 155 verify(mCallback).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_REACH), 156 anyFloat(), anyFloat(), eq(null)); 157 158 mDozeSensors.requestTemporaryDisable(); 159 reset(mCallback); 160 mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class)); 161 mTestableLooper.processAllMessages(); 162 verify(mCallback, never()).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_REACH), 163 anyFloat(), anyFloat(), eq(null)); 164 } 165 166 @Test testSetListening_firstTrue_registerSettingsObserver()167 public void testSetListening_firstTrue_registerSettingsObserver() { 168 verify(mSensorManager, never()).registerListener(any(), any(Sensor.class), anyInt()); 169 mDozeSensors.setListening(true, true, true); 170 171 verify(mTriggerSensor).registerSettingsObserver(any(ContentObserver.class)); 172 } 173 174 @Test testSetListening_twiceTrue_onlyRegisterSettingsObserverOnce()175 public void testSetListening_twiceTrue_onlyRegisterSettingsObserverOnce() { 176 verify(mSensorManager, never()).registerListener(any(), any(Sensor.class), anyInt()); 177 mDozeSensors.setListening(true, true, true); 178 mDozeSensors.setListening(true, true, true); 179 180 verify(mTriggerSensor, times(1)).registerSettingsObserver(any(ContentObserver.class)); 181 } 182 183 @Test testDestroy()184 public void testDestroy() { 185 mDozeSensors.destroy(); 186 187 verify(mProximitySensor).destroy(); 188 verify(mTriggerSensor).setListening(false); 189 } 190 191 @Test testRegisterSensorsUsingProx()192 public void testRegisterSensorsUsingProx() { 193 // GIVEN we only should register sensors using prox when not in low-powered mode / off 194 // and the single tap sensor uses the proximity sensor 195 when(mDozeParameters.getSelectivelyRegisterSensorsUsingProx()).thenReturn(true); 196 when(mDozeParameters.singleTapUsesProx(anyInt())).thenReturn(true); 197 TestableDozeSensors dozeSensors = new TestableDozeSensors(); 198 199 // THEN on initialization, the tap sensor isn't requested 200 assertFalse(mSensorTap.mRequested); 201 202 // WHEN we're now in a low powered state 203 dozeSensors.setListeningWithPowerState(true, true, true, true); 204 205 // THEN the tap sensor is registered 206 assertTrue(mSensorTap.mRequested); 207 } 208 209 @Test testDozeSensorSetListening()210 public void testDozeSensorSetListening() { 211 // GIVEN doze sensors enabled 212 when(mAmbientDisplayConfiguration.enabled(anyInt())).thenReturn(true); 213 214 // GIVEN a trigger sensor that's enabled by settings 215 Sensor mockSensor = mock(Sensor.class); 216 TriggerSensor triggerSensor = mDozeSensors.createDozeSensorWithSettingEnabled( 217 mockSensor, 218 /* settingEnabled */ true 219 ); 220 when(mSensorManager.requestTriggerSensor(eq(triggerSensor), eq(mockSensor))) 221 .thenReturn(true); 222 223 // WHEN we want to listen for the trigger sensor 224 triggerSensor.setListening(true); 225 226 // THEN the sensor is registered 227 assertTrue(triggerSensor.mRegistered); 228 } 229 230 @Test testDozeSensorSettingDisabled()231 public void testDozeSensorSettingDisabled() { 232 // GIVEN doze sensors enabled 233 when(mAmbientDisplayConfiguration.enabled(anyInt())).thenReturn(true); 234 235 // GIVEN a trigger sensor that's not enabled by settings 236 Sensor mockSensor = mock(Sensor.class); 237 TriggerSensor triggerSensor = mDozeSensors.createDozeSensorWithSettingEnabled( 238 mockSensor, 239 /* settingEnabled*/ false 240 ); 241 when(mSensorManager.requestTriggerSensor(eq(triggerSensor), eq(mockSensor))) 242 .thenReturn(true); 243 244 // WHEN setListening is called 245 triggerSensor.setListening(true); 246 247 // THEN the sensor is not registered 248 assertFalse(triggerSensor.mRegistered); 249 } 250 251 @Test testDozeSensorIgnoreSetting()252 public void testDozeSensorIgnoreSetting() { 253 // GIVEN doze sensors enabled 254 when(mAmbientDisplayConfiguration.enabled(anyInt())).thenReturn(true); 255 256 // GIVEN a trigger sensor that's not enabled by settings 257 Sensor mockSensor = mock(Sensor.class); 258 TriggerSensor triggerSensor = mDozeSensors.createDozeSensorWithSettingEnabled( 259 mockSensor, 260 /* settingEnabled*/ false 261 ); 262 when(mSensorManager.requestTriggerSensor(eq(triggerSensor), eq(mockSensor))) 263 .thenReturn(true); 264 265 // GIVEN sensor is listening 266 triggerSensor.setListening(true); 267 268 // WHEN ignoreSetting is called 269 triggerSensor.ignoreSetting(true); 270 271 // THEN the sensor is still registered since the setting is ignore 272 assertTrue(triggerSensor.mRegistered); 273 } 274 275 @Test testUpdateListeningAfterAlreadyRegistered()276 public void testUpdateListeningAfterAlreadyRegistered() { 277 // GIVEN doze sensors enabled 278 when(mAmbientDisplayConfiguration.enabled(anyInt())).thenReturn(true); 279 280 // GIVEN a trigger sensor 281 Sensor mockSensor = mock(Sensor.class); 282 TriggerSensor triggerSensor = mDozeSensors.createDozeSensorWithSettingEnabled( 283 mockSensor, 284 /* settingEnabled*/ true 285 ); 286 when(mSensorManager.requestTriggerSensor(eq(triggerSensor), eq(mockSensor))) 287 .thenReturn(true); 288 289 // WHEN setListening is called AND updateListening is called 290 triggerSensor.setListening(true); 291 triggerSensor.updateListening(); 292 293 // THEN the sensor is still registered 294 assertTrue(triggerSensor.mRegistered); 295 } 296 297 @Test testPostureStartStateClosed_registersCorrectSensor()298 public void testPostureStartStateClosed_registersCorrectSensor() throws Exception { 299 // GIVEN doze sensor that supports postures 300 Sensor closedSensor = createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT); 301 Sensor openedSensor = createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_LIGHT); 302 TriggerSensor triggerSensor = mDozeSensors.createDozeSensorForPosture( 303 new Sensor[] { 304 null /* unknown */, 305 closedSensor, 306 null /* half-opened */, 307 openedSensor}, 308 DevicePostureController.DEVICE_POSTURE_CLOSED); 309 310 // WHEN trigger sensor requests listening 311 triggerSensor.setListening(true); 312 313 // THEN the correct sensor is registered 314 verify(mSensorManager).requestTriggerSensor(eq(triggerSensor), eq(closedSensor)); 315 verify(mSensorManager, never()).requestTriggerSensor(eq(triggerSensor), eq(openedSensor)); 316 } 317 318 @Test testPostureChange_registersCorrectSensor()319 public void testPostureChange_registersCorrectSensor() throws Exception { 320 // GIVEN doze sensor that supports postures 321 Sensor closedSensor = createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT); 322 Sensor openedSensor = createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_LIGHT); 323 TriggerSensor triggerSensor = mDozeSensors.createDozeSensorForPosture( 324 new Sensor[] { 325 null /* unknown */, 326 closedSensor, 327 null /* half-opened */, 328 openedSensor}, 329 DevicePostureController.DEVICE_POSTURE_CLOSED); 330 331 // GIVEN sensor is listening 332 when(mSensorManager.requestTriggerSensor(any(), any())).thenReturn(true); 333 triggerSensor.setListening(true); 334 reset(mSensorManager); 335 assertTrue(triggerSensor.mRegistered); 336 337 // WHEN posture changes 338 boolean sensorChanged = 339 triggerSensor.setPosture(DevicePostureController.DEVICE_POSTURE_OPENED); 340 341 // THEN the correct sensor is registered 342 assertTrue(sensorChanged); 343 verify(mSensorManager).requestTriggerSensor(eq(triggerSensor), eq(openedSensor)); 344 verify(mSensorManager, never()).requestTriggerSensor(eq(triggerSensor), eq(closedSensor)); 345 } 346 347 @Test testPostureChange_noSensorChange()348 public void testPostureChange_noSensorChange() throws Exception { 349 // GIVEN doze sensor that supports postures 350 Sensor closedSensor = createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT); 351 Sensor openedSensor = createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_LIGHT); 352 TriggerSensor triggerSensor = mDozeSensors.createDozeSensorForPosture( 353 new Sensor[] { 354 null /* unknown */, 355 closedSensor, 356 openedSensor /* half-opened uses the same sensor as opened*/, 357 openedSensor}, 358 DevicePostureController.DEVICE_POSTURE_HALF_OPENED); 359 360 // GIVEN sensor is listening 361 when(mSensorManager.requestTriggerSensor(any(), any())).thenReturn(true); 362 triggerSensor.setListening(true); 363 reset(mSensorManager); 364 365 // WHEN posture changes 366 boolean sensorChanged = 367 triggerSensor.setPosture(DevicePostureController.DEVICE_POSTURE_OPENED); 368 369 // THEN no change in sensor 370 assertFalse(sensorChanged); 371 verify(mSensorManager, never()).requestTriggerSensor(eq(triggerSensor), any()); 372 } 373 374 @Test testFindSensor()375 public void testFindSensor() throws Exception { 376 // GIVEN a prox sensor 377 List<Sensor> sensors = new ArrayList<>(); 378 Sensor proxSensor = 379 createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY); 380 sensors.add(proxSensor); 381 382 when(mSensorManager.getSensorList(anyInt())).thenReturn(sensors); 383 384 // WHEN we try to find the prox sensor with the same type and name 385 // THEN we find the added sensor 386 assertEquals( 387 proxSensor, 388 DozeSensors.findSensor( 389 mSensorManager, 390 Sensor.STRING_TYPE_PROXIMITY, 391 proxSensor.getName())); 392 393 // WHEN we try to find a prox sensor with a different name 394 // THEN no sensor is found 395 assertEquals( 396 null, 397 DozeSensors.findSensor( 398 mSensorManager, 399 Sensor.STRING_TYPE_PROXIMITY, 400 "some other name")); 401 } 402 403 @Test testUdfpsEnrollmentChanged()404 public void testUdfpsEnrollmentChanged() throws Exception { 405 // GIVEN a UDFPS_LONG_PRESS trigger sensor that's not configured 406 Sensor mockSensor = mock(Sensor.class); 407 TriggerSensor triggerSensor = mDozeSensors.createDozeSensorForPosture( 408 mockSensor, 409 REASON_SENSOR_UDFPS_LONG_PRESS, 410 /* configured */ false); 411 mDozeSensors.addSensor(triggerSensor); 412 when(mSensorManager.requestTriggerSensor(eq(triggerSensor), eq(mockSensor))) 413 .thenReturn(true); 414 415 // WHEN listening state is set to TRUE 416 mDozeSensors.setListening(true, true, true); 417 418 // THEN mRegistered is still false b/c !mConfigured 419 assertFalse(triggerSensor.mConfigured); 420 assertFalse(triggerSensor.mRegistered); 421 422 // WHEN enrollment changes to TRUE 423 when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(true); 424 mAuthControllerCallback.onEnrollmentsChanged(TYPE_FINGERPRINT); 425 426 // THEN mConfigured = TRUE 427 assertTrue(triggerSensor.mConfigured); 428 429 // THEN mRegistered = TRUE 430 assertTrue(triggerSensor.mRegistered); 431 } 432 433 @Test testGesturesAllInitiallyRespectSettings()434 public void testGesturesAllInitiallyRespectSettings() { 435 DozeSensors dozeSensors = new DozeSensors(mResources, mSensorManager, mDozeParameters, 436 mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback, mDozeLog, 437 mProximitySensor, mFakeSettings, mAuthController, 438 mDevicePostureController, mUserTracker); 439 440 for (TriggerSensor sensor : dozeSensors.mTriggerSensors) { 441 assertFalse(sensor.mIgnoresSetting); 442 } 443 } 444 445 @Test aodOnlySensor_onlyRegisteredWhenAodSensorsIncluded()446 public void aodOnlySensor_onlyRegisteredWhenAodSensorsIncluded() { 447 // GIVEN doze sensors enabled 448 when(mAmbientDisplayConfiguration.enabled(anyInt())).thenReturn(true); 449 450 // GIVEN a trigger sensor that requires aod 451 Sensor mockSensor = mock(Sensor.class); 452 TriggerSensor aodOnlyTriggerSensor = mDozeSensors.createDozeSensorRequiringAod(mockSensor); 453 when(mSensorManager.requestTriggerSensor(eq(aodOnlyTriggerSensor), eq(mockSensor))) 454 .thenReturn(true); 455 mDozeSensors.addSensor(aodOnlyTriggerSensor); 456 457 // WHEN aod only sensors aren't included 458 mDozeSensors.setListening(/* listen */ true, /* includeTouchScreenSensors */true, 459 /* includeAodOnlySensors */false); 460 461 // THEN the sensor is not registered or requested 462 assertFalse(aodOnlyTriggerSensor.mRequested); 463 assertFalse(aodOnlyTriggerSensor.mRegistered); 464 465 // WHEN aod only sensors ARE included 466 mDozeSensors.setListening(/* listen */ true, /* includeTouchScreenSensors */true, 467 /* includeAodOnlySensors */true); 468 469 // THEN the sensor is registered and requested 470 assertTrue(aodOnlyTriggerSensor.mRequested); 471 assertTrue(aodOnlyTriggerSensor.mRegistered); 472 } 473 474 @Test liftToWake_defaultSetting_configDefaultFalse()475 public void liftToWake_defaultSetting_configDefaultFalse() { 476 // WHEN the default lift to wake gesture setting is false 477 when(mResources.getBoolean( 478 com.android.internal.R.bool.config_dozePickupGestureEnabled)).thenReturn(false); 479 480 DozeSensors dozeSensors = new DozeSensors(mResources, mSensorManager, mDozeParameters, 481 mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback, mDozeLog, 482 mProximitySensor, mFakeSettings, mAuthController, 483 mDevicePostureController, mUserTracker); 484 485 for (TriggerSensor sensor : dozeSensors.mTriggerSensors) { 486 // THEN lift to wake's TriggerSensor enabledBySettings is false 487 if (sensor.mPulseReason == DozeLog.REASON_SENSOR_PICKUP) { 488 assertFalse(sensor.enabledBySetting()); 489 } 490 } 491 } 492 493 @Test liftToWake_defaultSetting_configDefaultTrue()494 public void liftToWake_defaultSetting_configDefaultTrue() { 495 // WHEN the default lift to wake gesture setting is true 496 when(mResources.getBoolean( 497 com.android.internal.R.bool.config_dozePickupGestureEnabled)).thenReturn(true); 498 499 DozeSensors dozeSensors = new DozeSensors(mResources, mSensorManager, mDozeParameters, 500 mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback, mDozeLog, 501 mProximitySensor, mFakeSettings, mAuthController, 502 mDevicePostureController, mUserTracker); 503 504 for (TriggerSensor sensor : dozeSensors.mTriggerSensors) { 505 // THEN lift to wake's TriggerSensor enabledBySettings is true 506 if (sensor.mPulseReason == DozeLog.REASON_SENSOR_PICKUP) { 507 assertTrue(sensor.enabledBySetting()); 508 } 509 } 510 } 511 512 private class TestableDozeSensors extends DozeSensors { TestableDozeSensors()513 TestableDozeSensors() { 514 super(mResources, mSensorManager, mDozeParameters, 515 mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback, mDozeLog, 516 mProximitySensor, mFakeSettings, mAuthController, 517 mDevicePostureController, mUserTracker); 518 for (TriggerSensor sensor : mTriggerSensors) { 519 if (sensor instanceof PluginSensor 520 && ((PluginSensor) sensor).mPluginSensor.getType() 521 == TYPE_WAKE_LOCK_SCREEN) { 522 mWakeLockScreenListener = (PluginSensor) sensor; 523 } else if (sensor.mPulseReason == REASON_SENSOR_TAP) { 524 mSensorTap = sensor; 525 } 526 } 527 mTriggerSensors = new TriggerSensor[] {mTriggerSensor, mSensorTap}; 528 } 529 createDozeSensorWithSettingEnabled(Sensor sensor, boolean settingEnabled)530 public TriggerSensor createDozeSensorWithSettingEnabled(Sensor sensor, 531 boolean settingEnabled) { 532 return new TriggerSensor(/* sensor */ sensor, 533 /* setting name */ "test_setting", 534 /* settingDefault */ settingEnabled, 535 /* configured */ true, 536 /* pulseReason*/ 0, 537 /* reportsTouchCoordinate*/ false, 538 /* requiresTouchscreen */ false, 539 /* ignoresSetting */ false, 540 /* requiresProx */ false, 541 /* immediatelyReRegister */ true, 542 /* requiresAod */false 543 ); 544 } 545 createDozeSensorForPosture( Sensor sensor, int pulseReason, boolean configured )546 public TriggerSensor createDozeSensorForPosture( 547 Sensor sensor, 548 int pulseReason, 549 boolean configured 550 ) { 551 return new TriggerSensor(/* sensor */ sensor, 552 /* setting name */ "test_setting", 553 /* settingDefault */ true, 554 /* configured */ configured, 555 /* pulseReason*/ pulseReason, 556 /* reportsTouchCoordinate*/ false, 557 /* requiresTouchscreen */ false, 558 /* ignoresSetting */ false, 559 /* requiresTouchScreen */ false, 560 /* immediatelyReRegister*/ true, 561 false 562 ); 563 } 564 565 /** 566 * Create a doze sensor that requires Aod 567 */ createDozeSensorRequiringAod(Sensor sensor)568 public TriggerSensor createDozeSensorRequiringAod(Sensor sensor) { 569 return new TriggerSensor(/* sensor */ sensor, 570 /* setting name */ "aod_requiring_sensor", 571 /* settingDefault */ true, 572 /* configured */ true, 573 /* pulseReason*/ 0, 574 /* reportsTouchCoordinate*/ false, 575 /* requiresTouchscreen */ false, 576 /* ignoresSetting */ false, 577 /* requiresProx */ false, 578 /* immediatelyReRegister */ true, 579 /* requiresAoD */ true 580 ); 581 } 582 583 /** 584 * Create a doze sensor that supports postures and is enabled 585 */ createDozeSensorForPosture(Sensor[] sensors, int posture)586 public TriggerSensor createDozeSensorForPosture(Sensor[] sensors, int posture) { 587 return new TriggerSensor(/* sensor */ sensors, 588 /* setting name */ "posture_test_setting", 589 /* settingDefault */ true, 590 /* configured */ true, 591 /* pulseReason*/ 0, 592 /* reportsTouchCoordinate*/ false, 593 /* requiresTouchscreen */ false, 594 /* ignoresSetting */ true, 595 /* requiresProx */ false, 596 /* immediatelyReRegister */ true, 597 posture, 598 /* requiresUi */ false 599 ); 600 } 601 addSensor(TriggerSensor sensor)602 public void addSensor(TriggerSensor sensor) { 603 TriggerSensor[] newArray = new TriggerSensor[mTriggerSensors.length + 1]; 604 for (int i = 0; i < mTriggerSensors.length; i++) { 605 newArray[i] = mTriggerSensors[i]; 606 } 607 newArray[mTriggerSensors.length] = sensor; 608 mTriggerSensors = newArray; 609 } 610 } 611 setSensorType(Sensor sensor, int type, String strType)612 public static void setSensorType(Sensor sensor, int type, String strType) throws Exception { 613 Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE); 614 setter.setAccessible(true); 615 setter.invoke(sensor, type); 616 if (strType != null) { 617 Field f = sensor.getClass().getDeclaredField("mStringType"); 618 f.setAccessible(true); 619 f.set(sensor, strType); 620 } 621 } 622 createSensor(int type, String strType)623 public static Sensor createSensor(int type, String strType) throws Exception { 624 Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor(); 625 constr.setAccessible(true); 626 Sensor sensor = constr.newInstance(); 627 setSensorType(sensor, type, strType); 628 return sensor; 629 } 630 } 631