1 /*
2  * Copyright (C) 2008 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 android.hardware.cts;
18 
19 import android.hardware.cts.helpers.sensorverification.ContinuousEventSanitizedVerification;
20 import android.support.test.InstrumentationRegistry;
21 import com.android.compatibility.common.util.SystemUtil;
22 import junit.framework.Assert;
23 
24 import android.content.Context;
25 import android.content.pm.PackageManager;
26 import android.hardware.Sensor;
27 import android.hardware.SensorEvent;
28 import android.hardware.SensorEventListener;
29 import android.hardware.SensorEventListener2;
30 import android.hardware.SensorManager;
31 import android.hardware.TriggerEvent;
32 import android.hardware.TriggerEventListener;
33 import android.hardware.cts.helpers.SensorCtsHelper;
34 import android.hardware.cts.helpers.SensorNotSupportedException;
35 import android.hardware.cts.helpers.SensorTestStateNotSupportedException;
36 import android.hardware.cts.helpers.TestSensorEnvironment;
37 import android.hardware.cts.helpers.TestSensorEventListener;
38 import android.hardware.cts.helpers.TestSensorManager;
39 import android.hardware.cts.helpers.sensoroperations.ParallelSensorOperation;
40 import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
41 import android.hardware.cts.helpers.sensorverification.EventGapVerification;
42 import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
43 import android.hardware.cts.helpers.sensorverification.EventTimestampSynchronizationVerification;
44 import android.os.Handler;
45 import android.os.HandlerThread;
46 import android.os.PowerManager;
47 import android.os.SystemClock;
48 import android.platform.test.annotations.Presubmit;
49 import android.util.Log;
50 
51 import java.io.IOException;
52 import java.util.ArrayList;
53 import java.util.List;
54 import java.util.concurrent.CountDownLatch;
55 import java.util.concurrent.TimeUnit;
56 
57 public class SensorTest extends SensorTestCase {
58     private static final String TAG = "SensorTest";
59 
60     // Test only SDK defined sensors. Any sensors with type > 100 are ignored.
61     private static final int MAX_OFFICIAL_ANDROID_SENSOR_TYPE = 100;
62 
63     private PowerManager.WakeLock mWakeLock;
64     private SensorManager mSensorManager;
65     private TestSensorManager mTestSensorManager;
66     private NullTriggerEventListener mNullTriggerEventListener;
67     private NullSensorEventListener mNullSensorEventListener;
68     private Sensor mTriggerSensor;
69     private List<Sensor> mSensorList;
70     private List<Sensor> mAndroidSensorList;
71 
72     @Override
setUp()73     protected void setUp() throws Exception {
74         Context context = getContext();
75         PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
76         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
77 
78         mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
79         mNullTriggerEventListener = new NullTriggerEventListener();
80         mNullSensorEventListener = new NullSensorEventListener();
81 
82         mSensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
83         assertNotNull("SensorList was null.", mSensorList);
84         if (mSensorList.isEmpty()) {
85             // several devices will not have sensors, so we need to skip the tests in those cases
86             throw new SensorTestStateNotSupportedException(
87                     "Sensors are not available in the system.");
88         }
89 
90         mAndroidSensorList = new ArrayList<>();
91         for (Sensor s : mSensorList) {
92             if (s.getType() < Sensor.TYPE_DEVICE_PRIVATE_BASE) {
93                 mAndroidSensorList.add(s);
94             }
95         }
96 
97         mWakeLock.acquire();
98     }
99 
100     @Override
tearDown()101     protected void tearDown() {
102         if (mSensorManager != null) {
103             // SensorManager will check listener and status, so just unregister listener
104             mSensorManager.unregisterListener(mNullSensorEventListener);
105             if (mTriggerSensor != null) {
106                 mSensorManager.cancelTriggerSensor(mNullTriggerEventListener, mTriggerSensor);
107                 mTriggerSensor = null;
108             }
109         }
110 
111         if (mTestSensorManager != null) {
112             mTestSensorManager.unregisterListener();
113             mTestSensorManager = null;
114         }
115 
116         if (mWakeLock != null && mWakeLock.isHeld()) {
117             mWakeLock.release();
118         }
119     }
120 
121     @SuppressWarnings("deprecation")
testSensorOperations()122     public void testSensorOperations() {
123         // Because we can't know every sensors unit details, so we can't assert
124         // get values with specified values.
125         Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
126         boolean hasAccelerometer = getContext().getPackageManager().hasSystemFeature(
127                 PackageManager.FEATURE_SENSOR_ACCELEROMETER);
128         // accelerometer sensor is optional
129         if (hasAccelerometer) {
130             assertEquals(Sensor.TYPE_ACCELEROMETER, sensor.getType());
131             assertSensorValues(sensor);
132         } else {
133             assertNull(sensor);
134         }
135 
136         sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
137         boolean hasStepCounter = getContext().getPackageManager().hasSystemFeature(
138                 PackageManager.FEATURE_SENSOR_STEP_COUNTER);
139         // stepcounter sensor is optional
140         if (hasStepCounter) {
141             assertEquals(Sensor.TYPE_STEP_COUNTER, sensor.getType());
142             assertSensorValues(sensor);
143         } else {
144             assertNull(sensor);
145         }
146 
147         sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
148         boolean hasStepDetector = getContext().getPackageManager().hasSystemFeature(
149                 PackageManager.FEATURE_SENSOR_STEP_DETECTOR);
150         // stepdetector sensor is optional
151         if (hasStepDetector) {
152             assertEquals(Sensor.TYPE_STEP_DETECTOR, sensor.getType());
153             assertSensorValues(sensor);
154         } else {
155             assertNull(sensor);
156         }
157 
158         sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
159         boolean hasHeartRate = getContext().getPackageManager().hasSystemFeature(
160                 PackageManager.FEATURE_SENSOR_HEART_RATE);
161         // heartrate sensor is optional
162         if (hasHeartRate) {
163             assertEquals(Sensor.TYPE_HEART_RATE, sensor.getType());
164             assertSensorValues(sensor);
165         } else {
166             assertNull(sensor);
167         }
168 
169         sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
170         boolean hasCompass = getContext().getPackageManager().hasSystemFeature(
171                 PackageManager.FEATURE_SENSOR_COMPASS);
172         // compass sensor is optional
173         if (hasCompass) {
174             assertEquals(Sensor.TYPE_MAGNETIC_FIELD, sensor.getType());
175             assertSensorValues(sensor);
176         } else {
177             assertNull(sensor);
178         }
179 
180         sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
181         // Note: orientation sensor is deprecated.
182         if (sensor != null) {
183             assertEquals(Sensor.TYPE_ORIENTATION, sensor.getType());
184             assertSensorValues(sensor);
185         }
186 
187         sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE);
188         // temperature sensor is optional
189         if (sensor != null) {
190             assertEquals(Sensor.TYPE_TEMPERATURE, sensor.getType());
191             assertSensorValues(sensor);
192         }
193     }
194 
testValuesForAllSensors()195     public void testValuesForAllSensors() {
196         for (Sensor sensor : mSensorList) {
197             assertSensorValues(sensor);
198         }
199     }
200 
hasOnlyOneWakeUpSensorOrEmpty(List<Sensor> sensors)201     private void hasOnlyOneWakeUpSensorOrEmpty(List<Sensor> sensors) {
202         if (sensors == null || sensors.isEmpty()) return;
203         if (sensors.size() > 1) {
204             fail("More than one " + sensors.get(0).getName() + " defined.");
205             return;
206         }
207         assertTrue(sensors.get(0).getName() + " defined as non-wake-up sensor",
208                 sensors.get(0).isWakeUpSensor());
209     }
210 
211     // Some sensors like proximity, significant motion etc. are defined as wake-up sensors by
212     // default. Check if the wake-up flag is set correctly.
213     @Presubmit
testWakeUpFlags()214     public void testWakeUpFlags() {
215         final int TYPE_WAKE_GESTURE = 23;
216         final int TYPE_GLANCE_GESTURE = 24;
217         final int TYPE_PICK_UP_GESTURE = 25;
218 
219         hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(Sensor.TYPE_SIGNIFICANT_MOTION));
220         hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_WAKE_GESTURE));
221         hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_GLANCE_GESTURE));
222         hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_PICK_UP_GESTURE));
223 
224         List<Sensor> proximity_sensors = mSensorManager.getSensorList(Sensor.TYPE_PROXIMITY);
225         if (proximity_sensors.isEmpty()) return;
226         boolean hasWakeUpProximitySensor = false;
227         for (Sensor sensor : proximity_sensors) {
228             if (sensor.isWakeUpSensor()) {
229                 hasWakeUpProximitySensor = true;
230                 break;
231             }
232         }
233         assertTrue("No wake-up proximity sensors implemented", hasWakeUpProximitySensor);
234     }
235 
testGetDefaultSensorWithWakeUpFlag()236     public void testGetDefaultSensorWithWakeUpFlag() {
237         // With wake-up flags set to false, the sensor returned should be a non wake-up sensor.
238         for (Sensor sensor : mSensorList) {
239             Sensor curr_sensor = mSensorManager.getDefaultSensor(sensor.getType(), false);
240             if (curr_sensor != null) {
241                 assertFalse("getDefaultSensor wakeup=false returns a wake-up sensor" +
242                         curr_sensor.getName(),
243                         curr_sensor.isWakeUpSensor());
244             }
245 
246             curr_sensor = mSensorManager.getDefaultSensor(sensor.getType(), true);
247             if (curr_sensor != null) {
248                 assertTrue("getDefaultSensor wake-up returns non wake sensor" +
249                         curr_sensor.getName(),
250                         curr_sensor.isWakeUpSensor());
251             }
252         }
253     }
254 
255     @Presubmit
testSensorStringTypes()256     public void testSensorStringTypes() {
257         for (Sensor sensor : mSensorList) {
258             if (sensor.getType() < MAX_OFFICIAL_ANDROID_SENSOR_TYPE &&
259                     !sensor.getStringType().startsWith("android.sensor.")) {
260                 fail("StringType not set correctly for android defined sensor " +
261                         sensor.getName() + " " + sensor.getStringType());
262             }
263         }
264     }
265 
testRequestTriggerWithNonTriggerSensor()266     public void testRequestTriggerWithNonTriggerSensor() {
267         mTriggerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
268         if (mTriggerSensor == null) {
269             throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER);
270         }
271         boolean  result =
272             mSensorManager.requestTriggerSensor(mNullTriggerEventListener, mTriggerSensor);
273         assertFalse(result);
274     }
275 
testCancelTriggerWithNonTriggerSensor()276     public void testCancelTriggerWithNonTriggerSensor() {
277         mTriggerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
278         if (mTriggerSensor == null) {
279             throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER);
280         }
281         boolean result =
282             mSensorManager.cancelTriggerSensor(mNullTriggerEventListener, mTriggerSensor);
283         assertFalse(result);
284     }
285 
testRegisterWithTriggerSensor()286     public void testRegisterWithTriggerSensor() {
287         Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
288         if (sensor == null) {
289             throw new SensorNotSupportedException(Sensor.TYPE_SIGNIFICANT_MOTION);
290         }
291         boolean result = mSensorManager.registerListener(
292                 mNullSensorEventListener,
293                 sensor,
294                 SensorManager.SENSOR_DELAY_NORMAL);
295         assertFalse(result);
296     }
297 
testRegisterTwiceWithSameSensor()298     public void testRegisterTwiceWithSameSensor() {
299         Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
300         if (sensor == null) {
301             throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER);
302         }
303 
304         boolean result = mSensorManager.registerListener(mNullSensorEventListener, sensor,
305                 SensorManager.SENSOR_DELAY_NORMAL);
306         assertTrue(result);
307 
308         result = mSensorManager.registerListener(mNullSensorEventListener, sensor,
309                 SensorManager.SENSOR_DELAY_NORMAL);
310         assertFalse(result);
311     }
312 
313     /**
314      * Verifies that if the UID is idle the continuous events are being reported
315      * but sanitized - all events are the same as the first one delivered except
316      * for their timestamps. From the point of view of an idle app these events are
317      * being properly generated but the sensor reading does not change - privacy.
318      */
319     // TODO: remove when parametrized tests are supported and EventTimestampSynchronization
testSanitizedContinuousEventsUidIdle()320     public void testSanitizedContinuousEventsUidIdle() throws Exception {
321         ArrayList<Throwable> errorsFound = new ArrayList<>();
322         for (Sensor sensor : mAndroidSensorList) {
323             // If the UID is active no sanitization should be performed
324             verifyLongActivation(sensor, 0 /* maxReportLatencyUs */,
325                     5 /* duration */, TimeUnit.SECONDS, "continuous event",
326                     false /* sanitized */, errorsFound);
327             verifyLongActivation(sensor, (int) TimeUnit.SECONDS.toMicros(10),
328                     5 /* duration */, TimeUnit.SECONDS, "continuous event",
329                     false /* sanitized */, errorsFound);
330 
331             // If the UID is idle sanitization should be performed
332             makeMyPackageIdle();
333             try {
334                 verifyLongActivation(sensor, 0 /* maxReportLatencyUs */,
335                         5 /* duration */, TimeUnit.SECONDS, "continuous event",
336                         true /* sanitized */, errorsFound);
337                 verifyLongActivation(sensor, (int) TimeUnit.SECONDS.toMicros(10),
338                         5 /* duration */, TimeUnit.SECONDS, "continuous event",
339                         true /* sanitized */, errorsFound);
340             } finally {
341                 makeMyPackageActive();
342             }
343 
344             // If the UID is active no sanitization should be performed
345             verifyLongActivation(sensor, 0 /* maxReportLatencyUs */,
346                     5 /* duration */, TimeUnit.SECONDS, "continuous event",
347                     false /* sanitized */, errorsFound);
348             verifyLongActivation(sensor, (int) TimeUnit.SECONDS.toMicros(10),
349                     5 /* duration */, TimeUnit.SECONDS, "continuous event",
350                     false /* sanitized */, errorsFound);
351         }
352         assertOnErrors(errorsFound);
353     }
354 
355     // TODO: remove when parametrized tests are supported and EventTimestampSynchronization
356     //       verification is added to default verifications
testSensorTimeStamps()357     public void testSensorTimeStamps() throws Exception {
358         ArrayList<Throwable> errorsFound = new ArrayList<>();
359         for (Sensor sensor : mAndroidSensorList) {
360             // test both continuous and batching mode sensors
361             verifyLongActivation(sensor, 0 /* maxReportLatencyUs */,
362                     20 /* duration */, TimeUnit.SECONDS, "timestamp", false
363                     /* sanitized */, errorsFound);
364             verifyLongActivation(sensor, (int) TimeUnit.SECONDS.toMicros(10),
365                     20 /* duration */, TimeUnit.SECONDS, "timestamp",
366                     false /* sanitized */, errorsFound);
367         }
368         assertOnErrors(errorsFound);
369     }
370 
371     // TODO: remove when parameterized tests are supported (see SensorBatchingTests.java)
testBatchAndFlush()372     public void testBatchAndFlush() throws Exception {
373         SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
374         ArrayList<Throwable> errorsFound = new ArrayList<>();
375         for (Sensor sensor : mAndroidSensorList) {
376             verifyRegisterListenerCallFlush(sensor, null /* handler */, errorsFound,
377                     false /* flushWhileIdle */);
378         }
379         assertOnErrors(errorsFound);
380     }
381 
382     /**
383      * Verifies that if the UID is idle flush events are reported. Since
384      * these events have no payload with private data they are working as
385      * for a non-idle UID.
386      */
387     // TODO: remove when parametized tests are supported and EventTimestampSynchronization
testBatchAndFlushUidIdle()388     public void testBatchAndFlushUidIdle() throws Exception {
389         SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
390         ArrayList<Throwable> errorsFound = new ArrayList<>();
391         for (Sensor sensor : mAndroidSensorList) {
392             verifyRegisterListenerCallFlush(sensor, null /* handler */, errorsFound,
393                     true /* flushWhileIdle */);
394         }
395         assertOnErrors(errorsFound);
396     }
397 
398     /**
399      * Verifies that sensor events arrive in the given message queue (Handler).
400      */
testBatchAndFlushWithHandler()401     public void testBatchAndFlushWithHandler() throws Exception {
402         SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
403         Sensor sensor = null;
404         for (Sensor s : mAndroidSensorList) {
405             if (s.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) {
406                 sensor = s;
407                 break;
408             }
409         }
410         if (sensor == null) {
411             throw new SensorTestStateNotSupportedException(
412                     "There are no Continuous sensors in the device.");
413         }
414 
415         TestSensorEnvironment environment = new TestSensorEnvironment(
416                 getContext(),
417                 sensor,
418                 SensorManager.SENSOR_DELAY_FASTEST,
419                 (int) TimeUnit.SECONDS.toMicros(5));
420         mTestSensorManager = new TestSensorManager(environment);
421 
422         HandlerThread handlerThread = new HandlerThread("sensorThread");
423         handlerThread.start();
424         Handler handler = new Handler(handlerThread.getLooper());
425         TestSensorEventListener listener = new TestSensorEventListener(environment, handler);
426 
427         CountDownLatch eventLatch = mTestSensorManager.registerListener(listener, 1);
428         listener.waitForEvents(eventLatch, 1, true);
429         CountDownLatch flushLatch = mTestSensorManager.requestFlush();
430         listener.waitForFlushComplete(flushLatch, true);
431         listener.assertEventsReceivedInHandler();
432     }
433 
434     /**
435      *  Explicit testing the SensorManager.registerListener(SensorEventListener, Sensor, int, int).
436      */
testBatchAndFlushUseDefaultHandler()437     public void testBatchAndFlushUseDefaultHandler() throws Exception {
438         SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
439         Sensor sensor = null;
440         for (Sensor s : mAndroidSensorList) {
441             if (s.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) {
442                 sensor = s;
443                 break;
444             }
445         }
446         if (sensor == null) {
447             throw new SensorTestStateNotSupportedException(
448                     "There are no Continuous sensors in the device.");
449         }
450 
451         TestSensorEnvironment environment = new TestSensorEnvironment(
452                 getContext(),
453                 sensor,
454                 SensorManager.SENSOR_DELAY_FASTEST,
455                 (int) TimeUnit.SECONDS.toMicros(5));
456         mTestSensorManager = new TestSensorManager(environment);
457 
458         TestSensorEventListener listener = new TestSensorEventListener(environment, null);
459 
460         // specifyHandler <= false, use the SensorManager API without Handler parameter
461         CountDownLatch eventLatch = mTestSensorManager.registerListener(listener, 1, false);
462         listener.waitForEvents(eventLatch, 1, true);
463         CountDownLatch flushLatch = mTestSensorManager.requestFlush();
464         listener.waitForFlushComplete(flushLatch, true);
465         listener.assertEventsReceivedInHandler();
466     }
467 
468     // TODO: after L release move to SensorBatchingTests and run in all sensors with default
469     //       verifications enabled
testBatchAndFlushWithMultipleSensors()470     public void testBatchAndFlushWithMultipleSensors() throws Exception {
471         SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
472         final int maxSensors = 3;
473         final int maxReportLatencyUs = (int) TimeUnit.SECONDS.toMicros(10);
474         List<Sensor> sensorsToTest = new ArrayList<Sensor>();
475         for (Sensor sensor : mAndroidSensorList) {
476             if (sensor.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) {
477                 sensorsToTest.add(sensor);
478                 if (sensorsToTest.size()  == maxSensors) break;
479             }
480         }
481         final int numSensorsToTest = sensorsToTest.size();
482         if (numSensorsToTest == 0) {
483             return;
484         }
485 
486         StringBuilder builder = new StringBuilder();
487         ParallelSensorOperation parallelSensorOperation = new ParallelSensorOperation();
488         for (Sensor sensor : sensorsToTest) {
489             TestSensorEnvironment environment = new TestSensorEnvironment(
490                     getContext(),
491                     sensor,
492                     shouldEmulateSensorUnderLoad(),
493                     SensorManager.SENSOR_DELAY_FASTEST,
494                     maxReportLatencyUs);
495             FlushExecutor executor = new FlushExecutor(environment, 500 /* eventCount */,
496                     false /* flushWhileIdle */);
497             parallelSensorOperation.add(new TestSensorOperation(environment, executor));
498             builder.append(sensor.getName()).append(", ");
499         }
500 
501         Log.i(TAG, "Testing batch/flush for sensors: " + builder);
502         parallelSensorOperation.execute(getCurrentTestNode());
503     }
504 
assertSensorValues(Sensor sensor)505     private void assertSensorValues(Sensor sensor) {
506         assertTrue("Max range must be positive. Range=" + sensor.getMaximumRange()
507                 + " " + sensor.getName(), sensor.getMaximumRange() >= 0);
508         assertTrue("Max power must be positive. Power=" + sensor.getPower() + " " +
509                 sensor.getName(), sensor.getPower() >= 0);
510         assertTrue("Max resolution must be positive. Resolution=" + sensor.getResolution() +
511                 " " + sensor.getName(), sensor.getResolution() >= 0);
512         assertNotNull("Vendor name must not be null " + sensor.getName(), sensor.getVendor());
513         assertTrue("Version must be positive version=" + sensor.getVersion() + " " +
514                 sensor.getName(), sensor.getVersion() > 0);
515         int fifoMaxEventCount = sensor.getFifoMaxEventCount();
516         int fifoReservedEventCount = sensor.getFifoReservedEventCount();
517         assertTrue(fifoMaxEventCount >= 0);
518         assertTrue(fifoReservedEventCount >= 0);
519         assertTrue(fifoReservedEventCount <= fifoMaxEventCount);
520         if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
521             assertTrue("One shot sensors should have zero FIFO Size " + sensor.getName(),
522                     sensor.getFifoMaxEventCount() == 0);
523             assertTrue("One shot sensors should have zero FIFO Size "  + sensor.getName(),
524                     sensor.getFifoReservedEventCount() == 0);
525         }
526     }
527 
528     @SuppressWarnings("deprecation")
testLegacySensorOperations()529     public void testLegacySensorOperations() {
530         final SensorManager mSensorManager =
531                 (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
532 
533         // We expect the set of sensors reported by the new and legacy APIs to be consistent.
534         int sensors = 0;
535         if (mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
536             sensors |= SensorManager.SENSOR_ACCELEROMETER;
537         }
538         if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null) {
539             sensors |= SensorManager.SENSOR_MAGNETIC_FIELD;
540         }
541         if (mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION) != null) {
542             sensors |= SensorManager.SENSOR_ORIENTATION | SensorManager.SENSOR_ORIENTATION_RAW;
543         }
544         assertEquals(sensors, mSensorManager.getSensors());
545     }
546 
547     /**
548      * Verifies that a continuous sensor produces events that have timestamps synchronized with
549      * {@link SystemClock#elapsedRealtimeNanos()} and that the events are sanitized/non-sanitized.
550      */
verifyLongActivation( Sensor sensor, int maxReportLatencyUs, long duration, TimeUnit durationTimeUnit, String testType, boolean sanitized, ArrayList<Throwable> errorsFound)551     private void verifyLongActivation(
552             Sensor sensor,
553             int maxReportLatencyUs,
554             long duration,
555             TimeUnit durationTimeUnit,
556             String testType,
557             boolean sanitized,
558             ArrayList<Throwable> errorsFound) throws InterruptedException {
559         if (sensor.getReportingMode() != Sensor.REPORTING_MODE_CONTINUOUS) {
560             return;
561         }
562 
563         try {
564             TestSensorEnvironment environment = new TestSensorEnvironment(
565                     getContext(),
566                     sensor,
567                     shouldEmulateSensorUnderLoad(),
568                     SensorManager.SENSOR_DELAY_FASTEST,
569                     maxReportLatencyUs);
570             TestSensorOperation operation = TestSensorOperation.createOperation(
571                     environment, duration, durationTimeUnit);
572             if (sanitized) {
573                 final long verificationDelayNano = TimeUnit.NANOSECONDS.convert(
574                         maxReportLatencyUs, TimeUnit.MICROSECONDS) * 2;
575                 operation.addVerification(ContinuousEventSanitizedVerification
576                         .getDefault(environment, verificationDelayNano));
577             } else {
578                 operation.addVerification(EventGapVerification.getDefault(environment));
579                 operation.addVerification(EventOrderingVerification.getDefault(environment));
580                 operation.addVerification(EventTimestampSynchronizationVerification
581                         .getDefault(environment));
582             }
583             Log.i(TAG, "Running " + testType + " test on: " + sensor.getName());
584             operation.execute(getCurrentTestNode());
585         } catch (InterruptedException e) {
586             // propagate so the test can stop
587             throw e;
588         } catch (Throwable e) {
589             errorsFound.add(e);
590             Log.e(TAG, e.getMessage());
591         }
592     }
593 
594     /**
595      * Verifies that a client can listen for events, and that
596      * {@link SensorManager#flush(SensorEventListener)} will trigger the appropriate notification
597      * for {@link SensorEventListener2#onFlushCompleted(Sensor)}.
598      */
verifyRegisterListenerCallFlush( Sensor sensor, Handler handler, ArrayList<Throwable> errorsFound, boolean flushWhileIdle)599     private void verifyRegisterListenerCallFlush(
600             Sensor sensor,
601             Handler handler,
602             ArrayList<Throwable> errorsFound,
603             boolean flushWhileIdle)
604             throws InterruptedException {
605         if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
606             return;
607         }
608 
609         try {
610             TestSensorEnvironment environment = new TestSensorEnvironment(
611                     getContext(),
612                     sensor,
613                     shouldEmulateSensorUnderLoad(),
614                     SensorManager.SENSOR_DELAY_FASTEST,
615                     (int) TimeUnit.SECONDS.toMicros(10));
616             FlushExecutor executor = new FlushExecutor(environment, 500 /* eventCount */,
617                     flushWhileIdle);
618             TestSensorOperation operation = new TestSensorOperation(environment, executor, handler);
619 
620             Log.i(TAG, "Running flush test on: " + sensor.getName());
621             operation.execute(getCurrentTestNode());
622         } catch (InterruptedException e) {
623             // propagate so the test can stop
624             throw e;
625         } catch (Throwable e) {
626             errorsFound.add(e);
627             Log.e(TAG, e.getMessage());
628         }
629     }
630 
assertOnErrors(List<Throwable> errorsFound)631     private void assertOnErrors(List<Throwable> errorsFound) {
632         if (!errorsFound.isEmpty()) {
633             StringBuilder builder = new StringBuilder();
634             for (Throwable error : errorsFound) {
635                 builder.append(error.getMessage()).append("\n");
636             }
637             Assert.fail(builder.toString());
638         }
639     }
640 
makeMyPackageActive()641     private static void makeMyPackageActive() throws IOException {
642         final String command = "cmd sensorservice reset-uid-state "
643                 +  InstrumentationRegistry.getTargetContext().getPackageName();
644         SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
645     }
646 
makeMyPackageIdle()647     private void makeMyPackageIdle() throws IOException {
648         final String command = "cmd sensorservice set-uid-state "
649                 + InstrumentationRegistry.getTargetContext().getPackageName() + " idle";
650         SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
651     }
652 
653     /**
654      * A delegate that drives the execution of Batch/Flush tests.
655      * It performs several operations in order:
656      * - registration
657      * - for continuous sensors it first ensures that the FIFO is filled
658      *      - if events do not arrive on time, an assert will be triggered
659      * - requests flush of sensor data
660      * - waits for {@link SensorEventListener2#onFlushCompleted(Sensor)}
661      *      - if the event does not arrive, an assert will be triggered
662      */
663     private class FlushExecutor implements TestSensorOperation.Executor {
664         private final TestSensorEnvironment mEnvironment;
665         private final int mEventCount;
666         private final boolean mFlushWhileIdle;
667 
FlushExecutor(TestSensorEnvironment environment, int eventCount, boolean flushWhileIdle)668         public FlushExecutor(TestSensorEnvironment environment, int eventCount,
669                 boolean flushWhileIdle) {
670             mEnvironment = environment;
671             mEventCount = eventCount;
672             mFlushWhileIdle = flushWhileIdle;
673         }
674 
675         /**
676          * Consider only continuous mode sensors for testing register listener.
677          *
678          * For on-change sensors, we only use
679          * {@link TestSensorManager#registerListener(TestSensorEventListener)} to associate the
680          * listener with the sensor. So that {@link TestSensorManager#requestFlush()} can be
681          * invoked on it.
682          */
683         @Override
execute(TestSensorManager sensorManager, TestSensorEventListener listener)684         public void execute(TestSensorManager sensorManager, TestSensorEventListener listener)
685                 throws Exception {
686             int sensorReportingMode = mEnvironment.getSensor().getReportingMode();
687             try {
688                 CountDownLatch eventLatch = sensorManager.registerListener(listener, mEventCount);
689                 if (sensorReportingMode == Sensor.REPORTING_MODE_CONTINUOUS) {
690                     listener.waitForEvents(eventLatch, mEventCount, true);
691                 }
692                 if (mFlushWhileIdle) {
693                     makeMyPackageIdle();
694                 }
695                 CountDownLatch flushLatch = sensorManager.requestFlush();
696                 listener.waitForFlushComplete(flushLatch, true);
697             } finally {
698                 sensorManager.unregisterListener();
699                 if (mFlushWhileIdle) {
700                     makeMyPackageActive();
701                 }
702             }
703         }
704     }
705 
706     private class NullTriggerEventListener extends TriggerEventListener {
707         @Override
onTrigger(TriggerEvent event)708         public void onTrigger(TriggerEvent event) {}
709     }
710 
711     private class NullSensorEventListener implements SensorEventListener {
712         @Override
onSensorChanged(SensorEvent event)713         public void onSensorChanged(SensorEvent event) {}
714 
715         @Override
onAccuracyChanged(Sensor sensor, int accuracy)716         public void onAccuracyChanged(Sensor sensor, int accuracy) {}
717     }
718 
719 }
720