1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.hardware.cts; 18 19 import android.content.Context; 20 import android.content.pm.PackageManager; 21 import android.hardware.Sensor; 22 import android.hardware.SensorEvent; 23 import android.hardware.SensorEventListener; 24 import android.hardware.SensorEventListener2; 25 import android.hardware.SensorManager; 26 import android.hardware.TriggerEvent; 27 import android.hardware.TriggerEventListener; 28 import android.hardware.cts.helpers.SensorCtsHelper; 29 import android.hardware.cts.helpers.SensorNotSupportedException; 30 import android.hardware.cts.helpers.SensorTestStateNotSupportedException; 31 import android.hardware.cts.helpers.TestSensorEnvironment; 32 import android.hardware.cts.helpers.TestSensorEventListener; 33 import android.hardware.cts.helpers.TestSensorManager; 34 import android.hardware.cts.helpers.sensoroperations.ParallelSensorOperation; 35 import android.hardware.cts.helpers.sensoroperations.TestSensorOperation; 36 import android.hardware.cts.helpers.sensorverification.ContinuousEventSanitizedVerification; 37 import android.hardware.cts.helpers.sensorverification.EventGapVerification; 38 import android.hardware.cts.helpers.sensorverification.EventOrderingVerification; 39 import android.hardware.cts.helpers.sensorverification.EventTimestampSynchronizationVerification; 40 import android.os.Build.VERSION_CODES; 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.AppModeFull; 46 import android.platform.test.annotations.Presubmit; 47 import android.util.Log; 48 49 import com.android.compatibility.common.util.CddTest; 50 import com.android.compatibility.common.util.PropertyUtil; 51 52 import com.google.common.collect.ArrayListMultimap; 53 import com.google.common.collect.Multimap; 54 55 import junit.framework.Assert; 56 57 import java.util.ArrayList; 58 import java.util.List; 59 import java.util.concurrent.CountDownLatch; 60 import java.util.concurrent.TimeUnit; 61 62 public class SensorTest extends SensorTestCase { 63 private static final String TAG = "SensorTest"; 64 65 // Test only SDK defined sensors. Any sensors with type > 100 are ignored. 66 private static final int MAX_OFFICIAL_ANDROID_SENSOR_TYPE = 100; 67 68 private PowerManager.WakeLock mWakeLock; 69 private SensorManager mSensorManager; 70 private TestSensorManager mTestSensorManager; 71 private NullTriggerEventListener mNullTriggerEventListener; 72 private NullSensorEventListener mNullSensorEventListener; 73 private Sensor mTriggerSensor; 74 private List<Sensor> mSensorList; 75 private List<Sensor> mAndroidSensorList; 76 77 @Override setUp()78 protected void setUp() throws Exception { 79 Context context = getContext(); 80 PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 81 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 82 83 mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 84 mNullTriggerEventListener = new NullTriggerEventListener(); 85 mNullSensorEventListener = new NullSensorEventListener(); 86 87 mSensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL); 88 assertNotNull("SensorList was null.", mSensorList); 89 if (mSensorList.isEmpty()) { 90 // several devices will not have sensors, so we need to skip the tests in those cases 91 throw new SensorTestStateNotSupportedException( 92 "Sensors are not available in the system."); 93 } 94 95 mAndroidSensorList = new ArrayList<>(); 96 for (Sensor s : mSensorList) { 97 if (s.getType() < Sensor.TYPE_DEVICE_PRIVATE_BASE && 98 (!context.getPackageManager().isInstantApp() || s.getType() != Sensor.TYPE_HEART_RATE)) { 99 mAndroidSensorList.add(s); 100 } 101 } 102 103 mWakeLock.acquire(); 104 } 105 106 @Override tearDown()107 protected void tearDown() { 108 if (mSensorManager != null) { 109 // SensorManager will check listener and status, so just unregister listener 110 mSensorManager.unregisterListener(mNullSensorEventListener); 111 if (mTriggerSensor != null) { 112 mSensorManager.cancelTriggerSensor(mNullTriggerEventListener, mTriggerSensor); 113 mTriggerSensor = null; 114 } 115 } 116 117 if (mTestSensorManager != null) { 118 mTestSensorManager.unregisterListener(); 119 mTestSensorManager = null; 120 } 121 122 if (mWakeLock != null && mWakeLock.isHeld()) { 123 mWakeLock.release(); 124 } 125 } 126 127 /** 128 * testSensorOperations 129 * 130 * Because we can't know every sensors unit details, so we can't assert 131 * get values with specified values. 132 */ 133 @CddTest(requirement = "7.3.1/C-2-1") testSensorOperations_accelerometer()134 public void testSensorOperations_accelerometer() { 135 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 136 boolean hasAccelerometer = getContext().getPackageManager().hasSystemFeature( 137 PackageManager.FEATURE_SENSOR_ACCELEROMETER); 138 // accelerometer sensor is optional 139 if (hasAccelerometer) { 140 assertNotNull(sensor); 141 assertEquals(Sensor.TYPE_ACCELEROMETER, sensor.getType()); 142 assertSensorValues(sensor); 143 } else { 144 assertNull(sensor); 145 } 146 } 147 testSensorOperations_stepCounter()148 public void testSensorOperations_stepCounter() { 149 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER); 150 boolean hasStepCounter = getContext().getPackageManager().hasSystemFeature( 151 PackageManager.FEATURE_SENSOR_STEP_COUNTER); 152 // stepcounter sensor is optional 153 if (hasStepCounter) { 154 assertNotNull(sensor); 155 assertEquals(Sensor.TYPE_STEP_COUNTER, sensor.getType()); 156 assertSensorValues(sensor); 157 } else { 158 assertNull(sensor); 159 } 160 } 161 testSensorOperations_stepDetector()162 public void testSensorOperations_stepDetector() { 163 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR); 164 boolean hasStepDetector = getContext().getPackageManager().hasSystemFeature( 165 PackageManager.FEATURE_SENSOR_STEP_DETECTOR); 166 // stepdetector sensor is optional 167 if (hasStepDetector) { 168 assertNotNull(sensor); 169 assertEquals(Sensor.TYPE_STEP_DETECTOR, sensor.getType()); 170 assertSensorValues(sensor); 171 } else { 172 assertNull(sensor); 173 } 174 } 175 testSensorOperations_magneticField()176 public void testSensorOperations_magneticField() { 177 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); 178 boolean hasCompass = getContext().getPackageManager().hasSystemFeature( 179 PackageManager.FEATURE_SENSOR_COMPASS); 180 // compass sensor is optional 181 if (hasCompass) { 182 assertNotNull(sensor); 183 assertEquals(Sensor.TYPE_MAGNETIC_FIELD, sensor.getType()); 184 assertSensorValues(sensor); 185 } else { 186 assertNull(sensor); 187 } 188 } 189 190 @CddTest(requirement = "7.3.4/C-2-1") testSensorOperations_gyroscope()191 public void testSensorOperations_gyroscope() { 192 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); 193 boolean hasGyroscope = getContext().getPackageManager().hasSystemFeature( 194 PackageManager.FEATURE_SENSOR_GYROSCOPE); 195 // gyroscope sensor is optional 196 if (hasGyroscope) { 197 assertNotNull(sensor); 198 assertEquals(Sensor.TYPE_GYROSCOPE, sensor.getType()); 199 assertSensorValues(sensor); 200 } else { 201 assertNull(sensor); 202 } 203 } 204 testSensorOperations_pressure()205 public void testSensorOperations_pressure() { 206 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); 207 boolean hasPressure = getContext().getPackageManager().hasSystemFeature( 208 PackageManager.FEATURE_SENSOR_BAROMETER); 209 // pressure sensor is optional 210 if (hasPressure) { 211 assertNotNull(sensor); 212 assertEquals(Sensor.TYPE_PRESSURE, sensor.getType()); 213 assertSensorValues(sensor); 214 } else { 215 assertNull(sensor); 216 } 217 } 218 219 @SuppressWarnings("deprecation") testSensorOperations_orientation()220 public void testSensorOperations_orientation() { 221 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); 222 // Note: orientation sensor is deprecated. 223 if (sensor != null) { 224 assertEquals(Sensor.TYPE_ORIENTATION, sensor.getType()); 225 assertSensorValues(sensor); 226 } 227 } 228 229 @SuppressWarnings("deprecation") testSensorOperations_temperature()230 public void testSensorOperations_temperature() { 231 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE); 232 // temperature sensor is optional 233 if (sensor != null) { 234 assertEquals(Sensor.TYPE_TEMPERATURE, sensor.getType()); 235 assertSensorValues(sensor); 236 } 237 } 238 testSensorOperations_hingeAngle()239 public void testSensorOperations_hingeAngle() { 240 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HINGE_ANGLE); 241 boolean hasHingeAngle = getContext().getPackageManager().hasSystemFeature( 242 PackageManager.FEATURE_SENSOR_HINGE_ANGLE); 243 244 if (hasHingeAngle) { 245 assertNotNull(sensor); 246 assertEquals(Sensor.TYPE_HINGE_ANGLE, sensor.getType()); 247 assertSensorValues(sensor); 248 assertTrue("Max range must not be larger than 360. Range=" + sensor.getMaximumRange() 249 + " " + sensor.getName(), sensor.getMaximumRange() <= 360); 250 } else { 251 assertNull(sensor); 252 } 253 } 254 255 @CddTest(requirement = "7.3.1/C-3-1") testSensorOperations_accelerometerLimitedAxes()256 public void testSensorOperations_accelerometerLimitedAxes() { 257 validateLimitedAxesImuSensorType(Sensor.TYPE_ACCELEROMETER_LIMITED_AXES, 258 PackageManager.FEATURE_SENSOR_ACCELEROMETER_LIMITED_AXES); 259 } 260 testSensorOperations_gyroscopeLimitedAxes()261 public void testSensorOperations_gyroscopeLimitedAxes() { 262 validateLimitedAxesImuSensorType(Sensor.TYPE_GYROSCOPE_LIMITED_AXES, 263 PackageManager.FEATURE_SENSOR_GYROSCOPE_LIMITED_AXES); 264 } 265 266 @CddTest(requirement = "7.3.4/C-3-1") testSensorOperations_accelerometerLimitedAxesUncalibrated()267 public void testSensorOperations_accelerometerLimitedAxesUncalibrated() { 268 validateLimitedAxesImuSensorType(Sensor.TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED, 269 PackageManager.FEATURE_SENSOR_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED); 270 } 271 testSensorOperations_gyroscopeLimitedAxesUncalibrated()272 public void testSensorOperations_gyroscopeLimitedAxesUncalibrated() { 273 validateLimitedAxesImuSensorType(Sensor.TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED, 274 PackageManager.FEATURE_SENSOR_GYROSCOPE_LIMITED_AXES_UNCALIBRATED); 275 } 276 validateLimitedAxesImuSensorType(int sensorType, String systemFeature)277 private void validateLimitedAxesImuSensorType(int sensorType, String systemFeature) { 278 Sensor sensor = mSensorManager.getDefaultSensor(sensorType); 279 boolean hasSensorFeature = getContext().getPackageManager().hasSystemFeature(systemFeature); 280 if (hasSensorFeature) { 281 assertNotNull(sensor); 282 assertEquals(sensorType, sensor.getType()); 283 assertSensorValues(sensor); 284 } else { 285 assertNull(sensor); 286 } 287 } 288 testSensorOperations_heading()289 public void testSensorOperations_heading() { 290 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HEADING); 291 boolean hasHeadingSensor = getContext().getPackageManager().hasSystemFeature( 292 PackageManager.FEATURE_SENSOR_HEADING); 293 boolean isAutomotive = mContext.getPackageManager().hasSystemFeature( 294 PackageManager.FEATURE_AUTOMOTIVE); 295 if (isAutomotive && hasHeadingSensor) { 296 assertNotNull(sensor); 297 assertEquals(Sensor.TYPE_HEADING, sensor.getType()); 298 assertSensorValues(sensor); 299 assertTrue("Max range must not be greater or equal to 360. Range=" 300 + sensor.getMaximumRange() + " " + sensor.getName(), 301 sensor.getMaximumRange() < 360); 302 } else if (isAutomotive) { 303 assertNull(sensor); 304 } else { 305 // There isn't good test coverage for heading, particularly for non-automotive devices. 306 // So if a non-automotive device wants to implement this, requirements for the sensor 307 // and how to test for those requirements should be re-discussed. 308 assertNull("If the heading sensor is being implemented on a non-automotive device, " 309 + "the team would love to hear from you. Please reach out!", sensor); 310 } 311 } 312 313 @AppModeFull(reason = "Instant apps cannot access body sensors") testBodySensorOperations()314 public void testBodySensorOperations() { 315 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE); 316 boolean hasHeartRate = getContext().getPackageManager().hasSystemFeature( 317 PackageManager.FEATURE_SENSOR_HEART_RATE); 318 // heartrate sensor is optional 319 if (hasHeartRate) { 320 assertEquals(Sensor.TYPE_HEART_RATE, sensor.getType()); 321 assertSensorValues(sensor); 322 } else { 323 assertNull(sensor); 324 } 325 } 326 assertAllSensorsNameUniqueness()327 private void assertAllSensorsNameUniqueness() { 328 Multimap<Integer, String> sensorTypeNameMap = ArrayListMultimap.create(); 329 330 for (Sensor sensor : mSensorList) { 331 assertFalse("Duplicate sensor name " + sensor.getName() + " for type " + sensor.getType(), 332 sensorTypeNameMap.containsEntry(sensor.getType(), sensor.getName())); 333 sensorTypeNameMap.put(sensor.getType(), sensor.getName()); 334 } 335 } 336 testValuesForAllSensors()337 public void testValuesForAllSensors() { 338 for (Sensor sensor : mSensorList) { 339 assertSensorValues(sensor); 340 } 341 assertAllSensorsNameUniqueness(); 342 } 343 hasOnlyOneWakeUpSensorOrEmpty(List<Sensor> sensors)344 private void hasOnlyOneWakeUpSensorOrEmpty(List<Sensor> sensors) { 345 if (sensors == null || sensors.isEmpty()) return; 346 if (sensors.size() > 1) { 347 fail("More than one " + sensors.get(0).getName() + " defined."); 348 return; 349 } 350 assertTrue(sensors.get(0).getName() + " defined as non-wake-up sensor", 351 sensors.get(0).isWakeUpSensor()); 352 } 353 hasDefaultWakeupSensorOrEmpty(int sensorType, String sensorName)354 private void hasDefaultWakeupSensorOrEmpty(int sensorType, String sensorName) { 355 Sensor sensor = mSensorManager.getDefaultSensor(sensorType); 356 if (sensor == null) return; 357 358 assertTrue("Default " + sensorName + " sensor is not a wake-up sensor", sensor.isWakeUpSensor()); 359 } 360 361 // Some sensors like proximity, significant motion etc. are defined as wake-up sensors by 362 // default. Check if the wake-up flag is set correctly. 363 @Presubmit testWakeUpFlags()364 public void testWakeUpFlags() { 365 final int TYPE_WAKE_GESTURE = 23; 366 final int TYPE_GLANCE_GESTURE = 24; 367 final int TYPE_PICK_UP_GESTURE = 25; 368 369 hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(Sensor.TYPE_SIGNIFICANT_MOTION)); 370 hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_WAKE_GESTURE)); 371 hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_GLANCE_GESTURE)); 372 hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_PICK_UP_GESTURE)); 373 374 hasDefaultWakeupSensorOrEmpty(Sensor.TYPE_PROXIMITY, "proximity"); 375 hasDefaultWakeupSensorOrEmpty(Sensor.TYPE_HINGE_ANGLE, "hinge"); 376 } 377 testGetDefaultSensorWithWakeUpFlag()378 public void testGetDefaultSensorWithWakeUpFlag() { 379 // With wake-up flags set to false, the sensor returned should be a non wake-up sensor. 380 for (Sensor sensor : mSensorList) { 381 Sensor curr_sensor = mSensorManager.getDefaultSensor(sensor.getType(), false); 382 if (curr_sensor != null) { 383 assertFalse("getDefaultSensor wakeup=false returns a wake-up sensor" + 384 curr_sensor.getName(), 385 curr_sensor.isWakeUpSensor()); 386 } 387 388 curr_sensor = mSensorManager.getDefaultSensor(sensor.getType(), true); 389 if (curr_sensor != null) { 390 assertTrue("getDefaultSensor wake-up returns non wake sensor" + 391 curr_sensor.getName(), 392 curr_sensor.isWakeUpSensor()); 393 } 394 } 395 } 396 397 @Presubmit testSensorStringTypes()398 public void testSensorStringTypes() { 399 for (Sensor sensor : mSensorList) { 400 if (sensor.getType() < MAX_OFFICIAL_ANDROID_SENSOR_TYPE && 401 !sensor.getStringType().startsWith("android.sensor.")) { 402 fail("StringType not set correctly for android defined sensor " + 403 sensor.getName() + " " + sensor.getStringType()); 404 } 405 } 406 } 407 testRequestTriggerWithNonTriggerSensor()408 public void testRequestTriggerWithNonTriggerSensor() { 409 mTriggerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 410 if (mTriggerSensor == null) { 411 throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER); 412 } 413 boolean result = 414 mSensorManager.requestTriggerSensor(mNullTriggerEventListener, mTriggerSensor); 415 assertFalse(result); 416 } 417 testCancelTriggerWithNonTriggerSensor()418 public void testCancelTriggerWithNonTriggerSensor() { 419 mTriggerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 420 if (mTriggerSensor == null) { 421 throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER); 422 } 423 boolean result = 424 mSensorManager.cancelTriggerSensor(mNullTriggerEventListener, mTriggerSensor); 425 assertFalse(result); 426 } 427 testRegisterWithTriggerSensor()428 public void testRegisterWithTriggerSensor() { 429 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION); 430 if (sensor == null) { 431 throw new SensorNotSupportedException(Sensor.TYPE_SIGNIFICANT_MOTION); 432 } 433 boolean result = mSensorManager.registerListener( 434 mNullSensorEventListener, 435 sensor, 436 SensorManager.SENSOR_DELAY_NORMAL); 437 assertFalse(result); 438 } 439 testRegisterTwiceWithSameSensor()440 public void testRegisterTwiceWithSameSensor() { 441 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 442 if (sensor == null) { 443 throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER); 444 } 445 446 boolean result = mSensorManager.registerListener(mNullSensorEventListener, sensor, 447 SensorManager.SENSOR_DELAY_NORMAL); 448 assertTrue(result); 449 450 result = mSensorManager.registerListener(mNullSensorEventListener, sensor, 451 SensorManager.SENSOR_DELAY_NORMAL); 452 assertFalse(result); 453 } 454 455 /** 456 * Verifies that if the UID is idle the continuous events are being reported 457 * but sanitized - all events are the same as the first one delivered except 458 * for their timestamps. From the point of view of an idle app these events are 459 * being properly generated but the sensor reading does not change - privacy. 460 */ 461 // TODO: remove when parametrized tests are supported and EventTimestampSynchronization testSanitizedContinuousEventsUidIdle()462 public void testSanitizedContinuousEventsUidIdle() throws Exception { 463 ArrayList<Throwable> errorsFound = new ArrayList<>(); 464 for (Sensor sensor : mAndroidSensorList) { 465 // If the UID is active no sanitization should be performed 466 verifyLongActivation(sensor, 0 /* maxReportLatencyUs */, 467 5 /* duration */, TimeUnit.SECONDS, "continuous event", 468 false /* sanitized */, errorsFound); 469 verifyLongActivation(sensor, (int) TimeUnit.SECONDS.toMicros(10), 470 5 /* duration */, TimeUnit.SECONDS, "continuous event", 471 false /* sanitized */, errorsFound); 472 473 // If the UID is idle sanitization should be performed 474 475 SensorCtsHelper.makeMyPackageIdle(); 476 try { 477 verifyLongActivation(sensor, 0 /* maxReportLatencyUs */, 478 5 /* duration */, TimeUnit.SECONDS, "continuous event", 479 true /* sanitized */, errorsFound); 480 verifyLongActivation(sensor, (int) TimeUnit.SECONDS.toMicros(10), 481 5 /* duration */, TimeUnit.SECONDS, "continuous event", 482 true /* sanitized */, errorsFound); 483 } finally { 484 SensorCtsHelper.makeMyPackageActive(); 485 } 486 487 // If the UID is active no sanitization should be performed 488 verifyLongActivation(sensor, 0 /* maxReportLatencyUs */, 489 5 /* duration */, TimeUnit.SECONDS, "continuous event", 490 false /* sanitized */, errorsFound); 491 verifyLongActivation(sensor, (int) TimeUnit.SECONDS.toMicros(10), 492 5 /* duration */, TimeUnit.SECONDS, "continuous event", 493 false /* sanitized */, errorsFound); 494 } 495 assertOnErrors(errorsFound); 496 } 497 498 // TODO: remove when parametrized tests are supported and EventTimestampSynchronization 499 // verification is added to default verifications testSensorTimeStamps()500 public void testSensorTimeStamps() throws Exception { 501 ArrayList<Throwable> errorsFound = new ArrayList<>(); 502 for (Sensor sensor : mAndroidSensorList) { 503 // test both continuous and batching mode sensors 504 verifyLongActivation(sensor, 0 /* maxReportLatencyUs */, 505 20 /* duration */, TimeUnit.SECONDS, "timestamp", false 506 /* sanitized */, errorsFound); 507 verifyLongActivation(sensor, (int) TimeUnit.SECONDS.toMicros(10), 508 20 /* duration */, TimeUnit.SECONDS, "timestamp", 509 false /* sanitized */, errorsFound); 510 } 511 assertOnErrors(errorsFound); 512 } 513 514 // TODO: remove when parameterized tests are supported (see SensorBatchingTests.java) testBatchAndFlush()515 public void testBatchAndFlush() throws Exception { 516 SensorCtsHelper.sleep(3, TimeUnit.SECONDS); 517 ArrayList<Throwable> errorsFound = new ArrayList<>(); 518 for (Sensor sensor : mAndroidSensorList) { 519 verifyRegisterListenerCallFlush(sensor, null /* handler */, errorsFound, 520 false /* flushWhileIdle */); 521 } 522 assertOnErrors(errorsFound); 523 } 524 525 /** 526 * Verifies that if the UID is idle flush events are reported. Since 527 * these events have no payload with private data they are working as 528 * for a non-idle UID. 529 */ 530 // TODO: remove when parametized tests are supported and EventTimestampSynchronization testBatchAndFlushUidIdle()531 public void testBatchAndFlushUidIdle() throws Exception { 532 SensorCtsHelper.sleep(3, TimeUnit.SECONDS); 533 ArrayList<Throwable> errorsFound = new ArrayList<>(); 534 for (Sensor sensor : mAndroidSensorList) { 535 verifyRegisterListenerCallFlush(sensor, null /* handler */, errorsFound, 536 true /* flushWhileIdle */); 537 } 538 assertOnErrors(errorsFound); 539 } 540 541 /** 542 * Verifies that sensor events arrive in the given message queue (Handler). 543 */ testBatchAndFlushWithHandler()544 public void testBatchAndFlushWithHandler() throws Exception { 545 SensorCtsHelper.sleep(3, TimeUnit.SECONDS); 546 Sensor sensor = null; 547 for (Sensor s : mAndroidSensorList) { 548 if (s.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) { 549 sensor = s; 550 break; 551 } 552 } 553 if (sensor == null) { 554 throw new SensorTestStateNotSupportedException( 555 "There are no Continuous sensors in the device."); 556 } 557 558 TestSensorEnvironment environment = new TestSensorEnvironment( 559 getContext(), 560 sensor, 561 SensorManager.SENSOR_DELAY_FASTEST, 562 (int) TimeUnit.SECONDS.toMicros(5)); 563 mTestSensorManager = new TestSensorManager(environment); 564 565 HandlerThread handlerThread = new HandlerThread("sensorThread"); 566 handlerThread.start(); 567 Handler handler = new Handler(handlerThread.getLooper()); 568 TestSensorEventListener listener = new TestSensorEventListener(environment, handler); 569 570 CountDownLatch eventLatch = mTestSensorManager.registerListener(listener, 1); 571 listener.waitForEvents(eventLatch, 1, true); 572 CountDownLatch flushLatch = mTestSensorManager.requestFlush(); 573 listener.waitForFlushComplete(flushLatch, true); 574 listener.assertEventsReceivedInHandler(); 575 } 576 577 /** 578 * Explicit testing the SensorManager.registerListener(SensorEventListener, Sensor, int, int). 579 */ testBatchAndFlushUseDefaultHandler()580 public void testBatchAndFlushUseDefaultHandler() throws Exception { 581 SensorCtsHelper.sleep(3, TimeUnit.SECONDS); 582 Sensor sensor = null; 583 for (Sensor s : mAndroidSensorList) { 584 if (s.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) { 585 sensor = s; 586 break; 587 } 588 } 589 if (sensor == null) { 590 throw new SensorTestStateNotSupportedException( 591 "There are no Continuous sensors in the device."); 592 } 593 594 TestSensorEnvironment environment = new TestSensorEnvironment( 595 getContext(), 596 sensor, 597 SensorManager.SENSOR_DELAY_FASTEST, 598 (int) TimeUnit.SECONDS.toMicros(5)); 599 mTestSensorManager = new TestSensorManager(environment); 600 601 TestSensorEventListener listener = new TestSensorEventListener(environment, null); 602 603 // specifyHandler <= false, use the SensorManager API without Handler parameter 604 CountDownLatch eventLatch = mTestSensorManager.registerListener(listener, 1, false); 605 listener.waitForEvents(eventLatch, 1, true); 606 CountDownLatch flushLatch = mTestSensorManager.requestFlush(); 607 listener.waitForFlushComplete(flushLatch, true); 608 listener.assertEventsReceivedInHandler(); 609 } 610 611 // TODO: after L release move to SensorBatchingTests and run in all sensors with default 612 // verifications enabled testBatchAndFlushWithMultipleSensors()613 public void testBatchAndFlushWithMultipleSensors() throws Exception { 614 SensorCtsHelper.sleep(3, TimeUnit.SECONDS); 615 final int maxSensors = 3; 616 final int maxReportLatencyUs = (int) TimeUnit.SECONDS.toMicros(10); 617 List<Sensor> sensorsToTest = new ArrayList<Sensor>(); 618 for (Sensor sensor : mAndroidSensorList) { 619 if (sensor.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) { 620 sensorsToTest.add(sensor); 621 if (sensorsToTest.size() == maxSensors) break; 622 } 623 } 624 final int numSensorsToTest = sensorsToTest.size(); 625 if (numSensorsToTest == 0) { 626 return; 627 } 628 629 StringBuilder builder = new StringBuilder(); 630 ParallelSensorOperation parallelSensorOperation = new ParallelSensorOperation(); 631 for (Sensor sensor : sensorsToTest) { 632 TestSensorEnvironment environment = new TestSensorEnvironment( 633 getContext(), 634 sensor, 635 shouldEmulateSensorUnderLoad(), 636 SensorManager.SENSOR_DELAY_FASTEST, 637 maxReportLatencyUs); 638 FlushExecutor executor = new FlushExecutor(environment, 500 /* eventCount */, 639 false /* flushWhileIdle */); 640 parallelSensorOperation.add(new TestSensorOperation(environment, executor)); 641 builder.append(sensor.getName()).append(", "); 642 } 643 644 Log.i(TAG, "Testing batch/flush for sensors: " + builder); 645 parallelSensorOperation.execute(getCurrentTestNode()); 646 } 647 assertSensorValues(Sensor sensor)648 private void assertSensorValues(Sensor sensor) { 649 assertTrue("Max range must be positive. Range=" + sensor.getMaximumRange() 650 + " " + sensor.getName(), sensor.getMaximumRange() >= 0); 651 assertTrue("Max power must be positive. Power=" + sensor.getPower() + " " + 652 sensor.getName(), sensor.getPower() >= 0); 653 654 // Only assert sensor resolution is non-zero for official sensor types since that's what's 655 // required by the CDD. 656 if (sensor.getType() < MAX_OFFICIAL_ANDROID_SENSOR_TYPE) { 657 assertTrue("Max resolution must be non-zero and positive. Resolution=" + sensor.getResolution() + 658 " " + sensor.getName(), sensor.getResolution() > 0); 659 } else { 660 assertTrue("Max resolution must be positive. Resolution=" + sensor.getResolution() + 661 " " + sensor.getName(), sensor.getResolution() >= 0); 662 } 663 664 boolean hasHifiSensors = getContext().getPackageManager().hasSystemFeature( 665 PackageManager.FEATURE_HIFI_SENSORS); 666 if (SensorCtsHelper.hasMaxResolutionRequirement(sensor, hasHifiSensors)) { 667 float maxResolution = SensorCtsHelper.getRequiredMaxResolutionForSensor(sensor); 668 assertTrue("Resolution must be <= " + maxResolution + ". Resolution=" + 669 sensor.getResolution() + " " + sensor.getName(), 670 sensor.getResolution() <= maxResolution); 671 } 672 673 // The minimum resolution requirement was introduced to the CDD in R so 674 // it's only possible to assert compliance for devices that release with 675 // R or later. 676 if (PropertyUtil.getFirstApiLevel() >= VERSION_CODES.R && 677 SensorCtsHelper.hasMinResolutionRequirement(sensor)) { 678 float minResolution = SensorCtsHelper.getRequiredMinResolutionForSensor(sensor); 679 assertTrue("Resolution must be >= " + minResolution + ". Resolution =" + 680 sensor.getResolution() + " " + sensor.getName(), 681 sensor.getResolution() >= minResolution); 682 } 683 684 assertNotNull("Vendor name must not be null " + sensor.getName(), sensor.getVendor()); 685 assertTrue("Version must be positive version=" + sensor.getVersion() + " " + 686 sensor.getName(), sensor.getVersion() > 0); 687 int fifoMaxEventCount = sensor.getFifoMaxEventCount(); 688 int fifoReservedEventCount = sensor.getFifoReservedEventCount(); 689 assertTrue(fifoMaxEventCount >= 0); 690 assertTrue(fifoReservedEventCount >= 0); 691 assertTrue(fifoReservedEventCount <= fifoMaxEventCount); 692 if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 693 assertTrue("One shot sensors should have zero FIFO Size " + sensor.getName(), 694 sensor.getFifoMaxEventCount() == 0); 695 assertTrue("One shot sensors should have zero FIFO Size " + sensor.getName(), 696 sensor.getFifoReservedEventCount() == 0); 697 } 698 } 699 700 @SuppressWarnings("deprecation") testLegacySensorOperations()701 public void testLegacySensorOperations() { 702 final SensorManager mSensorManager = 703 (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); 704 705 // We expect the set of sensors reported by the new and legacy APIs to be consistent. 706 int sensors = 0; 707 if (mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) { 708 sensors |= SensorManager.SENSOR_ACCELEROMETER; 709 } 710 if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null) { 711 sensors |= SensorManager.SENSOR_MAGNETIC_FIELD; 712 } 713 if (mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION) != null) { 714 sensors |= SensorManager.SENSOR_ORIENTATION | SensorManager.SENSOR_ORIENTATION_RAW; 715 } 716 assertEquals(sensors, mSensorManager.getSensors()); 717 } 718 719 /** 720 * Verifies that a continuous sensor produces events that have timestamps synchronized with 721 * {@link SystemClock#elapsedRealtimeNanos()} and that the events are sanitized/non-sanitized. 722 */ verifyLongActivation( Sensor sensor, int maxReportLatencyUs, long duration, TimeUnit durationTimeUnit, String testType, boolean sanitized, ArrayList<Throwable> errorsFound)723 private void verifyLongActivation( 724 Sensor sensor, 725 int maxReportLatencyUs, 726 long duration, 727 TimeUnit durationTimeUnit, 728 String testType, 729 boolean sanitized, 730 ArrayList<Throwable> errorsFound) throws InterruptedException { 731 if (sensor.getReportingMode() != Sensor.REPORTING_MODE_CONTINUOUS) { 732 return; 733 } 734 735 try { 736 TestSensorEnvironment environment = new TestSensorEnvironment( 737 getContext(), 738 sensor, 739 shouldEmulateSensorUnderLoad(), 740 SensorManager.SENSOR_DELAY_FASTEST, 741 maxReportLatencyUs); 742 TestSensorOperation operation = TestSensorOperation.createOperation( 743 environment, duration, durationTimeUnit); 744 if (sanitized) { 745 final long verificationDelayNano = TimeUnit.NANOSECONDS.convert( 746 maxReportLatencyUs, TimeUnit.MICROSECONDS) * 2; 747 operation.addVerification(ContinuousEventSanitizedVerification 748 .getDefault(environment, verificationDelayNano)); 749 } else { 750 operation.addVerification(EventGapVerification.getDefault(environment)); 751 operation.addVerification(EventOrderingVerification.getDefault(environment)); 752 operation.addVerification(EventTimestampSynchronizationVerification 753 .getDefault(environment)); 754 } 755 Log.i(TAG, "Running " + testType + " test on: " + sensor.getName()); 756 operation.execute(getCurrentTestNode()); 757 } catch (InterruptedException e) { 758 // propagate so the test can stop 759 throw e; 760 } catch (Throwable e) { 761 errorsFound.add(e); 762 Log.e(TAG, e.getMessage()); 763 } 764 } 765 766 /** 767 * Verifies that a client can listen for events, and that 768 * {@link SensorManager#flush(SensorEventListener)} will trigger the appropriate notification 769 * for {@link SensorEventListener2#onFlushCompleted(Sensor)}. 770 */ verifyRegisterListenerCallFlush( Sensor sensor, Handler handler, ArrayList<Throwable> errorsFound, boolean flushWhileIdle)771 private void verifyRegisterListenerCallFlush( 772 Sensor sensor, 773 Handler handler, 774 ArrayList<Throwable> errorsFound, 775 boolean flushWhileIdle) 776 throws InterruptedException { 777 if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 778 return; 779 } 780 781 try { 782 TestSensorEnvironment environment = new TestSensorEnvironment( 783 getContext(), 784 sensor, 785 shouldEmulateSensorUnderLoad(), 786 SensorManager.SENSOR_DELAY_FASTEST, 787 (int) TimeUnit.SECONDS.toMicros(10)); 788 FlushExecutor executor = new FlushExecutor(environment, 500 /* eventCount */, 789 flushWhileIdle); 790 TestSensorOperation operation = new TestSensorOperation(environment, executor, handler); 791 792 Log.i(TAG, "Running flush test on: " + sensor.getName()); 793 operation.execute(getCurrentTestNode()); 794 } catch (InterruptedException e) { 795 // propagate so the test can stop 796 throw e; 797 } catch (Throwable e) { 798 errorsFound.add(e); 799 Log.e(TAG, e.getMessage()); 800 } 801 } 802 assertOnErrors(List<Throwable> errorsFound)803 private void assertOnErrors(List<Throwable> errorsFound) { 804 if (!errorsFound.isEmpty()) { 805 StringBuilder builder = new StringBuilder(); 806 for (Throwable error : errorsFound) { 807 builder.append(error.getMessage()).append("\n"); 808 } 809 Assert.fail(builder.toString()); 810 } 811 } 812 813 /** 814 * A delegate that drives the execution of Batch/Flush tests. 815 * It performs several operations in order: 816 * - registration 817 * - for continuous sensors it first ensures that the FIFO is filled 818 * - if events do not arrive on time, an assert will be triggered 819 * - requests flush of sensor data 820 * - waits for {@link SensorEventListener2#onFlushCompleted(Sensor)} 821 * - if the event does not arrive, an assert will be triggered 822 */ 823 private class FlushExecutor implements TestSensorOperation.Executor { 824 private final TestSensorEnvironment mEnvironment; 825 private final int mEventCount; 826 private final boolean mFlushWhileIdle; 827 FlushExecutor(TestSensorEnvironment environment, int eventCount, boolean flushWhileIdle)828 public FlushExecutor(TestSensorEnvironment environment, int eventCount, 829 boolean flushWhileIdle) { 830 mEnvironment = environment; 831 mEventCount = eventCount; 832 mFlushWhileIdle = flushWhileIdle; 833 } 834 835 /** 836 * Consider only continuous mode sensors for testing register listener. 837 * 838 * For on-change sensors, we only use 839 * {@link TestSensorManager#registerListener(TestSensorEventListener)} to associate the 840 * listener with the sensor. So that {@link TestSensorManager#requestFlush()} can be 841 * invoked on it. 842 */ 843 @Override execute(TestSensorManager sensorManager, TestSensorEventListener listener)844 public void execute(TestSensorManager sensorManager, TestSensorEventListener listener) 845 throws Exception { 846 int sensorReportingMode = mEnvironment.getSensor().getReportingMode(); 847 try { 848 CountDownLatch eventLatch = sensorManager.registerListener(listener, mEventCount); 849 if (sensorReportingMode == Sensor.REPORTING_MODE_CONTINUOUS) { 850 listener.waitForEvents(eventLatch, mEventCount, true); 851 } 852 if (mFlushWhileIdle) { 853 SensorCtsHelper.makeMyPackageIdle(); 854 sensorManager.assertFlushFail(); 855 } else { 856 CountDownLatch flushLatch = sensorManager.requestFlush(); 857 listener.waitForFlushComplete(flushLatch, true); 858 } 859 } finally { 860 sensorManager.unregisterListener(); 861 if (mFlushWhileIdle) { 862 SensorCtsHelper.makeMyPackageActive(); 863 } 864 } 865 } 866 } 867 868 private class NullTriggerEventListener extends TriggerEventListener { 869 @Override onTrigger(TriggerEvent event)870 public void onTrigger(TriggerEvent event) {} 871 } 872 873 private class NullSensorEventListener implements SensorEventListener { 874 @Override onSensorChanged(SensorEvent event)875 public void onSensorChanged(SensorEvent event) {} 876 877 @Override onAccuracyChanged(Sensor sensor, int accuracy)878 public void onAccuracyChanged(Sensor sensor, int accuracy) {} 879 } 880 881 } 882