• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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