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;
18 
19 import android.hardware.Sensor;
20 import android.hardware.SensorManager;
21 import android.hardware.cts.helpers.SensorCtsHelper;
22 import android.hardware.cts.helpers.SensorStats;
23 import android.hardware.cts.helpers.TestSensorEnvironment;
24 import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
25 import android.hardware.cts.helpers.sensorverification.EventBasicVerification;
26 import android.hardware.cts.helpers.sensorverification.ISensorVerification;
27 import android.hardware.cts.helpers.sensorverification.MeanLargerThanVerification;
28 
29 import java.util.concurrent.TimeUnit;
30 
31 /**
32  * Set of tests to verify that sensors operate correctly when operating in batching mode.
33  * This class defines tests for continuous sensors when the device is awake.
34  * On-change and special sensors are tested separately inside CtsVerifier, and they are defined in:
35  * {@link com.android.cts.verifier.sensors.BatchingTestActivity}.
36  *
37  * Each test is expected to pass even if batching is not supported for a particular sensor. This is
38  * usually achieved by ensuring that {@link ISensorVerification}s fallback accordingly.
39  *
40  * <p>To execute these test cases, the following command can be used:</p>
41  * <pre>
42  * adb shell am instrument -e class android.hardware.cts.SensorBatchingTests \
43  *     -w android.hardware.cts/android.test.AndroidJUnitRunner
44  * </pre>
45  */
46 public class SensorBatchingTests extends SensorTestCase {
47     private static final String TAG = "SensorBatchingTests";
48 
49     private static final int BATCHING_PERIOD = 10;  // sec
50     private static final int RATE_50HZ = 20000;
51     private static final int RATE_FASTEST = SensorManager.SENSOR_DELAY_FASTEST;
52 
53     /**
54      * An arbitrary 'padding' time slot to wait for events after batching latency expires.
55      * This allows for the test to wait for event arrivals after batching was expected.
56      */
57     private static final int BATCHING_PADDING_TIME_S = (int) Math.ceil(BATCHING_PERIOD * 0.1f + 2);
58 
testAccelerometer_fastest_batching()59     public void testAccelerometer_fastest_batching() throws Throwable {
60         runBatchingSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_FASTEST, BATCHING_PERIOD);
61     }
62 
testAccelerometer_50hz_batching()63     public void testAccelerometer_50hz_batching() throws Throwable {
64         runBatchingSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_50HZ, BATCHING_PERIOD);
65     }
66 
testAccelerometer_fastest_flush()67     public void testAccelerometer_fastest_flush() throws Throwable {
68         runFlushSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_FASTEST, BATCHING_PERIOD);
69     }
70 
testAccelerometer_50hz_flush()71     public void testAccelerometer_50hz_flush() throws Throwable {
72         runFlushSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_50HZ, BATCHING_PERIOD);
73     }
74 
testAccelerometerUncalibrated_fastest_batching()75     public void testAccelerometerUncalibrated_fastest_batching() throws Throwable {
76         runBatchingSensorTest(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED,
77                               RATE_FASTEST,
78                               BATCHING_PERIOD);
79     }
80 
testAccelUncalibrated()81     public void testAccelUncalibrated() throws Throwable {
82         runBatchingSensorTest(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED,
83                               RATE_FASTEST,
84                               BATCHING_PERIOD);
85     }
86 
testAccelUncalibrated_50hz_batching()87     public void testAccelUncalibrated_50hz_batching() throws Throwable {
88         runBatchingSensorTest(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED, RATE_50HZ, BATCHING_PERIOD);
89     }
90 
testAccelUncalibrated_fastest_flush()91     public void testAccelUncalibrated_fastest_flush() throws Throwable {
92         runFlushSensorTest(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED, RATE_FASTEST, BATCHING_PERIOD);
93     }
94 
testAccelUncalibrated_50hz_flush()95     public void testAccelUncalibrated_50hz_flush() throws Throwable {
96         runFlushSensorTest(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED, RATE_50HZ, BATCHING_PERIOD);
97     }
98 
testMagneticField_fastest_batching()99     public void testMagneticField_fastest_batching() throws Throwable {
100         runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_FASTEST, BATCHING_PERIOD);
101     }
102 
testMagneticField_50hz_batching()103     public void testMagneticField_50hz_batching() throws Throwable {
104         runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_50HZ, BATCHING_PERIOD);
105     }
106 
testMagneticField_fastest_flush()107     public void testMagneticField_fastest_flush() throws Throwable {
108         runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_FASTEST, BATCHING_PERIOD);
109     }
110 
testMagneticField_50hz_flush()111     public void testMagneticField_50hz_flush() throws Throwable {
112         runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_50HZ, BATCHING_PERIOD);
113     }
114 
115     @SuppressWarnings("deprecation")
testOrientation_fastest_batching()116     public void testOrientation_fastest_batching() throws Throwable {
117         runBatchingSensorTest(Sensor.TYPE_ORIENTATION, RATE_FASTEST, BATCHING_PERIOD);
118     }
119 
120     @SuppressWarnings("deprecation")
testOrientation_50hz_batching()121     public void testOrientation_50hz_batching() throws Throwable {
122         runBatchingSensorTest(Sensor.TYPE_ORIENTATION, RATE_50HZ, BATCHING_PERIOD);
123     }
124 
125     @SuppressWarnings("deprecation")
testOrientation_fastest_flush()126     public void testOrientation_fastest_flush() throws Throwable {
127         runFlushSensorTest(Sensor.TYPE_ORIENTATION, RATE_FASTEST, BATCHING_PERIOD);
128     }
129 
130     @SuppressWarnings("deprecation")
testOrientation_50hz_flush()131     public void testOrientation_50hz_flush() throws Throwable {
132         runFlushSensorTest(Sensor.TYPE_ORIENTATION, RATE_50HZ, BATCHING_PERIOD);
133     }
134 
testGyroscope_fastest_batching()135     public void testGyroscope_fastest_batching() throws Throwable {
136         runBatchingSensorTest(Sensor.TYPE_GYROSCOPE, RATE_FASTEST, BATCHING_PERIOD);
137     }
138 
testGyroscope_50hz_batching()139     public void testGyroscope_50hz_batching() throws Throwable {
140         runBatchingSensorTest(Sensor.TYPE_GYROSCOPE, RATE_50HZ, BATCHING_PERIOD);
141     }
142 
testGyroscope_fastest_flush()143     public void testGyroscope_fastest_flush() throws Throwable {
144         runFlushSensorTest(Sensor.TYPE_GYROSCOPE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_PERIOD);
145     }
146 
testGyroscope_50hz_flush()147     public void testGyroscope_50hz_flush() throws Throwable {
148         runFlushSensorTest(Sensor.TYPE_GYROSCOPE, RATE_50HZ, BATCHING_PERIOD);
149     }
150 
testPressure_fastest_batching()151     public void testPressure_fastest_batching() throws Throwable {
152         runBatchingSensorTest(Sensor.TYPE_PRESSURE, RATE_FASTEST, BATCHING_PERIOD);
153     }
154 
testPressure_50hz_batching()155     public void testPressure_50hz_batching() throws Throwable {
156         runBatchingSensorTest(Sensor.TYPE_PRESSURE, RATE_50HZ, BATCHING_PERIOD);
157     }
158 
testPressure_fastest_flush()159     public void testPressure_fastest_flush() throws Throwable {
160         runFlushSensorTest(Sensor.TYPE_PRESSURE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_PERIOD);
161     }
162 
testPressure_50hz_flush()163     public void testPressure_50hz_flush() throws Throwable {
164         runFlushSensorTest(Sensor.TYPE_PRESSURE, RATE_50HZ, BATCHING_PERIOD);
165     }
166 
testGravity_fastest_batching()167     public void testGravity_fastest_batching() throws Throwable {
168         runBatchingSensorTest(Sensor.TYPE_GRAVITY, RATE_FASTEST, BATCHING_PERIOD);
169     }
170 
testGravity_50hz_batching()171     public void testGravity_50hz_batching() throws Throwable {
172         runBatchingSensorTest(Sensor.TYPE_GRAVITY, RATE_50HZ, BATCHING_PERIOD);
173     }
174 
testGravity_fastest_flush()175     public void testGravity_fastest_flush() throws Throwable {
176         runFlushSensorTest(Sensor.TYPE_GRAVITY, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_PERIOD);
177     }
178 
testGravity_50hz_flush()179     public void testGravity_50hz_flush() throws Throwable {
180         runFlushSensorTest(Sensor.TYPE_GRAVITY, RATE_50HZ, BATCHING_PERIOD);
181     }
182 
testRotationVector_fastest_batching()183     public void testRotationVector_fastest_batching() throws Throwable {
184         runBatchingSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
185     }
186 
testRotationVector_50hz_batching()187     public void testRotationVector_50hz_batching() throws Throwable {
188         runBatchingSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
189     }
190 
testRotationVector_fastest_flush()191     public void testRotationVector_fastest_flush() throws Throwable {
192         runFlushSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
193     }
194 
testRotationVector_50hz_flush()195     public void testRotationVector_50hz_flush() throws Throwable {
196         runFlushSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
197     }
198 
testMagneticFieldUncalibrated_fastest_batching()199     public void testMagneticFieldUncalibrated_fastest_batching() throws Throwable {
200         runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_FASTEST, BATCHING_PERIOD);
201     }
202 
testMagneticFieldUncalibrated_50hz_batching()203     public void testMagneticFieldUncalibrated_50hz_batching() throws Throwable {
204         runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_50HZ, BATCHING_PERIOD);
205     }
206 
testMagneticFieldUncalibrated_fastest_flush()207     public void testMagneticFieldUncalibrated_fastest_flush() throws Throwable {
208         runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_FASTEST, BATCHING_PERIOD);
209     }
210 
testMagneticFieldUncalibrated_50hz_flush()211     public void testMagneticFieldUncalibrated_50hz_flush() throws Throwable {
212         runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_50HZ, BATCHING_PERIOD);
213     }
214 
testGameRotationVector_fastest_batching()215     public void testGameRotationVector_fastest_batching() throws Throwable {
216         runBatchingSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
217     }
218 
testGameRotationVector_50hz_batching()219     public void testGameRotationVector_50hz_batching() throws Throwable {
220         runBatchingSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
221     }
222 
testGameRotationVector_fastest_flush()223     public void testGameRotationVector_fastest_flush() throws Throwable {
224         runFlushSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
225     }
226 
testGameRotationVector_50hz_flush()227     public void testGameRotationVector_50hz_flush() throws Throwable {
228         runFlushSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
229     }
230 
testGyroscopeUncalibrated_fastest_batching()231     public void testGyroscopeUncalibrated_fastest_batching() throws Throwable {
232         runBatchingSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_FASTEST, BATCHING_PERIOD);
233     }
234 
testGyroscopeUncalibrated_50hz_batching()235     public void testGyroscopeUncalibrated_50hz_batching() throws Throwable {
236         runBatchingSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_50HZ, BATCHING_PERIOD);
237     }
238 
testGyroscopeUncalibrated_fastest_flush()239     public void testGyroscopeUncalibrated_fastest_flush() throws Throwable {
240         runFlushSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_FASTEST, BATCHING_PERIOD);
241     }
242 
testGyroscopeUncalibrated_50hz_flush()243     public void testGyroscopeUncalibrated_50hz_flush() throws Throwable {
244         runFlushSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_50HZ, BATCHING_PERIOD);
245     }
246 
testLinearAcceleration_fastest_batching()247     public void testLinearAcceleration_fastest_batching() throws Throwable {
248         runBatchingSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_FASTEST, BATCHING_PERIOD);
249     }
250 
testLinearAcceleration_50hz_batching()251     public void testLinearAcceleration_50hz_batching() throws Throwable {
252         runBatchingSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_50HZ, BATCHING_PERIOD);
253     }
254 
testLinearAcceleration_fastest_flush()255     public void testLinearAcceleration_fastest_flush() throws Throwable {
256         runFlushSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_FASTEST, BATCHING_PERIOD);
257     }
258 
testLinearAcceleration_50hz_flush()259     public void testLinearAcceleration_50hz_flush() throws Throwable {
260         runFlushSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_50HZ, BATCHING_PERIOD);
261     }
262 
testGeomagneticRotationVector_fastest_batching()263     public void testGeomagneticRotationVector_fastest_batching() throws Throwable {
264         runBatchingSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
265     }
266 
testGeomagneticRotationVector_50hz_batching()267     public void testGeomagneticRotationVector_50hz_batching() throws Throwable {
268         runBatchingSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
269     }
270 
testGeomagneticRotationVector_fastest_flush()271     public void testGeomagneticRotationVector_fastest_flush() throws Throwable {
272         runFlushSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
273     }
274 
testGeomagneticRotationVector_50hz_flush()275     public void testGeomagneticRotationVector_50hz_flush() throws Throwable {
276         runFlushSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
277     }
278 
runBatchingSensorTest(int sensorType, int rateUs, int maxBatchReportLatencySec)279     private void runBatchingSensorTest(int sensorType, int rateUs, int maxBatchReportLatencySec)
280             throws Throwable {
281         int maxBatchReportLatencyUs = (int) TimeUnit.SECONDS.toMicros(maxBatchReportLatencySec);
282         int testDurationSec = maxBatchReportLatencySec + BATCHING_PADDING_TIME_S;
283 
284         TestSensorEnvironment environment = new TestSensorEnvironment(
285                 getContext(),
286                 sensorType,
287                 shouldEmulateSensorUnderLoad(),
288                 rateUs,
289                 maxBatchReportLatencyUs);
290         TestSensorOperation operation =
291                 TestSensorOperation.createOperation(environment, testDurationSec, TimeUnit.SECONDS);
292 
293         operation.addVerification(
294                 EventBasicVerification.getDefault(
295                         environment, TimeUnit.SECONDS.toMicros(testDurationSec)
296                 )
297         );
298         if (sensorType == Sensor.TYPE_GYROSCOPE_UNCALIBRATED) {
299             // Checks gyroscope uncalibrated should not have high pass filter.
300             operation.addVerification(
301                 MeanLargerThanVerification.getDefault(environment)
302             );
303         }
304         executeTest(environment, operation, false /* flushExpected */);
305     }
306 
runFlushSensorTest(int sensorType, int rateUs, int maxBatchReportLatencySec)307     private void runFlushSensorTest(int sensorType, int rateUs, int maxBatchReportLatencySec)
308             throws Throwable {
309         int maxBatchReportLatencyUs = (int) TimeUnit.SECONDS.toMicros(maxBatchReportLatencySec);
310         int flushDurationSec = maxBatchReportLatencySec / 2;
311 
312         TestSensorEnvironment environment = new TestSensorEnvironment(
313                 getContext(),
314                 sensorType,
315                 shouldEmulateSensorUnderLoad(),
316                 rateUs,
317                 maxBatchReportLatencyUs);
318         TestSensorOperation operation = TestSensorOperation
319                 .createFlushOperation(environment, flushDurationSec, TimeUnit.SECONDS);
320 
321         executeTest(environment, operation, true /* flushExpected */);
322     }
323 
executeTest( TestSensorEnvironment environment, TestSensorOperation operation, boolean flushExpected)324     private void executeTest(
325             TestSensorEnvironment environment,
326             TestSensorOperation operation,
327             boolean flushExpected) throws Throwable {
328         SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
329         operation.addDefaultVerifications();
330 
331         try {
332             operation.execute(getCurrentTestNode());
333         } finally {
334             SensorStats stats = operation.getStats();
335             stats.log(TAG);
336 
337             String sensorRate;
338             if (environment.getRequestedSamplingPeriodUs() == SensorManager.SENSOR_DELAY_FASTEST) {
339                 sensorRate = "fastest";
340             } else {
341                 sensorRate = String.format("%.0fhz", environment.getFrequencyHz());
342             }
343             String batching = environment.getMaxReportLatencyUs() > 0 ? "_batching" : "";
344             String flush = flushExpected ? "_flush" : "";
345             String fileName = String.format(
346                     "batching_%s_%s%s%s.txt",
347                     SensorStats.getSanitizedSensorName(environment.getSensor()),
348                     sensorRate,
349                     batching,
350                     flush);
351             stats.logToFile(environment.getContext(), fileName);
352         }
353     }
354 }
355