blob: 9d36f377aebe0ca8b6e07cfffc16014dd6545b0a [file] [log] [blame]
Eric Roweadabd172014-03-18 18:16:50 -07001/*
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
17package android.hardware.cts.helpers.sensorverification;
18
Tarandeep Singhe219b9a2015-06-11 19:58:15 +053019import android.content.Context;
20import android.content.pm.PackageManager;
21
22import android.util.Log;
Eric Roweadabd172014-03-18 18:16:50 -070023import android.hardware.Sensor;
24import android.hardware.cts.helpers.SensorCtsHelper;
25import android.hardware.cts.helpers.SensorStats;
destradaab7f89492014-09-19 14:23:04 -070026import android.hardware.cts.helpers.TestSensorEnvironment;
Eric Roweadabd172014-03-18 18:16:50 -070027import android.hardware.cts.helpers.TestSensorEvent;
destradaa485d4db2014-10-02 17:06:45 -070028import android.util.SparseIntArray;
Eric Roweadabd172014-03-18 18:16:50 -070029
John Rusnak86905512014-06-11 21:57:40 -070030import com.android.cts.util.StatisticsUtils;
31
Eric Roweadabd172014-03-18 18:16:50 -070032import java.util.ArrayList;
Eric Roweadabd172014-03-18 18:16:50 -070033import java.util.LinkedList;
34import java.util.List;
Peng Xu40b86b72015-09-15 13:11:58 -070035import junit.framework.Assert;
Eric Roweadabd172014-03-18 18:16:50 -070036
37/**
38 * A {@link ISensorVerification} which verifies that the sensor jitter is in an acceptable range.
39 */
40public class JitterVerification extends AbstractSensorVerification {
41 public static final String PASSED_KEY = "jitter_passed";
42
43 // sensorType: threshold (% of expected period)
destradaa485d4db2014-10-02 17:06:45 -070044 private static final SparseIntArray DEFAULTS = new SparseIntArray(12);
Peng Xud1ade0d2015-09-15 13:11:58 -070045 // Max allowed jitter in +/- sense (in percentage).
Ashutosh Joshid9229082015-08-21 14:51:57 -070046 private static final int GRACE_FACTOR = 2;
47 private static final int THRESHOLD_PERCENT_FOR_HIFI_SENSORS = 1 * GRACE_FACTOR;
Peng Xud1ade0d2015-09-15 13:11:58 -070048
49 // Margin sample intervals that considered outliers, lower and higher margin is discarded
50 // before verification
51 private static final float OUTLIER_MARGIN = 0.025f; //2.5%
52
Eric Roweadabd172014-03-18 18:16:50 -070053 static {
54 // Use a method so that the @deprecation warning can be set for that method only
55 setDefaults();
56 }
57
Peng Xud1ade0d2015-09-15 13:11:58 -070058 private final float mOutlierMargin;
59 private final long mThresholdNs;
60 private final long mExpectedPeriodNs; // for error message only
destradaa485d4db2014-10-02 17:06:45 -070061 private final List<Long> mTimestamps = new LinkedList<Long>();
Eric Roweadabd172014-03-18 18:16:50 -070062
63 /**
64 * Construct a {@link JitterVerification}
65 *
destradaa485d4db2014-10-02 17:06:45 -070066 * @param thresholdAsPercentage the acceptable margin of error as a percentage
Eric Roweadabd172014-03-18 18:16:50 -070067 */
Peng Xud1ade0d2015-09-15 13:11:58 -070068 public JitterVerification(float outlierMargin, long thresholdNs, long expectedPeriodNs) {
69 mExpectedPeriodNs = expectedPeriodNs;
70 mOutlierMargin = outlierMargin;
71 mThresholdNs = thresholdNs;
Eric Roweadabd172014-03-18 18:16:50 -070072 }
73
74 /**
75 * Get the default {@link JitterVerification} for a sensor.
76 *
destradaab7f89492014-09-19 14:23:04 -070077 * @param environment the test environment
Eric Roweadabd172014-03-18 18:16:50 -070078 * @return the verification or null if the verification does not apply to the sensor.
79 */
destradaab7f89492014-09-19 14:23:04 -070080 public static JitterVerification getDefault(TestSensorEnvironment environment) {
81 int sensorType = environment.getSensor().getType();
Peng Xud1ade0d2015-09-15 13:11:58 -070082
83 int thresholdPercent = DEFAULTS.get(sensorType, -1);
84 if (thresholdPercent == -1) {
Eric Roweadabd172014-03-18 18:16:50 -070085 return null;
86 }
Tarandeep Singhe219b9a2015-06-11 19:58:15 +053087 boolean hasHifiSensors = environment.getContext().getPackageManager().hasSystemFeature(
88 PackageManager.FEATURE_HIFI_SENSORS);
89 if (hasHifiSensors) {
Peng Xud1ade0d2015-09-15 13:11:58 -070090 thresholdPercent = THRESHOLD_PERCENT_FOR_HIFI_SENSORS;
Tarandeep Singhe219b9a2015-06-11 19:58:15 +053091 }
Peng Xud1ade0d2015-09-15 13:11:58 -070092
93 long expectedPeriodNs = (long) environment.getExpectedSamplingPeriodUs() * 1000;
94 long jitterThresholdNs = expectedPeriodNs * thresholdPercent * 2 / 100; // *2 is for +/-
95 return new JitterVerification(OUTLIER_MARGIN, jitterThresholdNs, expectedPeriodNs);
Eric Roweadabd172014-03-18 18:16:50 -070096 }
97
98 /**
99 * Verify that the 95th percentile of the jitter is in the acceptable range. Add
destradaa485d4db2014-10-02 17:06:45 -0700100 * {@value #PASSED_KEY} and {@value SensorStats#JITTER_95_PERCENTILE_PERCENT_KEY} keys to
Eric Roweadabd172014-03-18 18:16:50 -0700101 * {@link SensorStats}.
102 *
103 * @throws AssertionError if the verification failed.
104 */
105 @Override
destradaab7f89492014-09-19 14:23:04 -0700106 public void verify(TestSensorEnvironment environment, SensorStats stats) {
destradaa485d4db2014-10-02 17:06:45 -0700107 int timestampsCount = mTimestamps.size();
108 if (timestampsCount < 2 || environment.isSensorSamplingRateOverloaded()) {
destradaab7f89492014-09-19 14:23:04 -0700109 // the verification is not reliable in environments under load
Eric Roweadabd172014-03-18 18:16:50 -0700110 stats.addValue(PASSED_KEY, true);
111 return;
112 }
113
Peng Xud1ade0d2015-09-15 13:11:58 -0700114 List<Long> deltas = getDeltaValues();
115 float percentiles[] = new float[2];
116 percentiles[0] = mOutlierMargin;
117 percentiles[1] = 1 - percentiles[0];
Eric Roweadabd172014-03-18 18:16:50 -0700118
Peng Xud1ade0d2015-09-15 13:11:58 -0700119 List<Long> percentileValues = SensorCtsHelper.getPercentileValue(deltas, percentiles);
120 double normalizedRange =
121 (double)(percentileValues.get(1) - percentileValues.get(0)) / mThresholdNs;
122
123 double percentageJitter =
124 (double)(percentileValues.get(1) - percentileValues.get(0)) /
125 mExpectedPeriodNs / 2 * 100; //one side variation comparing to sample time
126
127 stats.addValue(SensorStats.JITTER_95_PERCENTILE_PERCENT_KEY, percentageJitter);
128
129 boolean success = normalizedRange <= 1.0;
destradaa485d4db2014-10-02 17:06:45 -0700130 stats.addValue(PASSED_KEY, success);
Eric Roweadabd172014-03-18 18:16:50 -0700131
destradaa485d4db2014-10-02 17:06:45 -0700132 if (!success) {
133 String message = String.format(
Peng Xud1ade0d2015-09-15 13:11:58 -0700134 "Jitter out of range: requested period = %dns, " +
135 "jitter min, max, range (95th percentile) = (%dns, %dns, %dns), " +
136 "jitter expected range <= %dns",
137 mExpectedPeriodNs,
138 percentileValues.get(0), percentileValues.get(1),
139 percentileValues.get(1) - percentileValues.get(0),
140 mThresholdNs);
destradaa485d4db2014-10-02 17:06:45 -0700141 Assert.fail(message);
Eric Roweadabd172014-03-18 18:16:50 -0700142 }
143 }
144
145 /**
146 * {@inheritDoc}
147 */
148 @Override
149 public JitterVerification clone() {
Peng Xud1ade0d2015-09-15 13:11:58 -0700150 return new JitterVerification(mOutlierMargin, mThresholdNs, mExpectedPeriodNs);
Eric Roweadabd172014-03-18 18:16:50 -0700151 }
152
153 /**
154 * {@inheritDoc}
155 */
156 @Override
157 protected void addSensorEventInternal(TestSensorEvent event) {
158 mTimestamps.add(event.timestamp);
159 }
160
161 /**
Peng Xud1ade0d2015-09-15 13:11:58 -0700162 * Get the list of delta values. Exposed for unit testing.
Eric Roweadabd172014-03-18 18:16:50 -0700163 */
Peng Xud1ade0d2015-09-15 13:11:58 -0700164 List<Long> getDeltaValues() {
Eric Roweadabd172014-03-18 18:16:50 -0700165 List<Long> deltas = new ArrayList<Long>(mTimestamps.size() - 1);
166 for (int i = 1; i < mTimestamps.size(); i++) {
destradaa485d4db2014-10-02 17:06:45 -0700167 deltas.add(mTimestamps.get(i) - mTimestamps.get(i - 1));
Eric Roweadabd172014-03-18 18:16:50 -0700168 }
Peng Xud1ade0d2015-09-15 13:11:58 -0700169 return deltas;
Eric Roweadabd172014-03-18 18:16:50 -0700170 }
171
172 @SuppressWarnings("deprecation")
173 private static void setDefaults() {
Eric Roweadabd172014-03-18 18:16:50 -0700174 DEFAULTS.put(Sensor.TYPE_ACCELEROMETER, Integer.MAX_VALUE);
175 DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD, Integer.MAX_VALUE);
destradaa485d4db2014-10-02 17:06:45 -0700176 DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, Integer.MAX_VALUE);
Eric Roweadabd172014-03-18 18:16:50 -0700177 DEFAULTS.put(Sensor.TYPE_GYROSCOPE, Integer.MAX_VALUE);
destradaa485d4db2014-10-02 17:06:45 -0700178 DEFAULTS.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, Integer.MAX_VALUE);
Eric Roweadabd172014-03-18 18:16:50 -0700179 DEFAULTS.put(Sensor.TYPE_ORIENTATION, Integer.MAX_VALUE);
180 DEFAULTS.put(Sensor.TYPE_PRESSURE, Integer.MAX_VALUE);
181 DEFAULTS.put(Sensor.TYPE_GRAVITY, Integer.MAX_VALUE);
182 DEFAULTS.put(Sensor.TYPE_LINEAR_ACCELERATION, Integer.MAX_VALUE);
183 DEFAULTS.put(Sensor.TYPE_ROTATION_VECTOR, Integer.MAX_VALUE);
Eric Roweadabd172014-03-18 18:16:50 -0700184 DEFAULTS.put(Sensor.TYPE_GAME_ROTATION_VECTOR, Integer.MAX_VALUE);
Eric Roweadabd172014-03-18 18:16:50 -0700185 DEFAULTS.put(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, Integer.MAX_VALUE);
186 }
187}