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