| /* |
| * 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 junit.framework.Assert; |
| |
| import android.hardware.Sensor; |
| import android.hardware.cts.helpers.SensorStats; |
| import android.hardware.cts.helpers.TestSensorEnvironment; |
| import android.hardware.cts.helpers.TestSensorEvent; |
| |
| 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_out_of_order_passed"; |
| |
| // Number of indices to print in assert message before truncating |
| private static final int TRUNCATE_MESSAGE_LENGTH = 3; |
| |
| private Long mMaxTimestamp = null; |
| private final List<IndexedEventPair> mOutOfOrderEvents = new LinkedList<IndexedEventPair>(); |
| private TestSensorEvent mPreviousEvent = null; |
| private int mIndex = 0; |
| |
| /** |
| * Get the default {@link EventOrderingVerification} for a sensor. |
| * |
| * @param environment the test environment |
| * @return the verification or null if the verification does not apply to the sensor. |
| */ |
| @SuppressWarnings("deprecation") |
| public static EventOrderingVerification getDefault(TestSensorEnvironment environment) { |
| int reportingMode = environment.getSensor().getReportingMode(); |
| if (reportingMode != Sensor.REPORTING_MODE_CONTINUOUS |
| && reportingMode != Sensor.REPORTING_MODE_ON_CHANGE) { |
| return null; |
| } |
| return new EventOrderingVerification(); |
| } |
| |
| /** |
| * 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(TestSensorEnvironment environment, SensorStats stats) { |
| verify(stats); |
| } |
| |
| /** |
| * Visible for unit tests only. |
| */ |
| void verify(SensorStats stats) { |
| final int count = mOutOfOrderEvents.size(); |
| stats.addValue(PASSED_KEY, count == 0); |
| stats.addValue(SensorStats.EVENT_OUT_OF_ORDER_COUNT_KEY, count); |
| |
| final int[] indices = new int[count]; |
| 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 (count > 0) { |
| StringBuilder sb = new StringBuilder(); |
| sb.append(count).append(" events out of order: "); |
| for (int i = 0; i < Math.min(count, TRUNCATE_MESSAGE_LENGTH); i++) { |
| IndexedEventPair info = mOutOfOrderEvents.get(i); |
| sb.append(String.format("position=%d, previous=%d, timestamp=%d; ", info.index, |
| info.previousEvent.timestamp, info.event.timestamp)); |
| } |
| if (count > TRUNCATE_MESSAGE_LENGTH) { |
| sb.append(count - TRUNCATE_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 IndexedEventPair(mIndex, event, mPreviousEvent)); |
| } else if (event.timestamp > mMaxTimestamp) { |
| mMaxTimestamp = event.timestamp; |
| } |
| } |
| |
| mPreviousEvent = event; |
| mIndex++; |
| } |
| } |