Modify tests for barometer
Update barometer MeanVerification according to Android O CDD update and add InitialValueVerification. The CTS pass on 2016 and 2017 devices.
Test: runtest --path cts/tests/sensor/src/android/hardware/cts/helpers/sensorverification
Test: cts-tradefed run cts --module CtsSensorTestCases --test android.hardware.cts
Bug: 38205487
Change-Id: Id9bf5d282a7ff46e55c1148ff64485236ed04ec1
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
index 52b3dee..4c8204f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
@@ -100,6 +100,7 @@
TestSensorOperation.createOperation(environment, 100 /* event count */);
verifyMeasurements.addVerification(new MeanVerification(
expectations,
+ new float[]{1.95f, 1.95f, 1.95f} /* m / s^2 */,
new float[]{1.95f, 1.95f, 1.95f} /* m / s^2 */));
verifyMeasurements.execute(getCurrentTestNode());
return null;
diff --git a/tests/sensor/src/android/hardware/cts/helpers/FrameworkUnitTests.java b/tests/sensor/src/android/hardware/cts/helpers/FrameworkUnitTests.java
index 87a9a2e..6480f55 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/FrameworkUnitTests.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/FrameworkUnitTests.java
@@ -23,6 +23,7 @@
import android.hardware.cts.helpers.sensorverification.EventGapVerificationTest;
import android.hardware.cts.helpers.sensorverification.EventOrderingVerificationTest;
import android.hardware.cts.helpers.sensorverification.FrequencyVerificationTest;
+import android.hardware.cts.helpers.sensorverification.InitialValueVerificationTest;
import android.hardware.cts.helpers.sensorverification.JitterVerificationTest;
import android.hardware.cts.helpers.sensorverification.MagnitudeVerificationTest;
import android.hardware.cts.helpers.sensorverification.MeanVerificationTest;
@@ -42,12 +43,13 @@
addTestSuite(SensorStatsTest.class);
// sensorverification
+ addTestSuite(EventGapVerificationTest.class);
addTestSuite(EventOrderingVerificationTest.class);
addTestSuite(FrequencyVerificationTest.class);
+ addTestSuite(InitialValueVerificationTest.class);
addTestSuite(JitterVerificationTest.class);
addTestSuite(MagnitudeVerificationTest.class);
addTestSuite(MeanVerificationTest.class);
- addTestSuite(EventGapVerificationTest.class);
addTestSuite(StandardDeviationVerificationTest.class);
addTestSuite(TimestampClockSourceVerificationTest.class);
diff --git a/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java b/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java
index 69ccfb3..06aa815 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java
@@ -227,6 +227,30 @@
}
/**
+ * Format an array of floats.
+ *
+ * @param array the array of floats
+ *
+ * @return The formatted string
+ */
+ public static String formatFloatArray(float[] array) {
+ StringBuilder sb = new StringBuilder();
+ if (array.length > 1) {
+ sb.append("(");
+ }
+ for (int i = 0; i < array.length; i++) {
+ sb.append(String.format("%.2f", array[i]));
+ if (i != array.length - 1) {
+ sb.append(", ");
+ }
+ }
+ if (array.length > 1) {
+ sb.append(")");
+ }
+ return sb.toString();
+ }
+
+ /**
* @return A {@link File} representing a root directory to store sensor tests data.
*/
public static File getSensorTestDataDirectory() throws IOException {
diff --git a/tests/sensor/src/android/hardware/cts/helpers/SensorStats.java b/tests/sensor/src/android/hardware/cts/helpers/SensorStats.java
index bc3db99..3892366 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/SensorStats.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/SensorStats.java
@@ -64,6 +64,8 @@
public static final String STANDARD_DEVIATION_KEY = "standard_deviation";
public static final String MAGNITUDE_KEY = "magnitude";
public static final String DELAYED_BATCH_DELIVERY = "delayed_batch_delivery";
+ public static final String INITIAL_MEAN_KEY = "initial_mean";
+ public static final String LATER_MEAN_KEY = "later_mean";
private final Map<String, Object> mValues = new HashMap<>();
private final Map<String, SensorStats> mSensorStats = new HashMap<>();
diff --git a/tests/sensor/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java b/tests/sensor/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
index 5ef2d3c..8aaadab 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
@@ -40,6 +40,7 @@
import android.hardware.cts.helpers.sensorverification.JitterVerification;
import android.hardware.cts.helpers.sensorverification.MagnitudeVerification;
import android.hardware.cts.helpers.sensorverification.MeanVerification;
+import android.hardware.cts.helpers.sensorverification.InitialValueVerification;
import android.hardware.cts.helpers.sensorverification.StandardDeviationVerification;
import android.os.Handler;
import android.os.SystemClock;
@@ -110,6 +111,7 @@
addVerification(MeanVerification.getDefault(mEnvironment));
addVerification(StandardDeviationVerification.getDefault(mEnvironment));
addVerification(EventTimestampSynchronizationVerification.getDefault(mEnvironment));
+ addVerification(InitialValueVerification.getDefault(mEnvironment));
}
public void addVerification(ISensorVerification verification) {
diff --git a/tests/sensor/src/android/hardware/cts/helpers/sensorverification/InitialValueVerification.java b/tests/sensor/src/android/hardware/cts/helpers/sensorverification/InitialValueVerification.java
new file mode 100644
index 0000000..da6a013
--- /dev/null
+++ b/tests/sensor/src/android/hardware/cts/helpers/sensorverification/InitialValueVerification.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.cts.helpers.sensorverification;
+
+import android.hardware.Sensor;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.TestSensorEvent;
+import android.util.Pair;
+
+import junit.framework.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A {@link ISensorVerification} which verifies that there are no ramps when starting the
+ * collection. To verify this, we compute the mean value at the beginning of the collection and
+ * compare it to the mean value at the end of the collection.
+ */
+public class InitialValueVerification extends AbstractSensorVerification {
+ public static final String PASSED_KEY = "initial_value_passed";
+ // Default length of the initial window: 2 seconds in ns
+ private static final long DEFAULT_INITIAL_WINDOW_LENGTH = 2_000_000_000L;
+
+ // sensorType: max absolute delta between the two means and initial window length
+ private static final Map<Integer, Pair<Float, Long>> DEFAULTS =
+ new HashMap<Integer, Pair<Float, Long>>(12);
+
+ static {
+ // Use a method so that the @deprecation warning can be set for that method only
+ setDefaults();
+ }
+
+ // First time stamp in nano seconds
+ private long mFirstTimestamp;
+ private float[] mInitialSum = null;
+ private int mInitialCount = 0;
+ private float[] mLaterSum = null;
+ private int mLaterCount = 0;
+
+ private final float mMaxAbsoluteDelta;
+ private final long mInitialWindowLength;
+
+ /**
+ * Construct a {@link InitialValueVerification}
+ *
+ * @param maxAbsoluteDelta the acceptable max absolute delta between the two means.
+ */
+ public InitialValueVerification(float maxAbsoluteDelta, long initialWindowLength) {
+ mMaxAbsoluteDelta = maxAbsoluteDelta;
+ mInitialWindowLength = initialWindowLength;
+ }
+
+ /**
+ * Get the default {@link InitialValueVerification} for a sensor.
+ *
+ * @param environment the test environment
+ * @return the verification or null if the verification does not apply to the sensor.
+ */
+ public static InitialValueVerification getDefault(TestSensorEnvironment environment) {
+ int sensorType = environment.getSensor().getType();
+ if (!DEFAULTS.containsKey(sensorType)) {
+ return null;
+ }
+ Pair<Float, Long> maxAbsoluteDeltaAndInitialWindowLength = DEFAULTS.get(sensorType);
+ return new InitialValueVerification(maxAbsoluteDeltaAndInitialWindowLength.first,
+ maxAbsoluteDeltaAndInitialWindowLength.second);
+ }
+
+ /**
+ * Verify that the mean at the initial window and later are similar to each other. Add
+ * {@value #PASSED_KEY}, {@value SensorStats#INITIAL_MEAN_KEY},
+ * {@value SensorStats#LATER_MEAN_KEY} keys to {@link SensorStats}.
+ *
+ * @throws AssertionError if the verification failed.
+ */
+ @Override
+ public void verify(TestSensorEnvironment environment, SensorStats stats) {
+ verify(stats);
+ }
+
+ /**
+ * Visible for unit tests only.
+ */
+ void verify(SensorStats stats) {
+ if (mInitialCount == 0) {
+ Assert.fail("Didn't collect any measurements");
+ }
+ if (mLaterCount == 0) {
+ Assert.fail(String.format("Didn't collect any measurements after %dns",
+ mInitialWindowLength));
+ }
+ float[] initialMeans = new float[mInitialSum.length];
+ float[] laterMeans = new float[mInitialSum.length];
+ boolean success = true;
+ for (int i = 0; i < mInitialSum.length; i++) {
+ initialMeans[i] = mInitialSum[i] / mInitialCount;
+ laterMeans[i] = mLaterSum[i] / mLaterCount;
+ if (Math.abs(initialMeans[i] - laterMeans[i]) > mMaxAbsoluteDelta) {
+ success = false;
+ }
+ }
+ stats.addValue(SensorStats.INITIAL_MEAN_KEY, initialMeans);
+ stats.addValue(SensorStats.LATER_MEAN_KEY, laterMeans);
+ stats.addValue(PASSED_KEY, success);
+ if (!success) {
+ Assert.fail(String.format(
+ "Means too far from each other: initial means = %s,"
+ + "later means = %s, max allowed delta = %.2f",
+ SensorCtsHelper.formatFloatArray(initialMeans),
+ SensorCtsHelper.formatFloatArray(laterMeans),
+ mMaxAbsoluteDelta));
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public InitialValueVerification clone() {
+ return new InitialValueVerification(mMaxAbsoluteDelta, mInitialWindowLength);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void addSensorEventInternal(TestSensorEvent event) {
+ if (mInitialSum == null) {
+ mFirstTimestamp = event.timestamp;
+ mInitialSum = new float[event.values.length];
+ mLaterSum = new float[event.values.length];
+ }
+ if (event.timestamp - mFirstTimestamp <= mInitialWindowLength) {
+ for (int i = 0; i < event.values.length; i++) {
+ mInitialSum[i] += event.values[i];
+ }
+ mInitialCount++;
+ } else {
+ for (int i = 0; i < event.values.length; i++) {
+ mLaterSum[i] += event.values[i];
+ }
+ mLaterCount++;
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private static void setDefaults() {
+ DEFAULTS.put(Sensor.TYPE_ACCELEROMETER,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ DEFAULTS.put(Sensor.TYPE_GYROSCOPE,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ DEFAULTS.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ DEFAULTS.put(Sensor.TYPE_ORIENTATION,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ // Very tight absolute delta for the barometer.
+ DEFAULTS.put(Sensor.TYPE_PRESSURE,
+ new Pair<Float, Long>(3f, DEFAULT_INITIAL_WINDOW_LENGTH));
+ DEFAULTS.put(Sensor.TYPE_GRAVITY,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ DEFAULTS.put(Sensor.TYPE_LINEAR_ACCELERATION,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ DEFAULTS.put(Sensor.TYPE_ROTATION_VECTOR,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ DEFAULTS.put(Sensor.TYPE_GAME_ROTATION_VECTOR,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ DEFAULTS.put(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR,
+ new Pair<Float, Long>(Float.MAX_VALUE, DEFAULT_INITIAL_WINDOW_LENGTH));
+ }
+}
+
diff --git a/tests/sensor/src/android/hardware/cts/helpers/sensorverification/InitialValueVerificationTest.java b/tests/sensor/src/android/hardware/cts/helpers/sensorverification/InitialValueVerificationTest.java
new file mode 100644
index 0000000..5e28d26
--- /dev/null
+++ b/tests/sensor/src/android/hardware/cts/helpers/sensorverification/InitialValueVerificationTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cts.helpers.sensorverification;
+
+import junit.framework.TestCase;
+
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Tests for {@link InitialValueVerification}.
+ */
+public class InitialValueVerificationTest extends TestCase {
+ private static final long INITIAL_WINDOW_LENGTH = 2_000_000_000L; // 2s
+ private static final long TOTAL_WINDOW_LENGTH = 5_000_000_000L; // 5s
+ private static final long SENSOR_PERIOD = 500_000_000L; // 0.5s
+ private static final float MAX_ABSOLUTE_DELTA = 3f;
+ private static final Random random = new Random(123L);
+ private static final float NOISE_STD = 0.01f;
+
+ /**
+ * Test {@link InitialValueVerification#verify(SensorStats)}.
+ */
+ public void testVerify() {
+ float[] initialValues = new float[] {80.4f, 12.3f, -67f};
+ verifyStatsWithTwoWindows(initialValues, initialValues, true);
+
+ // Only modify the first element in the array but close enough
+ float[] laterValues = new float[] {78.1f, 12.3f, -67f};
+ verifyStatsWithTwoWindows(initialValues, laterValues, true);
+ // Only modify the first element in the array but by more than the MAX_ABSOLUTE_DELTA
+ laterValues = new float[] {70.1f, 12.3f, -67f};
+ verifyStatsWithTwoWindows(initialValues, laterValues, false);
+
+ // Only modify the second element in the array but close enough
+ laterValues = new float[] {80.4f, 11.3f, -67f};
+ verifyStatsWithTwoWindows(initialValues, laterValues, true);
+ // Only modify the second element in the array but by more than the MAX_ABSOLUTE_DELTA
+ laterValues = new float[] {80.4f, 7.3f, -67f};
+ verifyStatsWithTwoWindows(initialValues, laterValues, false);
+
+ // Only modify the third element in the array but close enough
+ laterValues = new float[] {80.4f, 12.3f, -65f};
+ verifyStatsWithTwoWindows(initialValues, laterValues, true);
+ // Only modify the third element in the array but by more than the MAX_ABSOLUTE_DELTA
+ laterValues = new float[] {80.4f, 12.3f, 45f};
+ verifyStatsWithTwoWindows(initialValues, laterValues, false);
+ }
+
+ private static InitialValueVerification getVerification(Collection<TestSensorEvent> events,
+ float maxAbsoluteDelta, long initialWindowLength) {
+ InitialValueVerification verification =
+ new InitialValueVerification(maxAbsoluteDelta, initialWindowLength);
+ verification.addSensorEvents(events);
+ return verification;
+ }
+
+ private static void verifyStatsWithTwoWindows(float[] initialValues, float[] laterValues,
+ boolean pass) {
+ List<TestSensorEvent> events = new ArrayList<>();
+ // Initial window
+ for (long timestamp = 0L; timestamp <= INITIAL_WINDOW_LENGTH; timestamp += SENSOR_PERIOD) {
+ float[] initialValuesWithNoise = addNoise(initialValues);
+ events.add(new TestSensorEvent(null /* sensor */, timestamp, 0 /* accuracy */,
+ initialValuesWithNoise));
+ }
+ // Later window
+ for (long timestamp = INITIAL_WINDOW_LENGTH
+ + SENSOR_PERIOD; timestamp <= TOTAL_WINDOW_LENGTH; timestamp += SENSOR_PERIOD) {
+ float[] laterValuesWithNoise = addNoise(laterValues);
+ events.add(new TestSensorEvent(null /* sensor */, timestamp, 0 /* accuracy */,
+ laterValuesWithNoise));
+ }
+ SensorStats stats = new SensorStats();
+ InitialValueVerification verification =
+ getVerification(events, MAX_ABSOLUTE_DELTA, INITIAL_WINDOW_LENGTH);
+
+ try {
+ verification.verify(stats);
+ assertTrue(pass);
+ } catch (AssertionError e) {
+ assertFalse(pass);
+ }
+ verifyStats(stats, pass, initialValues, laterValues);
+ }
+
+ private static float[] addNoise(float[] values) {
+ float[] valuesWithNoise = new float[values.length];
+ for(int i = 0; i < values.length; i++) {
+ valuesWithNoise[i] = values[i] + random.nextFloat() * NOISE_STD;
+ }
+ return valuesWithNoise;
+ }
+
+ private static void verifyStats(SensorStats stats, boolean passed, float[] initialMeans,
+ float[] laterMeans) {
+ assertEquals(passed, stats.getValue(InitialValueVerification.PASSED_KEY));
+ float[] actualInitialMeans = (float[]) stats.getValue(SensorStats.INITIAL_MEAN_KEY);
+ float[] actualLaterMeans = (float[]) stats.getValue(SensorStats.LATER_MEAN_KEY);
+ assertEquals(initialMeans.length, actualInitialMeans.length);
+ assertEquals(laterMeans.length, actualLaterMeans.length);
+ for (int i = 0; i < initialMeans.length; i++) {
+ assertEquals(initialMeans[i], actualInitialMeans[i], 0.1);
+ assertEquals(laterMeans[i], actualLaterMeans[i], 0.1);
+ }
+ }
+}
diff --git a/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java b/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java
index 6603895..17882d7 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java
@@ -20,6 +20,7 @@
import android.hardware.Sensor;
import android.hardware.SensorManager;
+import android.hardware.cts.helpers.SensorCtsHelper;
import android.hardware.cts.helpers.SensorStats;
import android.hardware.cts.helpers.TestSensorEnvironment;
@@ -33,24 +34,28 @@
public static final String PASSED_KEY = "mean_passed";
// sensorType: {expected, threshold}
- private static final Map<Integer, Object[]> DEFAULTS = new HashMap<Integer, Object[]>(5);
+ private static final Map<Integer, ExpectedValuesAndThresholds> DEFAULTS
+ = new HashMap<Integer, ExpectedValuesAndThresholds>(5);
static {
// Use a method so that the @deprecation warning can be set for that method only
setDefaults();
}
private final float[] mExpected;
- private final float[] mThreshold;
+ private final float[] mUpperThresholds;
+ private final float[] mLowerThresholds;
/**
* Construct a {@link MeanVerification}
*
* @param expected the expected values
- * @param threshold the thresholds
+ * @param upperThresholds the upper thresholds
+ * @param lowerThresholds the lower thresholds
*/
- public MeanVerification(float[] expected, float[] threshold) {
+ public MeanVerification(float[] expected, float[] upperThresholds, float[] lowerThresholds) {
mExpected = expected;
- mThreshold = threshold;
+ mUpperThresholds = upperThresholds;
+ mLowerThresholds = lowerThresholds;
}
/**
@@ -64,9 +69,10 @@
if (!DEFAULTS.containsKey(sensorType)) {
return null;
}
- float[] expected = (float[]) DEFAULTS.get(sensorType)[0];
- float[] threshold = (float[]) DEFAULTS.get(sensorType)[1];
- return new MeanVerification(expected, threshold);
+ float[] expected = DEFAULTS.get(sensorType).mExpectedValues;
+ float[] upperThresholds = DEFAULTS.get(sensorType).mUpperThresholds;
+ float[] lowerThresholds = DEFAULTS.get(sensorType).mLowerThresholds;
+ return new MeanVerification(expected, upperThresholds, lowerThresholds);
}
/**
@@ -92,66 +98,104 @@
float[] means = getMeans();
boolean failed = false;
- StringBuilder meanSb = new StringBuilder();
- StringBuilder expectedSb = new StringBuilder();
-
- if (means.length > 1) {
- meanSb.append("(");
- expectedSb.append("(");
- }
for (int i = 0; i < means.length; i++) {
- if (Math.abs(means[i] - mExpected[i]) > mThreshold[i]) {
+ if (means[i] > mExpected[i] + mUpperThresholds[i]) {
failed = true;
}
- meanSb.append(String.format("%.2f", means[i]));
- if (i != means.length - 1) meanSb.append(", ");
- expectedSb.append(String.format("%.2f+/-%.2f", mExpected[i], mThreshold[i]));
- if (i != means.length - 1) expectedSb.append(", ");
- }
- if (means.length > 1) {
- meanSb.append(")");
- expectedSb.append(")");
+ if (means[i] < mExpected[i] - mLowerThresholds[i]) {
+ failed = true;
+ }
}
stats.addValue(PASSED_KEY, !failed);
stats.addValue(SensorStats.MEAN_KEY, means);
if (failed) {
- Assert.fail(String.format("Mean out of range: mean=%s (expected %s)", meanSb.toString(),
- expectedSb.toString()));
+ Assert.fail(String.format("Mean out of range: mean=%s (expected %s)",
+ SensorCtsHelper.formatFloatArray(means),
+ SensorCtsHelper.formatFloatArray(mExpected)));
}
}
@Override
public MeanVerification clone() {
- return new MeanVerification(mExpected, mThreshold);
+ return new MeanVerification(mExpected, mUpperThresholds, mLowerThresholds);
}
@SuppressWarnings("deprecation")
private static void setDefaults() {
// Sensors that we don't want to test at this time but still want to record the values.
// Gyroscope should be 0 for a static device
- DEFAULTS.put(Sensor.TYPE_GYROSCOPE, new Object[]{
- new float[]{0.0f, 0.0f, 0.0f},
- new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE}});
+ DEFAULTS.put(Sensor.TYPE_GYROSCOPE,
+ new ExpectedValuesAndThresholds(new float[]{0.0f, 0.0f, 0.0f},
+ new float[]{Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE},
+ new float[]{Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE}));
// Pressure will not be exact in a controlled environment but should be relatively close to
- // sea level. Second values should always be 0.
- DEFAULTS.put(Sensor.TYPE_PRESSURE, new Object[]{
- new float[]{SensorManager.PRESSURE_STANDARD_ATMOSPHERE, 0.0f, 0.0f},
- new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE}});
+ // sea level (400HPa and 200HPa are very lax thresholds).
+ // Second values should always be 0.
+ DEFAULTS.put(Sensor.TYPE_PRESSURE,
+ new ExpectedValuesAndThresholds(new float[]{SensorManager.PRESSURE_STANDARD_ATMOSPHERE,
+ 0.0f,
+ 0.0f},
+ new float[]{100f,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE},
+ new float[]{400f,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE}));
// Linear acceleration should be 0 in all directions for a static device
- DEFAULTS.put(Sensor.TYPE_LINEAR_ACCELERATION, new Object[]{
- new float[]{0.0f, 0.0f, 0.0f},
- new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE}});
+ DEFAULTS.put(Sensor.TYPE_LINEAR_ACCELERATION,
+ new ExpectedValuesAndThresholds(new float[]{0.0f, 0.0f, 0.0f},
+ new float[]{Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE},
+ new float[]{Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE}));
// Game rotation vector should be (0, 0, 0, 1, 0) for a static device
- DEFAULTS.put(Sensor.TYPE_GAME_ROTATION_VECTOR, new Object[]{
- new float[]{0.0f, 0.0f, 0.0f, 1.0f, 0.0f},
- new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
- Float.MAX_VALUE}});
+ DEFAULTS.put(Sensor.TYPE_GAME_ROTATION_VECTOR,
+ new ExpectedValuesAndThresholds(new float[]{0.0f, 0.0f, 0.0f, 1.0f, 0.0f},
+ new float[]{Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE},
+ new float[]{Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE}));
// Uncalibrated gyroscope should be 0 for a static device but allow a bigger threshold
- DEFAULTS.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, new Object[]{
- new float[]{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
- new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
- Float.MAX_VALUE, Float.MAX_VALUE}});
+ DEFAULTS.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED,
+ new ExpectedValuesAndThresholds(new float[]{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
+ new float[]{Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE},
+ new float[]{Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE,
+ Float.MAX_VALUE}));
+ }
+
+ private static final class ExpectedValuesAndThresholds {
+ private float[] mExpectedValues;
+ private float[] mUpperThresholds;
+ private float[] mLowerThresholds;
+ private ExpectedValuesAndThresholds(float[] expectedValues,
+ float[] upperThresholds,
+ float[] lowerThresholds) {
+ mExpectedValues = expectedValues;
+ mUpperThresholds = upperThresholds;
+ mLowerThresholds = lowerThresholds;
+ }
}
}
diff --git a/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerificationTest.java b/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerificationTest.java
index 64aef60..6661e78 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerificationTest.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/sensorverification/MeanVerificationTest.java
@@ -29,6 +29,7 @@
* Tests for {@link MeanVerification}.
*/
public class MeanVerificationTest extends TestCase {
+ private static final float[] MEANS = {2.0f, 3.0f, 6.0f};
/**
* Test {@link MeanVerification#verify(TestSensorEnvironment, SensorStats)}.
@@ -43,62 +44,106 @@
};
float[] expected = {2.0f, 3.0f, 6.0f};
- float[] threshold = {0.1f, 0.1f, 0.1f};
+ float[] upperThresholds = {0.3f, 0.3f, 0.3f};
+ float[] lowerThresholds = {0.1f, 0.1f, 0.1f};
SensorStats stats = new SensorStats();
- MeanVerification verification = getVerification(expected, threshold, values);
+ MeanVerification verification =
+ getVerification(expected, upperThresholds, lowerThresholds, values);
verification.verify(stats);
- verifyStats(stats, true, new float[]{2.0f, 3.0f, 6.0f});
+ verifyStats(stats, true, MEANS);
- expected = new float[]{2.5f, 2.5f, 5.5f};
- threshold = new float[]{0.6f, 0.6f, 0.6f};
+ // Test the lower threshold
+ expected = new float[]{2.4f, 3.3f, 6.4f};
+ lowerThresholds = new float[]{0.6f, 0.6f, 0.6f};
stats = new SensorStats();
- verification = getVerification(expected, threshold, values);
+ verification = getVerification(expected, upperThresholds, lowerThresholds, values);
verification.verify(stats);
- verifyStats(stats, true, new float[]{2.0f, 3.0f, 6.0f});
+ verifyStats(stats, true, MEANS);
- expected = new float[]{2.5f, 2.5f, 5.5f};
- threshold = new float[]{0.1f, 0.6f, 0.6f};
+ lowerThresholds = new float[]{0.1f, 0.6f, 0.6f};
stats = new SensorStats();
- verification = getVerification(expected, threshold, values);
+ verification = getVerification(expected, upperThresholds, lowerThresholds, values);
try {
verification.verify(stats);
throw new Error("Expected an AssertionError");
} catch (AssertionError e) {
// Expected;
}
- verifyStats(stats, false, new float[]{2.0f, 3.0f, 6.0f});
+ verifyStats(stats, false, MEANS);
- expected = new float[]{2.5f, 2.5f, 5.5f};
- threshold = new float[]{0.6f, 0.1f, 0.6f};
+ lowerThresholds = new float[]{0.6f, 0.1f, 0.6f};
stats = new SensorStats();
- verification = getVerification(expected, threshold, values);
+ verification = getVerification(expected, upperThresholds, lowerThresholds, values);
try {
verification.verify(stats);
throw new Error("Expected an AssertionError");
} catch (AssertionError e) {
// Expected;
}
- verifyStats(stats, false, new float[]{2.0f, 3.0f, 6.0f});
+ verifyStats(stats, false, MEANS);
- threshold = new float[]{0.6f, 0.6f, 0.1f};
+ lowerThresholds = new float[]{0.6f, 0.6f, 0.1f};
stats = new SensorStats();
- verification = getVerification(expected, threshold, values);
+ verification = getVerification(expected, upperThresholds, lowerThresholds, values);
try {
verification.verify(stats);
throw new Error("Expected an AssertionError");
} catch (AssertionError e) {
// Expected;
}
- verifyStats(stats, false, new float[]{2.0f, 3.0f, 6.0f});
+ verifyStats(stats, false, MEANS);
+
+ // Test the upper threshold
+ expected = new float[]{1.5f, 2.8f, 5.7f};
+ upperThresholds = new float[]{0.6f, 0.6f, 0.6f};
+ lowerThresholds = new float[]{0.1f, 0.1f, 0.1f};
+ stats = new SensorStats();
+ verification = getVerification(expected, upperThresholds, lowerThresholds, values);
+ verification.verify(stats);
+ verifyStats(stats, true, MEANS);
+
+ upperThresholds = new float[]{0.1f, 0.6f, 0.6f};
+ stats = new SensorStats();
+ verification = getVerification(expected, upperThresholds, lowerThresholds, values);
+ try {
+ verification.verify(stats);
+ throw new Error("Expected an AssertionError");
+ } catch (AssertionError e) {
+ // Expected;
+ }
+ verifyStats(stats, false, MEANS);
+
+ upperThresholds = new float[]{0.6f, 0.1f, 0.6f};
+ stats = new SensorStats();
+ verification = getVerification(expected, upperThresholds, lowerThresholds, values);
+ try {
+ verification.verify(stats);
+ throw new Error("Expected an AssertionError");
+ } catch (AssertionError e) {
+ // Expected;
+ }
+ verifyStats(stats, false, MEANS);
+
+ upperThresholds = new float[]{0.6f, 0.6f, 0.1f};
+ stats = new SensorStats();
+ verification = getVerification(expected, upperThresholds, lowerThresholds, values);
+ try {
+ verification.verify(stats);
+ throw new Error("Expected an AssertionError");
+ } catch (AssertionError e) {
+ // Expected;
+ }
+ verifyStats(stats, false, MEANS);
}
- private static MeanVerification getVerification(float[] expected, float[] threshold,
- float[] ... values) {
+ private static MeanVerification getVerification(float[] expected, float[] upperThresholds,
+ float[] lowerThresholds, float[] ... values) {
Collection<TestSensorEvent> events = new ArrayList<>(values.length);
for (float[] value : values) {
events.add(new TestSensorEvent(null, 0, 0, value));
}
- MeanVerification verification = new MeanVerification(expected, threshold);
+ MeanVerification verification =
+ new MeanVerification(expected, upperThresholds, lowerThresholds);
verification.addSensorEvents(events);
return verification;
}
@@ -106,6 +151,7 @@
private void verifyStats(SensorStats stats, boolean passed, float[] means) {
assertEquals(passed, stats.getValue(MeanVerification.PASSED_KEY));
float[] actual = (float[]) stats.getValue(SensorStats.MEAN_KEY);
+ assertEquals(means.length, actual.length);
for (int i = 0; i < means.length; i++) {
assertEquals(means[i], actual[i], 0.1);
}