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 44bed6c..5a0af28 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/AccelerometerMeasurementTestActivity.java
@@ -18,7 +18,8 @@
 
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
-import android.hardware.cts.helpers.sensoroperations.VerifySensorOperation;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.MeanVerification;
 
 import java.util.concurrent.TimeUnit;
 
@@ -74,15 +75,15 @@
      */
     private void verifyMeasurements(float ... expectations) throws Throwable {
         Thread.sleep(500 /*ms*/);
-        VerifySensorOperation verifyMeasurements = new VerifySensorOperation(
+        TestSensorOperation verifyMeasurements = new TestSensorOperation(
                 getApplicationContext(),
                 Sensor.TYPE_ACCELEROMETER,
                 SensorManager.SENSOR_DELAY_FASTEST,
                 0 /*reportLatencyInUs*/,
                 100 /* event count */);
-        verifyMeasurements.verifyMean(
+        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();
         logSuccess();
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
index cdb5b3f..066bda4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/GyroscopeMeasurementTestActivity.java
@@ -18,7 +18,8 @@
 
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
-import android.hardware.cts.helpers.sensoroperations.VerifySensorOperation;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.SigNumVerification;
 
 /**
  * Semi-automated test that focuses on characteristics associated with Accelerometer measurements.
@@ -96,15 +97,15 @@
         waitForUser();
 
         Thread.sleep(500 /*ms*/);
-        VerifySensorOperation verifySignum = new VerifySensorOperation(
+        TestSensorOperation verifySignum = new TestSensorOperation(
                 getApplicationContext(),
                 Sensor.TYPE_GYROSCOPE,
                 SensorManager.SENSOR_DELAY_FASTEST,
                 0 /*reportLatencyInUs*/,
                 100 /* event count */);
-        verifySignum.verifySignum(
+        verifySignum.addVerification(new SigNumVerification(
                 expectations,
-                new float[]{0.2f, 0.2f, 0.2f} /*noiseThreshold*/);
+                new float[]{0.2f, 0.2f, 0.2f} /*noiseThreshold*/));
         verifySignum.execute();
         logSuccess();
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java
index d36c998..a131b2b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagneticFieldMeasurementTestActivity.java
@@ -21,8 +21,11 @@
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener2;
 import android.hardware.SensorManager;
+import android.hardware.cts.helpers.TestSensorEventListener;
 import android.hardware.cts.helpers.TestSensorManager;
-import android.hardware.cts.helpers.sensoroperations.VerifySensorOperation;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.MagnitudeVerification;
+import android.hardware.cts.helpers.sensorverification.StandardDeviationVerification;
 
 /**
  * Semi-automated test that focuses characteristics associated with Accelerometer measurements.
@@ -64,9 +67,9 @@
 
         TestSensorManager magnetometer = new TestSensorManager(
                 this.getApplicationContext(), Sensor.TYPE_MAGNETIC_FIELD,
-                SensorManager.SENSOR_DELAY_NORMAL, 0, listener);
+                SensorManager.SENSOR_DELAY_NORMAL, 0);
         try {
-            magnetometer.registerListener();
+            magnetometer.registerListener(new TestSensorEventListener(listener));
             waitForUser();
         } finally {
             magnetometer.unregisterListener();
@@ -98,15 +101,15 @@
                 (SensorManager.MAGNETIC_FIELD_EARTH_MAX + SensorManager.MAGNETIC_FIELD_EARTH_MIN) / 2;
         float magneticFieldEarthThreshold =
                 expectedMagneticFieldEarth - SensorManager.MAGNETIC_FIELD_EARTH_MIN;
-        VerifySensorOperation verifyNorm = new VerifySensorOperation(
+        TestSensorOperation verifyNorm = new TestSensorOperation(
                 this.getApplicationContext(),
                 Sensor.TYPE_MAGNETIC_FIELD,
                 SensorManager.SENSOR_DELAY_FASTEST,
                 0 /*reportLatencyInUs*/,
                 100 /* event count */);
-        verifyNorm.verifyMagnitude(
+        verifyNorm.addVerification(new MagnitudeVerification(
                 expectedMagneticFieldEarth,
-                magneticFieldEarthThreshold);
+                magneticFieldEarthThreshold));
         verifyNorm.execute();
         logSuccess();
     }
@@ -135,14 +138,14 @@
      * the failure to help track down the issue.
      */
     private void verifyStandardDeviation() throws Throwable {
-        VerifySensorOperation verifyStdDev = new VerifySensorOperation(
+        TestSensorOperation verifyStdDev = new TestSensorOperation(
                 this.getApplicationContext(),
                 Sensor.TYPE_MAGNETIC_FIELD,
                 SensorManager.SENSOR_DELAY_FASTEST,
                 0 /*reportLatencyInUs*/,
                 100 /* event count */);
-        verifyStdDev.verifyStandardDeviation(
-                new float[]{2f, 2f, 2f} /* uT */);
+        verifyStdDev.addVerification(new StandardDeviationVerification(
+                new float[]{2f, 2f, 2f} /* uT */));
         verifyStdDev.execute();
         logSuccess();
     }
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
index bcf9755..c27d108 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
@@ -25,7 +25,8 @@
 import android.hardware.cts.helpers.sensoroperations.ParallelSensorOperation;
 import android.hardware.cts.helpers.sensoroperations.RepeatingSensorOperation;
 import android.hardware.cts.helpers.sensoroperations.SequentialSensorOperation;
-import android.hardware.cts.helpers.sensoroperations.VerifySensorOperation;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -96,22 +97,22 @@
 
         ParallelSensorOperation operation = new ParallelSensorOperation();
         for(int sensorType : sensorTypes) {
-            VerifySensorOperation continuousOperation = new VerifySensorOperation(
+            TestSensorOperation continuousOperation = new TestSensorOperation(
                     context,
                     sensorType,
                     SensorManager.SENSOR_DELAY_NORMAL,
                     0 /* reportLatencyInUs */,
                     100 /* event count */);
-            continuousOperation.verifyEventOrdering();
+            continuousOperation.addVerification(new EventOrderingVerification());
             operation.add(new RepeatingSensorOperation(continuousOperation, ITERATIONS));
 
-            VerifySensorOperation batchingOperation = new VerifySensorOperation(
+            TestSensorOperation batchingOperation = new TestSensorOperation(
                     context,
                     sensorType,
                     SensorTestInformation.getMaxSamplingRateInUs(context, sensorType),
                     SensorCtsHelper.getSecondsAsMicroSeconds(BATCHING_RATE_IN_SECONDS),
                     100);
-            batchingOperation.verifyEventOrdering();
+            batchingOperation.addVerification(new EventOrderingVerification());
             operation.add(new RepeatingSensorOperation(batchingOperation, ITERATIONS));
         }
         operation.execute();
@@ -154,13 +155,13 @@
             for(int instance = 0; instance < INSTANCES_TO_USE; ++instance) {
                 SequentialSensorOperation sequentialOperation = new SequentialSensorOperation();
                 for(int iteration = 0; iteration < ITERATIONS_TO_EXECUTE; ++iteration) {
-                    VerifySensorOperation sensorOperation = new VerifySensorOperation(
+                    TestSensorOperation sensorOperation = new TestSensorOperation(
                             this.getContext(),
                             sensorType,
                             this.generateSamplingRateInUs(sensorType),
                             this.generateReportLatencyInUs(),
                             100);
-                    sensorOperation.verifyEventOrdering();
+                    sensorOperation.addVerification(new EventOrderingVerification());
                     sequentialOperation.add(sensorOperation);
                 }
                 operation.add(sequentialOperation);
@@ -218,21 +219,21 @@
     public void testSensorStoppingInteraction() throws Throwable {
         Context context = this.getContext();
 
-        VerifySensorOperation tester = new VerifySensorOperation(
+        TestSensorOperation tester = new TestSensorOperation(
                 context,
                 mSensorTypeTester,
                 SensorManager.SENSOR_DELAY_NORMAL,
                 0 /*reportLatencyInUs*/,
                 100 /* event count */);
-        tester.verifyEventOrdering();
+        tester.addVerification(new EventOrderingVerification());
 
-        VerifySensorOperation testee = new VerifySensorOperation(
+        TestSensorOperation testee = new TestSensorOperation(
                 context,
                 mSensorTypeTestee,
                 SensorManager.SENSOR_DELAY_UI,
                 0 /*reportLatencyInUs*/,
                 100 /* event count */);
-        testee.verifyEventOrdering();
+        testee.addVerification(new EventOrderingVerification());
 
         ParallelSensorOperation operation = new ParallelSensorOperation();
         operation.add(tester, testee);
diff --git a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
index 8bdc161..647e7dc 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
@@ -22,11 +22,13 @@
 import android.hardware.cts.helpers.SensorStats;
 import android.hardware.cts.helpers.SensorTestCase;
 import android.hardware.cts.helpers.SensorTestInformation;
-import android.hardware.cts.helpers.sensoroperations.VerifySensorOperation;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.util.Log;
 
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Set of tests to verify that sensors operate correctly when operating alone.
@@ -214,12 +216,21 @@
                 minDelay * 8,
                 minDelay * 16,
         };
+        int[] maxBatchReportLatencyUss = {
+                0, // No batching
+                (int) TimeUnit.MICROSECONDS.convert(1, TimeUnit.SECONDS),
+                (int) TimeUnit.MICROSECONDS.convert(5, TimeUnit.SECONDS),
+        };
         for (int rateUs : rateUss) {
-            VerifySensorOperation op = new VerifySensorOperation(this.getContext(), sensorType,
-                    rateUs, 0, 100);
-            op.setDefaultVerifications();
-            op.execute();
-            SensorStats.logStats(TAG, op.getStats());
+            for (int maxBatchReportLatencyUs : maxBatchReportLatencyUss) {
+                Log.v(TAG, String.format("Run on %d with rate %d and batch %d", sensorType, rateUs,
+                        maxBatchReportLatencyUs));
+                TestSensorOperation op = new TestSensorOperation(this.getContext(), sensorType,
+                        rateUs, maxBatchReportLatencyUs, 1, TimeUnit.SECONDS);
+                op.setDefaultVerifications();
+                op.execute();
+                SensorStats.logStats(TAG, op.getStats());
+            }
         }
     }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/CollectingSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/CollectingSensorEventListener.java
new file mode 100644
index 0000000..981d74c
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/CollectingSensorEventListener.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 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;
+
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener2;
+import android.os.SystemClock;
+
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link TestSensorEventListener} which collects events to be processed after the test is run.
+ * This should only be used for short tests.
+ */
+public class CollectingSensorEventListener extends TestSensorEventListener {
+    private final ConcurrentLinkedDeque<TestSensorEvent> mSensorEventsList =
+            new ConcurrentLinkedDeque<TestSensorEvent>();
+
+    /**
+     * Constructs a {@link CollectingSensorEventListener} with an additional
+     * {@link SensorEventListener2}.
+     */
+    public CollectingSensorEventListener(SensorEventListener2 listener) {
+        super(listener);
+    }
+
+    /**
+     * Constructs a {@link CollectingSensorEventListener}.
+     */
+    public CollectingSensorEventListener() {
+        this(null);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+        super.onSensorChanged(event);
+        mSensorEventsList.addLast(new TestSensorEvent(event, SystemClock.elapsedRealtimeNanos()));
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Clears the event queue before starting.
+     * </p>
+     */
+    @Override
+    public void waitForEvents(int eventCount) {
+        clearEvents();
+        super.waitForEvents(eventCount);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Clears the event queue before starting.
+     * </p>
+     */
+    @Override
+    public void waitForEvents(long duration, TimeUnit timeUnit) {
+        clearEvents();
+        super.waitForEvents(duration, timeUnit);
+    }
+
+    /**
+     * Get the {@link TestSensorEvent} array from the event queue.
+     */
+    public TestSensorEvent[] getEvents() {
+        return mSensorEventsList.toArray(new TestSensorEvent[0]);
+    }
+
+    /**
+     * Clear the event queue.
+     */
+    public void clearEvents() {
+        mSensorEventsList.clear();
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/FrameworkUnitTests.java b/tests/tests/hardware/src/android/hardware/cts/helpers/FrameworkUnitTests.java
new file mode 100644
index 0000000..872bf28
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/FrameworkUnitTests.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 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;
+
+import android.hardware.cts.helpers.sensoroperations.SensorOperationTest;
+import android.hardware.cts.helpers.sensorverification.EventOrderingVerificationTest;
+import android.hardware.cts.helpers.sensorverification.FrequencyVerificationTest;
+import android.hardware.cts.helpers.sensorverification.JitterVerificationTest;
+import android.hardware.cts.helpers.sensorverification.MagnitudeVerificationTest;
+import android.hardware.cts.helpers.sensorverification.MeanVerificationTest;
+import android.hardware.cts.helpers.sensorverification.SigNumVerificationTest;
+import android.hardware.cts.helpers.sensorverification.StandardDeviationVerificationTest;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test suite for the CTS sensor framework.
+ */
+public class FrameworkUnitTests extends TestSuite {
+
+    public FrameworkUnitTests() {
+        super();
+
+        // helpers
+        addTestSuite(SensorCtsHelperTest.class);
+        addTestSuite(SensorStatsTest.class);
+
+        // sensorverification
+        addTestSuite(EventOrderingVerificationTest.class);
+        addTestSuite(FrequencyVerificationTest.class);
+        addTestSuite(JitterVerificationTest.class);
+        addTestSuite(MagnitudeVerificationTest.class);
+        addTestSuite(MeanVerificationTest.class);
+        addTestSuite(SigNumVerificationTest.class);
+        addTestSuite(StandardDeviationVerificationTest.class);
+
+        // sensorOperations
+        addTestSuite(SensorOperationTest.class);
+    }
+
+    public static Test suite() {
+        return new FrameworkUnitTests();
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
index 9f281b9..65e0072 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
@@ -56,72 +56,6 @@
     }
 
     /**
-     * Calculates the mean for each of the values in the set of TestSensorEvents.
-     *
-     * @throws IllegalArgumentException if there are no events
-     */
-    public static Float[] getMeans(TestSensorEvent[] events) {
-        if (events.length == 0) {
-            throw new IllegalArgumentException("Events cannot be empty");
-        }
-
-        Float[] means = new Float[events[0].values.length];
-        for (int i = 0; i < means.length; i++) {
-            means[i] = 0.0f;
-        }
-        for (TestSensorEvent event : events) {
-            for (int i = 0; i < means.length; i++) {
-                means[i] += event.values[i];
-            }
-        }
-        for (int i = 0; i < means.length; i++) {
-            means[i] /= events.length;
-        }
-        return means;
-    }
-
-    /**
-     * Calculates the bias-corrected variance for each of the values in the set of TestSensorEvents.
-     *
-     * @throws IllegalArgumentException if there are no events
-     */
-    public static Float[] getVariances(TestSensorEvent[] events) {
-        Float[] means = getMeans(events);
-        Float[] variances = new Float[means.length];
-        for (int i = 0; i < variances.length; i++) {
-            variances[i] = 0.0f;
-        }
-        for (int i = 0; i < means.length; i++) {
-            Collection<Float> squaredDiffs = new ArrayList<Float>(events.length);
-            for (TestSensorEvent event : events) {
-                float diff = event.values[i] - means[i];
-                squaredDiffs.add(diff * diff);
-            }
-            float sum = 0.0f;
-            for (float value : squaredDiffs) {
-                sum += value;
-            }
-            variances[i] = sum / (events.length - 1);
-        }
-        return variances;
-    }
-
-    /**
-     * Calculates the bias-corrected standard deviation for each of the values in the set of
-     * TestSensorEvents.
-     *
-     * @throws IllegalArgumentException if there are no events
-     */
-    public static Float[] getStandardDeviations(TestSensorEvent[] events) {
-        Float[] variances = getVariances(events);
-        Float[] stdDevs = new Float[variances.length];
-        for (int i = 0; i < variances.length; i++) {
-            stdDevs[i] = (float) Math.sqrt(variances[i]);
-        }
-        return stdDevs;
-    }
-
-    /**
      * Calculate the mean of a collection.
      *
      * @throws IllegalArgumentException if the collection is null or empty
@@ -169,41 +103,6 @@
     }
 
     /**
-     * Get a list containing the delay between sensor events.
-     *
-     * @param events The array of {@link TestSensorEvent}.
-     * @return A list containing the delay between sensor events in nanoseconds.
-     */
-    public static List<Long> getTimestampDelayValues(TestSensorEvent[] events) {
-        if (events.length < 2) {
-            return new ArrayList<Long>();
-        }
-        List<Long> timestampDelayValues = new ArrayList<Long>(events.length - 1);
-        for (int i = 1; i < events.length; i++) {
-            timestampDelayValues.add(events[i].timestamp - events[i - 1].timestamp);
-        }
-        return timestampDelayValues;
-    }
-
-    /**
-     * Get a list containing the jitter values for a collection of sensor events.
-     *
-     * @param events The array of {@link TestSensorEvent}.
-     * @return A list containing the jitter values between each event.
-     * @throws IllegalArgumentException if the number of events is less that 2.
-     */
-    public static List<Double> getJitterValues(TestSensorEvent[] events) {
-        List<Long> timestampDelayValues = getTimestampDelayValues(events);
-        double averageTimestampDelay = getMean(timestampDelayValues);
-
-        List<Double> jitterValues = new ArrayList<Double>(timestampDelayValues.size());
-        for (long timestampDelay : timestampDelayValues) {
-            jitterValues.add(Math.abs(timestampDelay - averageTimestampDelay));
-        }
-        return jitterValues;
-    }
-
-    /**
      * Get the default sensor for a given type.
      */
     public static Sensor getSensor(Context context, int sensorType) {
@@ -279,6 +178,16 @@
     }
 
     /**
+     * Return true if the operation rate is not one of {@link SensorManager#SENSOR_DELAY_GAME},
+     * {@link SensorManager#SENSOR_DELAY_UI}, or {@link SensorManager#SENSOR_DELAY_NORMAL}.
+     */
+    public boolean isDelayRateTestable(int rateUs) {
+        return (rateUs != SensorManager.SENSOR_DELAY_GAME
+                && rateUs != SensorManager.SENSOR_DELAY_UI
+                && rateUs != SensorManager.SENSOR_DELAY_NORMAL);
+    }
+
+    /**
      * Helper method to sleep for a given duration.
      */
     public static void sleep(long duration, TimeUnit timeUnit) {
@@ -291,6 +200,34 @@
     }
 
     /**
+     * Format an assertion message.
+     *
+     * @param sensor the {@link Sensor}
+     * @param label the verification name
+     * @return The formatted string
+     */
+    public static String formatAssertionMessage(Sensor sensor, String label) {
+        return String.format("%s | %s, handle: %d", label,
+                SensorTestInformation.getSensorName(sensor.getType()), sensor.getHandle());
+    }
+
+    /**
+     * Format an assertion message with a custom message.
+     *
+     * @param sensor the {@link Sensor}
+     * @param label the verification name
+     * @param format the additional format string
+     * @param params the additional format params
+     * @return The formatted string
+     */
+    public static String formatAssertionMessage(Sensor sensor, String label, String format,
+            Object ... params) {
+        return String.format("%s | %s, handle: %d | %s", label,
+                SensorTestInformation.getSensorName(sensor.getType()), sensor.getHandle(),
+                String.format(format, params));
+    }
+
+    /**
      * Validate that a collection is not null or empty.
      *
      * @throws IllegalStateException if collection is null or empty.
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java
index b8cb06f..6f99692 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java
@@ -53,73 +53,6 @@
     }
 
     /**
-     * Test {@link SensorCtsHelper#getMeans(TestSensorEvent[])}.
-     */
-    public void testGetMeans() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-
-        float[] values = {0, 1, 2, 3, 4};  // 2.0
-        Float[] means = SensorCtsHelper.getMeans(getSensorEvents(timestamps, values));
-        assertEquals(1, means.length);
-        assertEquals(2.0, means[0], 0.00001);
-
-        float[] values1 = {0, 1, 2, 3, 4};  // 2.0
-        float[] values2 = {1, 2, 3, 4, 5};  // 3.0
-        float[] values3 = {0, 1, 4, 9, 16};  // 6.0
-        means = SensorCtsHelper.getMeans(
-                getSensorEvents(timestamps, values1, values2, values3));
-        assertEquals(3, means.length);
-        assertEquals(2.0, means[0], 0.00001);
-        assertEquals(3.0, means[1], 0.00001);
-        assertEquals(6.0, means[2], 0.00001);
-    }
-
-    /**
-     * Test {@link SensorCtsHelper#getVariances(TestSensorEvent[])}.
-     */
-    public void testGetVariences() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-
-        float[] values = {0, 1, 2, 3, 4};  // 2.5
-        Float[] variances = SensorCtsHelper.getVariances(getSensorEvents(timestamps, values));
-        assertEquals(1, variances.length);
-        assertEquals(2.5, variances[0], 0.00001);
-
-        float[] values1 = {0, 1, 2, 3, 4};  // 2.5
-        float[] values2 = {1, 2, 3, 4, 5};  // 2.5
-        float[] values3 = {0, 2, 4, 6, 8};  // 10.0
-        variances = SensorCtsHelper.getVariances(
-                getSensorEvents(timestamps, values1, values2, values3));
-        assertEquals(3, variances.length);
-        assertEquals(2.5, variances[0], 0.00001);
-        assertEquals(2.5, variances[1], 0.00001);
-        assertEquals(10.0, variances[2], 0.00001);
-    }
-
-    /**
-     * Test {@link SensorCtsHelper#getStandardDeviations(TestSensorEvent[])}.
-     */
-    public void testGetStandardDeviations() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-
-        float[] values = {0, 1, 2, 3, 4};  // sqrt(2.5)
-        Float[] stddev = SensorCtsHelper.getStandardDeviations(
-                getSensorEvents(timestamps, values));
-        assertEquals(1, stddev.length);
-        assertEquals(Math.sqrt(2.5), stddev[0], 0.00001);
-
-        float[] values1 = {0, 1, 2, 3, 4};  // sqrt(2.5)
-        float[] values2 = {1, 2, 3, 4, 5};  // sqrt(2.5)
-        float[] values3 = {0, 2, 4, 6, 8};  // sqrt(10.0)
-        stddev = SensorCtsHelper.getStandardDeviations(
-                getSensorEvents(timestamps, values1, values2, values3));
-        assertEquals(3, stddev.length);
-        assertEquals(Math.sqrt(2.5), stddev[0], 0.00001);
-        assertEquals(Math.sqrt(2.5), stddev[1], 0.00001);
-        assertEquals(Math.sqrt(10.0), stddev[2], 0.00001);
-    }
-
-    /**
      * Test {@link SensorCtsHelper#getMean(Collection)}.
      */
     public void testGetMean() {
@@ -171,22 +104,6 @@
     }
 
     /**
-     * Test {@link SensorCtsHelper#getTimestampDelayValues(TestSensorEvent[])}.
-     */
-    public void testGetTimestampDelayValues() {
-        float[] values = {0, 1, 2, 3, 4};
-
-        long[] timestamps = {0, 0, 1, 3, 100};
-        List<Long> timestampDelayValues = SensorCtsHelper.getTimestampDelayValues(
-                getSensorEvents(timestamps, values));
-        assertEquals(4, timestampDelayValues.size());
-        assertEquals(0, (long) timestampDelayValues.get(0));
-        assertEquals(1, (long) timestampDelayValues.get(1));
-        assertEquals(2, (long) timestampDelayValues.get(2));
-        assertEquals(97, (long) timestampDelayValues.get(3));
-    }
-
-    /**
      * Test {@link SensorCtsHelper#getFrequency(Number, TimeUnit)}.
      */
     public void testGetFrequency() {
@@ -217,50 +134,4 @@
         assertEquals(100, SensorCtsHelper.getPeriod(10000000, TimeUnit.NANOSECONDS), 0.001);
         assertEquals(1, SensorCtsHelper.getPeriod(1000000000, TimeUnit.NANOSECONDS), 0.001);
     }
-
-    /**
-     * Test {@link SensorCtsHelper#getJitterValues(TestSensorEvent[])}.
-     */
-    public void testGetJitterValues() {
-        float[] values = {0, 1, 2, 3, 4};
-
-        long[] timestamps1 = {0, 1, 2, 3, 4};
-        List<Double> jitterValues = SensorCtsHelper.getJitterValues(
-                getSensorEvents(timestamps1, values));
-        assertEquals(4, jitterValues.size());
-        assertEquals(0.0, (double) jitterValues.get(0));
-        assertEquals(0.0, (double) jitterValues.get(1));
-        assertEquals(0.0, (double) jitterValues.get(2));
-        assertEquals(0.0, (double) jitterValues.get(3));
-
-        long[] timestamps2 = {0, 0, 2, 4, 4};
-        jitterValues = SensorCtsHelper.getJitterValues(
-                getSensorEvents(timestamps2, values));
-        assertEquals(4, jitterValues.size());
-        assertEquals(1.0, (double) jitterValues.get(0));
-        assertEquals(1.0, (double) jitterValues.get(1));
-        assertEquals(1.0, (double) jitterValues.get(2));
-        assertEquals(1.0, (double) jitterValues.get(3));
-
-        long[] timestamps3 = {0, 1, 4, 9, 16};
-        jitterValues = SensorCtsHelper.getJitterValues(
-                getSensorEvents(timestamps3, values));
-        assertEquals(4, jitterValues.size());
-        assertEquals(3.0, (double) jitterValues.get(0));
-        assertEquals(1.0, (double) jitterValues.get(1));
-        assertEquals(1.0, (double) jitterValues.get(2));
-        assertEquals(3.0, (double) jitterValues.get(3));
-    }
-
-    private TestSensorEvent[] getSensorEvents(long[] timestamps, float[] ... values) {
-        TestSensorEvent[] events = new TestSensorEvent[timestamps.length];
-        for (int i = 0; i < timestamps.length; i++) {
-            float[] eventValues = new float[values.length];
-            for (int j = 0; j < values.length; j++) {
-                eventValues[j] = values[j][i];
-            }
-            events[i] = new TestSensorEvent(null, timestamps[i], 0, eventValues);
-        }
-        return events;
-    }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
index 48f8136..1898570 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
@@ -20,11 +20,13 @@
 import android.util.Log;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
 /**
  * Class used to store stats related to {@link ISensorOperation}s.  Sensor stats may be linked
@@ -33,6 +35,17 @@
 public class SensorStats {
     public static final String DELIMITER = "__";
 
+    public static final String FIRST_TIMESTAMP_KEY = "first_timestamp";
+    public static final String LAST_TIMESTAMP_KEY = "last_timestamp";
+    public static final String EVENT_COUNT_KEY = "event_count";
+    public static final String EVENT_OUT_OF_ORDER_COUNT_KEY = "event_out_of_order_count";
+    public static final String EVENT_OUT_OF_ORDER_POSITIONS_KEY = "event_out_of_order_positions";
+    public static final String FREQUENCY_KEY = "frequency";
+    public static final String JITTER_95_PERCENTILE_KEY = "jitter_95_percentile";
+    public static final String MEAN_KEY = "mean";
+    public static final String STANDARD_DEVIATION_KEY = "standard_deviation";
+    public static final String MAGNITUDE_KEY = "magnitude";
+
     private final Map<String, Object> mValues = new HashMap<String, Object>();
     private final Map<String, SensorStats> mSensorStats = new HashMap<String, SensorStats>();
 
@@ -64,6 +77,22 @@
     }
 
     /**
+     * Get the keys from the values table. Will not get the keys from the nested
+     * {@link SensorStats}.
+     */
+    public synchronized Set<String> getKeys() {
+        return mValues.keySet();
+    }
+
+    /**
+     * Get a value from the values table. Will not attempt to get values from nested
+     * {@link SensorStats}.
+     */
+    public synchronized Object getValue(String key) {
+        return mValues.get(key);
+    }
+
+    /**
      * Flattens the map and all sub {@link SensorStats} objects. Keys will be flattened using
      * {@value #DELIMITER}. For example, if a sub {@link SensorStats} is added with key
      * {@code "key1"} containing the key value pair {@code ("key2", "value")}, the flattened map
@@ -91,11 +120,31 @@
         Collections.sort(keys);
         for (String key : keys) {
             Object value = flattened.get(key);
-            if (value instanceof Double || value instanceof Float) {
-                Log.v(tag, String.format("%s: %.4f", key, value));
+            if (value instanceof boolean[]) {
+                logStat(tag, key, Arrays.toString((boolean[]) value));
+            } else if (value instanceof byte[]) {
+                logStat(tag, key, Arrays.toString((byte[]) value));
+            } else if (value instanceof char[]) {
+                logStat(tag, key, Arrays.toString((char[]) value));
+            } else if (value instanceof double[]) {
+                logStat(tag, key, Arrays.toString((double[]) value));
+            } else if (value instanceof float[]) {
+                logStat(tag, key, Arrays.toString((float[]) value));
+            } else if (value instanceof int[]) {
+                logStat(tag, key, Arrays.toString((int[]) value));
+            } else if (value instanceof long[]) {
+                logStat(tag, key, Arrays.toString((long[]) value));
+            } else if (value instanceof short[]) {
+                logStat(tag, key, Arrays.toString((short[]) value));
+            } else if (value instanceof Object[]) {
+                logStat(tag, key, Arrays.toString((Object[]) value));
             } else {
-                Log.v(tag, String.format("%s: %s", key, value.toString()));
+                logStat(tag, key, value.toString());
             }
         }
     }
+
+    private static void logStat(String tag, String key, String value) {
+        Log.v(tag, String.format("%s: %s", key, value));
+    }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelper.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelper.java
deleted file mode 100644
index 76e243f..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelper.java
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Copyright (C) 2014 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;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Set of static helper methods to verify sensor CTS tests.
- */
-public class SensorVerificationHelper {
-
-    public static final String EVENT_ORDER_COUNT_KEY = "event_order_count";
-    public static final String EVENT_ORDER_POSITIONS_KEY = "event_order_positions";
-    public static final String FREQUENCY_KEY = "frequency";
-    public static final String JITTER_95_PERCENTILE_KEY = "jitter_95_percentile";
-    public static final String MEAN_KEY = "mean";
-    public static final String MAGNITUDE_KEY = "magnitude";
-    public static final String STANDARD_DEVIATION_KEY = "standard_deviation";
-
-    private static final int MESSAGE_LENGTH = 3;
-
-    /**
-     * Class which holds results from the verification.
-     */
-    public static class VerificationResult {
-        private boolean mFailed = false;
-        private String mMessage = null;
-        private Map<String, Object> mValueMap = new HashMap<String, Object>();
-
-        public void fail(String messageFormat, Object ... args) {
-            mFailed = true;
-            mMessage = String.format(messageFormat, args);
-        }
-
-        public boolean isFailed() {
-            return mFailed;
-        }
-
-        public String getFailureMessage() {
-            return mMessage;
-        }
-
-        public void putValue(String key, Object value) {
-            mValueMap.put(key, value);
-        }
-
-        public Set<String> getKeys() {
-            return mValueMap.keySet();
-        }
-
-        public Object getValue(String key) {
-            return mValueMap.get(key);
-        }
-    }
-
-    /**
-     * Private constructor for static class.
-     */
-    private SensorVerificationHelper() {}
-
-    /**
-     * Verify that the events are in the correct order.
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @return a {@link VerificationResult} containing the verification info including the keys
-     *     "count" which is the number of events out of order and "positions" which contains an
-     *     array of indexes that were out of order.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifyEventOrdering(TestSensorEvent[] events) {
-        VerificationResult result = new VerificationResult();
-        List<Integer> indices = new ArrayList<Integer>();
-        long maxTimestamp = events[0].timestamp;
-        for (int i = 1; i < events.length; i++) {
-            long currentTimestamp = events[i].timestamp;
-            if (currentTimestamp < maxTimestamp) {
-                indices.add(i);
-            } else if (currentTimestamp > maxTimestamp) {
-                maxTimestamp = currentTimestamp;
-            }
-        }
-
-        result.putValue(EVENT_ORDER_COUNT_KEY, indices.size());
-        result.putValue(EVENT_ORDER_POSITIONS_KEY, indices);
-
-        if (indices.size() > 0) {
-            StringBuilder sb = new StringBuilder();
-            sb.append(indices.size()).append(" events out of order: ");
-            for (int i = 0; i < Math.min(indices.size(), MESSAGE_LENGTH); i++) {
-                int index = indices.get(i);
-                sb.append(String.format("position=%d, previous=%d, timestamp=%d; ", index,
-                        events[index - 1].timestamp, events[index].timestamp));
-            }
-            if (indices.size() > MESSAGE_LENGTH) {
-                sb.append(indices.size() - MESSAGE_LENGTH).append(" more");
-            } else {
-                // Delete the "; "
-                sb.delete(sb.length() - 2, sb.length());
-            }
-
-            result.fail(sb.toString());
-        }
-
-        return result;
-    }
-
-    /**
-     * Verify that the sensor frequency matches the expected frequency.
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @param expected The expected frequency in Hz
-     * @param lowerThreshold The acceptable margin of error in Hz for the lower bound
-     * @param upperThreshold The acceptable margin of error in Hz for the upper bound
-     * @return a {@link VerificationResult} containing the verification info including the key
-     *     "frequency" which is the computed frequency of the events in Hz.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifyFrequency(TestSensorEvent[] events, double expected,
-            double lowerThreshold, double upperThreshold) {
-        VerificationResult result = new VerificationResult();
-        List<Long> timestampDelayValues = SensorCtsHelper.getTimestampDelayValues(events);
-        double frequency = SensorCtsHelper.getFrequency(
-                SensorCtsHelper.getMean(timestampDelayValues), TimeUnit.NANOSECONDS);
-        result.putValue(FREQUENCY_KEY, frequency);
-
-        if (frequency <= expected - lowerThreshold || frequency >= expected + upperThreshold) {
-            result.fail("Frequency out of range: frequency=%.2fHz, "
-                    + "expected=(%.2f-%.2fHz, %.2f+.%2f)", frequency, expected, lowerThreshold,
-                    expected, upperThreshold);
-        }
-        return result;
-    }
-
-    /**
-     * Verify that the jitter is in an acceptable range
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @param expected the expected period in ns
-     * @param threshold The acceptable margin of error as a percentage
-     * @return a {@link VerificationResult} containing the verification info including the keys
-     *     "jitter" which is the list of computed jitter values and "jitter95Percentile" which is
-     *     95th percentile of the jitter values.
-     * @throws IllegalStateException if number of events less than 2.
-     */
-    public static VerificationResult verifyJitter(TestSensorEvent[] events, int expected,
-            int threshold) {
-        VerificationResult result = new VerificationResult();
-        List<Double> jitterValues = SensorCtsHelper.getJitterValues(events);
-        double jitter95Percentile = SensorCtsHelper.get95PercentileValue(jitterValues);
-        result.putValue(JITTER_95_PERCENTILE_KEY, jitter95Percentile);
-
-        if (jitter95Percentile > expected * (threshold / 100.0)) {
-            result.fail("Jitter out of range: jitter at 95th percentile=%.0fns, expected=<%.0fns",
-                    jitter95Percentile, expected * (threshold / 100.0));
-        }
-        return result;
-    }
-
-    /**
-     * Verify that the means matches the expected measurement.
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @param expected The array of expected values
-     * @param threshold The array of thresholds
-     * @return a {@link VerificationResult} containing the verification info including the key
-     *     "mean" which is the computed means for each value of the sensor.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifyMean(TestSensorEvent[] events, float[] expected,
-            float[] threshold) {
-        VerificationResult result = new VerificationResult();
-        Float[] means = SensorCtsHelper.getMeans(events);
-        result.putValue(MEAN_KEY, Arrays.asList(means));
-
-        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] - expected[i]) > threshold[i]) {
-                failed = true;
-            }
-            meanSb.append(String.format("%.2f", means[i]));
-            if (i != means.length - 1) meanSb.append(", ");
-            expectedSb.append(String.format("%.2f+/-%.2f", expected[i], threshold[i]));
-            if (i != means.length - 1) expectedSb.append(", ");
-        }
-        if (means.length > 1) {
-            meanSb.append(")");
-            expectedSb.append(")");
-        }
-
-        if (failed) {
-            result.fail("Mean out of range: mean=%s, expected=%s",
-                    meanSb.toString(), expectedSb.toString());
-        }
-        return result;
-    }
-
-    /**
-     * Verify that the mean of the magnitude of the sensors vector is within the expected range.
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @param expected The expected value
-     * @param threshold The threshold
-     * @return a {@link VerificationResult} containing the verification info including the key
-     *     "magnitude" which is the mean of the computed magnitude of the sensor values.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifyMagnitude(TestSensorEvent[] events, float expected,
-            float threshold) {
-        VerificationResult result = new VerificationResult();
-        Collection<Float> magnitudes = new ArrayList<Float>(events.length);
-
-        for (TestSensorEvent event : events) {
-            float sumOfSquares = 0;
-            for (int i = 0; i < event.values.length; i++) {
-                sumOfSquares += event.values[i] * event.values[i];
-            }
-            magnitudes.add((float) Math.sqrt(sumOfSquares));
-        }
-
-        float mean = (float) SensorCtsHelper.getMean(magnitudes);
-        result.putValue(MAGNITUDE_KEY, mean);
-
-        if (Math.abs(mean - expected) > threshold) {
-            result.fail(String.format("Magnitude mean out of range: mean=%s, expected=%s+/-%s",
-                    mean, expected, threshold));
-        }
-        return result;
-    }
-
-    /**
-     * Verify that the sign of each of the sensor values is correct.
-     * <p>
-     * If the value of the measurement is in [-threshold, threshold], the sign is considered 0. If
-     * it is less than -threshold, it is considered -1. If it is greater than threshold, it is
-     * considered 1.
-     * </p>
-     *
-     * @param events
-     * @param threshold The threshold that needs to be crossed to consider a measurement nonzero
-     * @return a {@link VerificationResult} containing the verification info including the key
-     *     "mean" which is the computed means for each value of the sensor.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifySignum(TestSensorEvent[] events, int[] expected,
-            float[] threshold) {
-        VerificationResult result = new VerificationResult();
-        for (int i = 0; i < expected.length; i++) {
-            if (!(expected[i] == -1 || expected[i] == 0 || expected[i] == 1)) {
-                throw new IllegalArgumentException("Expected value must be -1, 0, or 1");
-            }
-        }
-        Float[] means = SensorCtsHelper.getMeans(events);
-        result.putValue(MEAN_KEY, Arrays.asList(means));
-
-        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++) {
-            meanSb.append(String.format("%.2f", means[i]));
-            if (i != means.length - 1) meanSb.append(", ");
-
-            if (expected[i] == 0) {
-                if (Math.abs(means[i]) > threshold[i]) {
-                    failed = true;
-                }
-                expectedSb.append(String.format("[%.2f, %.2f]", -threshold[i], threshold[i]));
-            } else {
-                if (expected[i] > 0) {
-                    if (means[i] <= threshold[i]) {
-                        failed = true;
-                    }
-                    expectedSb.append(String.format("(%.2f, inf)", threshold[i]));
-                } else {
-                    if (means[i] >= -1 * threshold[i]) {
-                        failed = true;
-                    }
-                    expectedSb.append(String.format("(-inf, %.2f)", -1 * threshold[i]));
-                }
-            }
-            if (i != means.length - 1) expectedSb.append(", ");
-        }
-        if (means.length > 1) {
-            meanSb.append(")");
-            expectedSb.append(")");
-        }
-
-        if (failed) {
-            result.fail("Signum out of range: mean=%s, expected=%s",
-                    meanSb.toString(), expectedSb.toString());
-        }
-        return result;
-    }
-
-    /**
-     * Verify that the standard deviations is within the expected range.
-     *
-     * @param events The array of {@link TestSensorEvent}
-     * @param threshold The array of thresholds
-     * @return a {@link VerificationResult} containing the verification info including the key
-     *     "stddevs" which is the computed standard deviations for each value of the sensor.
-     * @throws IllegalStateException if number of events less than 1.
-     */
-    public static VerificationResult verifyStandardDeviation(TestSensorEvent[] events,
-            float[] threshold) {
-        VerificationResult result = new VerificationResult();
-        Float[] standardDeviations = SensorCtsHelper.getStandardDeviations(events);
-        result.putValue(STANDARD_DEVIATION_KEY, Arrays.asList(standardDeviations));
-
-        boolean failed = false;
-        StringBuilder stddevSb = new StringBuilder();
-        StringBuilder expectedSb = new StringBuilder();
-
-        if (standardDeviations.length > 1) {
-            stddevSb.append("(");
-            expectedSb.append("(");
-        }
-        for (int i = 0; i < standardDeviations.length; i++) {
-            if (standardDeviations[i] > threshold[i]) {
-                failed = true;
-            }
-            stddevSb.append(String.format("%.2f", standardDeviations[i]));
-            if (i != standardDeviations.length - 1) stddevSb.append(", ");
-            expectedSb.append(String.format("<%.2f", threshold[i]));
-            if (i != standardDeviations.length - 1) expectedSb.append(", ");
-        }
-        if (standardDeviations.length > 1) {
-            stddevSb.append(")");
-            expectedSb.append(")");
-        }
-
-        if (failed) {
-            result.fail("Standard deviation out of range: stddev=%s, expected=%s",
-                    stddevSb.toString(), expectedSb.toString());
-        }
-        return result;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelperTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelperTest.java
deleted file mode 100644
index fd3c03c..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorVerificationHelperTest.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (C) 2014 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;
-
-import android.hardware.cts.helpers.SensorVerificationHelper.VerificationResult;
-
-import junit.framework.TestCase;
-
-import java.util.List;
-
-/**
- * Unit tests for the {@link SensorVerificationHelper} class.
- */
-public class SensorVerificationHelperTest extends TestCase {
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyEventOrdering(TestSensorEvent[])}.
-     */
-    @SuppressWarnings("unchecked")
-    public void testVerifyEventOrdering() {
-        float[] values = {0, 1, 2, 3, 4};
-
-        long[] timestamps1 = {0, 0, 0, 0, 0};
-        TestSensorEvent[] events1 = getSensorEvents(timestamps1, values);
-        VerificationResult result = SensorVerificationHelper.verifyEventOrdering(events1);
-        assertFalse(result.isFailed());
-        assertEquals(0, result.getValue(SensorVerificationHelper.EVENT_ORDER_COUNT_KEY));
-
-        long[] timestamps2 = {0, 1, 2, 3, 4};
-        TestSensorEvent[] events2 = getSensorEvents(timestamps2, values);
-        result = SensorVerificationHelper.verifyEventOrdering(events2);
-        assertFalse(result.isFailed());
-        assertEquals(0, result.getValue(SensorVerificationHelper.EVENT_ORDER_COUNT_KEY));
-
-        long[] timestamps3 = {0, 2, 1, 3, 4};
-        TestSensorEvent[] events3 = getSensorEvents(timestamps3, values);
-        result = SensorVerificationHelper.verifyEventOrdering(events3);
-        assertTrue(result.isFailed());
-        assertEquals(1, result.getValue(SensorVerificationHelper.EVENT_ORDER_COUNT_KEY));
-        List<Integer> indices = (List<Integer>) result.getValue(
-                SensorVerificationHelper.EVENT_ORDER_POSITIONS_KEY);
-        assertTrue(indices.contains(2));
-
-        long[] timestamps4 = {4, 0, 1, 2, 3};
-        TestSensorEvent[] events4 = getSensorEvents(timestamps4, values);
-        result = SensorVerificationHelper.verifyEventOrdering(events4);
-        assertTrue(result.isFailed());
-        assertEquals(4, result.getValue(SensorVerificationHelper.EVENT_ORDER_COUNT_KEY));
-        indices = (List<Integer>) result.getValue(
-                SensorVerificationHelper.EVENT_ORDER_POSITIONS_KEY);
-        assertTrue(indices.contains(1));
-        assertTrue(indices.contains(2));
-        assertTrue(indices.contains(3));
-        assertTrue(indices.contains(4));
-    }
-
-    /**
-     * Test
-     * {@link SensorVerificationHelper#verifyFrequency(TestSensorEvent[], double, double, double)}.
-     */
-    public void testVerifyFrequency() {
-        float[] values = {0, 1, 2, 3, 4};
-        long[] timestamps = {0, 1000000, 2000000, 3000000, 4000000};  // 1000Hz
-        TestSensorEvent[] events = getSensorEvents(timestamps, values);
-
-        VerificationResult result = SensorVerificationHelper.verifyFrequency(events, 1000.0, 1.0,
-                1.0);
-        assertFalse(result.isFailed());
-        assertEquals(1000.0, (Double) result.getValue("frequency"), 0.01);
-
-        result = SensorVerificationHelper.verifyFrequency(events, 950.0, 100.0, 100.0);
-        assertFalse(result.isFailed());
-        assertEquals(1000.0, (Double) result.getValue("frequency"), 0.01);
-
-        result = SensorVerificationHelper.verifyFrequency(events, 1050.0, 100.0, 100.0);
-        assertFalse(result.isFailed());
-        assertEquals(1000.0, (Double) result.getValue("frequency"), 0.01);
-
-        result = SensorVerificationHelper.verifyFrequency(events, 950.0, 100.0, 25.0);
-        assertTrue(result.isFailed());
-        assertEquals(1000.0, (Double) result.getValue("frequency"), 0.01);
-
-        result = SensorVerificationHelper.verifyFrequency(events, 1050.0, 25.0, 100.0);
-        assertTrue(result.isFailed());
-        assertEquals(1000.0, (Double) result.getValue("frequency"), 0.01);
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyJitter(TestSensorEvent[], int, int)}.
-     */
-    public void testVerifyJitter() {
-        final int SAMPLE_SIZE = 100;
-        float[] values = new float[SAMPLE_SIZE];
-        for (int i = 0; i < SAMPLE_SIZE; i++) {
-            values[i] = i;
-        }
-
-        long[] timestamps1 = new long[SAMPLE_SIZE];  // 100 samples at 1000Hz
-        for (int i = 0; i < SAMPLE_SIZE; i++) {
-            timestamps1[i] = i * 100000;
-        }
-        TestSensorEvent[] events1 = getSensorEvents(timestamps1, values);
-        VerificationResult result = SensorVerificationHelper.verifyJitter(events1, 1000, 10);
-        assertFalse(result.isFailed());
-        Double jitter95 = (Double) result.getValue(
-                SensorVerificationHelper.JITTER_95_PERCENTILE_KEY);
-        assertEquals(0.0, jitter95, 0.01);
-
-        long[] timestamps2 = new long[SAMPLE_SIZE];  // 90 samples at 1000Hz, 10 samples at 2000Hz
-        long timestamp = 0;
-        for (int i = 0; i < SAMPLE_SIZE; i++) {
-            timestamps2[i] = timestamp;
-            timestamp += (i % 10 == 0) ? 500000 : 1000000;
-        }
-        TestSensorEvent[] events2 = getSensorEvents(timestamps2, values);
-        result = SensorVerificationHelper.verifyJitter(events2, 1000, 10);
-        assertTrue(result.isFailed());
-        assertNotNull(result.getValue(SensorVerificationHelper.JITTER_95_PERCENTILE_KEY));
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyMean(TestSensorEvent[], float[], float[])}.
-     */
-    public void testVerifyMean() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-        float[] values1 = {0, 1, 2, 3, 4};
-        float[] values2 = {1, 2, 3, 4, 5};
-        float[] values3 = {0, 1, 4, 9, 16};
-        TestSensorEvent[] events = getSensorEvents(timestamps, values1, values2, values3);
-
-        float[] expected1 = {2.0f, 3.0f, 6.0f};
-        float[] threshold1 = {0.1f, 0.1f, 0.1f};
-        VerificationResult result = SensorVerificationHelper.verifyMean(events, expected1,
-                threshold1);
-        assertFalse(result.isFailed());
-        @SuppressWarnings("unchecked")
-        List<Float> means = (List<Float>) result.getValue(SensorVerificationHelper.MEAN_KEY);
-        assertEquals(2.0f, means.get(0), 0.01);
-        assertEquals(3.0f, means.get(1), 0.01);
-        assertEquals(6.0f, means.get(2), 0.01);
-
-        float[] expected = {2.5f, 2.5f, 5.5f};
-        float[] threshold = {0.6f, 0.6f, 0.6f};
-        result = SensorVerificationHelper.verifyMean(events, expected, threshold);
-        assertFalse(result.isFailed());
-
-        expected = new float[]{2.5f, 2.5f, 5.5f};
-        threshold = new float[]{0.1f, 0.6f, 0.6f};
-        result = SensorVerificationHelper.verifyMean(events, expected, threshold);
-        assertTrue(result.isFailed());
-
-        expected = new float[]{2.5f, 2.5f, 5.5f};
-        threshold = new float[]{0.6f, 0.1f, 0.6f};
-        result = SensorVerificationHelper.verifyMean(events, expected, threshold);
-        assertTrue(result.isFailed());
-
-        threshold = new float[]{2.5f, 2.5f, 5.5f};
-        threshold = new float[]{0.6f, 0.6f, 0.1f};
-        result = SensorVerificationHelper.verifyMean(events, expected, threshold);
-        assertTrue(result.isFailed());
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyMagnitude(TestSensorEvent[], float, float)}.
-     */
-    public void testVerifyMagnitude() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-        float[] values1 = {0, 4, 3, 0, 6};
-        float[] values2 = {3, 0, 4, 0, 0};
-        float[] values3 = {4, 3, 0, 4, 0};
-        TestSensorEvent[] events = getSensorEvents(timestamps, values1, values2, values3);
-
-        float expected = 5.0f;
-        float threshold = 0.1f;
-        VerificationResult result = SensorVerificationHelper.verifyMagnitude(events, expected,
-                threshold);
-        assertFalse(result.isFailed());
-        assertEquals(5.0f, (Float) result.getValue(SensorVerificationHelper.MAGNITUDE_KEY), 0.01);
-
-        expected = 4.5f;
-        threshold = 0.6f;
-        result = SensorVerificationHelper.verifyMagnitude(events, expected, threshold);
-        assertFalse(result.isFailed());
-
-        expected = 5.5f;
-        threshold = 0.6f;
-        result = SensorVerificationHelper.verifyMagnitude(events, expected, threshold);
-        assertFalse(result.isFailed());
-
-        expected = 4.5f;
-        threshold = 0.1f;
-        result = SensorVerificationHelper.verifyMagnitude(events, expected, threshold);
-        assertTrue(result.isFailed());
-
-        expected = 5.5f;
-        threshold = 0.1f;
-        result = SensorVerificationHelper.verifyMagnitude(events, expected, threshold);
-        assertTrue(result.isFailed());
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifySignum(TestSensorEvent[], int[], float[])}.
-     */
-    public void testVerifySignum() {
-        long[] timestamps = {0};
-        float[][] values = {{1}, {0.2f}, {0}, {-0.2f}, {-1}};
-        TestSensorEvent[] events = getSensorEvents(timestamps, values);
-
-        int[] expected = {1, 1, 0, -1, -1};
-        float[] threshold = {0.1f, 0.1f, 0.1f, 0.1f, 0.1f};
-        VerificationResult result = SensorVerificationHelper.verifySignum(events, expected,
-                threshold);
-        assertFalse(result.isFailed());
-        assertNotNull(result.getValue(SensorVerificationHelper.MEAN_KEY));
-
-        expected = new int[]{1, 0, 0, 0, -1};
-        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
-        result = SensorVerificationHelper.verifySignum(events, expected, threshold);
-        assertFalse(result.isFailed());
-
-        expected = new int[]{0, 1, 0, -1, 0};
-        threshold = new float[]{1.5f, 0.1f, 0.1f, 0.1f, 1.5f};
-        result = SensorVerificationHelper.verifySignum(events, expected, threshold);
-        assertFalse(result.isFailed());
-
-        expected = new int[]{1, 0, 0, 0, 1};
-        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
-        result = SensorVerificationHelper.verifySignum(events, expected, threshold);
-        assertTrue(result.isFailed());
-
-        expected = new int[]{-1, 0, 0, 0, -1};
-        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
-        result = SensorVerificationHelper.verifySignum(events, expected, threshold);
-        assertTrue(result.isFailed());
-    }
-
-    /**
-     * Test {@link SensorVerificationHelper#verifyStandardDeviation(TestSensorEvent[], float[])}.
-     */
-    public void testVerifyStandardDeviation() {
-        long[] timestamps = {0, 1, 2, 3, 4};
-        float[] values1 = {0, 1, 2, 3, 4};  // sqrt(2.5)
-        float[] values2 = {1, 2, 3, 4, 5};  // sqrt(2.5)
-        float[] values3 = {0, 2, 4, 6, 8};  // sqrt(10.0)
-        TestSensorEvent[] events = getSensorEvents(timestamps, values1, values2, values3);
-
-        float[] threshold = {2, 2, 4};
-        VerificationResult result = SensorVerificationHelper.verifyStandardDeviation(events,
-                threshold);
-        assertFalse(result.isFailed());
-        @SuppressWarnings("unchecked")
-        List<Float> stddevs = (List<Float>) result.getValue(
-                SensorVerificationHelper.STANDARD_DEVIATION_KEY);
-        assertEquals(Math.sqrt(2.5), stddevs.get(0), 0.01);
-        assertEquals(Math.sqrt(2.5), stddevs.get(1), 0.01);
-        assertEquals(Math.sqrt(10.0), stddevs.get(2), 0.01);
-
-        threshold = new float[]{1, 2, 4};
-        result = SensorVerificationHelper.verifyStandardDeviation(events, threshold);
-        assertTrue(result.isFailed());
-
-        threshold = new float[]{2, 1, 4};
-        result = SensorVerificationHelper.verifyStandardDeviation(events, threshold);
-        assertTrue(result.isFailed());
-
-        threshold = new float[]{2, 2, 3};
-        result = SensorVerificationHelper.verifyStandardDeviation(events, threshold);
-        assertTrue(result.isFailed());
-    }
-
-    private TestSensorEvent[] getSensorEvents(long[] timestamps, float[] ... values) {
-        TestSensorEvent[] events = new TestSensorEvent[timestamps.length];
-        for (int i = 0; i < timestamps.length; i++) {
-            float[] eventValues = new float[values.length];
-            for (int j = 0; j < values.length; j++) {
-                eventValues[j] = values[j][i];
-            }
-            events[i] = new TestSensorEvent(null, timestamps[i], 0, eventValues);
-        }
-        return events;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEvent.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEvent.java
index c22ad8e..b349e1b 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEvent.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEvent.java
@@ -51,14 +51,14 @@
     /**
      * Constructor for TestSensorEvent. Exposed for unit testing.
      */
-    TestSensorEvent(Sensor sensor, long timestamp, int accuracy, float[] values) {
+    public TestSensorEvent(Sensor sensor, long timestamp, int accuracy, float[] values) {
         this(sensor, timestamp, timestamp, accuracy, values);
     }
 
     /**
      * Constructor for TestSensorEvent. Exposed for unit testing.
      */
-    TestSensorEvent(Sensor sensor, long timestamp, long receivedTimestamp, int accuracy,
+    public TestSensorEvent(Sensor sensor, long timestamp, long receivedTimestamp, int accuracy,
             float[] values) {
         this.sensor = sensor;
         this.timestamp = timestamp;
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
new file mode 100644
index 0000000..2d13ce9
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2014 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;
+
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener2;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link SensorEventListener2} which performs operations such as waiting for a specific number of
+ * events or for a specific time, or waiting for a flush to complete. This class performs
+ * verifications and will throw {@link AssertionError}s if there are any errors. It may also wrap
+ * another {@link SensorEventListener2}.
+ */
+public class TestSensorEventListener implements SensorEventListener2 {
+    public static final String LOG_TAG = "TestSensorEventListener";
+    public static final boolean DEBUG = true;
+    private static final long EVENT_TIMEOUT_US = TimeUnit.MICROSECONDS.convert(5, TimeUnit.SECONDS);
+    private static final long FLUSH_TIMEOUT_US = TimeUnit.MICROSECONDS.convert(5, TimeUnit.SECONDS);
+
+    private final SensorEventListener2 mListener;
+
+    private volatile CountDownLatch mEventLatch = null;
+    private volatile CountDownLatch mFlushLatch = new CountDownLatch(1);
+
+    private Sensor mSensor = null;
+    private int mRateUs = 0;
+    private int mMaxBatchReportLatencyUs = 0;
+
+    /**
+     * Construct a {@link TestSensorEventListener}.
+     */
+    public TestSensorEventListener() {
+        this(null);
+    }
+
+    /**
+     * Construct a {@link TestSensorEventListener} that wraps a {@link SensorEventListener2}.
+     */
+    public TestSensorEventListener(SensorEventListener2 listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Set the sensor, rate, and batch report latency used for the assertions.
+     */
+    public void setSensorInfo(Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
+        mSensor = sensor;
+        mRateUs = rateUs;
+        mMaxBatchReportLatencyUs = maxBatchReportLatencyUs;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+        if(mEventLatch != null) {
+            mEventLatch.countDown();
+        }
+        if (mListener != null) {
+            mListener.onSensorChanged(event);
+        }
+        if (DEBUG) {
+            StringBuilder valuesSb = new StringBuilder();
+            if (event.values.length == 1) {
+                valuesSb.append(String.format("%.2f", event.values[0]));
+            } else {
+                valuesSb.append("[").append(String.format("%.2f", event.values[0]));
+                for (int i = 1; i < event.values.length; i++) {
+                    valuesSb.append(String.format(", %.2f", event.values[i]));
+                }
+                valuesSb.append("]");
+            }
+
+            Log.v(LOG_TAG, String.format(
+                    "Sensor %d: device_timestamp=%d, values=%s",
+                    mSensor.getType(), event.timestamp, Arrays.toString(event.values)));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+        if (mListener != null) {
+            mListener.onAccuracyChanged(sensor, accuracy);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onFlushCompleted(Sensor sensor) {
+        CountDownLatch latch = mFlushLatch;
+        mFlushLatch = new CountDownLatch(1);
+        if(latch != null) {
+            latch.countDown();
+        }
+        if (mListener != null) {
+            mListener.onFlushCompleted(sensor);
+        }
+    }
+
+    /**
+     * Wait for {@link #onFlushCompleted(Sensor)} to be called.
+     *
+     * @throws AssertionError if there was a timeout after {@value #FLUSH_TIMEOUT_US} &micro;s
+     */
+    public void waitForFlushComplete() {
+        CountDownLatch latch = mFlushLatch;
+        try {
+            if(latch != null) {
+                String message = SensorCtsHelper.formatAssertionMessage(mSensor, "WaitForFlush");
+                Assert.assertTrue(message, latch.await(FLUSH_TIMEOUT_US, TimeUnit.MICROSECONDS));
+            }
+        } catch(InterruptedException e) {
+            // Ignore
+        }
+    }
+
+    /**
+     * Collect a specific number of {@link TestSensorEvent}s.
+     *
+     * @throws AssertionError if there was a timeout after {@value #FLUSH_TIMEOUT_US} &micro;s
+     */
+    public void waitForEvents(int eventCount) {
+        mEventLatch = new CountDownLatch(eventCount);
+        try {
+            int rateUs = SensorCtsHelper.getDelay(mSensor, mRateUs);
+            // Timeout is 2 * event count * expected period + batch timeout + default wait
+            long timeoutUs = ((2 * eventCount * rateUs)
+                    + mMaxBatchReportLatencyUs + EVENT_TIMEOUT_US);
+
+            String message = SensorCtsHelper.formatAssertionMessage(mSensor, "WaitForEvents",
+                    "count:%d, available:%d", eventCount, mEventLatch.getCount());
+            Assert.assertTrue(message, mEventLatch.await(timeoutUs, TimeUnit.MICROSECONDS));
+        } catch(InterruptedException e) {
+            // Ignore
+        } finally {
+            mEventLatch = null;
+        }
+    }
+
+    /**
+     * Collect {@link TestSensorEvent} for a specific duration.
+     */
+    public void waitForEvents(long duration, TimeUnit timeUnit) {
+        SensorCtsHelper.sleep(duration, timeUnit);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
index eb5c300..32bd3c9 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2014 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.
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.hardware.Sensor;
-import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorEventListener2;
 import android.hardware.SensorManager;
@@ -26,8 +25,6 @@
 
 import junit.framework.Assert;
 
-import java.util.concurrent.ConcurrentLinkedDeque;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -36,61 +33,41 @@
  * operations such as flushing the sensor events and gathering events. This class also manages
  * performing the test verifications for the sensor manager.
  * <p>
- * The class makes use of an internal {@link SensorEventListener2} in order to gather events and
- * check to make sure that flushes completed. An additionaly {@link SensorEventListener2} may be
- * provided in order to perform more complex tests.
- * </p><p>
  * This class requires that operations are performed in the following order:
  * <p><ul>
- * <li>{@link #registerListener()}</li>
- * <li>{@link #getEvents()}, {@link #getEvents(int)}, {@link #getEvents(long, TimeUnit)},
- * {@link #clearEvents()}, {@link #startFlush()}, {@link #waitForFlushCompleted()}, or {@link #flush()}.
+ * <li>{@link #registerListener(TestSensorEventListener)}</li>
+ * <li>{@link #startFlush()}, {@link #waitForFlushCompleted()}, or {@link #flush()}.
  * <li>{@link #unregisterListener()}</li>
  * </ul><p>Or:</p><ul>
- * <li>{@link #collectEvents(int)}</li>
+ * <li>{@link #runSensor(TestSensorEventListener, int)}</li>
  * </ul><p>Or:</p><ul>
- * <li>{@link #collectEvents(long, TimeUnit)}</li>
+ * <li>{@link #runSensor(TestSensorEventListener, long, TimeUnit)}</li>
  * </ul><p>
  * If methods are called outside of this order, they will print a warning to the log and then
- * return. Both {@link #collectEvents(int)} and {@link #collectEvents(long, TimeUnit)} will perform
- * the appropriate clean up and tear down.
+ * return. Both {@link #runSensor(TestSensorEventListener, int)}} and
+ * {@link #runSensor(TestSensorEventListener, long, TimeUnit)} will perform the appropriate
+ * set up and tear down.
  * <p>
  */
 public class TestSensorManager {
     private static final String LOG_TAG = "TestSensorManager";
-    private static final long EVENT_TIMEOUT_US = TimeUnit.MICROSECONDS.convert(5, TimeUnit.SECONDS);
-    private static final long FLUSH_TIMEOUT_US = TimeUnit.MICROSECONDS.convert(5, TimeUnit.SECONDS);
 
     private final SensorManager mSensorManager;
     private final Sensor mSensor;
     private final int mRateUs;
     private final int mMaxBatchReportLatencyUs;
-    private final SensorEventListener2 mSensorEventListener;
 
-    private TestSensorListener mTestSensorEventListener = null;
+    private TestSensorEventListener mTestSensorEventListener = null;
 
     /**
-     * Create a {@link TestSensorManager} with a {@link SensorEventListener2}. This can be used for
-     * tests which require special behavior to be triggered on methods such as
-     * {@link SensorEventListener2#onAccuracyChanged(Sensor, int)},
-     * {@link SensorEventListener2#onFlushCompleted(Sensor)}, or
-     * {@link SensorEventListener2#onSensorChanged(SensorEvent)}.
+     * Construct a {@link TestSensorManager}.
      */
     public TestSensorManager(Context context, int sensorType, int rateUs,
-            int maxBatchReportLatencyUs, SensorEventListener2 sensorEventListener) {
+            int maxBatchReportLatencyUs) {
         mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
         mSensor = SensorCtsHelper.getSensor(context, sensorType);
         mRateUs = rateUs;
         mMaxBatchReportLatencyUs = maxBatchReportLatencyUs;
-        mSensorEventListener = sensorEventListener;
-    }
-
-    /**
-     * Create a {@link TestSensorManager} without a {@link SensorEventListener2}.
-     */
-    public TestSensorManager(Context context, int sensorType, int rateUs,
-            int maxBatchReportLatencyUs) {
-        this(context, sensorType, rateUs, maxBatchReportLatencyUs, null);
     }
 
     /**
@@ -99,15 +76,16 @@
      * @throws AssertionError if there was an error registering the listener with the
      * {@link SensorManager}
      */
-    public void registerListener() {
+    public void registerListener(TestSensorEventListener listener) {
         if (mTestSensorEventListener != null) {
             Log.w(LOG_TAG, "Listener already registered, returning.");
             return;
         }
 
-        mTestSensorEventListener = new TestSensorListener(mSensorEventListener);
+        mTestSensorEventListener = listener != null ? listener : new TestSensorEventListener();
+        mTestSensorEventListener.setSensorInfo(mSensor, mRateUs, mMaxBatchReportLatencyUs);
 
-        String message = formatAssertionMessage("registerListener");
+        String message = SensorCtsHelper.formatAssertionMessage(mSensor, "registerListener");
         boolean result = mSensorManager.registerListener(mTestSensorEventListener, mSensor, mRateUs,
                 mMaxBatchReportLatencyUs);
         Assert.assertTrue(message, result);
@@ -127,64 +105,27 @@
     }
 
     /**
-     * Get a specific number of {@link TestSensorEvent}s and then clear the event queue. This method
-     * will perform a no-op if the sensor is not registered.
-     *
-     * @throws AssertionError if there is a time out while collecting events
+     * Wait for a specific number of events.
      */
-    public TestSensorEvent[] getEvents(int count) {
-        if (mTestSensorEventListener == null) {
-            Log.w(LOG_TAG, "No listener registered, returning.");
-            return null;
-        }
-
-        mTestSensorEventListener.waitForEvents(count);
-        TestSensorEvent[] events = mTestSensorEventListener.getEvents();
-        mTestSensorEventListener.clearEvents();
-
-        return events;
-    }
-
-    /**
-     * Get the {@link TestSensorEvent} for a specific duration and then clear the event queue. This
-     * method will perform a no-op if the sensor is not registered.
-     */
-    public TestSensorEvent[] getEvents(long duration, TimeUnit timeUnit) {
-        if (mTestSensorEventListener == null) {
-            Log.w(LOG_TAG, "No listener registered, returning.");
-            return null;
-        }
-
-        mTestSensorEventListener.waitForEvents(duration, timeUnit);
-        TestSensorEvent[] events = mTestSensorEventListener.getEvents();
-        mTestSensorEventListener.clearEvents();
-
-        return events;
-    }
-
-    /**
-     * Get the {@link TestSensorEvent} from the event queue. This method will perform a no-op if the
-     * sensor is not registered.
-     */
-    public TestSensorEvent[] getEvents() {
-        if (mTestSensorEventListener == null) {
-            Log.w(LOG_TAG, "No listener registered, returning.");
-            return null;
-        }
-
-        return mTestSensorEventListener.getEvents();
-    }
-
-    /**
-     * Clear the event queue. This method will perform a no-op if the sensor is not registered.
-     */
-    public void clearEvents() {
+    public void waitForEvents(int eventCount) {
         if (mTestSensorEventListener == null) {
             Log.w(LOG_TAG, "No listener registered, returning.");
             return;
         }
 
-        mTestSensorEventListener.clearEvents();
+        mTestSensorEventListener.waitForEvents(eventCount);
+    }
+
+    /**
+     * Wait for a specific duration.
+     */
+    public void waitForEvents(long duration, TimeUnit timeUnit) {
+        if (mTestSensorEventListener == null) {
+            Log.w(LOG_TAG, "No listener registered, returning.");
+            return;
+        }
+
+        mTestSensorEventListener.waitForEvents(duration, timeUnit);
     }
 
     /**
@@ -198,7 +139,7 @@
             return;
         }
 
-        String message = formatAssertionMessage("Flush");
+        String message = SensorCtsHelper.formatAssertionMessage(mSensor, "Flush");
         Assert.assertTrue(message, mSensorManager.flush(mTestSensorEventListener));
     }
 
@@ -236,43 +177,34 @@
     }
 
     /**
-     * Collect a specific number of {@link TestSensorEvent}s. This method registers the event
-     * listener before collecting the events and then unregisters the listener after. It will
-     * perform a no-op if the sensor is already registered.
-     *
-     * @throws AssertionError if there is are errors registering the event listener or if there is
-     * a time out collecting the events
+     * Register a listener, wait for a specific number of events, and then unregister the listener.
      */
-    public TestSensorEvent[] collectEvents(int eventCount) {
+    public void runSensor(TestSensorEventListener listener, int eventCount) {
         if (mTestSensorEventListener != null) {
             Log.w(LOG_TAG, "Listener already registered, returning.");
-            return null;
+            return;
         }
 
         try {
-            registerListener();
-            return getEvents(eventCount);
+            registerListener(listener);
+            waitForEvents(eventCount);
         } finally {
             unregisterListener();
         }
     }
 
     /**
-     * Collect the {@link TestSensorEvent} for a specific duration. This method registers the event
-     * listener before collecting the events and then unregisters the listener after. It will
-     * perform a no-op if the sensor is already registered.
-     *
-     * @throws AssertionError if there is are errors registering the event listener
+     * Register a listener, wait for a specific duration, and then unregister the listener.
      */
-    public TestSensorEvent[] collectEvents(long duration, TimeUnit timeUnit) {
+    public void runSensor(TestSensorEventListener listener, long duration, TimeUnit timeUnit) {
         if (mTestSensorEventListener != null) {
             Log.w(LOG_TAG, "Listener already registered, returning.");
-            return null;
+            return;
         }
 
         try {
-            registerListener();
-            return getEvents(duration, timeUnit);
+            registerListener(listener);
+            waitForEvents(duration, timeUnit);
         } finally {
             unregisterListener();
         }
@@ -284,143 +216,4 @@
     public Sensor getSensor() {
         return mSensor;
     }
-
-    /**
-     * Helper class which collects events and ensures the flushes are completed in a timely manner.
-     */
-    private class TestSensorListener implements SensorEventListener2 {
-        private final SensorEventListener2 mListener;
-
-        private final ConcurrentLinkedDeque<TestSensorEvent> mSensorEventsList =
-                new ConcurrentLinkedDeque<TestSensorEvent>();
-
-        private volatile CountDownLatch mEventLatch = null;
-        private volatile CountDownLatch mFlushLatch = new CountDownLatch(1);
-
-        public TestSensorListener(SensorEventListener2 listener) {
-            mListener = listener;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public void onSensorChanged(SensorEvent event) {
-            mSensorEventsList.addLast(new TestSensorEvent(event, System.nanoTime()));
-            if(mEventLatch != null) {
-                mEventLatch.countDown();
-            }
-            if (mListener != null) {
-                mListener.onSensorChanged(event);
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public void onAccuracyChanged(Sensor sensor, int accuracy) {
-            if (mListener != null) {
-                mListener.onAccuracyChanged(sensor, accuracy);
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public void onFlushCompleted(Sensor sensor) {
-            CountDownLatch latch = mFlushLatch;
-            mFlushLatch = new CountDownLatch(1);
-            if(latch != null) {
-                latch.countDown();
-            }
-            if (mListener != null) {
-                mListener.onFlushCompleted(sensor);
-            }
-        }
-
-        /**
-         * Wait for {@link #onFlushCompleted(Sensor)} to be called.
-         *
-         * @throws AssertionError if there was a timeout after {@value #FLUSH_TIMEOUT_US} &micro;s
-         * @throws InterruptedException if the thread was interrupted
-         */
-        public void waitForFlushComplete() throws InterruptedException {
-            CountDownLatch latch = mFlushLatch;
-            if(latch != null) {
-                String message = formatAssertionMessage("WaitForFlush");
-                Assert.assertTrue(message, latch.await(FLUSH_TIMEOUT_US, TimeUnit.MICROSECONDS));
-            }
-        }
-
-        /**
-         * Collect a specific number of {@link TestSensorEvent}s.
-         *
-         * @throws AssertionError if there was a timeout after {@value #FLUSH_TIMEOUT_US} &micro;s
-         */
-        public void waitForEvents(int eventCount) {
-            mEventLatch = new CountDownLatch(eventCount);
-            clearEvents();
-            try {
-                int rateUs = SensorCtsHelper.getDelay(mSensor, mRateUs);
-                // Timeout is 2 * event count * expected period + default wait
-                long timeoutUs = (2 * eventCount * rateUs) + EVENT_TIMEOUT_US;
-
-                String message = formatAssertionMessage("WaitForEvents",
-                        "count:%d, available:%d", eventCount, mSensorEventsList.size());
-                Assert.assertTrue(message, mEventLatch.await(timeoutUs, TimeUnit.MICROSECONDS));
-            } catch(InterruptedException e) {
-                // Ignore
-            } finally {
-                mEventLatch = null;
-            }
-        }
-
-        /**
-         * Collect {@link TestSensorEvent} for a specific duration.
-         */
-        public void waitForEvents(long duration, TimeUnit timeUnit) {
-            clearEvents();
-            SensorCtsHelper.sleep(duration, timeUnit);
-        }
-
-        /**
-         * Get the {@link TestSensorEvent} from the event queue.
-         */
-        public TestSensorEvent[] getEvents() {
-            return mSensorEventsList.toArray(new TestSensorEvent[0]);
-        }
-
-        /**
-         * Clear the event queue.
-         */
-        public void clearEvents() {
-            mSensorEventsList.clear();
-        }
-    }
-
-    /**
-     * Format an assertion message.
-     *
-     * @param label The verification name
-     * @return The formatted string
-     */
-    private String formatAssertionMessage(String label) {
-        return formatAssertionMessage(label, "");
-    }
-
-    /**
-     * Format an assertion message with a custom message.
-     *
-     * @param label The verification name
-     * @param format The additional format string
-     * @param params The additional format params
-     * @return The formatted string
-     */
-    private String formatAssertionMessage(String label, String format, Object ... params) {
-        return String.format("%s | %s, handle: %d | %s",
-                SensorTestInformation.getSensorName(mSensor.getType()), mSensor.getHandle(),
-                String.format(format, params));
-    }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/ValidatingSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/ValidatingSensorEventListener.java
new file mode 100644
index 0000000..b8f67be
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/ValidatingSensorEventListener.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014 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;
+
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener2;
+import android.hardware.cts.helpers.sensorverification.ISensorVerification;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * A {@link TestSensorEventListener} which performs validations on the received events on the fly.
+ * This class is useful for long running tests where it is not practical to store all the events to
+ * be processed after.
+ */
+public class ValidatingSensorEventListener extends TestSensorEventListener {
+
+    private final Collection<ISensorVerification> mVerifications =
+            new LinkedList<ISensorVerification>();
+
+    /**
+     * Construct a {@link ValidatingSensorEventListener} with an additional
+     * {@link SensorEventListener2}.
+     */
+    public ValidatingSensorEventListener(SensorEventListener2 listener,
+            ISensorVerification ... verifications) {
+        super(listener);
+        for (ISensorVerification verification : verifications) {
+            mVerifications.add(verification);
+        }
+    }
+
+    /**
+     * Construct a {@link ValidatingSensorEventListener} with an additional
+     * {@link SensorEventListener2}.
+     */
+    public ValidatingSensorEventListener(SensorEventListener2 listener,
+            Collection<ISensorVerification> verifications) {
+        this(listener, verifications.toArray(new ISensorVerification[0]));
+    }
+
+    /**
+     * Construct a {@link ValidatingSensorEventListener}.
+     */
+    public ValidatingSensorEventListener(ISensorVerification ... verifications) {
+        this(null, verifications);
+    }
+
+    /**
+     * Construct a {@link ValidatingSensorEventListener}.
+     */
+    public ValidatingSensorEventListener(Collection<ISensorVerification> verifications) {
+        this(null, verifications);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+        TestSensorEvent testEvent = new TestSensorEvent(event, System.nanoTime());
+        for (ISensorVerification verification : mVerifications) {
+            verification.addSensorEvent(testEvent);
+        }
+        super.onSensorChanged(event);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/AbstractSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/AbstractSensorOperation.java
index 5f6e558..db1dff7 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/AbstractSensorOperation.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/AbstractSensorOperation.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2014 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.sensoroperations;
 
 import android.hardware.cts.helpers.SensorStats;
@@ -8,14 +24,7 @@
  */
 public abstract class AbstractSensorOperation implements ISensorOperation {
 
-    private final SensorStats mStats = new SensorStats();
-
-    /**
-     * Wrapper around {@link SensorStats#addValue(String, Object)}
-     */
-    protected void addValue(String key, Object value) {
-        mStats.addValue(key, value);
-    }
+    protected final SensorStats mStats = new SensorStats();
 
     /**
      * Wrapper around {@link SensorStats#addSensorStats(String, SensorStats)}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/DelaySensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/DelaySensorOperation.java
index af78db0..bf43189 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/DelaySensorOperation.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/DelaySensorOperation.java
@@ -26,8 +26,6 @@
  * {@link ISensorOperation}.
  */
 public class DelaySensorOperation implements ISensorOperation {
-    private static final int NANOS_PER_MILLI = 1000000;
-
     private final ISensorOperation mOperation;
     private final long mDelay;
     private final TimeUnit mTimeUnit;
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/FakeSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/FakeSensorOperation.java
index 0c7e771..cbcbc0d 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/FakeSensorOperation.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/FakeSensorOperation.java
@@ -58,7 +58,7 @@
         long delayNs = TimeUnit.NANOSECONDS.convert(mDelay, mTimeUnit);
         try {
             Thread.sleep(delayNs / NANOS_PER_MILLI, (int) (delayNs % NANOS_PER_MILLI));
-            addValue("executed", new Boolean(true));
+            mStats.addValue("executed", true);
             if (mFail) {
                 Assert.fail("FakeSensorOperation failed");
             }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
new file mode 100644
index 0000000..b40176d
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2014 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.sensoroperations;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.SensorTestInformation;
+import android.hardware.cts.helpers.TestSensorManager;
+import android.hardware.cts.helpers.ValidatingSensorEventListener;
+import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
+import android.hardware.cts.helpers.sensorverification.FrequencyVerification;
+import android.hardware.cts.helpers.sensorverification.ISensorVerification;
+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.StandardDeviationVerification;
+
+import junit.framework.Assert;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorOperation} used to verify that sensor events and sensor values are correct.
+ * <p>
+ * Provides methods to set test expectations as well as providing a set of default expectations
+ * depending on sensor type.  When {{@link #execute()} is called, the sensor will collect the
+ * events and then run all the tests.
+ * </p>
+ */
+public class TestSensorOperation extends AbstractSensorOperation {
+    private final TestSensorManager mSensorManager;
+    private final Context mContext;
+    private final int mSensorType;
+    private final int mRateUs;
+    private final int mMaxBatchReportLatencyUs;
+    private final Integer mEventCount;
+    private final Long mDuration;
+    private final TimeUnit mTimeUnit;
+
+    private final Collection<ISensorVerification> mVerifications =
+            new HashSet<ISensorVerification>();
+
+    /**
+     * Create a {@link TestSensorOperation}.
+     *
+     * @param context the {@link Context}.
+     * @param sensorType the sensor type
+     * @param rateUs the rate that
+     * @param maxBatchReportLatencyUs the max batch report latency
+     * @param eventCount the number of events to gather
+     */
+    public TestSensorOperation(Context context, int sensorType, int rateUs,
+            int maxBatchReportLatencyUs, int eventCount) {
+        this(context, sensorType, rateUs, maxBatchReportLatencyUs, eventCount, null, null);
+    }
+
+    /**
+     * Create a {@link TestSensorOperation}.
+     *
+     * @param context the {@link Context}.
+     * @param sensorType the sensor type
+     * @param rateUs the rate that
+     * @param maxBatchReportLatencyUs the max batch report latency
+     * @param duration the duration to gather events for
+     * @param timeUnit the time unit of the duration
+     */
+    public TestSensorOperation(Context context, int sensorType, int rateUs,
+            int maxBatchReportLatencyUs, long duration, TimeUnit timeUnit) {
+        this(context, sensorType, rateUs, maxBatchReportLatencyUs, null, duration, timeUnit);
+    }
+
+    /**
+     * Private helper constructor.
+     */
+    private TestSensorOperation(Context context, int sensorType, int rateUs,
+            int maxBatchReportLatencyUs, Integer eventCount, Long duration, TimeUnit timeUnit) {
+        mContext = context;
+        mSensorType = sensorType;
+        mRateUs = rateUs;
+        mMaxBatchReportLatencyUs = maxBatchReportLatencyUs;
+        mEventCount = eventCount;
+        mDuration = duration;
+        mTimeUnit = timeUnit;
+        mSensorManager = new TestSensorManager(mContext, mSensorType, mRateUs,
+                mMaxBatchReportLatencyUs);
+    }
+
+    /**
+     * Set all of the default test expectations.
+     */
+    public void setDefaultVerifications() {
+        Sensor sensor = mSensorManager.getSensor();
+        addVerification(EventOrderingVerification.getDefault(sensor));
+        addVerification(FrequencyVerification.getDefault(sensor, mRateUs));
+        addVerification(JitterVerification.getDefault(sensor, mRateUs));
+        addVerification(MagnitudeVerification.getDefault(sensor));
+        addVerification(MeanVerification.getDefault(sensor));
+        // Skip SigNumVerification since it has no default
+        addVerification(StandardDeviationVerification.getDefault(sensor));
+    }
+
+    public void addVerification(ISensorVerification verification) {
+        if (verification != null) {
+            mVerifications.add(verification);
+        }
+    }
+
+    /**
+     * Collect the specified number of events from the sensor and run all enabled verifications.
+     */
+    @Override
+    public void execute() {
+        mStats.addValue("sensor_name", SensorTestInformation.getSensorName(mSensorType));
+        mStats.addValue("sensor_handle", mSensorManager.getSensor().getHandle());
+
+        ValidatingSensorEventListener listener = new ValidatingSensorEventListener(mVerifications);
+
+        if (mEventCount != null) {
+            mSensorManager.runSensor(listener, mEventCount);
+        } else {
+            mSensorManager.runSensor(listener, mDuration, mTimeUnit);
+        }
+
+        boolean failed = false;
+        StringBuilder sb = new StringBuilder();
+
+        for (ISensorVerification verification : mVerifications) {
+            failed |= evaluateResults(verification, sb);
+        }
+
+        if (failed) {
+            Assert.fail(SensorCtsHelper.formatAssertionMessage(mSensorManager.getSensor(),
+                    "VerifySensorOperation", sb.toString()));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public TestSensorOperation clone() {
+        TestSensorOperation operation;
+        if (mEventCount != null) {
+            operation = new TestSensorOperation(mContext, mSensorType, mRateUs,
+                    mMaxBatchReportLatencyUs, mEventCount);
+        } else {
+            operation = new TestSensorOperation(mContext, mSensorType, mRateUs,
+                    mMaxBatchReportLatencyUs, mDuration, mTimeUnit);
+        }
+
+        for (ISensorVerification verification : mVerifications) {
+            operation.addVerification(verification.clone());
+        }
+        return operation;
+    }
+
+    /**
+     * Evaluate the results of a test, aggregate the stats, and build the error message.
+     */
+    private boolean evaluateResults(ISensorVerification verification, StringBuilder sb) {
+        try {
+            verification.verify(mStats);
+        } catch (AssertionError e) {
+            if (sb.length() > 0) {
+                sb.append(", ");
+            }
+            sb.append(e.getMessage());
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/VerifySensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/VerifySensorOperation.java
deleted file mode 100644
index 6f53573..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/VerifySensorOperation.java
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * Copyright (C) 2014 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.sensoroperations;
-
-import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorManager;
-import android.hardware.cts.helpers.SensorCtsHelper;
-import android.hardware.cts.helpers.SensorTestInformation;
-import android.hardware.cts.helpers.SensorVerificationHelper;
-import android.hardware.cts.helpers.SensorVerificationHelper.VerificationResult;
-import android.hardware.cts.helpers.TestSensorEvent;
-import android.hardware.cts.helpers.TestSensorManager;
-import android.util.Log;
-
-import junit.framework.Assert;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A {@link ISensorOperation} used to verify that sensor events and sensor values are correct.
- * <p>
- * Provides methods to set test expectations as well as providing a set of default expectations
- * depending on sensor type.  When {{@link #execute()} is called, the sensor will collect the
- * events and then run all the tests.
- * </p>
- */
-public class VerifySensorOperation extends AbstractSensorOperation {
-    private static final String TAG = "VerifySensorOperation";
-
-    private static final boolean DEBUG = false;
-
-    // threshold is (100 - 10)% expected to (100 + 110)% expected
-    private static final int[] DEFAULT_FREQUENCY_THRESHOLDS = {10, 110};
-
-    private TestSensorManager mSensorManager;
-    private Context mContext = null;
-    private int mSensorType = 0;
-    private int mRateUs = 0;
-    private int mMaxBatchReportLatencyUs = 0;
-    private Integer mEventCount = null;
-    private Long mDuration = null;
-    private TimeUnit mTimeUnit = null;
-
-    private boolean mVerifyEventOrdering = false;
-
-    private boolean mVerifyFrequency = false;
-    private double mFrequencyExpected = 0.0;
-    private double mFrequencyLowerThreshold = 0.0;
-    private double mFrequencyUpperThreshold = 0.0;
-
-    private boolean mVerifyJitter = false;
-    private int mJitterExpected = 0;
-    private int mJitterThreshold = 0;
-
-    private boolean mVerifyMean = false;
-    private float[] mMeanExpected = null;
-    private float[] mMeanThreshold = null;
-
-    private boolean mVerifyMagnitude = false;
-    private float mMagnitudeExpected = 0.0f;
-    private float mMagnitudeThreshold = 0.0f;
-
-    private boolean mVerifySignum = false;
-    private int[] mSignumExpected = null;
-    private float[] mSignumThreshold = null;
-
-    private boolean mVerifyStandardDeviation = false;
-    private float[] mStandardDeviationThreshold = null;
-
-    /**
-     * Create a {@link VerifySensorOperation}.
-     *
-     * @param context the {@link Context}.
-     * @param sensorType the sensor type
-     * @param rateUs the rate that
-     * @param maxBatchReportLatencyUs the max batch report latency
-     * @param eventCount the number of events to gather
-     */
-    public VerifySensorOperation(Context context, int sensorType, int rateUs,
-            int maxBatchReportLatencyUs, int eventCount) {
-        mContext = context;
-        mSensorType = sensorType;
-        mRateUs = rateUs;
-        mMaxBatchReportLatencyUs = maxBatchReportLatencyUs;
-        mEventCount = eventCount;
-        mSensorManager = new TestSensorManager(mContext, mSensorType, mRateUs,
-                mMaxBatchReportLatencyUs);
-    }
-
-    /**
-     * Create a {@link VerifySensorOperation}.
-     *
-     * @param context the {@link Context}.
-     * @param sensorType the sensor type
-     * @param rateUs the rate that
-     * @param maxBatchReportLatencyUs the max batch report latency
-     * @param duration the duration to gather events for
-     * @param timeUnit the time unit of the duration
-     */
-    public VerifySensorOperation(Context context, int sensorType, int rateUs,
-            int maxBatchReportLatencyUs, long duration, TimeUnit timeUnit) {
-        mContext = context;
-        mSensorType = sensorType;
-        mRateUs = rateUs;
-        mMaxBatchReportLatencyUs = maxBatchReportLatencyUs;
-        mDuration = duration;
-        mTimeUnit = timeUnit;
-        mSensorManager = new TestSensorManager(mContext, mSensorType, mRateUs,
-                mMaxBatchReportLatencyUs);
-    }
-
-    /**
-     * Set all of the default test expectations.
-     */
-    public void setDefaultVerifications() {
-        setDefaultVerifyEventOrdering();
-        setDefaultVerifyFrequency();
-        setDefaultVerifyJitter();
-        setDefaultVerifyMean();
-        setDefaultVerifyMagnitude();
-        setDefaultVerifySignum();
-        setDefaultVerifyStandardDeviation();
-    }
-
-    /**
-     * Enable the event ordering verification.
-     */
-    public void verifyEventOrdering() {
-        mVerifyEventOrdering = true;
-    }
-
-    /**
-     * Set the default event ordering verification.
-     */
-    @SuppressWarnings("deprecation")
-    public void setDefaultVerifyEventOrdering() {
-        switch (mSensorType) {
-            case Sensor.TYPE_ACCELEROMETER:
-            case Sensor.TYPE_MAGNETIC_FIELD:
-            case Sensor.TYPE_ORIENTATION:
-            case Sensor.TYPE_GYROSCOPE:
-            case Sensor.TYPE_PRESSURE:
-            case Sensor.TYPE_GRAVITY:
-            case Sensor.TYPE_LINEAR_ACCELERATION:
-            case Sensor.TYPE_ROTATION_VECTOR:
-            case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
-            case Sensor.TYPE_GAME_ROTATION_VECTOR:
-            case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
-            case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
-                verifyEventOrdering();
-                break;
-        }
-    }
-
-    /**
-     * Enable the frequency verification.
-     *
-     * @param expected the expected frequency in Hz.
-     * @param threshold the threshold in Hz.
-     */
-    public void verifyFrequency(double expected, double threshold) {
-        mVerifyFrequency = true;
-        mFrequencyExpected = expected;
-        mFrequencyLowerThreshold = threshold;
-        mFrequencyUpperThreshold = threshold;
-    }
-
-    /**
-     * Enable the frequency verification.
-     *
-     * @param expected the expected frequency in Hz.
-     * @param lowerThreshold the lower threshold in Hz.
-     * @param upperThreshold the upper threshold in Hz.
-     */
-    public void verifyFrequency(double expected, double lowerThreshold, double upperThreshold) {
-        mVerifyFrequency = true;
-        mFrequencyExpected = expected;
-        mFrequencyLowerThreshold = lowerThreshold;
-        mFrequencyUpperThreshold = upperThreshold;
-    }
-
-    /**
-     * Set the default frequency verification depending on the sensor.
-     * <p>
-     * The expected frequency is based on {@link Sensor#getMinDelay()} and the threshold is
-     * calculated based on a percentage of the expected frequency.  The verification will not be run
-     * if the rate is set to {@link SensorManager#SENSOR_DELAY_GAME},
-     * {@link SensorManager#SENSOR_DELAY_UI}, or {@link SensorManager#SENSOR_DELAY_NORMAL} because
-     * these rates are not specified in the CDD.
-     */
-    @SuppressWarnings("deprecation")
-    public void setDefaultVerifyFrequency() {
-        if (!isRateValid()) {
-            return;
-        }
-
-        // sensorType: lowerThreshold, upperThreshold (% of expected frequency)
-        Map<Integer, int[]> defaults = new HashMap<Integer, int[]>(12);
-        defaults.put(Sensor.TYPE_ACCELEROMETER, DEFAULT_FREQUENCY_THRESHOLDS);
-        defaults.put(Sensor.TYPE_MAGNETIC_FIELD, DEFAULT_FREQUENCY_THRESHOLDS);
-        defaults.put(Sensor.TYPE_GYROSCOPE, DEFAULT_FREQUENCY_THRESHOLDS);
-        defaults.put(Sensor.TYPE_ORIENTATION, DEFAULT_FREQUENCY_THRESHOLDS);
-        defaults.put(Sensor.TYPE_PRESSURE, DEFAULT_FREQUENCY_THRESHOLDS);
-        defaults.put(Sensor.TYPE_GRAVITY, DEFAULT_FREQUENCY_THRESHOLDS);
-        defaults.put(Sensor.TYPE_LINEAR_ACCELERATION, DEFAULT_FREQUENCY_THRESHOLDS);
-        defaults.put(Sensor.TYPE_ROTATION_VECTOR, DEFAULT_FREQUENCY_THRESHOLDS);
-        defaults.put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, DEFAULT_FREQUENCY_THRESHOLDS);
-        defaults.put(Sensor.TYPE_GAME_ROTATION_VECTOR, DEFAULT_FREQUENCY_THRESHOLDS);
-        defaults.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, DEFAULT_FREQUENCY_THRESHOLDS);
-
-        if (defaults.containsKey(mSensorType)) {
-            // Expected frequency in Hz
-            double expected = SensorCtsHelper.getFrequency(
-                    SensorCtsHelper.getDelay(mSensorManager.getSensor(), mRateUs),
-                    TimeUnit.MICROSECONDS);
-            // Expected frequency * threshold percentage
-            double lowerThreshold = expected * defaults.get(mSensorType)[0] / 100;
-            double upperThreshold = expected * defaults.get(mSensorType)[1] / 100;
-            verifyFrequency(expected, lowerThreshold, upperThreshold);
-        }
-    }
-
-    /**
-     * Enable the jitter verification.
-     * <p>
-     * This test looks at the 95th percentile of the jitter and makes sure it is less than the
-     * threshold percentage of the expected period.
-     * </p>
-     *
-     * @param expected the expected period in ns.
-     * @param threshold the theshold as a percentage of the expected period.
-     */
-    public void verifyJitter(int expected, int threshold) {
-        mVerifyJitter = true;
-        mJitterExpected = expected;
-        mJitterThreshold = threshold;
-    }
-
-    /**
-     * Set the default jitter verification based on the sensor type.
-     * <p>
-     * The verification will not be run if the rate is set to
-     * {@link SensorManager#SENSOR_DELAY_GAME}, {@link SensorManager#SENSOR_DELAY_UI}, or
-     * {@link SensorManager#SENSOR_DELAY_NORMAL} because these rates are not specified in the CDD.
-     * </p>
-     */
-    @SuppressWarnings("deprecation")
-    public void setDefaultVerifyJitter() {
-        if (!isRateValid()) {
-            return;
-        }
-
-        // sensorType: threshold (% of expected period)
-        Map<Integer, Integer> defaults = new HashMap<Integer, Integer>(12);
-        // Sensors that we don't want to test at this time but still want to record the values.
-        defaults.put(Sensor.TYPE_ACCELEROMETER, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_MAGNETIC_FIELD, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_GYROSCOPE, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_ORIENTATION, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_PRESSURE, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_GRAVITY, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_LINEAR_ACCELERATION, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_ROTATION_VECTOR, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_GAME_ROTATION_VECTOR, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, Integer.MAX_VALUE);
-        defaults.put(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, Integer.MAX_VALUE);
-
-        if (defaults.containsKey(mSensorType)) {
-            int expected = (int) TimeUnit.NANOSECONDS.convert(
-                    SensorCtsHelper.getDelay(mSensorManager.getSensor(), mRateUs),
-                    TimeUnit.MICROSECONDS);
-            verifyJitter(expected, defaults.get(mSensorType));
-        }
-    }
-
-    /**
-     * Enable the mean verification.
-     *
-     * @param expected the expected means
-     * @param threshold the threshold
-     */
-    public void verifyMean(float[] expected, float[] threshold) {
-        mVerifyMean = true;
-        mMeanExpected = expected;
-        mMeanThreshold = threshold;
-    }
-
-    /**
-     * Set the default mean verification based on sensor type.
-     * <p>
-     * This sets the mean expectations for a device at rest in a standard environment. For sensors
-     * whose values vary depending on the orientation or environment, the expectations will not be
-     * set.
-     * </p><p>
-     * The following expectations are set for these sensors:
-     * </p><ul>
-     * <li>Gyroscope: all values should be 0.</li>
-     * <li>Pressure: values[0] should be close to the standard pressure.</li>
-     * <li>Linear acceleration: all values should be 0.</li>
-     * <li>Game rotation vector: all values should be 0 except values[3] which should be 1.</li>
-     * <li>Uncalibrated gyroscope: all values should be 0.</li>
-     * </ul>
-     */
-    @SuppressWarnings("deprecation")
-    public void setDefaultVerifyMean() {
-        // sensorType: {expected, threshold}
-        Map<Integer, Object[]> defaults = new HashMap<Integer, Object[]>(5);
-        // 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}});
-        // 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}});
-        // 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}});
-        // 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}});
-        // 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}});
-
-        if (defaults.containsKey(mSensorType)) {
-            float[] expected = (float[]) defaults.get(mSensorType)[0];
-            float[] threshold = (float[]) defaults.get(mSensorType)[1];
-            verifyMean(expected, threshold);
-        }
-    }
-
-    /**
-     * Enable the magnitude verification.
-     *
-     * @param expected the expected magnitude of the vector
-     * @param threshold the threshold
-     */
-    public void verifyMagnitude(float expected, float threshold) {
-        mVerifyMagnitude = true;
-        mMagnitudeExpected = expected;
-        mMagnitudeThreshold = threshold;
-    }
-
-    /**
-     * Set the default magnitude verification base on the sensor type.
-     * <p>
-     * This sets the magnitude expectations for a device at rest in a standard environment. For
-     * sensors whose values vary depending on the orientation or environment, the expectations will
-     * not be set.
-     * </p>
-     */
-    @SuppressWarnings("deprecation")
-    public void setDefaultVerifyMagnitude() {
-        // sensorType: {expected, threshold}
-        Map<Integer, Float[]> defaults = new HashMap<Integer, Float[]>(3);
-        defaults.put(Sensor.TYPE_ACCELEROMETER, new Float[]{SensorManager.STANDARD_GRAVITY, 1.5f});
-        defaults.put(Sensor.TYPE_GYROSCOPE, new Float[]{0.0f, 1.5f});
-        // Sensors that we don't want to test at this time but still want to record the values.
-        defaults.put(Sensor.TYPE_GRAVITY,
-                new Float[]{SensorManager.STANDARD_GRAVITY, Float.MAX_VALUE});
-
-        if (defaults.containsKey(mSensorType)) {
-            Float expected = defaults.get(mSensorType)[0];
-            Float threshold = defaults.get(mSensorType)[1];
-            verifyMagnitude(expected, threshold);
-        }
-    }
-
-    /**
-     * Enable the signum verification.
-     *
-     * @param expected the expected signs, an array of either -1s, 0s, or 1s.
-     * @param threshold the threshold
-     */
-    public void verifySignum(int[] expected, float[] threshold) {
-        mVerifySignum = true;
-        mSignumExpected = expected;
-        mSignumThreshold = threshold;
-    }
-
-    /**
-     * Set the default signum verification base on the sensor type.
-     * <p>
-     * This is a no-op since currently all sensors which can specify a default sign can also specify
-     * a default mean which is a more precise test.
-     * </p>
-     */
-    public void setDefaultVerifySignum() {
-        // No-op: All sensors that have an expected sign when static are already tested in
-        // setDefaultVerifyMean().
-    }
-
-    /**
-     * Enable the standard deviation verification.
-     *
-     * @param threshold the threshold.
-     */
-    public void verifyStandardDeviation(float[] threshold) {
-        mVerifyStandardDeviation = true;
-        mStandardDeviationThreshold = threshold;
-    }
-
-    /**
-     * Set the default standard deviation verification based on the sensor type.
-     */
-    @SuppressWarnings("deprecation")
-    public void setDefaultVerifyStandardDeviation() {
-        // sensorType: threshold
-        Map<Integer, float[]> defaults = new HashMap<Integer, float[]>(12);
-        defaults.put(Sensor.TYPE_ACCELEROMETER, new float[]{1.0f, 1.0f, 1.0f});
-        defaults.put(Sensor.TYPE_GYROSCOPE, new float[]{0.5f, 0.5f, 0.5f});
-        // Sensors that we don't want to test at this time but still want to record the values.
-        defaults.put(Sensor.TYPE_MAGNETIC_FIELD,
-                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
-        defaults.put(Sensor.TYPE_ORIENTATION,
-                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
-        defaults.put(Sensor.TYPE_PRESSURE,
-                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
-        defaults.put(Sensor.TYPE_GRAVITY,
-                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
-        defaults.put(Sensor.TYPE_LINEAR_ACCELERATION,
-                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
-        defaults.put(Sensor.TYPE_ROTATION_VECTOR,
-                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
-                Float.MAX_VALUE});
-        defaults.put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED,
-                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
-                Float.MAX_VALUE, Float.MAX_VALUE});
-        defaults.put(Sensor.TYPE_GAME_ROTATION_VECTOR,
-                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
-                Float.MAX_VALUE});
-        defaults.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED,
-                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
-                Float.MAX_VALUE, Float.MAX_VALUE});
-        defaults.put(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR,
-                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
-                Float.MAX_VALUE});
-
-        if (defaults.containsKey(mSensorType)) {
-            float[] threshold = defaults.get(mSensorType);
-            verifyStandardDeviation(threshold);
-        }
-    }
-
-    /**
-     * Collect the specified number of events from the sensor and run all enabled verifications.
-     */
-    @Override
-    public void execute() {
-        addValue("sensor_name", SensorTestInformation.getSensorName(mSensorType));
-        addValue("sensor_handle", mSensorManager.getSensor().getHandle());
-
-        TestSensorEvent[] events;
-        if (mEventCount != null) {
-            events = mSensorManager.collectEvents(mEventCount);
-        } else {
-            events = mSensorManager.collectEvents(mDuration, mTimeUnit);
-        }
-
-        boolean failed = false;
-        StringBuilder sb = new StringBuilder();
-        VerificationResult result = null;
-
-        if (mVerifyEventOrdering) {
-            result = SensorVerificationHelper.verifyEventOrdering(events);
-            // evaluateResults first so it is always called.
-            failed |= evaluateResults(result, sb);
-        }
-
-        if (mVerifyFrequency) {
-            result = SensorVerificationHelper.verifyFrequency(events, mFrequencyExpected,
-                    mFrequencyLowerThreshold, mFrequencyUpperThreshold);
-            failed |= evaluateResults(result, sb);
-        }
-
-        if (mVerifyJitter) {
-            result = SensorVerificationHelper.verifyJitter(events, mJitterExpected,
-                    mJitterThreshold);
-            failed |= evaluateResults(result, sb);
-        }
-
-        if (mVerifyMean) {
-            result = SensorVerificationHelper.verifyMean(events, mMeanExpected, mMeanThreshold);
-            failed |= evaluateResults(result, sb);
-        }
-
-        if (mVerifyMagnitude) {
-            result = SensorVerificationHelper.verifyMagnitude(events, mMagnitudeExpected,
-                    mMagnitudeThreshold);
-            failed |= evaluateResults(result, sb);
-        }
-
-        if (mVerifySignum) {
-            result = SensorVerificationHelper.verifySignum(events, mSignumExpected,
-                    mSignumThreshold);
-            failed |= evaluateResults(result, sb);
-        }
-
-        if (mVerifyStandardDeviation) {
-            result = SensorVerificationHelper.verifyStandardDeviation(events,
-                    mStandardDeviationThreshold);
-            failed |= evaluateResults(result, sb);
-        }
-
-        if (DEBUG) {
-            logStats(events);
-        }
-
-        if (failed) {
-            Assert.fail(String.format("%s, handle %d: %s",
-                    SensorTestInformation.getSensorName(mSensorType),
-                    mSensorManager.getSensor().getHandle(), sb.toString()));
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public VerifySensorOperation clone() {
-        VerifySensorOperation operation;
-        if (mEventCount != null) {
-            operation = new VerifySensorOperation(mContext, mSensorType, mRateUs,
-                    mMaxBatchReportLatencyUs, mEventCount);
-        } else {
-            operation = new VerifySensorOperation(mContext, mSensorType, mRateUs,
-                    mMaxBatchReportLatencyUs, mDuration, mTimeUnit);
-        }
-        if (mVerifyEventOrdering) {
-            operation.verifyEventOrdering();
-        }
-        if (mVerifyFrequency) {
-            operation.verifyFrequency(mFrequencyExpected, mFrequencyLowerThreshold,
-                    mFrequencyUpperThreshold);
-        }
-        if (mVerifyJitter) {
-            operation.verifyJitter(mJitterExpected, mJitterThreshold);
-        }
-        if (mVerifyMean) {
-            operation.verifyMean(mMeanExpected, mMeanThreshold);
-        }
-        if (mVerifyMagnitude) {
-            operation.verifyMagnitude(mMagnitudeExpected, mMagnitudeThreshold);
-        }
-        if (mVerifySignum) {
-            operation.verifySignum(mSignumExpected, mSignumThreshold);
-        }
-        if (mVerifyStandardDeviation) {
-            operation.verifyStandardDeviation(mStandardDeviationThreshold);
-        }
-        return operation;
-    }
-
-    /**
-     * Return true if the operation rate is not one of {@link SensorManager#SENSOR_DELAY_GAME},
-     * {@link SensorManager#SENSOR_DELAY_UI}, or {@link SensorManager#SENSOR_DELAY_NORMAL}.
-     */
-    private boolean isRateValid() {
-        return (mRateUs != SensorManager.SENSOR_DELAY_GAME
-                && mRateUs != SensorManager.SENSOR_DELAY_UI
-                && mRateUs != SensorManager.SENSOR_DELAY_NORMAL);
-    }
-
-    /**
-     * Evaluate the results of a test, aggregate the stats, and build the error message.
-     */
-    private boolean evaluateResults(VerificationResult result, StringBuilder sb) {
-        for (String key : result.getKeys()) {
-            addValue(key, result.getValue(key));
-        }
-
-        if (result.isFailed()) {
-            if (sb.length() > 0) {
-                sb.append(", ");
-            }
-            sb.append(result.getFailureMessage());
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Log the events to the logcat.
-     */
-    private void logStats(TestSensorEvent[] events) {
-        if (events.length <= 0) {
-            return;
-        }
-
-        List<Double> jitterValues = null;
-        if (events.length > 1) {
-            jitterValues = SensorCtsHelper.getJitterValues(events);
-        }
-
-        logTestSensorEvent(0, events[0], null, null);
-        for (int i = 1; i < events.length; i++) {
-            Double jitter = jitterValues == null ? null : jitterValues.get(i - 1);
-            logTestSensorEvent(i, events[i], events[i - 1], jitter);
-        }
-    }
-
-    /**
-     * Log a single sensor event to the logcat.
-     */
-    private void logTestSensorEvent(int index, TestSensorEvent event, TestSensorEvent prevEvent,
-            Double jitter) {
-        String deltaStr = prevEvent == null ? null : String.format("%d",
-                event.timestamp - prevEvent.timestamp);
-        String jitterStr = jitter == null ? null : String.format("%.2f", jitter);
-
-        StringBuilder valuesSb = new StringBuilder();
-        if (event.values.length == 1) {
-            valuesSb.append(String.format("%.2f", event.values[0]));
-        } else {
-            valuesSb.append("[").append(String.format("%.2f", event.values[0]));
-            for (int i = 1; i < event.values.length; i++) {
-                valuesSb.append(String.format(", %.2f", event.values[i]));
-            }
-            valuesSb.append("]");
-        }
-
-        Log.v(TAG, String.format(
-                "Sensor %d: Event %d: device_timestamp=%d, delta_timestamp=%s, jitter=%s, "
-                + "values=%s", mSensorManager.getSensor().getType(), index, event.timestamp,
-                deltaStr, jitterStr, valuesSb.toString()));
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractMeanVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractMeanVerification.java
new file mode 100644
index 0000000..8d132a3
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractMeanVerification.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+/**
+ * Abstract class that calculates of the mean event values.
+ */
+public abstract class AbstractMeanVerification extends AbstractSensorVerification {
+    private float[] mSums = null;
+    private int mCount = 0;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mSums == null) {
+            mSums = new float[event.values.length];
+        }
+        Assert.assertEquals(mSums.length, event.values.length);
+        for (int i = 0; i < mSums.length; i++) {
+            mSums[i] += event.values[i];
+        }
+        mCount++;
+    }
+
+    /**
+     * Return the number of events.
+     */
+    protected int getCount() {
+        return mCount;
+    }
+
+    /**
+     * Return the means of the event values.
+     */
+    protected float[] getMeans() {
+        if (mCount < 0) {
+            return null;
+        }
+
+        float[] means = new float[mSums.length];
+        for (int i = 0; i < mSums.length; i++) {
+            means[i] = mSums[i] / mCount;
+        }
+        return means;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java
new file mode 100644
index 0000000..f11f7a4
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.TestSensorEvent;
+
+/**
+ * Abstract class that deals with the synchronization of the sensor verifications.
+ */
+public abstract class AbstractSensorVerification implements ISensorVerification {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void addSensorEvents(TestSensorEvent ... events) {
+        for (TestSensorEvent event : events) {
+            addSensorEventInternal(event);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void addSensorEvent(TestSensorEvent event) {
+        addSensorEventInternal(event);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public abstract ISensorVerification clone();
+
+    /**
+     * Used by implementing classes to add a sensor event.
+     */
+    protected abstract void addSensorEventInternal(TestSensorEvent event);
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java
new file mode 100644
index 0000000..28ddfe7
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2014 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.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A {@link ISensorVerification} which verifies that all events are received in the correct order.
+ */
+public class EventOrderingVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "event_order_passed";
+
+    private static final int MESSAGE_LENGTH = 3;
+
+    private Long mMaxTimestamp = null;
+    private TestSensorEvent mPreviousEvent = null;
+    private final List<EventInfo> mOutOfOrderEvents = new LinkedList<EventInfo>();
+    private int mCount = 0;
+    private int mIndex = 0;
+
+    /**
+     * Get the default {@link EventOrderingVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    @SuppressWarnings("deprecation")
+    public static EventOrderingVerification getDefault(Sensor sensor) {
+        switch (sensor.getType()) {
+            case Sensor.TYPE_ACCELEROMETER:
+            case Sensor.TYPE_MAGNETIC_FIELD:
+            case Sensor.TYPE_ORIENTATION:
+            case Sensor.TYPE_GYROSCOPE:
+            case Sensor.TYPE_PRESSURE:
+            case Sensor.TYPE_GRAVITY:
+            case Sensor.TYPE_LINEAR_ACCELERATION:
+            case Sensor.TYPE_ROTATION_VECTOR:
+            case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+            case Sensor.TYPE_GAME_ROTATION_VECTOR:
+            case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
+            case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+                return new EventOrderingVerification();
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Verify that the events are in the correct order.  Add {@value #PASSED_KEY},
+     * {@value SensorStats#EVENT_OUT_OF_ORDER_COUNT_KEY}, and
+     * {@value SensorStats#EVENT_OUT_OF_ORDER_POSITIONS_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        stats.addValue(PASSED_KEY, mCount == 0);
+        stats.addValue(SensorStats.EVENT_OUT_OF_ORDER_COUNT_KEY, mCount);
+
+        int[] indices = new int[mOutOfOrderEvents.size()];
+        for (int i = 0; i < indices.length; i++) {
+            indices[i] = mOutOfOrderEvents.get(i).index;
+        }
+        stats.addValue(SensorStats.EVENT_OUT_OF_ORDER_POSITIONS_KEY, indices);
+
+        if (mOutOfOrderEvents.size() > 0) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(mCount).append(" events out of order: ");
+            for (int i = 0; i < Math.min(mOutOfOrderEvents.size(), MESSAGE_LENGTH); i++) {
+                EventInfo info = mOutOfOrderEvents.get(i);
+                sb.append(String.format("position=%d, previous=%d, timestamp=%d; ", info.index,
+                        info.previousEvent.timestamp, info.event.timestamp));
+            }
+            if (mOutOfOrderEvents.size() > MESSAGE_LENGTH) {
+                sb.append(mOutOfOrderEvents.size() - MESSAGE_LENGTH).append(" more");
+            } else {
+                // Delete the trailing "; "
+                sb.delete(sb.length() - 2, sb.length());
+            }
+
+            Assert.fail(sb.toString());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public EventOrderingVerification clone() {
+        return new EventOrderingVerification();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mPreviousEvent == null) {
+            mMaxTimestamp = event.timestamp;
+        } else {
+            if (event.timestamp < mMaxTimestamp) {
+                mOutOfOrderEvents.add(new EventInfo(mIndex, event, mPreviousEvent));
+                mCount++;
+            } else if (event.timestamp > mMaxTimestamp) {
+                mMaxTimestamp = event.timestamp;
+            }
+        }
+
+        mPreviousEvent = event;
+        mIndex++;
+    }
+
+    private class EventInfo {
+        public final int index;
+        public final TestSensorEvent event;
+        public final TestSensorEvent previousEvent;
+
+        public EventInfo(int index, TestSensorEvent event, TestSensorEvent previousEvent) {
+            this.index = index;
+            this.event = event;
+            this.previousEvent = previousEvent;
+        }
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerificationTest.java
new file mode 100644
index 0000000..28cbd01
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerificationTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link EventOrderingVerification}.
+ */
+public class EventOrderingVerificationTest extends TestCase {
+
+    /**
+     * Test that the verification passes when there are no results.
+     */
+    public void testNoEvents() {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification();
+        verification.verify(stats);
+        verifyStats(stats, true, 0);
+    }
+
+    /**
+     * Test that the verification passes when the timestamps are the same.
+     */
+    public void testSameTimestamp() {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(0, 0, 0, 0, 0);
+        verification.verify(stats);
+        verifyStats(stats, true, 0);
+    }
+
+    /**
+     * Test that the verification passes when the timestamps are increasing.
+     */
+    public void testSequentialTimestamp() {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(0, 1, 2, 3, 4);
+        verification.verify(stats);
+        verifyStats(stats, true, 0);
+    }
+
+    /**
+     * Test that the verification fails when there is one event out of order.
+     */
+    public void testSingleOutofOrder() {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(0, 2, 1, 3, 4);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, 1);
+        List<Integer> indices = getIndices(stats);
+        assertTrue(indices.contains(2));
+    }
+
+    /**
+     * Test that the verification fails when there are multiple events out of order.
+     */
+    public void testMultipleOutOfOrder() {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(4, 0, 1, 2, 3);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, 4);
+        List<Integer> indices = getIndices(stats);
+        assertTrue(indices.contains(1));
+        assertTrue(indices.contains(2));
+        assertTrue(indices.contains(3));
+        assertTrue(indices.contains(4));
+    }
+
+    private ISensorVerification getVerification(long ... timestamps) {
+        ISensorVerification verification = new EventOrderingVerification();
+        for (long timestamp : timestamps) {
+            verification.addSensorEvent(new TestSensorEvent(null, timestamp, 0, null));
+        }
+        return verification;
+    }
+
+    private void verifyStats(SensorStats stats, boolean passed, int count) {
+        assertEquals(passed, stats.getValue(EventOrderingVerification.PASSED_KEY));
+        assertEquals(count, stats.getValue(SensorStats.EVENT_OUT_OF_ORDER_COUNT_KEY));
+        assertNotNull(stats.getValue(SensorStats.EVENT_OUT_OF_ORDER_POSITIONS_KEY));
+    }
+
+    private List<Integer> getIndices(SensorStats stats) {
+        int[] primitiveIndices = (int[]) stats.getValue(
+                SensorStats.EVENT_OUT_OF_ORDER_POSITIONS_KEY);
+        List<Integer> indices = new ArrayList<Integer>(primitiveIndices.length);
+        for (int index : primitiveIndices) {
+            indices.add(index);
+        }
+        return indices;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
new file mode 100644
index 0000000..030bfeb
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2014 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.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorVerification} which verifies that the sensor frequency are within the expected
+ * range.
+ */
+public class FrequencyVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "frequency_passed";
+
+    // threshold is (100 - 10)% expected to (100 + 110)% expected
+    private static final int[] DEFAULT_THRESHOLDS = {10, 110};
+
+    // sensorType: lowerThreshold, upperThreshold (% of expected frequency)
+    private final static Map<Integer, int[]> DEFAULTS = new HashMap<Integer, int[]>(12);
+    static {
+        // Use a method so that the @deprecation warning can be set for that method only
+        setDefaults();
+    }
+
+    private final double mExpected;
+    private final double mLowerThreshold;
+    private final double mUpperThreshold;
+
+    private long mMinTimestamp = 0;
+    private long mMaxTimestamp = 0;
+    private int mCount = 0;
+
+    /**
+     * Construct a {@link FrequencyVerification}.
+     *
+     * @param expected the expected frequency in Hz.
+     * @param lowerTheshold the lower threshold in Hz. {@code expected - lower} should be the
+     * slowest acceptable frequency of the sensor.
+     * @param upperThreshold the upper threshold in Hz. {@code expected + upper} should be the
+     * fastest acceptable frequency of the sensor.
+     */
+    public FrequencyVerification(double expected, double lowerTheshold, double upperThreshold) {
+        mExpected = expected;
+        mLowerThreshold = lowerTheshold;
+        mUpperThreshold = upperThreshold;
+    }
+
+    /**
+     * Get the default {@link FrequencyVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @param rateUs the desired rate of the sensor
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    public static FrequencyVerification getDefault(Sensor sensor, int rateUs) {
+        if (!DEFAULTS.containsKey(sensor.getType())) {
+            return null;
+        }
+
+        // Expected frequency in Hz
+        double expected = SensorCtsHelper.getFrequency(SensorCtsHelper.getDelay(sensor, rateUs),
+                TimeUnit.MICROSECONDS);
+        // Expected frequency * threshold percentage
+        double lowerThreshold = expected * DEFAULTS.get(sensor.getType())[0] / 100;
+        double upperThreshold = expected * DEFAULTS.get(sensor.getType())[1] / 100;
+        return new FrequencyVerification(expected, lowerThreshold, upperThreshold);
+    }
+
+    /**
+     * Verify that the frequency is correct. Add {@value #PASSED_KEY} and
+     * {@value SensorStats#FREQUENCY_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (mCount < 2) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        double frequency = SensorCtsHelper.getFrequency(
+                ((double) (mMaxTimestamp - mMinTimestamp)) / (mCount - 1), TimeUnit.NANOSECONDS);
+        boolean failed = (frequency <= mExpected - mLowerThreshold
+                || frequency >= mExpected + mUpperThreshold);
+
+        stats.addValue(SensorStats.FREQUENCY_KEY, frequency);
+        stats.addValue(PASSED_KEY, !failed);
+
+        if (failed) {
+            Assert.fail(String.format("Frequency out of range: frequency=%.2fHz, "
+                    + "expected=(%.2f-%.2fHz, %.2f+%.2fHz)", frequency, mExpected, mLowerThreshold,
+                    mExpected, mUpperThreshold));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FrequencyVerification clone() {
+        return new FrequencyVerification(mExpected, mLowerThreshold, mUpperThreshold);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mCount == 0) {
+            mMinTimestamp = event.timestamp;
+            mMaxTimestamp = event.timestamp;
+        } else {
+            if (mMinTimestamp > event.timestamp) {
+                mMinTimestamp = event.timestamp;
+            }
+            if (mMaxTimestamp < event.timestamp) {
+                mMaxTimestamp = event.timestamp;
+            }
+        }
+        mCount++;
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void setDefaults() {
+        DEFAULTS.put(Sensor.TYPE_ACCELEROMETER, DEFAULT_THRESHOLDS);
+        DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD, DEFAULT_THRESHOLDS);
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE, DEFAULT_THRESHOLDS);
+        DEFAULTS.put(Sensor.TYPE_ORIENTATION, DEFAULT_THRESHOLDS);
+        DEFAULTS.put(Sensor.TYPE_PRESSURE, DEFAULT_THRESHOLDS);
+        DEFAULTS.put(Sensor.TYPE_GRAVITY, DEFAULT_THRESHOLDS);
+        DEFAULTS.put(Sensor.TYPE_LINEAR_ACCELERATION, DEFAULT_THRESHOLDS);
+        DEFAULTS.put(Sensor.TYPE_ROTATION_VECTOR, DEFAULT_THRESHOLDS);
+        DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, DEFAULT_THRESHOLDS);
+        DEFAULTS.put(Sensor.TYPE_GAME_ROTATION_VECTOR, DEFAULT_THRESHOLDS);
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, DEFAULT_THRESHOLDS);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerificationTest.java
new file mode 100644
index 0000000..cec09a5
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerificationTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link EventOrderingVerification}.
+ */
+public class FrequencyVerificationTest extends TestCase {
+
+    /**
+     * Test that the verifications passes/fails based on threshold given.
+     */
+    public void testVerifification() {
+        long[] timestamps = {0, 1000000, 2000000, 3000000, 4000000};  // 1000Hz
+
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(1000.0, 1.0, 1.0, timestamps);
+        verification.verify(stats);
+        verifyStats(stats, true, 1000.0);
+
+        stats = new SensorStats();
+        verification = getVerification(950.0, 100.0, 100.0, timestamps);
+        verification.verify(stats);
+        verifyStats(stats, true, 1000.0);
+
+        stats = new SensorStats();
+        verification = getVerification(1050.0, 100.0, 100.0, timestamps);
+        verification.verify(stats);
+        verifyStats(stats, true, 1000.0);
+
+        stats = new SensorStats();
+        verification = getVerification(950.0, 100.0, 25.0, timestamps);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, 1000.0);
+
+        stats = new SensorStats();
+        verification = getVerification(1050.0, 25.0, 100.0, timestamps);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, 1000.0);
+    }
+
+    private ISensorVerification getVerification(double expected, double lowerThreshold,
+            double upperThreshold, long ... timestamps) {
+        ISensorVerification verification = new FrequencyVerification(expected, lowerThreshold,
+                upperThreshold);
+        for (long timestamp : timestamps) {
+            verification.addSensorEvent(new TestSensorEvent(null, timestamp, 0, null));
+        }
+        return verification;
+    }
+
+    private void verifyStats(SensorStats stats, boolean passed, double frequency) {
+        assertEquals(passed, stats.getValue(FrequencyVerification.PASSED_KEY));
+        assertEquals(frequency, stats.getValue(SensorStats.FREQUENCY_KEY));
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/ISensorVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/ISensorVerification.java
new file mode 100644
index 0000000..07af392
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/ISensorVerification.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+/**
+ * Interface describing the sensor verification. This class was designed for to handle streaming
+ * events. The methods {@link #addSensorEvent(TestSensorEvent)} and
+ * {@link #addSensorEvents(TestSensorEvent...)} should be called in the order that the events are
+ * received. The method {@link #verify(SensorStats)} should be called after all events are added.
+ */
+public interface ISensorVerification {
+
+    /**
+     * Add a single {@link TestSensorEvent} to be evaluated.
+     */
+    public void addSensorEvent(TestSensorEvent event);
+
+    /**
+     * Add multiple {@link TestSensorEvent}s to be evaluated.
+     */
+    public void addSensorEvents(TestSensorEvent ... events);
+
+    /**
+     * Evaluate all added {@link TestSensorEvent}s and update stats.
+     *
+     * @param stats a {@link SensorStats} object used to keep track of the stats.
+     * @throws AssertionError if the verification fails.
+     */
+    public void verify(SensorStats stats);
+
+    /**
+     * Clones the {@link ISensorVerification}
+     */
+    public ISensorVerification clone();
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerification.java
new file mode 100644
index 0000000..7929ee9
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerification.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2014 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.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorVerification} which verifies that the sensor jitter is in an acceptable range.
+ */
+public class JitterVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "jitter_passed";
+
+    // sensorType: threshold (% of expected period)
+    private static final Map<Integer, Integer> DEFAULTS = new HashMap<Integer, Integer>(12);
+    static {
+        // Use a method so that the @deprecation warning can be set for that method only
+        setDefaults();
+    }
+
+    private final int mExpected;
+    private final int mThreshold;
+
+    private List<Long> mTimestamps = new LinkedList<Long>();
+
+    /**
+     * Construct a {@link JitterVerification}
+     *
+     * @param expected the expected period in ns
+     * @param threshold the acceptable margin of error as a percentage
+     */
+    public JitterVerification(int expected, int threshold) {
+        mExpected = expected;
+        mThreshold = threshold;
+    }
+
+    /**
+     * Get the default {@link JitterVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @param rateUs the desired rate of the sensor
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    public static JitterVerification getDefault(Sensor sensor, int rateUs) {
+        if (!DEFAULTS.containsKey(sensor.getType())) {
+            return null;
+        }
+
+        int expected = (int) TimeUnit.NANOSECONDS.convert(SensorCtsHelper.getDelay(sensor, rateUs),
+                TimeUnit.MICROSECONDS);
+        return new JitterVerification(expected, DEFAULTS.get(sensor.getType()));
+    }
+
+    /**
+     * Verify that the 95th percentile of the jitter is in the acceptable range. Add
+     * {@value #PASSED_KEY} and {@value SensorStats#JITTER_95_PERCENTILE_KEY} keys to
+     * {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (mTimestamps.size() < 2) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        List<Double> jitters = getJitterValues();
+        double jitter95Percentile = SensorCtsHelper.get95PercentileValue(jitters);
+        boolean failed = (jitter95Percentile > mExpected * (mThreshold / 100.0));
+
+        stats.addValue(PASSED_KEY, !failed);
+        stats.addValue(SensorStats.JITTER_95_PERCENTILE_KEY, jitter95Percentile);
+
+        if (failed) {
+            Assert.fail(String.format("Jitter out of range: jitter at 95th percentile=%.0fns, "
+                    + "expected=<%.0fns", jitter95Percentile, mExpected * (mThreshold / 100.0)));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public JitterVerification clone() {
+        return new JitterVerification(mExpected, mThreshold);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        mTimestamps.add(event.timestamp);
+    }
+
+    /**
+     * Get the list of all jitter values. Exposed for unit testing.
+     */
+    List<Double> getJitterValues() {
+        List<Long> deltas = new ArrayList<Long>(mTimestamps.size() - 1);
+        for (int i = 1; i < mTimestamps.size(); i++) {
+            deltas.add(mTimestamps.get(i) - mTimestamps.get(i -1));
+        }
+        double deltaMean = SensorCtsHelper.getMean(deltas);
+        List<Double> jitters = new ArrayList<Double>(deltas.size());
+        for (long delta : deltas) {
+            jitters.add(Math.abs(delta - deltaMean));
+        }
+        return jitters;
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void setDefaults() {
+        // Sensors that we don't want to test at this time but still want to record the values.
+        DEFAULTS.put(Sensor.TYPE_ACCELEROMETER, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_ORIENTATION, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_PRESSURE, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_GRAVITY, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_LINEAR_ACCELERATION, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_ROTATION_VECTOR, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_GAME_ROTATION_VECTOR, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, Integer.MAX_VALUE);
+        DEFAULTS.put(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, Integer.MAX_VALUE);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerificationTest.java
new file mode 100644
index 0000000..a9e872a
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerificationTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+
+/**
+ * Tests for {@link EventOrderingVerification}.
+ */
+public class JitterVerificationTest extends TestCase {
+
+
+    public void testVerify() {
+        final int SAMPLE_SIZE = 100;
+
+        // 100 samples at 1000Hz
+        long[] timestamps = new long[SAMPLE_SIZE];
+        for (int i = 0; i < SAMPLE_SIZE; i++) {
+            timestamps[i] = i * 100000;
+        }
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(1000, 1, timestamps);
+        verification.verify(stats);
+        verifyStats(stats, true, 0.0);
+
+        // 90 samples at 1000Hz, 10 samples at 2000Hz
+        long timestamp = 0;
+        for (int i = 0; i < SAMPLE_SIZE; i++) {
+            timestamps[i] = timestamp;
+            timestamp += (i % 10 == 0) ? 500000 : 1000000;
+        }
+        stats = new SensorStats();
+        verification = getVerification(1000, 1, timestamps);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, 449494.9494);
+    }
+
+    public void testCalculateJitter() {
+        long[] timestamps = new long[]{0, 1, 2, 3, 4};
+        JitterVerification verification = getVerification(1000, 1, timestamps);
+        List<Double> jitterValues = verification.getJitterValues();
+        assertEquals(4, jitterValues.size());
+        assertEquals(0.0, (double) jitterValues.get(0));
+        assertEquals(0.0, (double) jitterValues.get(1));
+        assertEquals(0.0, (double) jitterValues.get(2));
+        assertEquals(0.0, (double) jitterValues.get(3));
+
+        timestamps = new long[]{0, 0, 2, 4, 4};
+        verification = getVerification(1000, 1, timestamps);
+        jitterValues = verification.getJitterValues();
+        assertEquals(4, jitterValues.size());
+        assertEquals(1.0, (double) jitterValues.get(0));
+        assertEquals(1.0, (double) jitterValues.get(1));
+        assertEquals(1.0, (double) jitterValues.get(2));
+        assertEquals(1.0, (double) jitterValues.get(3));
+
+        timestamps = new long[]{0, 1, 4, 9, 16};
+        verification = getVerification(1000, 1, timestamps);
+        jitterValues = verification.getJitterValues();
+        assertEquals(4, jitterValues.size());
+        assertEquals(4, jitterValues.size());
+        assertEquals(3.0, (double) jitterValues.get(0));
+        assertEquals(1.0, (double) jitterValues.get(1));
+        assertEquals(1.0, (double) jitterValues.get(2));
+        assertEquals(3.0, (double) jitterValues.get(3));
+    }
+
+    private JitterVerification getVerification(int expected, int threshold, long ... timestamps) {
+        JitterVerification verification = new JitterVerification(expected, threshold);
+        for (long timestamp : timestamps) {
+            verification.addSensorEvent(new TestSensorEvent(null, timestamp, 0, null));
+        }
+        return verification;
+    }
+
+    private void verifyStats(SensorStats stats, boolean passed, double jitter95) {
+        assertEquals(passed, stats.getValue(JitterVerification.PASSED_KEY));
+        assertEquals(jitter95, (Double) stats.getValue(SensorStats.JITTER_95_PERCENTILE_KEY), 0.1);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerification.java
new file mode 100644
index 0000000..d987eef
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerification.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2014 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.SensorManager;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A {@link ISensorVerification} which verifies that the mean of the magnitude of the sensors vector
+ * is within the expected range.
+ */
+public class MagnitudeVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "magnitude_passed";
+
+    // sensorType: {expected, threshold}
+    private static Map<Integer, Float[]> DEFAULTS = new HashMap<Integer, Float[]>(3);
+    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 float mSum = 0.0f;
+    private int mCount = 0;
+
+    /**
+     * Construct a {@link MagnitudeVerification}
+     *
+     * @param expected the expected value
+     * @param threshold the threshold
+     */
+    public MagnitudeVerification(float expected, float threshold) {
+        mExpected = expected;
+        mThreshold = threshold;
+    }
+
+    /**
+     * Get the default {@link MagnitudeVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    public static MagnitudeVerification getDefault(Sensor sensor) {
+        if (!DEFAULTS.containsKey(sensor.getType())) {
+            return null;
+        }
+        Float expected = DEFAULTS.get(sensor.getType())[0];
+        Float threshold = DEFAULTS.get(sensor.getType())[1];
+        return new MagnitudeVerification(expected, threshold);
+    }
+
+    /**
+     * Verify that the magnitude is in the acceptable range. Add {@value #PASSED_KEY} and
+     * {@value SensorStats#MAGNITUDE_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (mCount < 1) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        float mean = mSum / mCount;
+        boolean failed = Math.abs(mean - mExpected) > mThreshold;
+
+        stats.addValue(PASSED_KEY, !failed);
+        stats.addValue(SensorStats.MAGNITUDE_KEY, mean);
+
+        if (failed) {
+            Assert.fail(String.format("Magnitude mean out of range: mean=%s, expected=%s+/-%s",
+                    mean, mExpected, mThreshold));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public MagnitudeVerification clone() {
+        return new MagnitudeVerification(mExpected, mThreshold);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        float sumOfSquares = 0.0f;
+        for (float value : event.values) {
+            sumOfSquares += value * value;
+        }
+        mSum += (float) Math.sqrt(sumOfSquares);
+        mCount++;
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void setDefaults() {
+        DEFAULTS.put(Sensor.TYPE_ACCELEROMETER, new Float[]{SensorManager.STANDARD_GRAVITY, 1.5f});
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE, new Float[]{0.0f, 1.5f});
+        // Sensors that we don't want to test at this time but still want to record the values.
+        DEFAULTS.put(Sensor.TYPE_GRAVITY,
+                new Float[]{SensorManager.STANDARD_GRAVITY, Float.MAX_VALUE});
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerificationTest.java
new file mode 100644
index 0000000..9a50753
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MagnitudeVerificationTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link MagnitudeVerification}.
+ */
+public class MagnitudeVerificationTest extends TestCase {
+
+    /**
+     * Test {@link MagnitudeVerification#verify(SensorStats)}.
+     */
+    public void testVerify() {
+        float[][] values = {
+                {0, 3, 4},
+                {4, 0, 3},
+                {3, 4, 0},
+                {0, 0, 4},
+                {6, 0, 0},
+        };
+
+        runStats(5.0f, 0.1f, values, true, 5.0f);
+        runStats(4.5f, 0.6f, values, true, 5.0f);
+        runStats(5.5f, 0.6f, values, true, 5.0f);
+        runStats(4.5f, 0.1f, values, false, 5.0f);
+        runStats(5.5f, 0.1f, values, false, 5.0f);
+    }
+
+    private void runStats(float expected, float threshold, float[][] values, boolean pass, float magnitude) {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(expected, threshold, values);
+        if (pass) {
+            verification.verify(stats);
+        } else {
+            try {
+                verification.verify(stats);
+                fail("Expected an AssertionError");
+            } catch (AssertionError e) {
+                // Expected;
+            }
+        }
+        assertEquals(pass, stats.getValue(MagnitudeVerification.PASSED_KEY));
+        assertEquals(magnitude, (Float) stats.getValue(SensorStats.MAGNITUDE_KEY), 0.01);
+    }
+
+    private ISensorVerification getVerification(float expected, float threshold,
+            float[] ... values) {
+        ISensorVerification verification = new MagnitudeVerification(expected, threshold);
+        for (float[] value : values) {
+            verification.addSensorEvent(new TestSensorEvent(null, 0, 0, value));
+        }
+        return verification;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java
new file mode 100644
index 0000000..315b3aa
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerification.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 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.SensorManager;
+import android.hardware.cts.helpers.SensorStats;
+
+import junit.framework.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A {@link ISensorVerification} which verifies that the means matches the expected measurement.
+ */
+public class MeanVerification extends AbstractMeanVerification {
+    public static final String PASSED_KEY = "mean_passed";
+
+    // sensorType: {expected, threshold}
+    private static final Map<Integer, Object[]> DEFAULTS = new HashMap<Integer, Object[]>(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;
+
+    /**
+     * Construct a {@link MeanVerification}
+     *
+     * @param expected the expected values
+     * @param threshold the thresholds
+     */
+    public MeanVerification(float[] expected, float[] threshold) {
+        mExpected = expected;
+        mThreshold = threshold;
+    }
+
+    /**
+     * Get the default {@link MeanVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    public static MeanVerification getDefault(Sensor sensor) {
+        if (!DEFAULTS.containsKey(sensor.getType())) {
+            return null;
+        }
+        float[] expected = (float[]) DEFAULTS.get(sensor.getType())[0];
+        float[] threshold = (float[]) DEFAULTS.get(sensor.getType())[1];
+        return new MeanVerification(expected, threshold);
+    }
+
+    /**
+     * Verify that the mean is in the acceptable range. Add {@value #PASSED_KEY} and
+     * {@value SensorStats#MEAN_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (getCount() < 1) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        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]) {
+                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(")");
+        }
+
+        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()));
+        }
+    }
+
+    @Override
+    public MeanVerification clone() {
+        return new MeanVerification(mExpected, mThreshold);
+    }
+
+    @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}});
+        // 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}});
+        // 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}});
+        // 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}});
+        // 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}});
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerificationTest.java
new file mode 100644
index 0000000..94b6362
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/MeanVerificationTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link MeanVerification}.
+ */
+public class MeanVerificationTest extends TestCase {
+
+    /**
+     * Test {@link MeanVerification#verify(SensorStats)}.
+     */
+    public void testVerify() {
+        float[][] values = {
+                {0, 1, 0},
+                {1, 2, 1},
+                {2, 3, 4},
+                {3, 4, 9},
+                {4, 5, 16},
+        };
+
+        float[] expected = {2.0f, 3.0f, 6.0f};
+        float[] threshold = {0.1f, 0.1f, 0.1f};
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(expected, threshold, values);
+        verification.verify(stats);
+        verifyStats(stats, true, new float[]{2.0f, 3.0f, 6.0f});
+
+        expected = new float[]{2.5f, 2.5f, 5.5f};
+        threshold = new float[]{0.6f, 0.6f, 0.6f};
+        stats = new SensorStats();
+        verification = getVerification(expected, threshold, values);
+        verification.verify(stats);
+        verifyStats(stats, true, new float[]{2.0f, 3.0f, 6.0f});
+
+        expected = new float[]{2.5f, 2.5f, 5.5f};
+        threshold = new float[]{0.1f, 0.6f, 0.6f};
+        stats = new SensorStats();
+        verification = getVerification(expected, threshold, values);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, new float[]{2.0f, 3.0f, 6.0f});
+
+        expected = new float[]{2.5f, 2.5f, 5.5f};
+        threshold = new float[]{0.6f, 0.1f, 0.6f};
+        stats = new SensorStats();
+        verification = getVerification(expected, threshold, values);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, new float[]{2.0f, 3.0f, 6.0f});
+
+        threshold = new float[]{2.5f, 2.5f, 5.5f};
+        threshold = new float[]{0.6f, 0.6f, 0.1f};
+        stats = new SensorStats();
+        verification = getVerification(expected, threshold, values);
+        try {
+            verification.verify(stats);
+            fail("Expected an AssertionError");
+        } catch (AssertionError e) {
+            // Expected;
+        }
+        verifyStats(stats, false, new float[]{2.0f, 3.0f, 6.0f});
+    }
+
+    private ISensorVerification getVerification(float[] expected, float[] threshold,
+            float[] ... values) {
+        ISensorVerification verification = new MeanVerification(expected, threshold);
+        for (float[] value : values) {
+            verification.addSensorEvent(new TestSensorEvent(null, 0, 0, value));
+        }
+        return verification;
+    }
+
+    private void verifyStats(SensorStats stats, boolean passed, float[] means) {
+        assertEquals(passed, stats.getValue(MeanVerification.PASSED_KEY));
+        float[] actual = (float[]) stats.getValue(SensorStats.MEAN_KEY);
+        for (int i = 0; i < means.length; i++) {
+            assertEquals(means[i], actual[i], 0.1);
+        }
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerification.java
new file mode 100644
index 0000000..9417cd3
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerification.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.SensorStats;
+
+import junit.framework.Assert;
+
+/**
+ * A {@link ISensorVerification} which verifies that the sign of each of the sensor values is
+ * correct.
+ * <p>
+ * If the value of the measurement is in [-threshold, threshold], the sign is considered 0. If
+ * it is less than -threshold, it is considered -1. If it is greater than threshold, it is
+ * considered 1.
+ * </p>
+ */
+public class SigNumVerification extends AbstractMeanVerification {
+    public static final String PASSED_KEY = "sig_num_passed";
+
+    private final int[] mExpected;
+    private final float[] mThreshold;
+
+    /**
+     * Construct a {@link SigNumVerification}
+     *
+     * @param expected the expected values
+     * @param threshold the threshold that needs to be crossed to consider a measurement nonzero
+     * @throws IllegalStateException if the expected values are not 0, -1, or 1.
+     */
+    public SigNumVerification(int[] expected, float[] threshold) {
+        for (int i = 0; i < expected.length; i++) {
+            if (!(expected[i] == -1 || expected[i] == 0 || expected[i] == 1)) {
+                throw new IllegalArgumentException("Expected value must be -1, 0, or 1");
+            }
+        }
+
+        mExpected = expected;
+        mThreshold = threshold;
+    }
+
+    /**
+     * Verify that the sign of each of the sensor values is correct. Add {@value #PASSED_KEY} and
+     * {@value SensorStats#MEAN_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (getCount() < 1) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        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++) {
+            meanSb.append(String.format("%.2f", means[i]));
+            if (i != means.length - 1) meanSb.append(", ");
+
+            if (mExpected[i] == 0) {
+                if (Math.abs(means[i]) > mThreshold[i]) {
+                    failed = true;
+                }
+                expectedSb.append(String.format("[%.2f, %.2f]", -mThreshold[i], mThreshold[i]));
+            } else {
+                if (mExpected[i] > 0) {
+                    if (means[i] <= mThreshold[i]) {
+                        failed = true;
+                    }
+                    expectedSb.append(String.format("(%.2f, inf)", mThreshold[i]));
+                } else {
+                    if (means[i] >= -1 * mThreshold[i]) {
+                        failed = true;
+                    }
+                    expectedSb.append(String.format("(-inf, %.2f)", -1 * mThreshold[i]));
+                }
+            }
+            if (i != means.length - 1) expectedSb.append(", ");
+        }
+        if (means.length > 1) {
+            meanSb.append(")");
+            expectedSb.append(")");
+        }
+
+        stats.addValue(PASSED_KEY, !failed);
+        stats.addValue(SensorStats.MEAN_KEY, means);
+
+        if (failed) {
+            Assert.fail(String.format("Signum out of range: mean=%s, expected=%s",
+                    meanSb.toString(), expectedSb.toString()));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SigNumVerification clone() {
+        return new SigNumVerification(mExpected, mThreshold);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerificationTest.java
new file mode 100644
index 0000000..009ab65
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/SigNumVerificationTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link SigNumVerification}.
+ */
+public class SigNumVerificationTest extends TestCase {
+
+    /**
+     * Test {@link SigNumVerification#verify(SensorStats)}.
+     */
+    public void testVerify() {
+        float[][] values = {{1.0f, 0.2f, 0.0f, -0.2f, -1.0f}};
+
+        int[] expected = {1, 1, 0, -1, -1};
+        float[] threshold = {0.1f, 0.1f, 0.1f, 0.1f, 0.1f};
+        runVerification(true, expected, threshold, values);
+
+        expected = new int[]{1, 0, 0, 0, -1};
+        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
+        runVerification(true, expected, threshold, values);
+
+        expected = new int[]{0, 1, 0, -1, 0};
+        threshold = new float[]{1.5f, 0.1f, 0.1f, 0.1f, 1.5f};
+        runVerification(true, expected, threshold, values);
+
+        expected = new int[]{1, 0, 0, 0, 1};
+        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
+        runVerification(false, expected, threshold, values);
+
+        expected = new int[]{-1, 0, 0, 0, -1};
+        threshold = new float[]{0.5f, 0.5f, 0.5f, 0.5f, 0.5f};
+        runVerification(false, expected, threshold, values);
+    }
+
+    private SigNumVerification getVerification(int[] expected, float[] threshold,
+            float[] ... values) {
+        SigNumVerification verification = new SigNumVerification(expected, threshold);
+        for (float[] value : values) {
+            verification.addSensorEvent(new TestSensorEvent(null, 0, 0, value));
+        }
+        return verification;
+    }
+
+    private void runVerification(boolean passed, int[] expected, float[] threshold,
+            float[][] values) {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(expected, threshold, values);
+        if (passed) {
+            verification.verify(stats);
+        } else {
+            try {
+                verification.verify(stats);
+                fail("Expected an AssertionError");
+            } catch (AssertionError e) {
+                // Expected;
+            }
+        }
+        assertEquals(passed, stats.getValue(SigNumVerification.PASSED_KEY));
+        assertNotNull(stats.getValue(SensorStats.MEAN_KEY));
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java
new file mode 100644
index 0000000..03db067
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2014 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.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A {@link ISensorVerification} which verifies that the standard deviations is within the expected
+ * range.
+ */
+public class StandardDeviationVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "standard_deviation_passed";
+
+    // sensorType: threshold
+    private static final Map<Integer, float[]> DEFAULTS = new HashMap<Integer, float[]>(12);
+    static {
+        // Use a method so that the @deprecation warning can be set for that method only
+        setDefaults();
+    }
+
+    private final float[] mThreshold;
+
+    private float[] mMeans = null;
+    private float[] mM2s = null;
+    private int mCount = 0;
+
+    /**
+     * Construct a {@link StandardDeviationVerification}
+     *
+     * @param threshold the thresholds
+     */
+    public StandardDeviationVerification(float[] threshold) {
+        mThreshold = threshold;
+    }
+
+    /**
+     * Get the default {@link StandardDeviationVerification} for a sensor.
+     *
+     * @param sensor a {@link Sensor}
+     * @return the verification or null if the verification does not apply to the sensor.
+     */
+    public static StandardDeviationVerification getDefault(Sensor sensor) {
+        if (!DEFAULTS.containsKey(sensor.getType())) {
+            return null;
+        }
+
+        return new StandardDeviationVerification(DEFAULTS.get(sensor.getType()));
+    }
+
+    /**
+     * Verify that the standard deviation is in the acceptable range. Add {@value #PASSED_KEY} and
+     * {@value SensorStats#STANDARD_DEVIATION_KEY} keys to {@link SensorStats}.
+     *
+     * @throws AssertionError if the verification failed.
+     */
+    @Override
+    public void verify(SensorStats stats) {
+        if (mCount < 2) {
+            stats.addValue(PASSED_KEY, true);
+            return;
+        }
+
+        float[] stdDevs = new float[mM2s.length];
+        for (int i = 0; i < mM2s.length; i++) {
+            stdDevs[i] = (float) Math.sqrt(mM2s[i] / (mCount - 1));
+        }
+
+        boolean failed = false;
+        StringBuilder stddevSb = new StringBuilder();
+        StringBuilder expectedSb = new StringBuilder();
+
+        if (stdDevs.length > 1) {
+            stddevSb.append("(");
+            expectedSb.append("(");
+        }
+        for (int i = 0; i < stdDevs.length; i++) {
+            if (stdDevs[i] > mThreshold[i]) {
+                failed = true;
+            }
+            stddevSb.append(String.format("%.2f", stdDevs[i]));
+            if (i != stdDevs.length - 1) stddevSb.append(", ");
+            expectedSb.append(String.format("<%.2f", mThreshold[i]));
+            if (i != stdDevs.length - 1) expectedSb.append(", ");
+        }
+        if (stdDevs.length > 1) {
+            stddevSb.append(")");
+            expectedSb.append(")");
+        }
+
+        stats.addValue(PASSED_KEY, !failed);
+        stats.addValue(SensorStats.STANDARD_DEVIATION_KEY, stdDevs);
+
+        if (failed) {
+            Assert.fail(String.format("Standard deviation out of range: stddev=%s, expected=%s",
+                    stddevSb.toString(), expectedSb.toString()));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public StandardDeviationVerification clone() {
+        return new StandardDeviationVerification(mThreshold);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Computes the standard deviation using
+     * <a href="http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm">
+     * Welford's algorith</a>.
+     * </p>
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mMeans == null || mM2s == null) {
+            mMeans = new float[event.values.length];
+            mM2s = new float[event.values.length];
+        }
+
+        Assert.assertEquals(mMeans.length, event.values.length);
+        Assert.assertEquals(mM2s.length, event.values.length);
+
+        mCount++;
+
+        for (int i = 0; i < event.values.length; i++) {
+            float delta = event.values[i] - mMeans[i];
+            mMeans[i] += delta / mCount;
+            mM2s[i] += delta * (event.values[i] - mMeans[i]);
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    private static void setDefaults() {
+        DEFAULTS.put(Sensor.TYPE_ACCELEROMETER, new float[]{1.0f, 1.0f, 1.0f});
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE, new float[]{0.5f, 0.5f, 0.5f});
+        // Sensors that we don't want to test at this time but still want to record the values.
+        DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_ORIENTATION,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_PRESSURE,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_GRAVITY,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_LINEAR_ACCELERATION,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_ROTATION_VECTOR,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_GAME_ROTATION_VECTOR,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                Float.MAX_VALUE, Float.MAX_VALUE});
+        DEFAULTS.put(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR,
+                new float[]{Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE,
+                Float.MAX_VALUE});
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerificationTest.java
new file mode 100644
index 0000000..0e5fb90
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerificationTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2014 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.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link StandardDeviationVerification}.
+ */
+public class StandardDeviationVerificationTest extends TestCase {
+
+    /**
+     * Test {@link StandardDeviationVerification#verify(SensorStats)}.
+     */
+    public void testVerify() {
+        // Stddev should be {sqrt(2.5), sqrt(2.5), sqrt(2.5)}
+        float[][] values = {
+                {0, 1, 0},
+                {1, 2, 2},
+                {2, 3, 4},
+                {3, 4, 6},
+                {4, 5, 8},
+        };
+        float[] standardDeviations = {
+                (float) Math.sqrt(2.5), (float) Math.sqrt(2.5), (float) Math.sqrt(10.0)
+        };
+
+        float[] threshold = {2, 2, 4};
+        runVerification(threshold, values, true, standardDeviations);
+
+        threshold = new float[]{1, 2, 4};
+        runVerification(threshold, values, false, standardDeviations);
+
+        threshold = new float[]{2, 1, 4};
+        runVerification(threshold, values, false, standardDeviations);
+
+        threshold = new float[]{2, 2, 3};
+        runVerification(threshold, values, false, standardDeviations);
+    }
+
+    private void runVerification(float[] threshold, float[][] values, boolean pass,
+            float[] standardDeviations) {
+        SensorStats stats = new SensorStats();
+        ISensorVerification verification = getVerification(threshold, values);
+        if (pass) {
+            verification.verify(stats);
+        } else {
+            try {
+                verification.verify(stats);
+                fail("Expected an AssertionError");
+            } catch (AssertionError e) {
+                // Expected;
+            }
+        }
+        assertEquals(pass, stats.getValue(StandardDeviationVerification.PASSED_KEY));
+        float[] actual = (float[]) stats.getValue(SensorStats.STANDARD_DEVIATION_KEY);
+        for (int i = 0; i < standardDeviations.length; i++) {
+            assertEquals(standardDeviations[i], actual[i], 0.1);
+        }
+    }
+
+    private ISensorVerification getVerification(float[] threshold, float[] ... values) {
+        ISensorVerification verification = new StandardDeviationVerification(threshold);
+        for (float[] value : values) {
+            verification.addSensorEvent(new TestSensorEvent(null, 0, 0, value));
+        }
+        return verification;
+    }
+}
