Merge "Tests to verify PICK and VIEW are handled." into klp-dev
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index d3068bd..f34b096 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -41,6 +41,8 @@
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
+
<uses-feature android:name="android.hardware.usb.accessory" />
<!-- Needed by the Audio Quality Verifier to store the sound samples that will be mailed. -->
@@ -52,7 +54,6 @@
android:debuggable="true"
android:largeHeap="true">
- <uses-library android:name="com.android.future.usb.accessory" />
<meta-data android:name="com.google.android.backup.api_key"
android:value="AEdPqrEAAAAIbK6ldcOzoeRtQ1u1dFVJ1A7KetRhit-a1Xa82Q" />
@@ -354,7 +355,7 @@
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_camera" />
<meta-data android:name="test_required_features" android:value="android.hardware.sensor.gyroscope" />
- <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
+ <meta-data android:name="test_required_features" android:value="android.hardware.camera"/>
</activity>
<activity
android:name=".camera.fov.DetermineFovActivity"
@@ -462,6 +463,18 @@
<meta-data android:name="test_category" android:value="@string/test_category_other" />
</activity>
+ <activity android:name=".deskclock.DeskClockTestsActivity"
+ android:label="@string/deskclock_tests">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.cts.intent.category.MANUAL_TEST" />
+ </intent-filter>
+ <meta-data android:name="test_category" android:value="@string/test_category_deskclock" />
+ </activity>
+
+ <activity android:name=".deskclock.ShowAlarmsTestActivity"
+ android:label="@string/dc_show_alarms_test"/>
+
<receiver android:name=".widget.WidgetCtsProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
diff --git a/apps/CtsVerifier/res/layout/dc_show_alarms.xml b/apps/CtsVerifier/res/layout/dc_show_alarms.xml
new file mode 100644
index 0000000..06a2bb1
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/dc_show_alarms.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <LinearLayout android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:padding="5dp"
+ >
+
+ <TextView android:layout_width="wrap_content"
+ android:textSize="18sp"
+ android:layout_height="wrap_content"
+ android:text="@string/dc_show_alarms_test_info"
+ />
+
+ <Button android:id="@+id/dc_show_alarms"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/dc_show_alarms_button"
+ />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ >
+ <include layout="@layout/pass_fail_buttons" />
+ </LinearLayout>
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index ed2ecd4..ef14be3 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -32,6 +32,7 @@
<string name="test_category_security">Security</string>
<string name="test_category_streaming">Streaming</string>
<string name="test_category_features">Features</string>
+ <string name="test_category_deskclock">Desk Clock</string>
<string name="test_category_other">Other</string>
<string name="clear">Clear</string>
<string name="test_results_cleared">Test results cleared.</string>
@@ -614,4 +615,22 @@
<string name="widget_name">Widget Framework Test</string>
<string name="widget_pass">Pass</string>
<string name="widget_fail">Fail</string>
+
+ <!-- Strings for DeskClock -->
+ <string name="deskclock_tests">Desk Clock Tests</string>
+ <string name="deskclock_tests_info">
+ The Desk Clock tests verify that the Desk Clock app implements the Clock API\'s properly.
+ </string>
+ <string name="deskclock_group_alarms">Alarms</string>
+ <string name="deskclock_group_timers">Timers</string>
+
+ <string name="dc_show_alarms_test">Show Alarms Test</string>
+ <string name="dc_show_alarms_test_info">
+ This test verifies that the SHOW_ALARMS API works.\n
+ 1. Press the "Show Alarms" button.\n
+ 2. Verify that the Desk Clock app is launched and displays the Alarms section\n
+ </string>
+ <string name="dc_show_alarms_button">Show Alarms</string>
+
+
</resources>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
new file mode 100644
index 0000000..91b9b98
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
@@ -0,0 +1,52 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+
+package com.android.cts.verifier.deskclock;
+
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.os.Bundle;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+
+/**
+ * Activity that lists all the DeskClock tests.
+ */
+public class DeskClockTestsActivity extends PassFailButtons.TestListActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.pass_fail_list);
+ setInfoResources(R.string.deskclock_tests, R.string.deskclock_tests_info, 0);
+ setPassFailButtonClickListeners();
+
+ getPassButton().setEnabled(false);
+
+ final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+
+ adapter.add(TestListItem.newCategory(this, R.string.deskclock_group_alarms));
+ adapter.add(TestListItem.newTest(this,
+ R.string.dc_show_alarms_test,
+ ShowAlarmsTestActivity.class.getName(),
+ new Intent(this, ShowAlarmsTestActivity.class), null));
+
+ adapter.registerDataSetObserver(new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ updatePassButton();
+ }
+ });
+
+ setTestListAdapter(adapter);
+ }
+
+ /**
+ * Enable Pass Button when the all tests passed.
+ */
+ private void updatePassButton() {
+ getPassButton().setEnabled(mAdapter.allTestsPassed());
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/ShowAlarmsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/ShowAlarmsTestActivity.java
new file mode 100644
index 0000000..0ce8f51
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/ShowAlarmsTestActivity.java
@@ -0,0 +1,37 @@
+// Copyright 2013 Google Inc. All Rights Reserved.
+
+package com.android.cts.verifier.deskclock;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.AlarmClock;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+public class ShowAlarmsTestActivity extends PassFailButtons.Activity implements OnClickListener {
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.dc_show_alarms);
+ setPassFailButtonClickListeners();
+
+ final View button = findViewById(R.id.dc_show_alarms);
+ button.setOnClickListener(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setResult(RESULT_CANCELED);
+ }
+
+ @Override
+ public void onClick(View v) {
+ startActivity(new Intent(AlarmClock.ACTION_SHOW_ALARMS));
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
index 46963a0..1a68b48 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
@@ -154,7 +154,7 @@
public static final Feature[] ALL_HONEYCOMB_MR1_FEATURES = {
new Feature("android.hardware.usb.host", false),
- new Feature("android.hardware.usb.accessory", true),
+ new Feature("android.hardware.usb.accessory", false),
};
public static final Feature[] ALL_HONEYCOMB_MR2_FEATURES = {
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
index 2968a47..7091cac 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -75,19 +75,33 @@
String[] ids = mCameraManager.getCameraIdList();
if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(ids));
- // Test: that if the device has a camera, there must be at least one reported id.
- assertTrue("At least one camera must be detected",
- ! mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
- || ids.length >= 1);
+ /**
+ * Test: that if there is at least one reported id, then the system must have
+ * the FEATURE_CAMERA_ANY feature.
+ */
+ assertTrue("System camera feature and camera id list don't match",
+ ids.length == 0 ||
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY));
/**
- * Test: that if the device has both front and rear facing cameras, then there
- * must be at lest two reported ids.
+ * Test: that if the device has front or rear facing cameras, then there
+ * must be matched system features.
*/
- assertTrue("At least two cameras must be detected",
- ! mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
- || ! mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)
- || ids.length >= 2);
+ for (int i = 0; i < ids.length; i++) {
+ CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+ assertNotNull("Can't get camera characteristics for camera " + ids[i], props);
+ Integer lensFacing = props.get(CameraCharacteristics.LENS_FACING);
+ assertNotNull("Can't get lens facing info", lensFacing);
+ if (lensFacing == CameraCharacteristics.LENS_FACING_FRONT) {
+ assertTrue("System doesn't have front camera feature",
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT));
+ } else if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
+ assertTrue("System doesn't have back camera feature",
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA));
+ } else {
+ fail("Unknown camera lens facing " + lensFacing.toString());
+ }
+ }
/**
* Test: that if there is one camera device, then the system must have some
diff --git a/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java b/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
index c2f0c32..326c959 100644
--- a/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
@@ -21,6 +21,7 @@
import android.media.MediaCodec;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaFormat;
+import android.os.Bundle;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -71,6 +72,18 @@
decode(BASIC_IVF);
}
+ /**
+ * Check if MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME is honored.
+ *
+ * At frame 15, request a sync frame. If one does not occur by EOF the
+ * encoder fails. The test does not verify the output stream.
+ */
+ public void testSyncFrame() throws Exception {
+ encodeSyncFrame(R.raw.video_176x144_yv12,
+ 176, // width
+ 144, // height
+ 30); // framerate
+ }
/**
* A basic check if an encoded stream is decodable.
@@ -221,7 +234,8 @@
ivf = new IvfWriter(outputFilename, frameWidth, frameHeight);
// encode loop
long presentationTimeUs = 0;
- int frameIndex = 0;
+ int inputFrameIndex = 0;
+ int outputFrameIndex = 0;
boolean sawInputEOS = false;
boolean sawOutputEOS = false;
@@ -241,8 +255,8 @@
mInputBuffers[inputBufIndex].put(frame);
mInputBuffers[inputBufIndex].rewind();
- presentationTimeUs = (frameIndex * 1000000) / frameRate;
- Log.d(TAG, "Encoding frame at index " + frameIndex);
+ presentationTimeUs = (inputFrameIndex * 1000000) / frameRate;
+ Log.d(TAG, "Encoding frame at index " + inputFrameIndex);
encoder.queueInputBuffer(
inputBufIndex,
0, // offset
@@ -250,7 +264,7 @@
presentationTimeUs,
sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
- frameIndex++;
+ inputFrameIndex++;
}
}
@@ -261,6 +275,12 @@
mOutputBuffers[outputBufIndex].rewind();
mOutputBuffers[outputBufIndex].get(buffer, 0, mBufferInfo.size);
+ if ((outputFrameIndex == 0)
+ && ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) == 0)) {
+ throw new RuntimeException("First frame is not a sync frame.");
+
+ }
+
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
sawOutputEOS = true;
} else {
@@ -268,6 +288,8 @@
}
encoder.releaseOutputBuffer(outputBufIndex,
false); // render
+
+ outputFrameIndex++;
} else if (result == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
mOutputBuffers = encoder.getOutputBuffers();
}
@@ -285,4 +307,128 @@
}
}
}
+
+
+ /**
+ * Request Sync Frames
+ *
+ * MediaCodec will raise an IllegalStateException
+ * whenever vp8 encoder fails to encode a frame.
+ *
+ * This presumes a file with 28 frames. Under normal circumstances there
+ * would only be one sync frame: the first one. This test will request an
+ * additional sync frame at 15 and ensure that it occurs by EOF.
+ *
+ * Color format of input file should be YUV420, and frameWidth,
+ * frameHeight should be supplied correctly as raw input file doesn't
+ * include any header data.
+ *
+ * @param rawInputFd File descriptor for the raw input file (YUV420)
+ * @param frameWidth Frame width of input file
+ * @param frameHeight Frame height of input file
+ * @param frameRate Frame rate of input file in frames per second
+ */
+ private void encodeSyncFrame(int rawInputFd, int frameWidth,
+ int frameHeight, int frameRate) throws Exception {
+ int frameSize = frameWidth * frameHeight * 3 / 2;
+
+
+ // Create a media format signifying desired output
+ MediaFormat format = MediaFormat.createVideoFormat(VP8_MIME, frameWidth, frameHeight);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, 100000);
+ format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
+ CodecCapabilities.COLOR_FormatYUV420Planar);
+ format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
+
+ Log.d(TAG, "Creating encoder");
+ MediaCodec encoder;
+ encoder = MediaCodec.createByCodecName(VPX_ENCODER_NAME);
+ encoder.configure(format,
+ null, // surface
+ null, // crypto
+ MediaCodec.CONFIGURE_FLAG_ENCODE);
+ encoder.start();
+
+ mInputBuffers = encoder.getInputBuffers();
+ mOutputBuffers = encoder.getOutputBuffers();
+
+ InputStream rawStream = null;
+
+ try {
+ rawStream = mResources.openRawResource(rawInputFd);
+ // encode loop
+ long presentationTimeUs = 0;
+ int inputFrameIndex = 0;
+ boolean sawInputEOS = false;
+ boolean sawOutputEOS = false;
+ boolean syncFrameRequested = false;
+ boolean matchedSyncFrame = false;
+
+ while (!sawOutputEOS) {
+ if (!sawInputEOS) {
+ int inputBufIndex = encoder.dequeueInputBuffer(DEFAULT_TIMEOUT_US);
+ if (inputBufIndex >= 0) {
+ byte[] frame = new byte[frameSize];
+ int bytesRead = rawStream.read(frame);
+
+ if (bytesRead == -1) {
+ sawInputEOS = true;
+ bytesRead = 0;
+ }
+
+ mInputBuffers[inputBufIndex].clear();
+ mInputBuffers[inputBufIndex].put(frame);
+ mInputBuffers[inputBufIndex].rewind();
+
+ if (inputFrameIndex == 15) {
+ Log.d(TAG, "Requesting sync frame at index " + inputFrameIndex);
+ Bundle syncFrame = new Bundle();
+ syncFrame.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
+ encoder.setParameters(syncFrame);
+ syncFrameRequested = true;
+ }
+
+ presentationTimeUs = (inputFrameIndex * 1000000) / frameRate;
+ encoder.queueInputBuffer(
+ inputBufIndex,
+ 0, // offset
+ bytesRead, // size
+ presentationTimeUs,
+ sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+
+ inputFrameIndex++;
+ }
+ }
+
+ int result = encoder.dequeueOutputBuffer(mBufferInfo, DEFAULT_TIMEOUT_US);
+ if (result >= 0) {
+ if (syncFrameRequested && ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0)) {
+ Log.d(TAG, "Found sync frame");
+ matchedSyncFrame = true;
+ }
+
+ if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+ sawOutputEOS = true;
+ }
+
+ encoder.releaseOutputBuffer(result,
+ false); // render
+
+ } else if (result == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+ mOutputBuffers = encoder.getOutputBuffers();
+ }
+ }
+
+ if (!matchedSyncFrame) {
+ throw new RuntimeException("Requested sync frame did not occur");
+ }
+
+ encoder.stop();
+ encoder.release();
+ } finally {
+ if (rawStream != null) {
+ rawStream.close();
+ }
+ }
+ }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
index e68286f..3f28a34 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
@@ -78,6 +78,13 @@
mHelper = new FileCopyHelper(mContext);
mRowsAdded = new ArrayList<Uri>();
+
+ String campath = Environment.getExternalStorageDirectory() + File.separator +
+ Environment.DIRECTORY_DCIM + File.separator + "Camera";
+ File camfile = new File(campath);
+ if (!camfile.exists()) {
+ assertTrue("failed to create " + campath, camfile.mkdir());
+ }
}
public void testInsertImageWithImagePath() throws Exception {
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
index e8a13a9..03adad7 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
@@ -68,6 +68,13 @@
mHelper = new FileCopyHelper(mContext);
mRowsAdded = new ArrayList<Uri>();
+
+ String campath = Environment.getExternalStorageDirectory() + File.separator +
+ Environment.DIRECTORY_DCIM + File.separator + "Camera";
+ File camfile = new File(campath);
+ if (!camfile.exists()) {
+ assertTrue("failed to create " + campath, camfile.mkdir());
+ }
}
public void testQueryInternalThumbnails() throws Exception {
diff --git a/tests/tests/text/src/android/text/cts/EmojiTest.java b/tests/tests/text/src/android/text/cts/EmojiTest.java
index a8d8d2d..f5f191f 100644
--- a/tests/tests/text/src/android/text/cts/EmojiTest.java
+++ b/tests/tests/text/src/android/text/cts/EmojiTest.java
@@ -222,6 +222,14 @@
webViewOnUiThread.loadDataAndWaitForCompletion("<html><body>" + String.valueOf(c) + "</body></html>",
"text/html; charset=utf-8", "utf-8");
+ // The Chromium-powered WebView renders asynchronously and there's nothing reliable
+ // we can easily wait for to be sure that capturePicture will return a fresh frame.
+ // So, just sleep for a sufficient time.
+ try {
+ Thread.sleep(250);
+ } catch (InterruptedException e) {
+ return null;
+ }
Picture picture = webViewOnUiThread.capturePicture();
if (picture == null || picture.getHeight() <= 0 || picture.getWidth() <= 0) {