1 /* 2 * Copyright (C) 2013 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 package android.hardware.cts; 17 18 import android.content.Context; 19 import android.hardware.Sensor; 20 import android.hardware.SensorManager; 21 import android.hardware.cts.helpers.SensorCtsHelper; 22 import android.hardware.cts.helpers.TestSensorEnvironment; 23 import android.hardware.cts.helpers.sensoroperations.ParallelSensorOperation; 24 import android.hardware.cts.helpers.sensoroperations.RepeatingSensorOperation; 25 import android.hardware.cts.helpers.sensoroperations.SequentialSensorOperation; 26 import android.hardware.cts.helpers.sensoroperations.TestSensorOperation; 27 import android.hardware.cts.helpers.sensorverification.EventOrderingVerification; 28 29 import java.util.Random; 30 import java.util.concurrent.TimeUnit; 31 32 /** 33 * Set of tests that verifies proper interaction of the sensors in the platform. 34 * 35 * To execute these test cases, the following command can be used: 36 * $ adb shell am instrument -e class android.hardware.cts.SensorIntegrationTests \ 37 * -w com.android.cts.hardware/android.test.InstrumentationCtsTestRunner 38 */ 39 public class SensorIntegrationTests extends SensorTestCase { 40 private static final String TAG = "SensorIntegrationTests"; 41 42 /** 43 * This test focuses in the interaction of continuous and batching clients for the same Sensor 44 * under test. The verification ensures that sensor clients can interact with the System and 45 * not affect other clients in the way. 46 * 47 * The test verifies for each client that the a set of sampled data arrives in order. However 48 * each client in the test has different set of parameters that represent different types of 49 * clients in the real world. 50 * 51 * A test failure might indicate that the HAL implementation does not respect the assumption 52 * that the sensors must be independent. Activating one sensor should not cause another sensor 53 * to deactivate or to change behavior. 54 * It is however, acceptable that when a client is activated at a higher sampling rate, it would 55 * cause other clients to receive data at a faster sampling rate. A client causing other clients 56 * to receive data at a lower sampling rate is, however, not acceptable. 57 * 58 * The assertion associated with the test failure provides: 59 * - the thread id on which the failure occurred 60 * - the sensor type and sensor handle that caused the failure 61 * - the event that caused the issue 62 * It is important to look at the internals of the Sensor HAL to identify how the interaction 63 * of several clients can lead to the failing state. 64 */ testSensorsWithSeveralClients()65 public void testSensorsWithSeveralClients() throws Throwable { 66 SensorCtsHelper.sleep(3, TimeUnit.SECONDS); 67 final int ITERATIONS = 50; 68 final int MAX_REPORTING_LATENCY_US = (int) TimeUnit.SECONDS.toMicros(5); 69 final Context context = getContext(); 70 71 int sensorTypes[] = { 72 Sensor.TYPE_ACCELEROMETER, 73 Sensor.TYPE_MAGNETIC_FIELD, 74 Sensor.TYPE_GYROSCOPE }; 75 76 ParallelSensorOperation operation = new ParallelSensorOperation(); 77 for(int sensorType : sensorTypes) { 78 TestSensorEnvironment environment = new TestSensorEnvironment( 79 context, 80 sensorType, 81 shouldEmulateSensorUnderLoad(), 82 SensorManager.SENSOR_DELAY_FASTEST); 83 TestSensorOperation continuousOperation = 84 TestSensorOperation.createOperation(environment, 100 /* eventCount */); 85 continuousOperation.addVerification(new EventOrderingVerification()); 86 operation.add(new RepeatingSensorOperation(continuousOperation, ITERATIONS)); 87 88 Sensor sensor = TestSensorEnvironment.getSensor(context, sensorType); 89 TestSensorEnvironment batchingEnvironment = new TestSensorEnvironment( 90 context, 91 sensorType, 92 shouldEmulateSensorUnderLoad(), 93 sensor.getMinDelay(), 94 MAX_REPORTING_LATENCY_US); 95 TestSensorOperation batchingOperation = 96 TestSensorOperation.createOperation(batchingEnvironment, 100 /* eventCount */); 97 batchingOperation.addVerification(new EventOrderingVerification()); 98 operation.add(new RepeatingSensorOperation(batchingOperation, ITERATIONS)); 99 } 100 operation.execute(getCurrentTestNode()); 101 operation.getStats().log(TAG); 102 } 103 104 /** 105 * This test focuses in the interaction of several sensor Clients. The test characterizes by 106 * using clients for different Sensors under Test that vary the sampling rates and report 107 * latencies for the requests. 108 * The verification ensures that the sensor clients can vary the parameters of their requests 109 * without affecting other clients. 110 * 111 * The test verifies for each client that a set of sampled data arrives in order. However each 112 * client in the test has different set of parameters that represent different types of clients 113 * in the real world. 114 * 115 * The test can be susceptible to issues when several clients interacting with the system 116 * actually affect the operation of other clients. 117 * 118 * The assertion associated with the test failure provides: 119 * - the thread id on which the failure occurred 120 * - the sensor type and sensor handle that caused the failure 121 * - the event that caused the issue 122 * It is important to look at the internals of the Sensor HAL to identify how the interaction 123 * of several clients can lead to the failing state. 124 */ testSensorsMovingRates()125 public void testSensorsMovingRates() throws Throwable { 126 SensorCtsHelper.sleep(3, TimeUnit.SECONDS); 127 // use at least two instances to ensure more than one client of any given sensor is in play 128 final int INSTANCES_TO_USE = 5; 129 final int ITERATIONS_TO_EXECUTE = 100; 130 131 ParallelSensorOperation operation = new ParallelSensorOperation(); 132 int sensorTypes[] = { 133 Sensor.TYPE_ACCELEROMETER, 134 Sensor.TYPE_MAGNETIC_FIELD, 135 Sensor.TYPE_GYROSCOPE }; 136 137 Context context = getContext(); 138 for(int sensorType : sensorTypes) { 139 for(int instance = 0; instance < INSTANCES_TO_USE; ++instance) { 140 SequentialSensorOperation sequentialOperation = new SequentialSensorOperation(); 141 for(int iteration = 0; iteration < ITERATIONS_TO_EXECUTE; ++iteration) { 142 TestSensorEnvironment environment = new TestSensorEnvironment( 143 context, 144 sensorType, 145 shouldEmulateSensorUnderLoad(), 146 generateSamplingRateInUs(sensorType), 147 generateReportLatencyInUs()); 148 TestSensorOperation sensorOperation = 149 TestSensorOperation.createOperation(environment, 100 /* eventCount */); 150 sensorOperation.addVerification(new EventOrderingVerification()); 151 sequentialOperation.add(sensorOperation); 152 } 153 operation.add(sequentialOperation); 154 } 155 } 156 157 operation.execute(getCurrentTestNode()); 158 operation.getStats().log(TAG); 159 } 160 161 /** 162 * Regress: 163 * - b/10641388 164 */ 165 testAccelerometerAccelerometerStopping()166 public void testAccelerometerAccelerometerStopping() throws Throwable { 167 verifySensorStoppingInteraction(Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER); 168 } 169 testAccelerometerGyroscopeStopping()170 public void testAccelerometerGyroscopeStopping() throws Throwable { 171 verifySensorStoppingInteraction(Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_GYROSCOPE); 172 } 173 testAccelerometerMagneticFieldStopping()174 public void testAccelerometerMagneticFieldStopping() throws Throwable { 175 verifySensorStoppingInteraction(Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_MAGNETIC_FIELD); 176 } 177 testGyroscopeAccelerometerStopping()178 public void testGyroscopeAccelerometerStopping() throws Throwable { 179 verifySensorStoppingInteraction(Sensor.TYPE_GYROSCOPE, Sensor.TYPE_ACCELEROMETER); 180 } 181 testGyroscopeGyroscopeStopping()182 public void testGyroscopeGyroscopeStopping() throws Throwable { 183 verifySensorStoppingInteraction(Sensor.TYPE_GYROSCOPE, Sensor.TYPE_GYROSCOPE); 184 } 185 testGyroscopeMagneticFieldStopping()186 public void testGyroscopeMagneticFieldStopping() throws Throwable { 187 verifySensorStoppingInteraction(Sensor.TYPE_GYROSCOPE, Sensor.TYPE_MAGNETIC_FIELD); 188 } 189 testMagneticFieldAccelerometerStopping()190 public void testMagneticFieldAccelerometerStopping() throws Throwable { 191 verifySensorStoppingInteraction(Sensor.TYPE_MAGNETIC_FIELD, Sensor.TYPE_ACCELEROMETER); 192 } 193 testMagneticFieldGyroscopeStopping()194 public void testMagneticFieldGyroscopeStopping() throws Throwable { 195 verifySensorStoppingInteraction(Sensor.TYPE_MAGNETIC_FIELD, Sensor.TYPE_GYROSCOPE); 196 } 197 testMagneticFieldMagneticFieldStopping()198 public void testMagneticFieldMagneticFieldStopping() throws Throwable { 199 verifySensorStoppingInteraction(Sensor.TYPE_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD); 200 } 201 202 /** 203 * This test verifies that starting/stopping a particular Sensor client in the System does not 204 * affect other sensor clients. 205 * the test is used to validate that starting/stopping operations are independent on several 206 * sensor clients. 207 * 208 * The test verifies for each client that the a set of sampled data arrives in order. However 209 * each client in the test has different set of parameters that represent different types of 210 * clients in the real world. 211 * 212 * The test can be susceptible to issues when several clients interacting with the system 213 * actually affect the operation of other clients. 214 * 215 * The assertion associated with the test failure provides: 216 * - the thread id on which the failure occurred 217 * - the sensor type and sensor handle that caused the failure 218 * - the event that caused the issue 219 * It is important to look at the internals of the Sensor HAL to identify how the interaction 220 * of several clients can lead to the failing state. 221 */ verifySensorStoppingInteraction( int sensorTypeTestee, int sensorTypeTester)222 public void verifySensorStoppingInteraction( 223 int sensorTypeTestee, 224 int sensorTypeTester) throws Throwable { 225 SensorCtsHelper.sleep(3, TimeUnit.SECONDS); 226 Context context = getContext(); 227 228 TestSensorEnvironment testerEnvironment = new TestSensorEnvironment( 229 context, 230 sensorTypeTester, 231 shouldEmulateSensorUnderLoad(), 232 SensorManager.SENSOR_DELAY_FASTEST); 233 TestSensorOperation tester = 234 TestSensorOperation.createOperation(testerEnvironment, 100 /* event count */); 235 tester.addVerification(new EventOrderingVerification()); 236 237 TestSensorEnvironment testeeEnvironment = new TestSensorEnvironment( 238 context, 239 sensorTypeTestee, 240 shouldEmulateSensorUnderLoad(), 241 SensorManager.SENSOR_DELAY_FASTEST); 242 TestSensorOperation testee = 243 TestSensorOperation.createOperation(testeeEnvironment, 100 /* event count */); 244 testee.addVerification(new EventOrderingVerification()); 245 246 ParallelSensorOperation operation = new ParallelSensorOperation(); 247 operation.add(tester, testee); 248 operation.execute(getCurrentTestNode()); 249 operation.getStats().log(TAG); 250 251 testee = testee.clone(); 252 testee.execute(getCurrentTestNode()); 253 testee.getStats().log(TAG); 254 } 255 256 /** 257 * Private helpers. 258 */ 259 private final Random mGenerator = new Random(); 260 generateSamplingRateInUs(int sensorType)261 private int generateSamplingRateInUs(int sensorType) { 262 int rate; 263 switch(mGenerator.nextInt(5)) { 264 case 0: 265 rate = SensorManager.SENSOR_DELAY_FASTEST; 266 break; 267 default: 268 Sensor sensor = TestSensorEnvironment.getSensor(getContext(), sensorType); 269 int maxSamplingRate = sensor.getMinDelay(); 270 rate = maxSamplingRate * mGenerator.nextInt(10); 271 } 272 return rate; 273 } 274 generateReportLatencyInUs()275 private int generateReportLatencyInUs() { 276 long reportLatencyUs = TimeUnit.SECONDS.toMicros(mGenerator.nextInt(5) + 1); 277 return (int) reportLatencyUs; 278 } 279 } 280