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