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