blob: 6567be2a5d46608c3d46f4e32e1d5027acda274f [file] [log] [blame]
/*
* 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 junit.framework.Assert;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener2;
import android.os.SystemClock;
import android.util.Log;
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";
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;
private volatile CountDownLatch mFlushLatch = new CountDownLatch(1);
private volatile TestSensorEnvironment mEnvironment;
private volatile boolean mLogEvents;
/**
* Construct a {@link TestSensorEventListener}.
*/
public TestSensorEventListener() {
this(null);
}
/**
* Construct a {@link TestSensorEventListener} that wraps a {@link SensorEventListener2}.
*/
public TestSensorEventListener(SensorEventListener2 listener) {
if (listener != null) {
mListener = listener;
} else {
// use a Null Object to simplify handling the listener
mListener = new SensorEventListener2() {
public void onFlushCompleted(Sensor sensor) {}
public void onSensorChanged(SensorEvent sensorEvent) {}
public void onAccuracyChanged(Sensor sensor, int i) {}
};
}
}
/**
* Set the sensor, rate, and batch report latency used for the assertions.
*/
public void setEnvironment(TestSensorEnvironment environment) {
mEnvironment = environment;
}
/**
* Set whether or not to log events
*/
public void setLogEvents(boolean log) {
mLogEvents = log;
}
/**
* {@inheritDoc}
*/
@Override
public void onSensorChanged(SensorEvent event) {
mListener.onSensorChanged(event);
if (mLogEvents) {
Log.v(LOG_TAG, String.format(
"Sensor %d: sensor_timestamp=%dns, received_timestamp=%dns, values=%s",
mEnvironment.getSensor().getType(),
event.timestamp,
SystemClock.elapsedRealtimeNanos(),
Arrays.toString(event.values)));
}
CountDownLatch eventLatch = mEventLatch;
if(eventLatch != null) {
eventLatch.countDown();
}
}
/**
* {@inheritDoc}
*/
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
mListener.onAccuracyChanged(sensor, accuracy);
}
/**
* {@inheritDoc}
*/
@Override
public void onFlushCompleted(Sensor sensor) {
CountDownLatch latch = mFlushLatch;
mFlushLatch = null;
if(latch != null) {
latch.countDown();
}
mListener.onFlushCompleted(sensor);
}
/**
* Wait for {@link #onFlushCompleted(Sensor)} to be called.
*
* @throws AssertionError if there was a timeout after {@link #FLUSH_TIMEOUT_US} µs
*/
public void waitForFlushComplete() throws InterruptedException {
CountDownLatch latch = mFlushLatch;
if(latch == null) {
return;
}
Assert.assertTrue(
SensorCtsHelper.formatAssertionMessage("WaitForFlush", mEnvironment),
latch.await(FLUSH_TIMEOUT_US, TimeUnit.MICROSECONDS));
}
/**
* Collect a specific number of {@link TestSensorEvent}s.
*
* @throws AssertionError if there was a timeout after {@link #FLUSH_TIMEOUT_US} µs
*/
public void waitForEvents(int eventCount) throws InterruptedException {
mEventLatch = new CountDownLatch(eventCount);
try {
int rateUs = mEnvironment.getExpectedSamplingPeriodUs();
// Timeout is 2 * event count * expected period + batch timeout + default wait
long timeoutUs = (2 * eventCount * rateUs)
+ mEnvironment.getMaxReportLatencyUs()
+ EVENT_TIMEOUT_US;
String message = SensorCtsHelper.formatAssertionMessage(
"WaitForEvents",
mEnvironment,
"requested:%d, received:%d",
eventCount,
eventCount - mEventLatch.getCount());
Assert.assertTrue(message, mEventLatch.await(timeoutUs, TimeUnit.MICROSECONDS));
} finally {
mEventLatch = null;
}
}
/**
* Collect {@link TestSensorEvent} for a specific duration.
*/
public void waitForEvents(long duration, TimeUnit timeUnit) throws InterruptedException {
SensorCtsHelper.sleep(duration, timeUnit);
}
}