Merge "add test for setLocalFosus and injectInputEvent" into klp-dev
diff --git a/tests/tests/graphics/src/android/opengl/cts/OpenGlEsVersionTest.java b/tests/tests/graphics/src/android/opengl/cts/OpenGlEsVersionTest.java
index 30a1f67..85159a8 100644
--- a/tests/tests/graphics/src/android/opengl/cts/OpenGlEsVersionTest.java
+++ b/tests/tests/graphics/src/android/opengl/cts/OpenGlEsVersionTest.java
@@ -68,9 +68,12 @@
reportedVersion, getVersionFromPackageManager(mActivity));
assertGlVersionString(1);
- if (detectedVersion >= 2) {
+ if (detectedVersion == 2) {
restartActivityWithClientVersion(2);
assertGlVersionString(2);
+ } else if (detectedVersion == 3) {
+ restartActivityWithClientVersion(3);
+ assertGlVersionString(3);
}
}
@@ -190,9 +193,6 @@
String versionString = "" + majorVersion;
String message = "OpenGL version string '" + mActivity.getVersionString()
+ "' is not " + majorVersion + ".0+.";
- if (majorVersion == 2) {
- versionString = "(2|3)";
- }
assertTrue(message, Pattern.matches(".*OpenGL.*ES.*" + versionString + "\\.\\d.*",
mActivity.getVersionString()));
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorAccelerometerTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorAccelerometerTest.java
index 51fd5f6..2e33a5d 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorAccelerometerTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorAccelerometerTest.java
@@ -20,6 +20,8 @@
import android.hardware.SensorManager;
public class SensorAccelerometerTest extends SensorCommonTests {
+ private final int AXIS_COUNT = 3;
+
@Override
protected int getMaxFrequencySupportedInuS() {
return 10000; // 100Hz
@@ -37,21 +39,13 @@
*/
@Override
public void testEventValidity() {
- final float THRESHOLD = 0.25f; // m / s^2
- validateSensorEvent(
- 0 /*x-axis*/,
- 0 /*y-axis*/,
- SensorManager.STANDARD_GRAVITY /*z-axis*/,
- THRESHOLD);
+ final float THRESHOLD = 0.5f; // m / s^2
+ validateNormForSensorEvent(SensorManager.STANDARD_GRAVITY, THRESHOLD, AXIS_COUNT);
}
@Override
- public void testVarianceWhileStatic() {
- final float THRESHOLD = 0.25f; // m / s^2
- validateVarianceWhileStatic(
- 0 /*x-axis*/,
- 0 /*y-axis*/,
- SensorManager.STANDARD_GRAVITY /*z-axis*/,
- THRESHOLD);
+ public void testStandardDeviationWhileStatic() {
+ final float STANDARD_DEVIATION = 1f; // m / s^2
+ validateStandardDeviationWhileStatic(STANDARD_DEVIATION, AXIS_COUNT);
}
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorCommonTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorCommonTests.java
index 5cc65bb..326963c 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorCommonTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorCommonTests.java
@@ -18,45 +18,34 @@
import android.content.Context;
-import android.hardware.FlushCompleteListener;
import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.TriggerEvent;
import android.hardware.TriggerEventListener;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.TestSensorManager;
+
import android.os.PowerManager;
+import android.os.SystemClock;
import android.test.AndroidTestCase;
-import java.util.List;
import android.util.Log;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-import java.text.SimpleDateFormat;
-
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
+import java.util.List;
import java.util.Random;
-import java.util.concurrent.ConcurrentLinkedDeque;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import junit.framework.Assert;
+
/**
* Class is not marked public to avoid TestRunner to pick the tests in it
*/
abstract class SensorCommonTests extends AndroidTestCase {
protected final String LOG_TAG = "TestRunner";
-
- protected SensorManager mSensorManager;
- protected Sensor mSensorUnderTest;
- protected TestSensorListener mEventListener;
-
- private FlushCompleteListener mFlushListener;
+ protected TestSensorManager mTestSensorManager;
private PowerManager.WakeLock mWakeLock;
protected SensorCommonTests() {}
@@ -71,15 +60,11 @@
* Abstract test methods that sensors need to verify
*/
public abstract void testEventValidity();
- public abstract void testVarianceWhileStatic();
+ public abstract void testStandardDeviationWhileStatic();
/**
* Methods to control the behavior of the tests by concrete sensor tests
*/
- protected int getWaitTimeoutInSeconds() {
- return 30;
- }
-
protected int getHighNumberOfIterationsToExecute() {
return 100;
}
@@ -101,31 +86,27 @@
Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getLogTag());
mWakeLock.acquire();
-
- mEventListener = new TestSensorListener();
- mFlushListener = new TestFlushListener();
}
@Override
protected void tearDown() throws Exception {
- mSensorManager.unregisterListener(mEventListener, mSensorUnderTest);
-
- mFlushListener = null;
- mEventListener = null;
- mSensorUnderTest = null;
+ if(mTestSensorManager != null) {
+ mTestSensorManager.close();
+ mTestSensorManager = null;
+ }
releaseWakeLock();
}
@Override
public void runBare() throws Throwable {
- mSensorManager = (SensorManager) this.getContext().getSystemService(Context.SENSOR_SERVICE);
- assertNotNull("getSystemService#Sensor_Service", mSensorManager);
+ SensorManager sensorManager = (SensorManager) this.getContext().getSystemService(Context.SENSOR_SERVICE);
+ assertNotNull("getSystemService#Sensor_Service", sensorManager);
- List<Sensor> availableSensors = mSensorManager.getSensorList(this.getSensorType());
+ List<Sensor> availableSensors = sensorManager.getSensorList(this.getSensorType());
// it is OK if there are no sensors available
for(Sensor sensor : availableSensors) {
- mSensorUnderTest = sensor;
+ mTestSensorManager = new TestSensorManager(this, sensorManager, sensor);
super.runBare();
}
}
@@ -134,49 +115,34 @@
* Test cases continuous mode.
*/
public void testCanRegisterListener() {
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- SensorManager.SENSOR_DELAY_NORMAL);
- assertTrue("registerListener", result);
+ mTestSensorManager.registerListener(SensorManager.SENSOR_DELAY_NORMAL);
}
public void testNotTriggerSensor() {
TestTriggerListener listener = new TestTriggerListener();
- assertFalse(
- "requestTriggerSensor",
- mSensorManager.requestTriggerSensor(listener, mSensorUnderTest));
+ boolean result = mTestSensorManager.getUnderlyingSensorManager().requestTriggerSensor(
+ listener,
+ mTestSensorManager.getSensorUnderTest());
+ assertFalse("requestTriggerSensor", result);
}
public void testCanReceiveEvents() {
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- SensorManager.SENSOR_DELAY_NORMAL);
- assertTrue("registerListener", result);
- mEventListener.waitForEvents(5);
+ mTestSensorManager.collectEvents(SensorManager.SENSOR_DELAY_NORMAL, 5);
}
public void testMaxFrequency() {
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- this.getMaxFrequencySupportedInuS());
- assertTrue("registerListener", result);
+ // TODO: verify that events do arrive at the proper rate
+ mTestSensorManager.registerListener(this.getMaxFrequencySupportedInuS());
}
public void testEventsArriveInOrder() {
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- SensorManager.SENSOR_DELAY_FASTEST);
- assertTrue("registerListener", result);
- mEventListener.waitForEvents(100);
-
- SensorEventForTest[] events = mEventListener.getAllEvents();
+ // TODO: test for other sensor frequencies, rely on helper test classes for sensors
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.collectEvents(
+ SensorManager.SENSOR_DELAY_FASTEST,
+ 100);
for(int i = 1; i < events.length; ++i) {
- long previousTimestamp = events[i-1].getTimestamp();
- long timestamp = events[i].getTimestamp();
+ long previousTimestamp = events[i-1].timestamp;
+ long timestamp = events[i].timestamp;
assertTrue(
String.format("[timestamp:%d] %d >= %d", i, previousTimestamp, timestamp),
previousTimestamp < timestamp);
@@ -184,17 +150,7 @@
}
public void testStartStopRepeatedly() {
- for(int i = 0; i < this.getLowNumberOfIterationsToExecute(); ++i) {
- String iterationInfo = String.format("registerListener:%d", i);
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- SensorManager.SENSOR_DELAY_FASTEST);
- assertTrue(iterationInfo, result);
- mEventListener.waitForEvents(1, iterationInfo);
-
- mSensorManager.unregisterListener(mEventListener, mSensorUnderTest);
- }
+ validateRegisterUnregisterRepeteadly(mTestSensorManager);
}
public void testUpdateRate() {
@@ -221,33 +177,87 @@
rate = this.getMaxFrequencySupportedInuS() * generator.nextInt(10);
}
- String iterationInfo = String.format("registerListener:%d, rate:%d", i, rate);
- assertTrue(
- iterationInfo,
- mSensorManager.registerListener(mEventListener, mSensorUnderTest, rate));
-
- mEventListener.waitForEvents(generator.nextInt(5) + 1, iterationInfo);
- mEventListener.clearEvents();
-
- mSensorManager.unregisterListener(mEventListener, mSensorUnderTest);
+ // TODO: check that the rate has indeed changed
+ mTestSensorManager.collectEvents(
+ rate,
+ generator.nextInt(5) + 1,
+ String.format("iteration:%d, rate:%d", i, rate));
}
}
- public void testSeveralClients() throws InterruptedException {
- ArrayList<Thread> threads = new ArrayList<Thread>();
- for(int i = 0; i < this.getNumberOfThreadsToUse(); ++i) {
- threads.add(new Thread() {
- @Override
- public void run() {
- testStartStopRepeatedly();
- }
- });
- }
+ public void testOneClientSeveralThreads() throws InterruptedException {
+ Runnable operation = new Runnable() {
+ @Override
+ public void run() {
+ validateRegisterUnregisterRepeteadly(mTestSensorManager);
+ }
+ };
+ SensorCtsHelper.performOperationInThreads(this.getNumberOfThreadsToUse(), operation);
+ }
- while(!threads.isEmpty()) {
- Thread thread = threads.remove(0);
- thread.join();
- }
+ public void testSeveralClients() throws InterruptedException {
+ final Assert assertionObject = this;
+ Runnable operation = new Runnable() {
+ @Override
+ public void run() {
+ TestSensorManager testSensorManager = new TestSensorManager(
+ assertionObject,
+ mTestSensorManager.getUnderlyingSensorManager(),
+ mTestSensorManager.getSensorUnderTest());
+ validateRegisterUnregisterRepeteadly(testSensorManager);
+ }
+ };
+ SensorCtsHelper.performOperationInThreads(this.getNumberOfThreadsToUse(), operation);
+ }
+
+ public void testStoppingOtherClients() {
+ // TODO: use a higher test abstraction and move these to integration tests
+ final int EVENT_COUNT = 1;
+ final int SECOND_EVENT_COUNT = 5;
+ TestSensorManager sensorManager2 = new TestSensorManager(
+ this,
+ mTestSensorManager.getUnderlyingSensorManager(),
+ mTestSensorManager.getSensorUnderTest());
+
+ mTestSensorManager.registerListener(SensorManager.SENSOR_DELAY_NORMAL);
+
+ // is receiving events
+ mTestSensorManager.getEvents(EVENT_COUNT);
+
+ // operate in a different client
+ sensorManager2.collectEvents(SensorManager.SENSOR_DELAY_FASTEST, SECOND_EVENT_COUNT);
+
+ // verify first client is still operating
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.getEvents(EVENT_COUNT);
+ assertTrue(
+ String.format("Events| expected:%d, actual:%d", EVENT_COUNT, events.length),
+ events.length >= EVENT_COUNT);
+ }
+
+ public void testStoppingOtherClientsBatching() {
+ final int EVENT_COUNT = 1;
+ final int SECOND_EVENT_COUNT = 5;
+ TestSensorManager sensorManager2 = new TestSensorManager(
+ this,
+ mTestSensorManager.getUnderlyingSensorManager(),
+ mTestSensorManager.getSensorUnderTest());
+
+ mTestSensorManager.registerListener(SensorManager.SENSOR_DELAY_NORMAL);
+
+ // is receiving events
+ mTestSensorManager.getEvents(EVENT_COUNT);
+
+ // operate in a different client
+ sensorManager2.collectBatchEvents(
+ SensorManager.SENSOR_DELAY_FASTEST,
+ SensorCtsHelper.getSecondsAsMicroSeconds(1),
+ SECOND_EVENT_COUNT);
+
+ // verify first client is still operating
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.getEvents(EVENT_COUNT);
+ assertTrue(
+ String.format("Events| expected:%d, actual:%d", EVENT_COUNT, events.length),
+ events.length >= EVENT_COUNT);
}
/**
@@ -255,50 +265,52 @@
*/
public void testRegisterForBatchingZeroReport() {
releaseWakeLock();
-
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- SensorManager.SENSOR_DELAY_NORMAL,
- 0 /*maxBatchReportLatencyUs*/,
- 0 /*reservedFlags*/,
- mFlushListener);
- assertTrue("registerListener", result);
- mEventListener.waitForEvents(10);
+ // TODO: use test wrappers to verify for reportLatency ==0 !=0
+ mTestSensorManager.collectBatchEvents(SensorManager.SENSOR_DELAY_NORMAL, 0, 10);
}
public void testCanReceiveBatchEvents() {
releaseWakeLock();
-
- // TODO: refactor out common code across tests that register for events and do post-process
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
+ mTestSensorManager.collectBatchEvents(
SensorManager.SENSOR_DELAY_NORMAL,
- 5 * 1000000 /*maxBatchReportLatencyUs*/,
- 0 /*reservedFlags*/,
- mFlushListener);
- assertTrue("registerListener", result);
- mEventListener.waitForEvents(10);
+ SensorCtsHelper.getSecondsAsMicroSeconds(5),
+ 10 /*eventCount*/);
+ }
+
+ /**
+ * Regress:
+ * -b/10790905
+ */
+ public void ignore_testBatchingReportLatency() {
+ long startTime = SystemClock.elapsedRealtimeNanos();
+ // TODO: define the sensor frequency per sensor
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.collectBatchEvents(
+ SensorCtsHelper.getSecondsAsMicroSeconds(1),
+ SensorCtsHelper.getSecondsAsMicroSeconds(5),
+ 1 /*eventCount*/);
+ long elapsedTime = SystemClock.elapsedRealtimeNanos() - startTime;
+ long expectedTime =
+ TimeUnit.NANOSECONDS.convert(5, TimeUnit.SECONDS) +
+ TimeUnit.NANOSECONDS.convert(500, TimeUnit.MILLISECONDS);
+
+ // TODO: ensure the proper batching time considers the size of the FIFO (fifoMaxEventCount),
+ // and make sure that no other application is registered
+ assertTrue(
+ String.format("WaitTime| expected:%d, actual:%d", expectedTime, elapsedTime),
+ elapsedTime <= expectedTime);
}
public void testBatchEventsArriveInOrder() {
releaseWakeLock();
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
+ // TODO: identify if we can reuse code from the non-batching case, same for other batch tests
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.collectBatchEvents(
SensorManager.SENSOR_DELAY_NORMAL,
- 5 * 1000000 /*maxBatchReportLatencyUs*/,
- 0 /*reservedFlags*/,
- mFlushListener);
- assertTrue("registerListener", result);
- mEventListener.waitForEvents(100);
-
- SensorEventForTest[] events = mEventListener.getAllEvents();
+ SensorCtsHelper.getSecondsAsMicroSeconds(5),
+ 100);
for(int i = 1; i < events.length; ++i) {
- long previousTimestamp = events[i-1].getTimestamp();
- long timestamp = events[i].getTimestamp();
+ long previousTimestamp = events[i-1].timestamp;
+ long timestamp = events[i].timestamp;
assertTrue(
String.format("[timestamp:%d] %d >= %d", i, previousTimestamp, timestamp),
previousTimestamp < timestamp);
@@ -307,22 +319,7 @@
public void testStartStopBatchingRepeatedly() {
releaseWakeLock();
-
- for(int i = 0; i < this.getLowNumberOfIterationsToExecute(); ++i) {
- String iterationInfo = String.format("registerListener:%d", i);
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- SensorManager.SENSOR_DELAY_FASTEST,
- 5 * 1000000 /*maxBatchReportLatencyUs*/,
- 0 /*reservedFlags*/,
- mFlushListener);
-
- assertTrue(iterationInfo, result);
- mEventListener.waitForEvents(5, iterationInfo);
-
- mSensorManager.unregisterListener(mEventListener, mSensorUnderTest);
- }
+ validateRegisterUnregisterRepeteadlyBatching(mTestSensorManager);
}
public void testUpdateBatchRate() {
@@ -351,41 +348,91 @@
rate = this.getMaxFrequencySupportedInuS() * generator.nextInt(10);
}
- String iterationInfo = String.format("registerListener:%d, rate:%d", i, rate);
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
+ String iterationInfo = String.format("iteration:%d, rate:%d", i, rate);
+ mTestSensorManager.collectBatchEvents(
rate,
- generator.nextInt(5 * 1000000),
- 0 /*reservedFlags*/,
- mFlushListener);
- assertTrue(iterationInfo, result);
-
- mEventListener.waitForEvents(generator.nextInt(5) + 1, iterationInfo);
- mSensorManager.unregisterListener(mEventListener, mSensorUnderTest);
- mEventListener.clearEvents();
+ generator.nextInt(SensorCtsHelper.getSecondsAsMicroSeconds(5)),
+ generator.nextInt(5) + 1,
+ iterationInfo);
}
}
- public void testSeveralClientsBatching() {
- ArrayList<Thread> threads = new ArrayList<Thread>();
- for(int i = 0; i < this.getNumberOfThreadsToUse(); ++i) {
- threads.add(new Thread() {
- @Override
- public void run() {
- testStartStopBatchingRepeatedly();
- }
- });
- }
-
- while(!threads.isEmpty()) {
- Thread thread = threads.remove(0);
- try {
- thread.join();
- } catch(InterruptedException e) {
- // just continue
+ public void testOneClientSeveralThreadsBatching() throws InterruptedException {
+ Runnable operation = new Runnable() {
+ @Override
+ public void run() {
+ validateRegisterUnregisterRepeteadlyBatching(mTestSensorManager);
}
- }
+ };
+ SensorCtsHelper.performOperationInThreads(this.getNumberOfThreadsToUse(), operation);
+ }
+
+ public void testSeveralClientsBatching() throws InterruptedException {
+ final Assert assertionObject = this;
+ Runnable operation = new Runnable() {
+ @Override
+ public void run() {
+ TestSensorManager testSensorManager = new TestSensorManager(
+ assertionObject,
+ mTestSensorManager.getUnderlyingSensorManager(),
+ mTestSensorManager.getSensorUnderTest());
+ validateRegisterUnregisterRepeteadlyBatching(testSensorManager);
+ }
+ };
+ SensorCtsHelper.performOperationInThreads(this.getNumberOfThreadsToUse(), operation);
+ }
+
+ public void testBatchingStoppingOtherClients() {
+ final int EVENT_COUNT = 1;
+ final int SECOND_EVENT_COUNT = 5;
+ TestSensorManager sensorManager2 = new TestSensorManager(
+ this,
+ mTestSensorManager.getUnderlyingSensorManager(),
+ mTestSensorManager.getSensorUnderTest());
+
+ mTestSensorManager.registerBatchListener(
+ SensorManager.SENSOR_DELAY_NORMAL,
+ SensorCtsHelper.getSecondsAsMicroSeconds(5));
+
+ // is receiving events
+ mTestSensorManager.getEvents(EVENT_COUNT);
+
+ // operate in a different client
+ sensorManager2.collectEvents(SensorManager.SENSOR_DELAY_FASTEST, SECOND_EVENT_COUNT);
+
+ // verify first client is still operating
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.getEvents(EVENT_COUNT);
+ assertTrue(
+ String.format("Events| expected:%d, actual:%d", EVENT_COUNT, events.length),
+ events.length >= EVENT_COUNT);
+ }
+
+ public void testBatchingStoppingOtherClientsBatching() {
+ final int EVENT_COUNT = 1;
+ final int SECOND_EVENT_COUNT = 5;
+ TestSensorManager sensorManager2 = new TestSensorManager(
+ this,
+ mTestSensorManager.getUnderlyingSensorManager(),
+ mTestSensorManager.getSensorUnderTest());
+
+ mTestSensorManager.registerBatchListener(
+ SensorManager.SENSOR_DELAY_NORMAL,
+ SensorCtsHelper.getSecondsAsMicroSeconds(5));
+
+ // is receiving events
+ mTestSensorManager.getEvents(EVENT_COUNT);
+
+ // operate in a different client
+ sensorManager2.collectBatchEvents(
+ SensorManager.SENSOR_DELAY_FASTEST,
+ SensorCtsHelper.getSecondsAsMicroSeconds(1),
+ SECOND_EVENT_COUNT);
+
+ // verify first client is still operating
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.getEvents(EVENT_COUNT);
+ assertTrue(
+ String.format("Events| expected:%d, actual:%d", EVENT_COUNT, events.length),
+ events.length >= EVENT_COUNT);
}
/**
@@ -394,33 +441,21 @@
public void testEventJittering() {
final long EXPECTED_TIMESTAMP_NS = this.getMaxFrequencySupportedInuS() * 1000;
final long THRESHOLD_IN_NS = EXPECTED_TIMESTAMP_NS / 10; // 10%
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- this.getMaxFrequencySupportedInuS());
- assertTrue("registerListener", result);
- mEventListener.waitForEvents(100);
- SensorEventForTest[] events = mEventListener.getAllEvents();
- ArrayList<Long> timestampDeltas = new ArrayList<Long>();
- for(int i = 1; i < events.length; ++i) {
- long previousTimestamp = events[i-1].getTimestamp();
- long timestamp = events[i].getTimestamp();
- long delta = timestamp - previousTimestamp;
- long jitterValue = Math.abs(EXPECTED_TIMESTAMP_NS - delta);
- timestampDeltas.add(jitterValue);
- }
-
- Collections.sort(timestampDeltas);
- long percentile95InNs = timestampDeltas.get(95);
- long actualPercentValue = (percentile95InNs * 100) / EXPECTED_TIMESTAMP_NS;
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.collectEvents(
+ this.getMaxFrequencySupportedInuS(),
+ 100);
+ ArrayList<Double> jitterValues = new ArrayList<Double>();
+ double jitterMean = SensorCtsHelper.getJitterMean(events, jitterValues);
+ double percentile95InNs = SensorCtsHelper.get95PercentileValue(jitterValues);
if(percentile95InNs > THRESHOLD_IN_NS) {
- for(long jitter : timestampDeltas) {
- Log.e(LOG_TAG, "Jittering delta: " + jitter);
+ for(double jitter : jitterValues) {
+ Log.e(LOG_TAG, "Jitter: " + jitter);
}
+ double actualPercentValue = (percentile95InNs * 100) / jitterMean;
String message = String.format(
- "95%%Jitter| 10%%:%dns, observed:%dns(%d%%)",
+ "95%% Jitter| 10%%:%dns, actual:%fns(%.2f%%)",
THRESHOLD_IN_NS,
percentile95InNs,
actualPercentValue);
@@ -428,6 +463,29 @@
}
}
+ public void testFrequencyAccuracy() {
+ final long EXPECTED_TIMESTAMP_NS = this.getMaxFrequencySupportedInuS() * 1000;
+ final long THRESHOLD_IN_NS = EXPECTED_TIMESTAMP_NS / 10; // 10%
+
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.collectEvents(
+ this.getMaxFrequencySupportedInuS(),
+ 100);
+ ArrayList<Long> timestampDelayValues = new ArrayList<Long>();
+ Double frequencyMean = SensorCtsHelper.getAverageTimestampDelayWithValues(
+ events,
+ timestampDelayValues);
+ if(Math.abs(EXPECTED_TIMESTAMP_NS - frequencyMean) > THRESHOLD_IN_NS) {
+ for(long value : timestampDelayValues) {
+ Log.e(LOG_TAG, "TimestampDelay: " + value);
+ }
+ String message = String.format(
+ "Frequency| expected:%d, actual:%f",
+ EXPECTED_TIMESTAMP_NS,
+ frequencyMean);
+ fail(message);
+ }
+ }
+
/**
* Private helpers.
*/
@@ -444,252 +502,84 @@
}
}
- private void collectBugreport() {
- String commands[] = new String[] {
- "dumpstate",
- "dumpsys",
- "logcat -d -v threadtime",
- "exit"
- };
-
- SimpleDateFormat dateFormat = new SimpleDateFormat("M-d-y_H:m:s.S");
- String outputFile = String.format(
- "%s/%s_%s",
- this.getLogTag(),
- "/sdcard/Download",
- dateFormat.format(new Date()));
-
- DataOutputStream processOutput = null;
- try {
- Process process = Runtime.getRuntime().exec("/system/bin/sh -");
- processOutput = new DataOutputStream(process.getOutputStream());
-
- for(String command : commands) {
- processOutput.writeBytes(String.format("%s >> %s\n", command, outputFile));
- }
-
- processOutput.flush();
- process.waitFor();
-
- Log.d(this.getLogTag(), String.format("Bug-Report collected at: %s", outputFile));
- } catch (IOException e) {
- fail("Unable to collect Bug Report. " + e.toString());
- } catch (InterruptedException e) {
- fail("Unable to collect Bug Report. " + e.toString());
- } finally {
- if(processOutput != null) {
- try {
- processOutput.close();
- } catch(IOException e) {}
- }
- }
- }
-
/**
* Test method helper implementations
*/
- protected void validateSensorEvent(
- float expectedX,
- float expectedY,
- float expectedZ,
- float threshold) {
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- SensorManager.SENSOR_DELAY_FASTEST);
+ protected void validateNormForSensorEvent(float reference, float threshold, int axisCount) {
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.collectEvents(
+ SensorManager.SENSOR_DELAY_FASTEST,
+ 1);
+ TestSensorManager.SensorEventForTest event = events[0];
- assertTrue("registerListener", result);
- mEventListener.waitForEvents(1);
- SensorEventForTest event = mEventListener.getLastEvent();
+ StringBuilder valuesBuilder = new StringBuilder();
+ double norm = 0.0;
+ for(int i = 0; i < axisCount; ++i) {
+ float value = event.values[i];
+ norm += Math.pow(value, 2);
- float xValue = event.getX();
- assertTrue(
- String.format("x-axis| expected:%f, actual:%f, threshold:%f", expectedX, xValue, threshold),
- Math.abs(expectedX - xValue) <= threshold);
+ valuesBuilder.append(value);
+ valuesBuilder.append(", ");
+ }
+ norm = Math.sqrt(norm);
- float yValue = event.getY();
- assertTrue(
- String.format("y-axis| expected:%f, actual:%f, threshold:%f", expectedY, yValue, threshold),
- Math.abs(expectedY - yValue) <= threshold);
-
- float zValue = event.getZ();
- assertTrue(
- String.format("z-axis| expected:%f, actual:%f, threshold:%f", expectedZ, zValue, threshold),
- Math.abs(expectedZ - zValue) <= threshold);
+ String message = String.format(
+ "Norm| expected:%f, threshold:%f, actual:%f (%s)",
+ reference,
+ threshold,
+ norm,
+ valuesBuilder.toString());
+ assertTrue(message, Math.abs(reference - norm) <= threshold);
}
- protected void validateVarianceWhileStatic(
- float referenceX,
- float referenceY,
- float referenceZ,
- float threshold) {
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- this.getMaxFrequencySupportedInuS());
- assertTrue("registerListener", result);
- mEventListener.waitForEvents(100);
-
- SensorEventForTest[] events = mEventListener.getAllEvents();
- ArrayList<Float> deltaValuesX = new ArrayList<Float>();
- ArrayList<Float> deltaValuesY = new ArrayList<Float>();
- ArrayList<Float> deltaValuesZ = new ArrayList<Float>();
- for(int i = 0; i < events.length; ++i) {
- SensorEventForTest event = events[i];
- deltaValuesX.add(Math.abs(event.getX() - referenceX));
- deltaValuesY.add(Math.abs(event.getY() - referenceY));
- deltaValuesZ.add(Math.abs(event.getZ() - referenceZ));
+ protected void validateRegisterUnregisterRepeteadly(TestSensorManager testSensorManager) {
+ for(int i = 0; i < this.getLowNumberOfIterationsToExecute(); ++i) {
+ String iterationInfo = String.format("iteration:%d", i);
+ testSensorManager.collectEvents(SensorManager.SENSOR_DELAY_FASTEST, 1, iterationInfo);
}
+ }
- Collections.sort(deltaValuesX);
- float percentile95X = deltaValuesX.get(95);
- if(percentile95X > threshold) {
- for(float valueX : deltaValuesX) {
- Log.e(LOG_TAG, "Variance|X delta: " + valueX);
- }
- String message = String.format(
- "95%%Variance|X expected:%f, observed:%f",
- threshold,
- percentile95X);
- fail(message);
+ protected void validateRegisterUnregisterRepeteadlyBatching(
+ TestSensorManager testSensorManager) {
+ // TODO: refactor if allowed with test wrapper abstractions
+ for(int i = 0; i < this.getLowNumberOfIterationsToExecute(); ++i) {
+ testSensorManager.collectBatchEvents(
+ SensorManager.SENSOR_DELAY_FASTEST,
+ SensorCtsHelper.getSecondsAsMicroSeconds(5),
+ 5 /*eventCont*/,
+ String.format("iteration:%d", i));
}
+ }
- Collections.sort(deltaValuesY);
- float percentile95Y = deltaValuesY.get(95);
- if(percentile95Y > threshold) {
- for(float valueY : deltaValuesY) {
- Log.e(LOG_TAG, "Variance|Y delta: " + valueY);
- }
- String message = String.format(
- "95%%Variance|Y expected:%f, observed:%f",
- threshold,
- percentile95Y);
- fail(message);
- }
+ protected void validateStandardDeviationWhileStatic(
+ float expectedStandardDeviation,
+ int axisCount) {
+ // TODO: refactor the report parameter with test wrappers if available
+ TestSensorManager.SensorEventForTest[] events = mTestSensorManager.collectEvents(
+ this.getMaxFrequencySupportedInuS(),
+ 100);
- Collections.sort(deltaValuesZ);
- float percentile95Z = deltaValuesZ.get(95);
- if(percentile95Z > threshold) {
- for(float valueZ : deltaValuesZ) {
- Log.e(LOG_TAG, "Variance|Z delta: " + valueZ);
+ for(int i = 0; i < axisCount; ++i) {
+ ArrayList<Float> values = new ArrayList<Float>();
+ for(TestSensorManager.SensorEventForTest event : events) {
+ values.add(event.values[i]);
}
+
+ double standardDeviation = SensorCtsHelper.getStandardDeviation(values);
String message = String.format(
- "95%%Variance|Z expected:%f, observed:%f",
- threshold,
- percentile95Z);
- fail(message);
+ "StandardDeviation| axis:%d, expected:%f, actual:%f",
+ i,
+ expectedStandardDeviation,
+ standardDeviation);
+ assertTrue(message, standardDeviation <= expectedStandardDeviation);
}
}
/**
* Private class definitions to support test of event handlers.
*/
- protected class SensorEventForTest {
- private Sensor mSensor;
- private long mTimestamp;
- private int mAccuracy;
-
- private float mValueX;
- private float mValueY;
- private float mValueZ;
-
- public SensorEventForTest(SensorEvent event) {
- mSensor = event.sensor;
- mTimestamp = event.timestamp;
- mAccuracy = event.accuracy;
- mValueX = event.values[0];
- mValueY = event.values[1];
- mValueZ = event.values[2];
- }
-
- public Sensor getSensor() {
- return mSensor;
- }
-
- public int getAccuracy() {
- return mAccuracy;
- }
-
- public float getX() {
- return mValueX;
- }
-
- public float getY() {
- return mValueY;
- }
-
- public float getZ() {
- return mValueZ;
- }
-
- public long getTimestamp() {
- return mTimestamp;
- }
- }
-
- protected class TestSensorListener implements SensorEventListener {
- private final ConcurrentLinkedDeque<SensorEventForTest> mSensorEventsList =
- new ConcurrentLinkedDeque<SensorEventForTest>();
- private volatile CountDownLatch mEventLatch;
-
- @Override
- public void onSensorChanged(SensorEvent event) {
- // copy the event because there is no better way to do this in the platform
- mSensorEventsList.addLast(new SensorEventForTest(event));
-
- CountDownLatch latch = mEventLatch;
- if(latch != null) {
- latch.countDown();
- }
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
-
- public void waitForEvents(int eventCount) {
- waitForEvents(eventCount, null);
- }
-
- public void waitForEvents(int eventCount, String timeoutInfo) {
- mEventLatch = new CountDownLatch(eventCount);
- try {
- boolean awaitCompleted = mEventLatch.await(getWaitTimeoutInSeconds(), TimeUnit.SECONDS);
- if(!awaitCompleted) {
- collectBugreport();
- }
-
- String assertMessage = String.format(
- "WaitForEvents:%d, available:%d, %s",
- eventCount,
- mSensorEventsList.size(),
- timeoutInfo);
- assertTrue(assertMessage, awaitCompleted);
- } catch(InterruptedException e) { }
- }
-
- public SensorEventForTest getLastEvent() {
- return mSensorEventsList.getLast();
- }
-
- public SensorEventForTest[] getAllEvents() {
- return mSensorEventsList.toArray(new SensorEventForTest[0]);
- }
-
- public void clearEvents() {
- mSensorEventsList.clear();
- }
- }
-
private class TestTriggerListener extends TriggerEventListener {
@Override
public void onTrigger(TriggerEvent event) {
}
}
-
- private class TestFlushListener implements FlushCompleteListener {
- @Override
- public void onFlushCompleted(Sensor sensor) {
- }
- }
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorGyroscopeTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorGyroscopeTest.java
index d3d72a3..b7c082e 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorGyroscopeTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorGyroscopeTest.java
@@ -19,6 +19,8 @@
import android.hardware.Sensor;
public class SensorGyroscopeTest extends SensorCommonTests {
+ private final int AXIS_COUNT = 3;
+
@Override
protected int getMaxFrequencySupportedInuS() {
return 10000; // 100Hz
@@ -32,20 +34,12 @@
@Override
public void testEventValidity() {
final float THRESHOLD = 0.1f; // dps
- validateSensorEvent(
- 0 /*x-axis*/,
- 0 /*y-axis*/,
- 0 /*z-axis*/,
- THRESHOLD);
+ validateNormForSensorEvent(0 /*reference*/, THRESHOLD, AXIS_COUNT);
}
@Override
- public void testVarianceWhileStatic() {
- final float THRESHOLD = 0.1f; // dps
- validateVarianceWhileStatic(
- 0 /*x-axis*/,
- 0 /*y-axis*/,
- 0 /*z-axis*/,
- THRESHOLD);
+ public void testStandardDeviationWhileStatic() {
+ final float STANDARD_DEVIATION = 0.5f; // dps
+ validateStandardDeviationWhileStatic(STANDARD_DEVIATION, AXIS_COUNT);
}
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
new file mode 100644
index 0000000..f764c6c
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2008 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;
+
+import android.content.Context;
+
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.TestSensorManager;
+
+import android.os.PowerManager;
+
+import android.test.AndroidTestCase;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class SensorIntegrationTests extends AndroidTestCase {
+ protected final String LOG_TAG = "SensorIntegrationTests";
+ private PowerManager.WakeLock mWakeLock;
+ private SensorManager mSensorManager;
+
+ /**
+ * Test execution methods
+ */
+ @Override
+ protected void setUp() throws Exception {
+ PowerManager powerManager = (PowerManager) this.getContext().getSystemService(
+ Context.POWER_SERVICE);
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
+ mWakeLock.acquire();
+
+ mSensorManager = (SensorManager) this.getContext().getSystemService(
+ Context.SENSOR_SERVICE);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mSensorManager = null;
+
+ mWakeLock.release();
+ mWakeLock = null;
+ }
+
+ /**
+ * Test cases.
+ */
+ public void testBatchAndFlush() throws InterruptedException {
+ List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+ for(Sensor sensor : sensorList) {
+ // skip all non-continuous mode sensors.
+ switch(sensor.getType()) {
+ case Sensor.TYPE_SIGNIFICANT_MOTION:
+ case Sensor.TYPE_STEP_COUNTER:
+ case Sensor.TYPE_STEP_DETECTOR:
+ case Sensor.TYPE_LIGHT:
+ case Sensor.TYPE_PROXIMITY:
+ case Sensor.TYPE_AMBIENT_TEMPERATURE:
+ continue;
+ }
+
+ TestSensorManager sensorManager = new TestSensorManager(this, mSensorManager, sensor);
+ sensorManager.registerBatchListener(SensorManager.SENSOR_DELAY_NORMAL, 0);
+
+ // wait for 25 events and call flush
+ sensorManager.getEvents(25);
+ sensorManager.waitForFlush();
+
+ sensorManager.unregisterListener();
+ }
+ }
+
+ /**
+ * Regress:
+ * - b/10641388
+ */
+ public void testAccelerometerDoesNotStopGyroscope() {
+ validateSensorCanBeStoppedIndependently(Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_GYROSCOPE);
+ }
+
+ public void testAccelerometerDoesNotStopMagnetometer() {
+ validateSensorCanBeStoppedIndependently(
+ Sensor.TYPE_ACCELEROMETER,
+ Sensor.TYPE_MAGNETIC_FIELD);
+ }
+
+ public void testGyroscopeDoesNotStopAccelerometer() {
+ validateSensorCanBeStoppedIndependently(Sensor.TYPE_GYROSCOPE, Sensor.TYPE_ACCELEROMETER);
+ }
+
+ public void testGyroscopeDoesNotStopMagnetometer() {
+ validateSensorCanBeStoppedIndependently(Sensor.TYPE_GYROSCOPE, Sensor.TYPE_MAGNETIC_FIELD);
+ }
+
+ public void testMagnetometerDoesNotStopAccelerometer() {
+ validateSensorCanBeStoppedIndependently(
+ Sensor.TYPE_MAGNETIC_FIELD,
+ Sensor.TYPE_ACCELEROMETER);
+ }
+
+ public void testMagnetometerDoesNotStopGyroscope() {
+ validateSensorCanBeStoppedIndependently(Sensor.TYPE_MAGNETIC_FIELD, Sensor.TYPE_GYROSCOPE);
+ }
+
+ /**
+ * Private methods for sensor validation.
+ */
+ public void validateSensorCanBeStoppedIndependently(int sensorTypeTester, int sensorTypeTestee) {
+ // if any of the required sensors is not supported, skip the test
+ Sensor sensorTester = mSensorManager.getDefaultSensor(sensorTypeTester);
+ if(sensorTester == null) {
+ return;
+ }
+ Sensor sensorTestee = mSensorManager.getDefaultSensor(sensorTypeTestee);
+ if(sensorTestee == null) {
+ return;
+ }
+
+ TestSensorManager tester = new TestSensorManager(this, mSensorManager, sensorTester);
+ tester.registerListener(SensorManager.SENSOR_DELAY_NORMAL);
+
+ TestSensorManager testee = new TestSensorManager(this, mSensorManager, sensorTestee);
+ testee.registerBatchListener(
+ (int) TimeUnit.MICROSECONDS.convert(200, TimeUnit.MILLISECONDS),
+ SensorCtsHelper.getSecondsAsMicroSeconds(10));
+
+ testee.getEvents(10);
+ tester.getEvents(5);
+
+ tester.unregisterListener();
+ testee.getEvents(5);
+
+ // clean up
+ tester.close();
+ testee.close();
+ }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorMagneticFieldTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorMagneticFieldTest.java
index 10cabb8..e4041d6 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorMagneticFieldTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorMagneticFieldTest.java
@@ -19,12 +19,9 @@
import android.hardware.Sensor;
import android.hardware.SensorManager;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
public class SensorMagneticFieldTest extends SensorCommonTests {
+ private final int AXIS_COUNT = 3;
+
@Override
protected int getMaxFrequencySupportedInuS() {
return 100000; // 10Hz
@@ -37,73 +34,15 @@
@Override
public void testEventValidity() {
- validateSensorEvent(
- 0 /*x-axis*/,
- 0 /*y-axis*/,
- 0 /*z-axis*/,
- SensorManager.MAGNETIC_FIELD_EARTH_MAX);
+ validateNormForSensorEvent(
+ SensorManager.MAGNETIC_FIELD_EARTH_MAX,
+ SensorManager.MAGNETIC_FIELD_EARTH_MIN,
+ AXIS_COUNT);
}
@Override
- public void testVarianceWhileStatic() {
- float THRESHOLD_IN_UT = SensorManager.MAGNETIC_FIELD_EARTH_MAX / 10;
- boolean result = mSensorManager.registerListener(
- mEventListener,
- mSensorUnderTest,
- this.getMaxFrequencySupportedInuS());
- assertTrue("registerListener", result);
- mEventListener.waitForEvents(100);
-
- SensorEventForTest[] events = mEventListener.getAllEvents();
- ArrayList<Float> deltaValuesX = new ArrayList<Float>();
- ArrayList<Float> deltaValuesY = new ArrayList<Float>();
- ArrayList<Float> deltaValuesZ = new ArrayList<Float>();
- for(int i = 1; i < events.length; ++i) {
- SensorEventForTest previousEvent = events[i-1];
- SensorEventForTest event = events[i];
-
- deltaValuesX.add(Math.abs(event.getX() - previousEvent.getX()));
- deltaValuesY.add(Math.abs(event.getY() - previousEvent.getY()));
- deltaValuesZ.add(Math.abs(event.getZ() - previousEvent.getZ()));
- }
-
- Collections.sort(deltaValuesX);
- float percentile95X = deltaValuesX.get(95);
- if(percentile95X > THRESHOLD_IN_UT) {
- for(float valueX : deltaValuesX) {
- Log.e(LOG_TAG, "Variance|X delta: " + valueX);
- }
- String message = String.format(
- "95%%Variance|X expected:%f, observed:%f",
- THRESHOLD_IN_UT,
- percentile95X);
- fail(message);
- }
-
- Collections.sort(deltaValuesY);
- float percentile95Y = deltaValuesY.get(95);
- if(percentile95Y > THRESHOLD_IN_UT) {
- for(float valueY : deltaValuesY) {
- Log.e(LOG_TAG, "Variance|Y delta: " + valueY);
- }
- String message = String.format(
- "95%%Variance|Y expected:%f, observed:%f",
- THRESHOLD_IN_UT,
- percentile95Y);
- fail(message);
- }
-
- Collections.sort(deltaValuesZ);
- float percentile95Z = deltaValuesZ.get(95);
- if(percentile95Z > THRESHOLD_IN_UT) {
- for(float valueZ : deltaValuesZ) {
- Log.e(LOG_TAG, "Variance|Z delta: " + valueZ);
- }
- String message = String.format(
- "95%%Variance|Z expected:%f, observed:%f",
- THRESHOLD_IN_UT,
- percentile95Z);
- fail(message);
- }
+ public void testStandardDeviationWhileStatic() {
+ final float STANDARD_DEVIATION = 2f; // uT
+ validateStandardDeviationWhileStatic(STANDARD_DEVIATION, AXIS_COUNT);
}
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
index 4af2a45..a0f1a96 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
@@ -23,10 +23,10 @@
import android.content.Context;
import android.content.pm.PackageManager;
-import android.hardware.FlushCompleteListener;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
+import android.hardware.SensorEventListener2;
import android.hardware.SensorManager;
import android.hardware.TriggerEvent;
import android.hardware.TriggerEventListener;
@@ -149,7 +149,8 @@
}
final CountDownLatch eventReceived = new CountDownLatch(25);
- SensorEventListener listener = new SensorEventListener() {
+ final CountDownLatch flushReceived = new CountDownLatch(1);
+ SensorEventListener2 listener = new SensorEventListener2() {
@Override
public void onSensorChanged(SensorEvent event) {
eventReceived.countDown();
@@ -158,22 +159,18 @@
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
- };
- final CountDownLatch flushReceived = new CountDownLatch(1);
- FlushCompleteListener flushCompleteListener = new FlushCompleteListener() {
@Override
public void onFlushCompleted(Sensor sensor) {
flushReceived.countDown();
}
};
boolean result = mSensorManager.registerListener(listener, sensor,
- SensorManager.SENSOR_DELAY_NORMAL, 10000000, 0,
- flushCompleteListener);
+ SensorManager.SENSOR_DELAY_NORMAL, 10000000);
assertTrue(result);
// Wait for 25 events and call flush.
eventReceived.await();
- result = mSensorManager.flush(sensor);
+ result = mSensorManager.flush(listener);
assertTrue(result);
flushReceived.await();
mSensorManager.unregisterListener(listener);
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
new file mode 100644
index 0000000..5abdd06
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2008 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.os.Environment;
+import android.util.Log;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import java.text.SimpleDateFormat;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Set of static helper methods for CTS tests.
+ */
+public class SensorCtsHelper {
+ /**
+ * This is an static class.
+ */
+ private SensorCtsHelper() {}
+
+ public static <TValue extends Comparable> TValue get95PercentileValue(
+ Collection<TValue> collection) {
+ validateCollection(collection);
+
+ ArrayList<TValue> arrayCopy = new ArrayList<TValue>(collection);
+ Collections.sort(arrayCopy);
+
+ // zero-based array index
+ int arrayIndex = (int)(arrayCopy.size() * 0.95) - 1;
+ if(arrayIndex < 0) {
+ arrayIndex = 0;
+ }
+
+ return arrayCopy.get(arrayIndex);
+ }
+
+ // TODO: are there any internal libraries for this?
+ public static <TValue extends Number> double getMean(Collection<TValue> collection) {
+ validateCollection(collection);
+
+ double sum = 0.0;
+ for(TValue value : collection) {
+ sum += value.doubleValue();
+ }
+ return sum / collection.size();
+ }
+
+ public static <TValue extends Number> double getVariance(Collection<TValue> collection) {
+ validateCollection(collection);
+
+ double mean = getMean(collection);
+ ArrayList<Double> squaredDifferences = new ArrayList<Double>();
+ for(TValue value : collection) {
+ double difference = mean - value.doubleValue();
+ squaredDifferences.add(Math.pow(difference, 2));
+ }
+
+ double variance = getMean(squaredDifferences);
+ return variance;
+ }
+
+ public static <TValue extends Number> double getStandardDeviation(Collection<TValue> collection) {
+ validateCollection(collection);
+
+ double variance = getVariance(collection);
+ return Math.sqrt(variance);
+ }
+
+ /**
+ * Gets the jitter values associated with a set of sensor events.
+ *
+ * @param events The events to use to obtain the jittering information.
+ * @param jitterValues The Collection that will contain the computed jitter values.
+ * @return The mean of the jitter Values.
+ */
+ public static double getJitterMean(
+ TestSensorManager.SensorEventForTest events[],
+ Collection<Double> jitterValues) {
+ ArrayList<Long> timestampDelayValues = new ArrayList<Long>();
+ double averageTimestampDelay = SensorCtsHelper.getAverageTimestampDelayWithValues(events,
+ timestampDelayValues);
+ for(long frequency : timestampDelayValues) {
+ jitterValues.add(Math.abs(averageTimestampDelay - frequency));
+ }
+
+ double jitterMean = SensorCtsHelper.getMean(timestampDelayValues);
+ return jitterMean;
+ }
+
+ /**
+ * Gets the frequency values associated with a set of sensor events.
+ *
+ * @param events The events to use to obtain the frequency information.
+ * @param timestampDelayValues The Collection that will contain the computed frequency values.
+ * @return The mean of the frequency values.
+ */
+ public static double getAverageTimestampDelayWithValues(
+ TestSensorManager.SensorEventForTest events[],
+ Collection<Long> timestampDelayValues) {
+ for(int i = 1; i < events.length; ++i) {
+ long previousTimestamp = events[i-1].timestamp;
+ long timestamp = events[i].timestamp;
+ timestampDelayValues.add(timestamp - previousTimestamp);
+ }
+
+ double timestampDelayMean = SensorCtsHelper.getMean(timestampDelayValues);
+ return timestampDelayMean;
+ }
+
+ public static int getSecondsAsMicroSeconds(int seconds) {
+ return (int) TimeUnit.MICROSECONDS.convert(seconds, TimeUnit.SECONDS);
+ }
+
+ /**
+ * NOTE: The bug report is usually written to /sdcard/Downloads
+ */
+ public static void collectBugreport(String collectorId)
+ throws IOException, InterruptedException {
+ String commands[] = new String[] {
+ "dumpstate",
+ "dumpsys",
+ "logcat -d -v threadtime",
+ "exit"
+ };
+
+ SimpleDateFormat dateFormat = new SimpleDateFormat("M-d-y_H:m:s.S");
+ String outputFile = String.format(
+ "%s/%s_%s",
+ collectorId,
+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
+ dateFormat.format(new Date()));
+
+ DataOutputStream processOutput = null;
+ try {
+ Process process = Runtime.getRuntime().exec("/system/bin/sh -");
+ processOutput = new DataOutputStream(process.getOutputStream());
+
+ for(String command : commands) {
+ processOutput.writeBytes(String.format("%s >> %s\n", command, outputFile));
+ }
+
+ processOutput.flush();
+ process.waitFor();
+
+ Log.d(collectorId, String.format("Bug-Report collected at: %s", outputFile));
+ } finally {
+ if(processOutput != null) {
+ try {
+ processOutput.close();
+ } catch(IOException e) {}
+ }
+ }
+ }
+
+ public static void performOperationInThreads(int numberOfThreadsToUse, Runnable operation)
+ throws InterruptedException {
+ ArrayList<Thread> threads = new ArrayList<Thread>();
+ for(int i = 0; i < numberOfThreadsToUse; ++i) {
+ threads.add(new Thread(operation));
+ }
+
+ while(!threads.isEmpty()) {
+ Thread thread = threads.remove(0);
+ thread.join();
+ }
+ }
+
+ /**
+ * Private helpers
+ */
+ private static void validateCollection(Collection collection) {
+ if(collection == null || collection.size() == 0) {
+ throw new IllegalStateException("Collection cannot be null or empty");
+ }
+ }
+}
+
+
+
+
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
new file mode 100644
index 0000000..9a95e9b
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2008 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.hardware.SensorManager;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
+
+import java.io.Closeable;
+
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.Assert;
+
+/**
+ * Test class to wrap SensorManager with verifications and test checks.
+ * This class allows to perform operations in the Sensor Manager and performs all the expected test
+ * verification on behalf of th owner.
+ * An object can be used to quickly writing tests that focus on the scenario that needs to be verified,
+ * and not in the implicit verifications that need to take place at any step.
+ */
+public class TestSensorManager implements Closeable {
+ private final int WAIT_TIMEOUT_IN_SECONDS = 30;
+
+ private Assert mAssert;
+ private SensorManager mSensorManager;
+ private Sensor mSensorUnderTest;
+ private TestSensorListener mEventListener;
+
+ public TestSensorManager(Assert assertionObject, SensorManager sensorManager, Sensor sensor) {
+ mAssert = assertionObject;
+ mSensorManager = sensorManager;
+ mSensorUnderTest = sensor;
+
+ mEventListener = new TestSensorListener();
+ }
+
+ public void close() {
+ this.unregisterListener();
+ mEventListener = null;
+ mSensorUnderTest = null;
+ }
+
+ public SensorManager getUnderlyingSensorManager() {
+ return mSensorManager;
+ }
+
+ public Sensor getSensorUnderTest() {
+ return mSensorUnderTest;
+ }
+
+ public void registerListener(int delay, String debugInfo) {
+ mAssert.assertTrue(
+ "registerListener| " + debugInfo,
+ mSensorManager.registerListener(mEventListener, mSensorUnderTest, delay));
+ }
+
+ public void registerListener(int delay) {
+ registerListener(delay, "");
+ }
+
+ public void registerBatchListener(int delay, int reportLatency, String debugInfo) {
+ boolean result = mSensorManager.registerListener(
+ mEventListener,
+ mSensorUnderTest,
+ delay,
+ reportLatency);
+ mAssert.assertTrue("registerBatchListener| " + debugInfo, result);
+ }
+
+ public void registerBatchListener(int delay, int reportLatency) {
+ registerBatchListener(delay, reportLatency, "");
+ }
+
+ public void unregisterListener() {
+ mSensorManager.unregisterListener(mEventListener, mSensorUnderTest);
+ }
+
+ public SensorEventForTest[] getEvents(int count, String debugInfo) {
+ mEventListener.waitForEvents(count, debugInfo);
+ SensorEventForTest[] events = mEventListener.getAllEvents();
+ mEventListener.clearEvents();
+
+ return events;
+ }
+
+ public SensorEventForTest[] getEvents(int count) {
+ return this.getEvents(count, "");
+ }
+
+ public SensorEventForTest[] collectEvents(
+ int collectionDelay,
+ int eventCount,
+ String debugInfo) {
+ this.registerListener(collectionDelay, debugInfo);
+ SensorEventForTest[] events = this.getEvents(eventCount, debugInfo);
+ this.unregisterListener();
+
+ return events;
+ }
+
+ public SensorEventForTest[] collectEvents(int collectionDelay, int eventCount) {
+ return this.collectEvents(collectionDelay, eventCount, "");
+ }
+
+ public SensorEventForTest[] collectBatchEvents(
+ int collectionDelay,
+ int batchReportLatency,
+ int eventCount,
+ String debugInfo) {
+ this.registerBatchListener(collectionDelay, batchReportLatency, debugInfo);
+ SensorEventForTest[] events = this.getEvents(eventCount, debugInfo);
+ this.unregisterListener();
+
+ return events;
+ }
+
+ public SensorEventForTest[] collectBatchEvents(
+ int collectionDelay,
+ int batchReportLatency,
+ int eventCount) {
+ return this.collectBatchEvents(collectionDelay, batchReportLatency, eventCount, "");
+ }
+
+ public void waitForFlush() throws InterruptedException {
+ mAssert.assertTrue(
+ String.format("flush| sensorType:%d", mSensorUnderTest.getType()),
+ mSensorManager.flush(mEventListener));
+ mEventListener.waitForFlushComplete();
+ }
+
+ /**
+ * Definition of support test classes.
+ */
+ public class SensorEventForTest {
+ public final Sensor sensor;
+ public final long timestamp;
+ public final int accuracy;
+ public final float values[];
+
+ public SensorEventForTest(SensorEvent event) {
+ values = new float[event.values.length];
+ System.arraycopy(event.values, 0, values, 0, event.values.length);
+
+ sensor = event.sensor;
+ timestamp = event.timestamp;
+ accuracy = event.accuracy;
+ }
+ }
+
+ private class TestSensorListener implements SensorEventListener2 {
+ private final ConcurrentLinkedDeque<SensorEventForTest> mSensorEventsList =
+ new ConcurrentLinkedDeque<SensorEventForTest>();
+ private volatile CountDownLatch mEventLatch;
+ private volatile CountDownLatch mFlushLatch;
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ CountDownLatch latch = mEventLatch;
+ if(latch != null) {
+ // copy the event because there is no better way to do this in the platform
+ mSensorEventsList.addLast(new SensorEventForTest(event));
+ latch.countDown();
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ }
+
+ @Override
+ public void onFlushCompleted(Sensor sensor) {
+ CountDownLatch latch = mFlushLatch;
+ mFlushLatch = new CountDownLatch(1);
+
+ if(latch != null) {
+ latch.countDown();
+ }
+ }
+
+ public void waitForFlushComplete() throws InterruptedException {
+ CountDownLatch latch = mFlushLatch;
+ mAssert.assertTrue(
+ "WaitForFlush",
+ latch.await(WAIT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS));
+ }
+
+ public void waitForEvents(int eventCount) {
+ waitForEvents(eventCount, "");
+ }
+
+ public void waitForEvents(int eventCount, String timeoutInfo) {
+ mEventLatch = new CountDownLatch(eventCount);
+ try {
+ boolean awaitCompleted = mEventLatch.await(WAIT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
+ // TODO: can we collect bug reports on error based only if needed? env var?
+
+ String assertMessage = String.format(
+ "WaitForEvents| count:%d, available:%d, %s",
+ eventCount,
+ mSensorEventsList.size(),
+ timeoutInfo);
+ mAssert.assertTrue(assertMessage, awaitCompleted);
+ } catch(InterruptedException e) {
+ } finally {
+ mEventLatch = null;
+ }
+ }
+
+ public SensorEventForTest getLastEvent() {
+ return mSensorEventsList.getLast();
+ }
+
+ public SensorEventForTest[] getAllEvents() {
+ return mSensorEventsList.toArray(new SensorEventForTest[0]);
+ }
+
+ public void clearEvents() {
+ mSensorEventsList.clear();
+ }
+ }
+
+ public class TestTriggerListener extends TriggerEventListener {
+ @Override
+ public void onTrigger(TriggerEvent event) {
+ }
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
new file mode 100644
index 0000000..4f8fb62
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2013 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.media.cts;
+
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.CodecProfileLevel;
+import android.media.MediaCodecList;
+import android.media.MediaPlayer;
+
+import android.util.Log;
+
+/**
+ * Basic sanity test of data returned by MediaCodeCapabilities.
+ */
+public class MediaCodecCapabilitiesTest extends MediaPlayerTestBase {
+
+ private static final String TAG = "MediaCodecCapabilitiesTest";
+ private static final String AVC_MIME = "video/avc";
+ private static final int PLAY_TIME_MS = 30000;
+
+ public void testAvcBaseline1() throws Exception {
+ if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline,
+ CodecProfileLevel.AVCLevel1)) {
+ throw new RuntimeException("AVCLevel1 support is required by CDD");
+ }
+ // We don't have a test stream, but at least we're testing
+ // that supports() returns true for something.
+ }
+
+ public void testAvcBaseline12() throws Exception {
+ if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline,
+ CodecProfileLevel.AVCLevel12)) {
+ Log.i(TAG, "AvcBaseline12 not supported");
+ return; // TODO: Can we make this mandatory?
+ }
+ playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ + "&itag=160&source=youtube&user=android-device-test"
+ + "&sparams=ip,ipbits,expire,id,itag,source,user"
+ + "&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
+ + "&signature=341692D20FACCAE25B90EA2C131EA6ADCD8E2384."
+ + "9EB08C174BE401AAD20FB85EE4DBA51A2882BB60"
+ + "&key=test_key1", 256, 144, PLAY_TIME_MS);
+ }
+
+ public void testAvcBaseline30() throws Exception {
+ if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline,
+ CodecProfileLevel.AVCLevel3)) {
+ Log.i(TAG, "AvcBaseline30 not supported");
+ return;
+ }
+ playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ + "&itag=18&source=youtube&user=android-device-test"
+ + "&sparams=ip,ipbits,expire,id,itag,source,user"
+ + "&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
+ + "&signature=8701A45F6422229D46ABB25A22E2C00C94024606."
+ + "08BCDF16C3F744C49D4C8A8AD1C38B3DC1810918"
+ + "&key=test_key1", 640, 360, PLAY_TIME_MS);
+ }
+
+ public void testAvcHigh31() throws Exception {
+ if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileHigh,
+ CodecProfileLevel.AVCLevel31)) {
+ Log.i(TAG, "AvcHigh31 not supported");
+ return;
+ }
+ playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ + "&itag=22&source=youtube&user=android-device-test"
+ + "&sparams=ip,ipbits,expire,id,itag,source,user"
+ + "&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
+ + "&signature=42969CA8F7FFAE432B7135BC811F96F7C4172C3F."
+ + "1A8A92EA714C1B7C98A05DDF2DE90854CDD7638B"
+ + "&key=test_key1", 1280, 720, PLAY_TIME_MS);
+
+ }
+
+ public void testAvcHigh40() throws Exception {
+ if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileHigh,
+ CodecProfileLevel.AVCLevel4)) {
+ Log.i(TAG, "AvcHigh40 not supported");
+ return;
+ }
+ playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ + "&itag=37&source=youtube&user=android-device-test"
+ + "&sparams=ip,ipbits,expire,id,itag,source,user"
+ + "&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
+ + "&signature=7C3BBFB2F493E1BC396B6D31DDAF2E1367624487."
+ + "64197F3BB46039669E912297DCD68D1FB2811D9F"
+ + "&key=test_key1", 1920, 1080, PLAY_TIME_MS);
+ }
+
+ private boolean supports(String mimeType, int profile, int level) {
+ int numCodecs = MediaCodecList.getCodecCount();
+ for (int i = 0; i < numCodecs; i++) {
+ MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
+ if (codecInfo.isEncoder()) {
+ continue;
+ }
+
+ CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);
+ for (CodecProfileLevel profileLevel : capabilities.profileLevels) {
+ if (profileLevel.profile == profile
+ && profileLevel.level >= level) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+}
diff --git a/tools/device-setup/TestDeviceSetup/Android.mk b/tools/device-setup/TestDeviceSetup/Android.mk
index 39f989e..ba1998c 100644
--- a/tools/device-setup/TestDeviceSetup/Android.mk
+++ b/tools/device-setup/TestDeviceSetup/Android.mk
@@ -27,7 +27,7 @@
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_SDK_VERSION := 17
+LOCAL_SDK_VERSION := current
LOCAL_PACKAGE_NAME := TestDeviceSetup
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoActivity.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoActivity.java
index 3614e22..e18e626 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoActivity.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoActivity.java
@@ -23,10 +23,10 @@
import android.content.res.Configuration;
import android.os.Bundle;
+import java.util.HashSet;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
-
/**
* Collect device information on target device.
*/
@@ -34,7 +34,7 @@
// work done should be reported in GLES..View
private CountDownLatch mDone = new CountDownLatch(1);
- private GLESSurfaceView mGLView;
+ private HashSet<String> mFormats = new HashSet<String>();
/**
* Other classes can call this function to wait for this activity
@@ -47,6 +47,37 @@
}
}
+ private void runIterations(int glVersion) {
+ for (int i = 1; i <= glVersion; i++) {
+ final CountDownLatch done = new CountDownLatch(1);
+ final int version = i;
+ DeviceInfoActivity.this.runOnUiThread(new Runnable() {
+ public void run() {
+ setContentView(new GLESSurfaceView(DeviceInfoActivity.this, version, done));
+ }
+ });
+ try {
+ done.await();
+ } catch (InterruptedException e) {
+ // just move on
+ }
+ }
+
+ StringBuilder builder = new StringBuilder();
+ for (String format: mFormats) {
+ builder.append(format);
+ builder.append(";");
+ }
+ DeviceInfoInstrument.addResult(
+ DeviceInfoConstants.OPEN_GL_COMPRESSED_TEXTURE_FORMATS,
+ builder.toString());
+ mDone.countDown();
+ }
+
+ public void addCompressedTextureFormat(String format) {
+ mFormats.add(format);
+ }
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -54,10 +85,12 @@
ActivityManager am =
(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo info = am.getDeviceConfigurationInfo();
- boolean useGL20 = (info.reqGlEsVersion >= 0x20000);
-
- mGLView = new GLESSurfaceView(this, useGL20, mDone);
- setContentView(mGLView);
+ final int glVersion = (info.reqGlEsVersion & 0xffff0000) >> 16;
+ new Thread() {
+ public void run() {
+ runIterations(glVersion);
+ }
+ }.start();
Configuration con = getResources().getConfiguration();
String touchScreen = null;
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
index c06c21e..4a0ea66 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
@@ -60,4 +60,6 @@
public static final String BUILD_VERSION = "buildVersion";
public static final String BUILD_TAGS = "build_tags";
public static final String SERIAL_NUMBER = "deviceID";
+ public static final String STORAGE_DEVICES = "storage_devices";
+ public static final String MULTI_USER = "multi_user";
}
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
index 49e96a0..29b29bf 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
@@ -25,6 +25,8 @@
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
+import android.os.UserManager;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -33,6 +35,8 @@
import java.io.IOException;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -135,6 +139,12 @@
String sysLibraries = getSystemLibraries();
addResult(SYS_LIBRARIES, sysLibraries);
+ // Storage devices
+ addResult(STORAGE_DEVICES, getStorageDevices());
+
+ // Multi-user support
+ addResult(MULTI_USER, getMultiUserInfo());
+
finish(Activity.RESULT_OK, mResults);
}
@@ -343,4 +353,42 @@
return builder.toString();
}
+
+ private String getStorageDevices() {
+ int count = 0;
+ count = Math.max(count, getContext().getExternalCacheDirs().length);
+ count = Math.max(count, getContext().getExternalFilesDirs(null).length);
+ count = Math.max(
+ count, getContext().getExternalFilesDirs(Environment.DIRECTORY_PICTURES).length);
+ count = Math.max(count, getContext().getObbDirs().length);
+
+ final String result;
+ if (Environment.isExternalStorageEmulated()) {
+ if (count == 1) {
+ return "1 emulated";
+ } else {
+ return "1 emulated, " + (count - 1) + " physical media";
+ }
+ } else {
+ return count + " physical media";
+ }
+ }
+
+ private String getMultiUserInfo() {
+ try {
+ final Method method = UserManager.class.getMethod("getMaxSupportedUsers");
+ final Integer maxUsers = (Integer) method.invoke(null);
+ if (maxUsers == 1) {
+ return "single user";
+ } else {
+ return maxUsers + " users supported";
+ }
+ } catch (ClassCastException e) {
+ } catch (NoSuchMethodException e) {
+ } catch (InvocationTargetException e) {
+ } catch (IllegalAccessException e) {
+ }
+
+ return "unknown";
+ }
}
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/GLESSurfaceView.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/GLESSurfaceView.java
index 0ec11b7..b2f2211 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/GLESSurfaceView.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/GLESSurfaceView.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.opengl.GLES20;
+import android.opengl.GLES30;
import android.opengl.GLSurfaceView;
import android.util.Log;
@@ -30,22 +31,24 @@
class GLESSurfaceView extends GLSurfaceView {
private static final String TAG = "GLESSurfaceView";
- private boolean mUseGL20;
- CountDownLatch mDone;
-
+ private int mGLVersion;//1, 2, 3
+ private CountDownLatch mDone;
+ private DeviceInfoActivity mParent;
/**
*
- * @param context
+ * @param parent
* @param useGL20 whether to use GLES2.0 API or not inside the view
* @param done to notify the completion of the task
*/
- public GLESSurfaceView(Context context, boolean useGL20, CountDownLatch done){
- super(context);
+ public GLESSurfaceView(DeviceInfoActivity parent, int glVersion, CountDownLatch done){
+ super(parent);
- mUseGL20 = useGL20;
+ mParent = parent;
+ mGLVersion = glVersion;
mDone = done;
- if (mUseGL20) {
- setEGLContextClientVersion(2);
+ if (glVersion > 1) {
+ // Default is 1 so only set if bigger than 1
+ setEGLContextClientVersion(glVersion);
}
setRenderer(new OpenGLESRenderer());
}
@@ -55,30 +58,26 @@
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
String extensions;
- if (mUseGL20) {
+ if (mGLVersion == 2) {
extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS);
+ } else if (mGLVersion == 3) {
+ extensions = GLES30.glGetString(GLES30.GL_EXTENSIONS);
} else {
extensions = gl.glGetString(GL10.GL_EXTENSIONS);
}
Log.i(TAG, "extensions : " + extensions);
Scanner scanner = new Scanner(extensions);
scanner.useDelimiter(" ");
- StringBuilder builder = new StringBuilder();
while (scanner.hasNext()) {
String ext = scanner.next();
if (ext.contains("texture")) {
if (ext.contains("compression") || ext.contains("compressed")) {
Log.i(TAG, "Compression supported: " + ext);
- builder.append(ext);
- builder.append(";");
+ mParent.addCompressedTextureFormat(ext);
}
}
}
- DeviceInfoInstrument.addResult(
- DeviceInfoConstants.OPEN_GL_COMPRESSED_TEXTURE_FORMATS,
- builder.toString());
-
mDone.countDown();
}
@@ -93,4 +92,4 @@
}
}
-}
\ No newline at end of file
+}
diff --git a/tools/tradefed-host/res/report/cts_result.xsd b/tools/tradefed-host/res/report/cts_result.xsd
index 3f7f384..ce606e9 100644
--- a/tools/tradefed-host/res/report/cts_result.xsd
+++ b/tools/tradefed-host/res/report/cts_result.xsd
@@ -78,6 +78,8 @@
<xs:attribute name="partitions" type="xs:string"/>
<xs:attribute name="build_abi" type="xs:string"/>
<xs:attribute name="build_abi2" type="xs:string"/>
+ <xs:attribute name="storage_devices" type="xs:string"/>
+ <xs:attribute name="multi_user" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="FeatureInfo" type="featureInfoType"/>
diff --git a/tools/tradefed-host/res/report/cts_result.xsl b/tools/tradefed-host/res/report/cts_result.xsl
index dfddc09..b6fb699 100644
--- a/tools/tradefed-host/res/report/cts_result.xsl
+++ b/tools/tradefed-host/res/report/cts_result.xsl
@@ -298,6 +298,18 @@
</pre>
</TD>
</TR>
+ <TR>
+ <TD class="rowtitle">Storage devices</TD>
+ <TD>
+ <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@storage_devices"/>
+ </TD>
+ </TR>
+ <TR>
+ <TD class="rowtitle">Multi-user support</TD>
+ <TD>
+ <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@multi_user"/>
+ </TD>
+ </TR>
</TABLE>
</TD>
</TR>