Merge "Send TAB instead of DPAD down to move focus"
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
index 2988db0..ee4068f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
@@ -35,9 +35,13 @@
/** Timing failures on first NUM_IGNORED_UPDATES updates are ignored. */
private static final int NUM_IGNORED_UPDATES = 2;
- /* The mean computed for the deltas should not be smaller
- * than mInterval * MIN_MEAN_RATIO */
- private static final double MIN_MEAN_RATIO = 0.75;
+ /* In active mode, the mean computed for the deltas should not be smaller
+ * than mInterval * ACTIVE_MIN_MEAN_RATIO */
+ private static final double ACTIVE_MIN_MEAN_RATIO = 0.75;
+
+ /* In passive mode, the mean computed for the deltas should not be smaller
+ * than mInterval * PASSIVE_MIN_MEAN_RATIO */
+ private static final double PASSIVE_MIN_MEAN_RATIO = 0.1;
/**
* The standard deviation computed for the deltas should not be bigger
@@ -96,8 +100,8 @@
mCb.log("active " + mProvider + " update (" + delta + "ms)");
if (mNumActiveUpdates >= mRequestedUpdates) {
- assertMeanAndStdev(mProvider, mActiveDeltas);
- assertMeanAndStdev(LocationManager.PASSIVE_PROVIDER, mPassiveDeltas);
+ assertMeanAndStdev(mProvider, mActiveDeltas, ACTIVE_MIN_MEAN_RATIO);
+ assertMeanAndStdev(LocationManager.PASSIVE_PROVIDER, mPassiveDeltas, PASSIVE_MIN_MEAN_RATIO);
pass();
}
}
@@ -110,11 +114,11 @@
public void onProviderDisabled(String provider) { }
}
- private void assertMeanAndStdev(String provider, List<Long> deltas) {
+ private void assertMeanAndStdev(String provider, List<Long> deltas, double minMeanRatio) {
double mean = computeMean(deltas);
double stdev = computeStdev(mean, deltas);
- double minMean = mInterval * MIN_MEAN_RATIO;
+ double minMean = mInterval * minMeanRatio;
if (mean < minMean) {
fail(provider + " provider mean too small: " + mean
+ " (min: " + minMean + ")");
diff --git a/tests/core/ctscore.mk b/tests/core/ctscore.mk
index 27ff881..0961c96 100644
--- a/tests/core/ctscore.mk
+++ b/tests/core/ctscore.mk
@@ -22,4 +22,8 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
# Don't delete META-INF from the core-tests jar
LOCAL_DONT_DELETE_JAR_META_INF := true
+
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+LOCAL_JNI_SHARED_LIBRARIES := libjavacoretests
+
include $(BUILD_PACKAGE)
diff --git a/tests/core/libcore/com/Android.mk b/tests/core/libcore/com/Android.mk
index 02dc3de..6c68f9d 100644
--- a/tests/core/libcore/com/Android.mk
+++ b/tests/core/libcore/com/Android.mk
@@ -20,5 +20,4 @@
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.com
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/dalvik/Android.mk b/tests/core/libcore/dalvik/Android.mk
index 7b77a75..5744fac 100644
--- a/tests/core/libcore/dalvik/Android.mk
+++ b/tests/core/libcore/dalvik/Android.mk
@@ -20,5 +20,4 @@
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.dalvik
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/libcore/Android.mk b/tests/core/libcore/libcore/Android.mk
index 382b386..160b996 100644
--- a/tests/core/libcore/libcore/Android.mk
+++ b/tests/core/libcore/libcore/Android.mk
@@ -20,5 +20,4 @@
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.libcore
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/org/Android.mk b/tests/core/libcore/org/Android.mk
index d7a96b3..adb26d5 100644
--- a/tests/core/libcore/org/Android.mk
+++ b/tests/core/libcore/org/Android.mk
@@ -20,5 +20,4 @@
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.org
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/sun/Android.mk b/tests/core/libcore/sun/Android.mk
index 44d3d70..d2754eb 100644
--- a/tests/core/libcore/sun/Android.mk
+++ b/tests/core/libcore/sun/Android.mk
@@ -20,5 +20,4 @@
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.sun
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/tests/Android.mk b/tests/core/libcore/tests/Android.mk
index bfd235f..0c1024e 100644
--- a/tests/core/libcore/tests/Android.mk
+++ b/tests/core/libcore/tests/Android.mk
@@ -20,5 +20,4 @@
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.tests
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
index 6a7e166..a8eecb5 100644
--- a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
@@ -268,16 +268,8 @@
MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);
for (int i = 0; i < capabilities.colorFormats.length; i++) {
int colorFormat = capabilities.colorFormats[i];
- switch (colorFormat) {
- // these are the formats we know how to handle for this test
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
- case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
- return colorFormat;
- default:
- break;
+ if (isRecognizedFormat(colorFormat)) {
+ return colorFormat;
}
}
fail("couldn't find a good color format for " + codecInfo.getName() + " / " + mimeType);
@@ -285,6 +277,42 @@
}
/**
+ * Returns true if this is a color format that this test code understands (i.e. we know how
+ * to read and generate frames in this format).
+ */
+ private static boolean isRecognizedFormat(int colorFormat) {
+ switch (colorFormat) {
+ // these are the formats we know how to handle for this test
+ case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
+ case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
+ case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
+ case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
+ case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if the specified color format is semi-planar YUV. Throws an exception
+ * if the color format is not recognized (e.g. not YUV).
+ */
+ private static boolean isSemiPlanarYUV(int colorFormat) {
+ switch (colorFormat) {
+ case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
+ case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
+ return false;
+ case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
+ case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
+ case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
+ return true;
+ default:
+ throw new RuntimeException("unknown format " + colorFormat);
+ }
+ }
+
+ /**
* Does the actual work for encoding frames from buffers of byte[].
*/
private void encodeDecodeVideoFromBuffer(MediaCodec encoder, int encoderColorFormat,
@@ -489,11 +517,8 @@
if (VERBOSE) Log.d(TAG, "output EOS");
outputDone = true;
}
+ decoder.releaseOutputBuffer(decoderStatus, false /*render*/);
} else {
- // Before we release+render this buffer, check to see if data from a
- // previous go-round has latched.
- surfaceStuff.checkNewImageIfAvailable();
-
if (VERBOSE) Log.d(TAG, "surface decoder given buffer " + decoderStatus +
" (size=" + info.size + ")");
rawSize += info.size;
@@ -501,20 +526,28 @@
if (VERBOSE) Log.d(TAG, "output EOS");
outputDone = true;
}
- }
- // If output is going to a Surface, the second argument should be true.
- // If not, the value doesn't matter.
- //
- // If we are sending to a Surface, then some time after we call this the
- // data will be made available to SurfaceTexture, and the onFrameAvailable()
- // callback will fire.
- decoder.releaseOutputBuffer(decoderStatus, true /*render*/);
+ boolean doRender = (info.size != 0);
+
+ // As soon as we call releaseOutputBuffer, the buffer will be forwarded
+ // to SurfaceTexture to convert to a texture. The API doesn't guarantee
+ // that the texture will be available before the call returns, so we
+ // need to wait for the onFrameAvailable callback to fire.
+ decoder.releaseOutputBuffer(decoderStatus, doRender);
+ if (doRender) {
+ if (VERBOSE) Log.d(TAG, "awaiting frame " + checkIndex);
+ surfaceStuff.awaitNewImage(checkIndex++);
+ }
+ }
}
}
}
- if (VERBOSE) Log.d(TAG, "encoded " + NUM_FRAMES + " frames at "
+ if (checkIndex != NUM_FRAMES) {
+ fail("expected " + NUM_FRAMES + " frames, only decoded " + checkIndex);
+ }
+
+ if (VERBOSE) Log.d(TAG, "decoded " + checkIndex + " frames at "
+ mWidth + "x" + mHeight + ": raw=" + rawSize + ", enc=" + encodedSize);
if (outputStream != null) {
try {
@@ -599,18 +632,18 @@
* Throws a failure if the frame looks wrong.
*/
private void checkFrame(int frameIndex, int colorFormat, ByteBuffer frameData) {
- final int HALF_WIDTH = mWidth / 2;
- boolean frameFailed = false;
-
- if (colorFormat == 0x7FA30C03) {
- // Nexus 4 decoder output OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka
+ // Check for color formats we don't understand. There is no requirement for video
+ // decoders to use a "mundane" format, so we just give a pass on proprietary formats.
+ // e.g. Nexus 4 0x7FA30C03 OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka
+ if (!isRecognizedFormat(colorFormat)) {
Log.d(TAG, "unable to check frame contents for colorFormat=" +
Integer.toHexString(colorFormat));
return;
}
- boolean semiPlanar = isSemiPlanarYUV(colorFormat);
- frameIndex %= 8;
+ final int HALF_WIDTH = mWidth / 2;
+ boolean frameFailed = false;
+ boolean semiPlanar = isSemiPlanarYUV(colorFormat);
for (int i = 0; i < 8; i++) {
int x, y;
@@ -637,7 +670,7 @@
}
boolean failed = false;
- if (i == frameIndex) {
+ if (i == frameIndex % 8) {
failed = !isColorClose(testY, TEST_Y) ||
!isColorClose(testU, TEST_U) ||
!isColorClose(testV, TEST_V);
@@ -648,7 +681,7 @@
!isColorClose(testV, 0);
}
if (failed) {
- Log.w(TAG, "Bad frame " + frameIndex + " (r=" + i + ": Y=" + testY +
+ Log.w(TAG, "Bad frame " + frameIndex + " (rect=" + i + ": Y=" + testY +
" U=" + testU + " V=" + testV + ")");
frameFailed = true;
}
@@ -673,24 +706,6 @@
}
/**
- * Returns true if the specified color format is semi-planar YUV. Throws an exception
- * if the color format is not recognized (e.g. not YUV).
- */
- private static boolean isSemiPlanarYUV(int colorFormat) {
- switch (colorFormat) {
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
- return false;
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
- case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
- return true;
- default:
- throw new RuntimeException("unknown format " + colorFormat);
- }
- }
-
- /**
* Holds state associated with a Surface used for output.
* <p>
* By default, the Surface will be using a BufferQueue in asynchronous mode, so we
@@ -706,7 +721,9 @@
private SurfaceTexture mSurfaceTexture;
private Surface mSurface;
- private boolean mFrameAvailable = false; // guarded by "this"
+
+ private Object mFrameSyncObject = new Object(); // guards mFrameAvailable
+ private boolean mFrameAvailable;
private int mWidth;
private int mHeight;
@@ -821,52 +838,59 @@
}
/**
- * Latches the next buffer into the texture if one is available, and checks it for
- * validity. Must be called from the thread that created the SurfaceStuff object.
+ * Latches the next buffer into the texture, and checks it for validity. Must be
+ * called from the thread that created the SurfaceStuff object, after the
+ * onFrameAvailable callback has signaled that new data is available.
*/
- public void checkNewImageIfAvailable() {
- boolean newStuff = false;
+ public void awaitNewImage(int frameIndex) {
+ final int TIMEOUT_MS = 500;
- synchronized (this) {
- if (mSurfaceTexture != null && mFrameAvailable) {
- mFrameAvailable = false;
- newStuff = true;
+ synchronized (mFrameSyncObject) {
+ while (!mFrameAvailable) {
+ try {
+ // Wait for onFrameAvailable() to signal us. Use a timeout to avoid
+ // stalling the test if it doesn't arrive.
+ mFrameSyncObject.wait(TIMEOUT_MS);
+ if (!mFrameAvailable) {
+ // TODO: if "spurious wakeup", continue while loop
+ fail("Surface frame wait timed out");
+ }
+ } catch (InterruptedException ie) {
+ // shouldn't happen
+ throw new RuntimeException(ie);
+ }
}
+ mFrameAvailable = false;
}
- if (newStuff) {
- mVideoRender.checkGlError("before updateTexImage");
- mSurfaceTexture.updateTexImage();
- mVideoRender.onDrawFrame(mSurfaceTexture);
- checkSurfaceFrame();
- }
+ // Latch the data, render it to the Surface, then check how it looks.
+ mVideoRender.checkGlError("before updateTexImage");
+ mSurfaceTexture.updateTexImage();
+ mVideoRender.onDrawFrame(mSurfaceTexture);
+ checkSurfaceFrame(frameIndex);
}
@Override
public void onFrameAvailable(SurfaceTexture st) {
if (VERBOSE) Log.d(TAG, "new frame available");
- synchronized (this) {
+ synchronized (mFrameSyncObject) {
+ if (mFrameAvailable) {
+ Log.e(TAG, "mFrameAvailable already set, frame could be dropped");
+ fail("dropped a frame");
+ }
mFrameAvailable = true;
+ mFrameSyncObject.notifyAll();
}
}
/**
- * Attempts to check the frame for correctness.
- * <p>
- * Our definition of "correct" is based on knowing what the frame sequence number is,
- * which we can't reliably get by counting frames since the underlying mechanism can
- * drop frames. The alternative would be to use the presentation time stamp that
- * we passed to the video encoder, but there's no way to get that from the texture.
- * <p>
- * All we can do is verify that it looks something like a frame we'd expect, i.e.
- * green with exactly one pink rectangle.
+ * Checks the frame for correctness.
*/
- private void checkSurfaceFrame() {
+ private void checkSurfaceFrame(int frameIndex) {
ByteBuffer pixelBuf = ByteBuffer.allocateDirect(4); // TODO - reuse this
+ boolean frameFailed = false;
- int numColoredRects = 0;
- int rectPosn = -1;
for (int i = 0; i < 8; i++) {
// Note the coordinates are inverted on the Y-axis in GL.
int x, y;
@@ -883,26 +907,27 @@
int g = pixelBuf.get(1) & 0xff;
int b = pixelBuf.get(2) & 0xff;
- if (isColorClose(r, TEST_R0) &&
- isColorClose(g, TEST_G0) &&
- isColorClose(b, TEST_B0)) {
- // empty space
- } else if (isColorClose(r, TEST_R1) &&
- isColorClose(g, TEST_G1) &&
- isColorClose(b, TEST_B1)) {
+ boolean failed = false;
+ if (i == frameIndex % 8) {
// colored rect
- numColoredRects++;
- rectPosn = i;
+ failed = !isColorClose(r, TEST_R1) ||
+ !isColorClose(g, TEST_G1) ||
+ !isColorClose(b, TEST_B1);
} else {
- // wtf
- Log.w(TAG, "found unexpected color r=" + r + " g=" + g + " b=" + b);
+ // zero background color
+ failed = !isColorClose(r, TEST_R0) ||
+ !isColorClose(g, TEST_G0) ||
+ !isColorClose(b, TEST_B0);
+ }
+ if (failed) {
+ Log.w(TAG, "Bad frame " + frameIndex + " (rect=" + i + ": r=" + r +
+ " g=" + g + " b=" + b + ")");
+ frameFailed = true;
}
}
- if (numColoredRects != 1) {
- fail("Found surface with colored rects != 1 (" + numColoredRects + ")");
- } else {
- if (VERBOSE) Log.d(TAG, "good surface, looks like index " + rectPosn);
+ if (frameFailed) {
+ fail("bad frame (" + frameIndex + ")");
}
}
}
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 1b09fb2..32fd18d 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -25,6 +25,7 @@
import java.io.File;
import java.io.FileFilter;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
@@ -392,6 +393,7 @@
"/data/drm/IDM/HTTP",
"/data/drm/rights",
"/data/dump",
+ "/data/efslog",
"/data/emt",
"/data/factory",
"/data/fics",
@@ -408,6 +410,8 @@
"/data/install",
"/data/internal-device",
"/data/internal-device/DCIM",
+ "/data/last_alog",
+ "/data/last_klog",
"/data/local",
"/data/local/logs",
"/data/local/logs/kernel",
@@ -517,6 +521,46 @@
writableDirs.isEmpty());
}
+ @LargeTest
+ public void testReadingSysFilesDoesntFail() throws Exception {
+ tryToReadFromAllIn(new File("/sys"));
+ }
+
+ private static void tryToReadFromAllIn(File dir) throws IOException {
+ assertTrue(dir.isDirectory());
+
+ if (isSymbolicLink(dir)) {
+ // don't examine symbolic links.
+ return;
+ }
+
+ File[] files = dir.listFiles();
+
+ if (files != null) {
+ for (File f : files) {
+ if (f.isDirectory()) {
+ tryToReadFromAllIn(f);
+ } else {
+ tryFileRead(f);
+ }
+ }
+ }
+ }
+
+ private static void tryFileRead(File f) {
+ byte[] b = new byte[1024];
+ try {
+ System.out.println("looking at " + f.getCanonicalPath());
+ FileInputStream fis = new FileInputStream(f);
+ while(fis.read(b) != -1) {
+ // throw away data
+ }
+ fis.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
private static final Set<File> SYS_EXCEPTIONS = new HashSet<File>(
Arrays.asList(
new File("/sys/kernel/debug/tracing/trace_marker")