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