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