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