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