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