1 /*
2  * Copyright (C) 2020 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.sensorverification;
18 
19 import junit.framework.Assert;
20 
21 import android.hardware.Sensor;
22 import android.hardware.cts.helpers.SensorStats;
23 import android.hardware.cts.helpers.TestSensorEnvironment;
24 import android.hardware.cts.helpers.TestSensorEvent;
25 
26 import java.lang.Math;
27 import java.util.LinkedList;
28 import java.util.List;
29 
30 /**
31  * A {@link ISensorVerification} that verifies the measurements of {@link Sensor#TYPE_HINGE_ANGLE}
32  *
33  * Its job is to verify that, while the tester manipulates the device:
34  * - Back-to-back duplicate values aren’t seen
35  * - Maximum range is not exceeded
36  * - No event values were less than 0
37  * - No updates were given more frequently than the resolution denotes
38  */
39 public class HingeAngleVerification extends AbstractSensorVerification {
40     public static final String PASSED_KEY = "hinge_angle_integration_passed";
41 
42     private final List<TestSensorEvent> mEvents = new LinkedList<>();
43 
44     @Override
verify(TestSensorEnvironment environment, SensorStats stats)45     public void verify(TestSensorEnvironment environment, SensorStats stats) {
46         float resolution = environment.getSensor().getResolution();
47         float maxRange = environment.getSensor().getMaximumRange();
48         TestSensorEvent lastEvent = null;
49 
50         boolean success = true;
51         StringBuilder builder = new StringBuilder("Hinge Angle | failures:");
52         Assert.assertTrue("The hinge angle sensor must output at least two sensor events",
53                 mEvents.size() >= 2);
54         for (int i = 0; i < mEvents.size(); i++) {
55             TestSensorEvent event = mEvents.get(i);
56             if (lastEvent != null && lastEvent.values[0] == event.values[0]) {
57                 success = false;
58                 String message = String.format("\nEvent time=%s, value=%s same as prior event" +
59                         " time=%s, value=%s", event.timestamp, event.values[0], lastEvent.timestamp,
60                         lastEvent.values[0]);
61                 builder.append(message);
62             }
63 
64             if (event.values[0] > maxRange) {
65                 success = false;
66                 String message = String.format("\nEvent time=%s, value=%s greater than maximum" +
67                         " range=%s", event.timestamp, event.values[0], maxRange);
68                 builder.append(message);
69             }
70 
71             if (event.values[0] < 0) {
72                 success = false;
73                 String message = String.format("\nEvent time=%s, value=%s less than 0",
74                         event.timestamp, event.values[0]);
75                 builder.append(message);
76             }
77 
78             // Make sure remainder is very close to zero, but not exactly to account for floating
79             // point division errors.
80             float remainder = event.values[0] == 0.0f ? 0 : Math.abs(event.values[0] % resolution);
81             if (remainder > 0.001 && resolution - remainder > 0.001) {
82                 success = false;
83                 String message = String.format("\nEvent time=%s, value=%s more fine grained than" +
84                         " resolution=%s %s", event.timestamp, event.values[0], resolution,
85                         remainder);
86                 builder.append(message);
87             }
88 
89             lastEvent = event;
90         }
91 
92         stats.addValue(PASSED_KEY, success);
93         Assert.assertTrue(builder.toString(), success);
94     }
95 
96     @Override
clone()97     public HingeAngleVerification clone() {
98         return new HingeAngleVerification();
99     }
100 
101     @Override
addSensorEventInternal(TestSensorEvent event)102     protected void addSensorEventInternal(TestSensorEvent event) {
103         mEvents.add(event);
104     }
105 }
106