1 /* 2 * Copyright (C) 2014 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.helpers; 18 19 import android.content.Context; 20 import android.hardware.Sensor; 21 import android.hardware.SensorManager; 22 import android.hardware.cts.helpers.sensoroperations.SensorOperation; 23 24 import java.util.concurrent.TimeUnit; 25 26 /* TODO: Refactor constructors into a builder */ 27 28 /** 29 * A class that encapsulates base environment information for the {@link SensorOperation}. 30 * The environment is self contained and carries its state around all the sensor test framework. 31 */ 32 public class TestSensorEnvironment { 33 34 /** 35 * It represents the fraction of the expected sampling frequency, at which the sensor can 36 * actually produce events. 37 */ 38 private static final float MAXIMUM_EXPECTED_SAMPLING_FREQUENCY_MULTIPLIER = 0.9f; 39 40 private final Context mContext; 41 private final Sensor mSensor; 42 private final boolean mSensorMightHaveMoreListeners; 43 private final int mSamplingPeriodUs; 44 private final int mMaxReportLatencyUs; 45 private final boolean mIsDeviceSuspendTest; 46 private final boolean mIsIntegrationTest; 47 48 /** 49 * Constructs an environment for sensor testing. 50 * 51 * @param context The context for the test 52 * @param sensorType The type of the sensor under test 53 * @param samplingPeriodUs The requested collection period for the sensor under test 54 * 55 * @deprecated Use variants with {@link Sensor} objects. 56 */ 57 @Deprecated TestSensorEnvironment(Context context, int sensorType, int samplingPeriodUs)58 public TestSensorEnvironment(Context context, int sensorType, int samplingPeriodUs) { 59 this(context, sensorType, false /* sensorMightHaveMoreListeners */, samplingPeriodUs); 60 } 61 62 /** 63 * Constructs an environment for sensor testing. 64 * 65 * @param context The context for the test 66 * @param sensorType The type of the sensor under test 67 * @param samplingPeriodUs The requested collection period for the sensor under test 68 * @param maxReportLatencyUs The requested collection report latency for the sensor under test 69 * 70 * @deprecated Use variants with {@link Sensor} objects. 71 */ 72 @Deprecated TestSensorEnvironment( Context context, int sensorType, int samplingPeriodUs, int maxReportLatencyUs)73 public TestSensorEnvironment( 74 Context context, 75 int sensorType, 76 int samplingPeriodUs, 77 int maxReportLatencyUs) { 78 this(context, 79 sensorType, 80 false /* sensorMightHaveMoreListeners */, 81 samplingPeriodUs, 82 maxReportLatencyUs); 83 } 84 85 /** 86 * Constructs an environment for sensor testing. 87 * 88 * @param context The context for the test 89 * @param sensorType The type of the sensor under test 90 * @param sensorMightHaveMoreListeners Whether the sensor under test is acting under load 91 * @param samplingPeriodUs The requested collection period for the sensor under test 92 * 93 * @deprecated Use variants with {@link Sensor} objects. 94 */ 95 @Deprecated TestSensorEnvironment( Context context, int sensorType, boolean sensorMightHaveMoreListeners, int samplingPeriodUs)96 public TestSensorEnvironment( 97 Context context, 98 int sensorType, 99 boolean sensorMightHaveMoreListeners, 100 int samplingPeriodUs) { 101 this(context, 102 sensorType, 103 sensorMightHaveMoreListeners, 104 samplingPeriodUs, 105 0 /* maxReportLatencyUs */); 106 } 107 108 /** 109 * Constructs an environment for sensor testing. 110 * 111 * @param context The context for the test 112 * @param sensorType The type of the sensor under test 113 * @param sensorMightHaveMoreListeners Whether the sensor under test is acting under load 114 * @param samplingPeriodUs The requested collection period for the sensor under test 115 * @param maxReportLatencyUs The requested collection report latency for the sensor under test 116 * 117 * @deprecated Use variants with {@link Sensor} objects. 118 */ 119 @Deprecated TestSensorEnvironment( Context context, int sensorType, boolean sensorMightHaveMoreListeners, int samplingPeriodUs, int maxReportLatencyUs)120 public TestSensorEnvironment( 121 Context context, 122 int sensorType, 123 boolean sensorMightHaveMoreListeners, 124 int samplingPeriodUs, 125 int maxReportLatencyUs) { 126 this(context, 127 getSensor(context, sensorType), 128 sensorMightHaveMoreListeners, 129 samplingPeriodUs, 130 maxReportLatencyUs); 131 } 132 133 /** 134 * Constructs an environment for sensor testing. 135 * 136 * @param context The context for the test 137 * @param sensorType The type of the sensor under test 138 * @param sensorMightHaveMoreListeners Whether the sensor under test is acting under load 139 * @param isIntegrationTest Whether this is an integration test (more than one sensor actived) 140 * @param samplingPeriodUs The requested collection period for the sensor under test 141 * @param maxReportLatencyUs The requested collection report latency for the sensor under test 142 * 143 * @deprecated Use variants with {@link Sensor} objects. 144 */ 145 @Deprecated TestSensorEnvironment( Context context, int sensorType, boolean sensorMightHaveMoreListeners, boolean isIntegrationTest, int samplingPeriodUs, int maxReportLatencyUs)146 public TestSensorEnvironment( 147 Context context, 148 int sensorType, 149 boolean sensorMightHaveMoreListeners, 150 boolean isIntegrationTest, 151 int samplingPeriodUs, 152 int maxReportLatencyUs) { 153 this(context, 154 getSensor(context, sensorType), 155 sensorMightHaveMoreListeners, 156 isIntegrationTest, 157 samplingPeriodUs, 158 maxReportLatencyUs); 159 } 160 161 /** 162 * Constructs an environment for sensor testing. 163 * 164 * @param context The context for the test 165 * @param sensor The sensor under test 166 * @param samplingPeriodUs The requested collection period for the sensor under test 167 * @param maxReportLatencyUs The requested collection report latency for the sensor under test 168 */ TestSensorEnvironment( Context context, Sensor sensor, int samplingPeriodUs, int maxReportLatencyUs)169 public TestSensorEnvironment( 170 Context context, 171 Sensor sensor, 172 int samplingPeriodUs, 173 int maxReportLatencyUs) { 174 this(context, 175 sensor, 176 false /* sensorMightHaveMoreListeners */, 177 samplingPeriodUs, 178 maxReportLatencyUs); 179 } 180 181 /** 182 * Constructs an environment for sensor testing. 183 * 184 * @param context The context for the test 185 * @param sensor The sensor under test 186 * @param sensorMightHaveMoreListeners Whether the sensor under test is acting under load (this 187 * usually implies that there are several listeners 188 * requesting different sampling periods) 189 * @param samplingPeriodUs The requested collection period for the sensor under test 190 * @param maxReportLatencyUs The requested collection report latency for the sensor under test 191 */ TestSensorEnvironment( Context context, Sensor sensor, boolean sensorMightHaveMoreListeners, int samplingPeriodUs, int maxReportLatencyUs)192 public TestSensorEnvironment( 193 Context context, 194 Sensor sensor, 195 boolean sensorMightHaveMoreListeners, 196 int samplingPeriodUs, 197 int maxReportLatencyUs) { 198 this(context, 199 sensor, 200 sensorMightHaveMoreListeners, 201 samplingPeriodUs, 202 maxReportLatencyUs, 203 false /* isDeviceSuspendTest */); 204 } 205 TestSensorEnvironment( Context context, Sensor sensor, boolean sensorMightHaveMoreListeners, boolean isIntegrationTest, int samplingPeriodUs, int maxReportLatencyUs)206 public TestSensorEnvironment( 207 Context context, 208 Sensor sensor, 209 boolean sensorMightHaveMoreListeners, 210 boolean isIntegrationTest, 211 int samplingPeriodUs, 212 int maxReportLatencyUs) { 213 this(context, 214 sensor, 215 sensorMightHaveMoreListeners, 216 samplingPeriodUs, 217 maxReportLatencyUs, 218 false /* isDeviceSuspendTest */, 219 isIntegrationTest); 220 } 221 TestSensorEnvironment( Context context, Sensor sensor, boolean sensorMightHaveMoreListeners, int samplingPeriodUs, int maxReportLatencyUs, boolean isDeviceSuspendTest)222 public TestSensorEnvironment( 223 Context context, 224 Sensor sensor, 225 boolean sensorMightHaveMoreListeners, 226 int samplingPeriodUs, 227 int maxReportLatencyUs, 228 boolean isDeviceSuspendTest) { 229 this(context, sensor, sensorMightHaveMoreListeners, 230 samplingPeriodUs, maxReportLatencyUs, 231 false /* isDeviceSuspendTest */, 232 false /* isIntegrationTest */); 233 } 234 TestSensorEnvironment( Context context, Sensor sensor, boolean sensorMightHaveMoreListeners, int samplingPeriodUs, int maxReportLatencyUs, boolean isDeviceSuspendTest, boolean isIntegrationTest)235 public TestSensorEnvironment( 236 Context context, 237 Sensor sensor, 238 boolean sensorMightHaveMoreListeners, 239 int samplingPeriodUs, 240 int maxReportLatencyUs, 241 boolean isDeviceSuspendTest, 242 boolean isIntegrationTest) { 243 mContext = context; 244 mSensor = sensor; 245 mSensorMightHaveMoreListeners = sensorMightHaveMoreListeners; 246 mSamplingPeriodUs = samplingPeriodUs; 247 mMaxReportLatencyUs = maxReportLatencyUs; 248 mIsDeviceSuspendTest = isDeviceSuspendTest; 249 mIsIntegrationTest = isIntegrationTest; 250 } 251 252 /** 253 * @return The context instance associated with the test. 254 */ getContext()255 public Context getContext() { 256 return mContext; 257 } 258 259 /** 260 * @return The sensor under test. 261 */ getSensor()262 public Sensor getSensor() { 263 return mSensor; 264 } 265 266 /** 267 * @return The requested collection rate in microseconds. 268 */ getRequestedSamplingPeriodUs()269 public int getRequestedSamplingPeriodUs() { 270 return mSamplingPeriodUs; 271 } 272 273 /** 274 * @return The frequency equivalent to {@link #getRequestedSamplingPeriodUs()}. 275 */ getFrequencyHz()276 public double getFrequencyHz() { 277 return SensorCtsHelper.getFrequency(mSamplingPeriodUs, TimeUnit.MICROSECONDS); 278 } 279 280 /** 281 * @return A string representing the frequency equivalent to 282 * {@link #getRequestedSamplingPeriodUs()}. 283 */ getFrequencyString()284 public String getFrequencyString() { 285 if (mSamplingPeriodUs == SensorManager.SENSOR_DELAY_FASTEST) { 286 return "fastest"; 287 } 288 return String.format("%.2fhz", getFrequencyHz()); 289 } 290 291 /** 292 * @return The requested collection max batch report latency in microseconds. 293 */ getMaxReportLatencyUs()294 public int getMaxReportLatencyUs() { 295 return mMaxReportLatencyUs; 296 } 297 298 /** 299 * Returns {@code true} if there might be other listeners of {@link #getSensor()} requesting 300 * data at different sampling rates (the rates are unknown); false otherwise. 301 */ isSensorSamplingRateOverloaded()302 public boolean isSensorSamplingRateOverloaded() { 303 return mSensorMightHaveMoreListeners 304 && mSamplingPeriodUs != SensorManager.SENSOR_DELAY_FASTEST; 305 } 306 307 /** 308 * Convert the {@link #getRequestedSamplingPeriodUs()} into delay in microseconds. 309 * <p> 310 * The flags SensorManager.SENSOR_DELAY_[GAME|UI|NORMAL] are not supported since the CDD does 311 * not specify values for these flags. The rate is set to the max of 312 * {@link Sensor#getMinDelay()} and the rate given. 313 * </p> 314 */ getExpectedSamplingPeriodUs()315 public int getExpectedSamplingPeriodUs() { 316 if (!isDelayRateTestable()) { 317 throw new IllegalArgumentException("rateUs cannot be SENSOR_DELAY_[GAME|UI|NORMAL]"); 318 } 319 320 int expectedSamplingPeriodUs = mSamplingPeriodUs; 321 int sensorMaxDelay = mSensor.getMaxDelay(); 322 if (sensorMaxDelay > 0) { 323 expectedSamplingPeriodUs = Math.min(expectedSamplingPeriodUs, sensorMaxDelay); 324 } 325 326 return Math.max(expectedSamplingPeriodUs, mSensor.getMinDelay()); 327 } 328 329 /** 330 * Calculate the maximum expected sampling period in us. 331 * @return The maximum acceptable actual sampling period of this sensor. 332 * For continuous sensors, this is higher than {@link #getExpectedSamplingPeriodUs()} 333 * because sensors are allowed to run up to 10% slower than requested. 334 * For sensors with other reporting modes, this is the maximum integer 335 * {@link Integer#MAX_VALUE} as they can report no events for long 336 * periods of time. 337 */ getMaximumExpectedSamplingPeriodUs()338 public int getMaximumExpectedSamplingPeriodUs() { 339 int sensorReportingMode = mSensor.getReportingMode(); 340 if (sensorReportingMode != Sensor.REPORTING_MODE_CONTINUOUS) { 341 return Integer.MAX_VALUE; 342 } 343 344 int expectedSamplingPeriodUs = getExpectedSamplingPeriodUs(); 345 return (int) (expectedSamplingPeriodUs / MAXIMUM_EXPECTED_SAMPLING_FREQUENCY_MULTIPLIER); 346 } 347 348 349 /** 350 * Calculate the allowed sensor start delay. 351 * 352 * CDD Section 7.3: 353 * MUST report the first sensor sample within 400 milliseconds + 2 * sample_time of the 354 * sensor being activated. It is acceptable for this sample to have an accuracy of 0. 355 * 356 * [CDD] Keep this updated with CDD. 357 */ getAllowedSensorStartDelay()358 public long getAllowedSensorStartDelay() { 359 return TimeUnit.MILLISECONDS.toMicros(400) + 2 * getMaximumExpectedSamplingPeriodUs(); 360 } 361 362 /** 363 * @return The number of axes in the coordinate system of the sensor under test. 364 */ getSensorAxesCount()365 public int getSensorAxesCount() { 366 switch (mSensor.getType()) { 367 case Sensor.TYPE_GYROSCOPE: 368 return 3; 369 default: 370 throw new IllegalStateException("Axes count needs to be defined for sensor type: " 371 + mSensor.getStringType()); 372 } 373 } 374 375 /** 376 * Get the default sensor for a given type. 377 * 378 * @deprecated Used for historical reasons, sensor tests must be written around Sensor objects, 379 * so all sensors of a given type are exercised. 380 */ 381 @Deprecated getSensor(Context context, int sensorType)382 public static Sensor getSensor(Context context, int sensorType) { 383 SensorManager sensorManager = 384 (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 385 if (sensorManager == null) { 386 throw new IllegalStateException("SensorService is not present in the system."); 387 } 388 389 Sensor sensor = sensorManager.getDefaultSensor(sensorType); 390 if(sensor == null) { 391 throw new SensorNotSupportedException(sensorType); 392 } 393 return sensor; 394 } 395 396 /** 397 * @return The maximum latency of a given sensor, on top of {@link #getMaxReportLatencyUs()}. 398 * 399 * NOTE: The latency is defined as the time between the event happens and the time the event is 400 * generated. 401 * 402 * - At time event_time (reported in the sensor event), the physical event happens 403 * - At time event_time + detection_latency, the physical event is detected and the event is 404 * saved in the hardware fifo 405 * - At time event_time + detection_latency + report_latency, the event is reported through the 406 * HAL 407 * 408 * Soon after that, the event is piped through the framework to the application. This time may 409 * vary depending on the CPU load. The time 'detection_latency' must be less than 410 * {@link #getSensorMaxDetectionLatencyNs(Sensor)}, and 'report_latency' must be less than 411 * {@link #getMaxReportLatencyUs()} passed through batch() at the HAL level. 412 */ 413 // TODO: when all tests are moved to use the Sensor test framework, make this method non-static getSensorMaxDetectionLatencyNs(Sensor sensor)414 public static long getSensorMaxDetectionLatencyNs(Sensor sensor) { 415 int reportLatencySec; 416 switch (sensor.getType()) { 417 case Sensor.TYPE_STEP_DETECTOR: 418 reportLatencySec = 2; 419 break; 420 case Sensor.TYPE_STEP_COUNTER: 421 reportLatencySec = 10; 422 break; 423 case Sensor.TYPE_SIGNIFICANT_MOTION: 424 reportLatencySec = 10; 425 break; 426 default: 427 reportLatencySec = 0; 428 } 429 return TimeUnit.SECONDS.toNanos(reportLatencySec); 430 } 431 432 @Override toString()433 public String toString() { 434 return String.format( 435 "Sensor='%s', SamplingRateOverloaded=%s, SamplingPeriod=%sus, " 436 + "MaxReportLatency=%sus", 437 mSensor, 438 isSensorSamplingRateOverloaded(), 439 mSamplingPeriodUs, 440 mMaxReportLatencyUs); 441 } 442 443 /** 444 * Return true if {@link #getRequestedSamplingPeriodUs()} is not one of 445 * {@link SensorManager#SENSOR_DELAY_GAME}, {@link SensorManager#SENSOR_DELAY_UI}, or 446 * {@link SensorManager#SENSOR_DELAY_NORMAL}. 447 */ isDelayRateTestable()448 private boolean isDelayRateTestable() { 449 return (mSamplingPeriodUs >= 0 450 && mSamplingPeriodUs != SensorManager.SENSOR_DELAY_GAME 451 && mSamplingPeriodUs != SensorManager.SENSOR_DELAY_UI 452 && mSamplingPeriodUs != SensorManager.SENSOR_DELAY_NORMAL); 453 } 454 isDeviceSuspendTest()455 public boolean isDeviceSuspendTest() { 456 return mIsDeviceSuspendTest; 457 } 458 isIntegrationTest()459 public boolean isIntegrationTest() { 460 return mIsIntegrationTest; 461 } 462 } 463 464