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