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 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 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 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 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 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 */ 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 */ 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 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 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 isDeviceSuspendTest, 232 false /* isIntegrationTest */); 233 } 234 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 */ 255 public Context getContext() { 256 return mContext; 257 } 258 259 /** 260 * @return The sensor under test. 261 */ 262 public Sensor getSensor() { 263 return mSensor; 264 } 265 266 /** 267 * @return The requested collection rate in microseconds. 268 */ 269 public int getRequestedSamplingPeriodUs() { 270 return mSamplingPeriodUs; 271 } 272 273 /** 274 * @return The frequency equivalent to {@link #getRequestedSamplingPeriodUs()}. 275 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 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 */ 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 455 public boolean isDeviceSuspendTest() { 456 return mIsDeviceSuspendTest; 457 } 458 459 public boolean isIntegrationTest() { 460 return mIsIntegrationTest; 461 } 462 } 463 464