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