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