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