Merge "Handle IOException from MediaCodec factory methods"
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index e85109d..bc29b27 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -39,6 +39,7 @@
CtsDeviceAdmin \
CtsMonkeyApp \
CtsMonkeyApp2 \
+ CtsSampleDeviceApp \
CtsSomeAccessibilityServices \
CtsTestStubs \
SignatureTest \
@@ -82,7 +83,6 @@
CtsDreamsTestCases \
CtsDrmTestCases \
CtsEffectTestCases \
- CtsExampleTestCases \
CtsGestureTestCases \
CtsGraphicsTestCases \
CtsGraphics2TestCases \
@@ -108,6 +108,7 @@
CtsRenderscriptTestCases \
CtsRenderscriptGraphicsTestCases \
CtsRsCppTestCases \
+ CtsSampleDeviceTestCases \
CtsSaxTestCases \
CtsSecurityTestCases \
CtsSpeechTestCases \
@@ -132,6 +133,7 @@
CtsAdbTests \
CtsAppSecurityTests \
CtsMonkeyTestCases \
+ CtsSampleHostTestCases \
CtsUsbTests
# Native test executables that need to have associated test XMLs.
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index b080b18..cf331eb 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -677,7 +677,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"/>
+ <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
</activity>
<activity
android:name=".camera.fov.DetermineFovActivity"
diff --git a/build/test_package.mk b/build/test_package.mk
index 73f2a13..a0adb5f 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -36,12 +36,12 @@
$(cts_package_xml): PRIVATE_PATH := $(LOCAL_PATH)
$(cts_package_xml): PRIVATE_INSTRUMENTATION := $(LOCAL_INSTRUMENTATION_FOR)
$(cts_package_xml): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
-ifneq ($(filter cts/suite/cts/%, $(LOCAL_PATH)),) # CTS
-PRIVATE_CTS_TEST_PACKAGE_NANE_ := com.android.cts.$(notdir $(LOCAL_PATH))
-else # CTS
-PRIVATE_CTS_TEST_PACKAGE_NANE_ := android.$(notdir $(LOCAL_PATH))
-endif # CTS
-$(cts_package_xml): PRIVATE_TEST_PACKAGE := $(PRIVATE_CTS_TEST_PACKAGE_NANE_)
+ifneq ($(filter cts/suite/cts/%, $(LOCAL_PATH)),)
+PRIVATE_CTS_TEST_PACKAGE_NAME_ := com.android.cts.$(notdir $(LOCAL_PATH))
+else
+PRIVATE_CTS_TEST_PACKAGE_NAME_ := android.$(notdir $(LOCAL_PATH))
+endif
+$(cts_package_xml): PRIVATE_TEST_PACKAGE := $(PRIVATE_CTS_TEST_PACKAGE_NAME_)
$(cts_package_xml): PRIVATE_MANIFEST := $(LOCAL_PATH)/AndroidManifest.xml
$(cts_package_xml): PRIVATE_TEST_TYPE := $(if $(LOCAL_CTS_TEST_RUNNER),$(LOCAL_CTS_TEST_RUNNER),'')
$(cts_package_xml): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk $(CTS_EXPECTATIONS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
diff --git a/hostsidetests/sample/Android.mk b/hostsidetests/sample/Android.mk
new file mode 100644
index 0000000..1d3ddc8
--- /dev/null
+++ b/hostsidetests/sample/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := optional
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_MODULE := CtsSampleHostTestCases
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed ddmlib-prebuilt tradefed-prebuilt
+
+LOCAL_CTS_TEST_PACKAGE := android.host.sample
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/example/Android.mk b/hostsidetests/sample/app/Android.mk
similarity index 76%
copy from tests/tests/example/Android.mk
copy to hostsidetests/sample/app/Android.mk
index c6ef67b..4af45b9 100644
--- a/tests/tests/example/Android.mk
+++ b/hostsidetests/sample/app/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 The Android Open Source Project
+# Copyright (C) 2014 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,22 +16,16 @@
include $(CLEAR_VARS)
-# Replace "Example" with your name.
-LOCAL_PACKAGE_NAME := CtsExampleTestCases
-
# Don't include this package in any target.
LOCAL_MODULE_TAGS := optional
# When built, explicitly put it in the data partition.
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-# All tests should include android.test.runner.
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-
LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := CtsSampleDeviceApp
+
LOCAL_SDK_VERSION := current
include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/sample/app/AndroidManifest.xml b/hostsidetests/sample/app/AndroidManifest.xml
new file mode 100755
index 0000000..c087435
--- /dev/null
+++ b/hostsidetests/sample/app/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.sample.app">
+
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <application>
+ <activity android:name=".SampleDeviceActivity" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+
diff --git a/hostsidetests/sample/app/src/android/sample/app/SampleDeviceActivity.java b/hostsidetests/sample/app/src/android/sample/app/SampleDeviceActivity.java
new file mode 100644
index 0000000..d7efc0c
--- /dev/null
+++ b/hostsidetests/sample/app/src/android/sample/app/SampleDeviceActivity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.sample.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+/**
+ * A simple activity which logs to Logcat.
+ */
+public class SampleDeviceActivity extends Activity {
+
+ private static final String TAG = SampleDeviceActivity.class.getSimpleName();
+
+ /**
+ * The test string to log.
+ */
+ private static final String TEST_STRING = "SampleTestString";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ // Log the test string to Logcat.
+ Log.i(TAG, TEST_STRING);
+ }
+
+}
diff --git a/hostsidetests/sample/src/android/sample/cts/SampleHostResultTest.java b/hostsidetests/sample/src/android/sample/cts/SampleHostResultTest.java
new file mode 100644
index 0000000..a3bc08f
--- /dev/null
+++ b/hostsidetests/sample/src/android/sample/cts/SampleHostResultTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.sample.cts;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.tradefed.util.HostReportLog;
+import com.android.cts.util.MeasureRun;
+import com.android.cts.util.MeasureTime;
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+import com.android.cts.util.ReportLog;
+import com.android.cts.util.Stat;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.IDevice;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.RunUtil;
+
+import java.io.File;
+import java.lang.Exception;
+
+/**
+ * Test to measure the transfer time of a file from the host to the device.
+ */
+public class SampleHostResultTest extends DeviceTestCase implements IBuildReceiver {
+
+ private static final String TAG = SampleHostResultTest.class.getSimpleName();
+
+ /**
+ * The number of times to repeat the test.
+ */
+ private static final int REPEAT = 5;
+
+ /**
+ * The name of the plan to transfer.
+ *
+ * In this case we will transfer the CTS.xml file.
+ */
+ private static final String PLAN_NAME = "CTS";
+
+ /**
+ * A reference to the build.
+ */
+ private CtsBuildHelper mBuild;
+
+ /**
+ * A reference to the device under test.
+ */
+ private ITestDevice mDevice;
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ // Get the build, this is used to access the APK.
+ mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ // Get the device, this gives a handle to run commands and install APKs.
+ mDevice = getDevice();
+ }
+
+ /**
+ * Measures the time taken to transfer a file to the device and then back.
+ *
+ * The workload is repeated several times and the report is populated with the result.
+ *
+ * @throws Exception
+ */
+ public void testTransferTime() throws Exception {
+ final ITestDevice device = mDevice;
+ // Get the external storage location and ensure its not null.
+ final String externalStorePath = mDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+ assertNotNull("External storage location no found", externalStorePath);
+ // Create the device side path where the file will be transfered.
+ final String devicePath = String.format("%s/%s", externalStorePath, "tmp_testPushPull.txt");
+ // Get the file from the build.
+ final File testFile = mBuild.getTestPlanFile(PLAN_NAME);
+ double[] result = MeasureTime.measure(REPEAT, new MeasureRun() {
+ @Override
+ public void prepare(int i) throws Exception {
+ device.executeShellCommand(String.format("rm %s", devicePath));
+ }
+ @Override
+ public void run(int i) throws Exception {
+ // Create a temporary file to compare with.
+ File tmpFile = FileUtil.createTempFile("tmp", "txt");
+ try {
+ // Push the file across and ensure it exists.
+ assertTrue("Could not push file", device.pushFile(testFile, devicePath));
+ assertTrue("Unsuccessful transfer", device.doesFileExist(devicePath));
+ // Pull the file back and ensure it is the same.
+ assertTrue("Could not pull file", device.pullFile(devicePath, tmpFile));
+ assertFilesAreEqual(testFile, tmpFile);
+ } finally {
+ // Clean up.
+ tmpFile.delete();
+ device.executeShellCommand(String.format("rm %s", devicePath));
+ }
+ }
+ });
+ // Compute the stats.
+ Stat.StatResult stat = Stat.getStat(result);
+ // Get the report for this test and add the results to record.
+ HostReportLog report = new HostReportLog(mDevice.getSerialNumber(),
+ ReportLog.getClassMethodNames());
+ report.printArray("Times", result, ResultType.LOWER_BETTER, ResultUnit.MS);
+ report.printValue("Min", stat.mMin, ResultType.LOWER_BETTER, ResultUnit.MS);
+ report.printValue("Max", stat.mMax, ResultType.LOWER_BETTER, ResultUnit.MS);
+ // Every report must have a summary,
+ report.printSummary("Average", stat.mAverage, ResultType.LOWER_BETTER, ResultUnit.MS);
+ // Send the report to Tradefed.
+ report.deliverReportToHost();
+ }
+
+ /**
+ * Asserts the two given files are equal using the diff utility.
+ *
+ * @throws Exception
+ */
+ private static void assertFilesAreEqual(File first, File second) throws Exception {
+ CommandResult result = RunUtil.getDefault().runTimedCmd(5000, "diff",
+ first.getAbsolutePath(), second.getAbsolutePath());
+ assertTrue("Diff failed to run", result.getStatus() == CommandStatus.SUCCESS);
+ assertTrue("Files are not equivalent", "".equals(result.getStdout()));
+ }
+
+}
diff --git a/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java b/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java
new file mode 100644
index 0000000..7ccde0e
--- /dev/null
+++ b/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.sample.cts;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.lang.String;
+import java.util.Scanner;
+
+/**
+ * Test to check the APK logs to Logcat.
+ *
+ * When this test builds, it also builds {@see android.sample.app.SampleDeviceActivity} into an APK
+ * which it then installs at runtime and starts. The activity simply prints a message to Logcat and
+ * then gets uninstalled.
+ */
+public class SampleHostTest extends DeviceTestCase implements IBuildReceiver {
+
+ /**
+ * The package name of the APK.
+ */
+ private static final String PACKAGE = "android.sample.app";
+
+ /**
+ * The file name of the APK.
+ */
+ private static final String APK = "CtsSampleDeviceApp.apk";
+
+ /**
+ * The class name of the main activity in the APK.
+ */
+ private static final String CLASS = "SampleDeviceActivity";
+
+ /**
+ * The command to launch the main activity.
+ */
+ private static final String START_COMMAND = String.format(
+ "am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE, PACKAGE, CLASS);
+
+ /**
+ * The test string to look for.
+ */
+ private static final String TEST_STRING = "SampleTestString";
+
+ /**
+ * A reference to the build.
+ */
+ private CtsBuildHelper mBuild;
+
+ /**
+ * A reference to the device under test.
+ */
+ private ITestDevice mDevice;
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ // Get the build, this is used to access the APK.
+ mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ // Get the device, this gives a handle to run commands and install APKs.
+ mDevice = getDevice();
+ // Remove any previously installed versions of this APK.
+ mDevice.uninstallPackage(PACKAGE);
+ // Get the APK from the build.
+ File app = mBuild.getTestApp(APK);
+ // Install the APK on the device.
+ mDevice.installPackage(app, false);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // Remove the package once complete.
+ mDevice.uninstallPackage(PACKAGE);
+ super.tearDown();
+ }
+
+ /**
+ * Tests the string was successfully logged to Logcat from the activity.
+ *
+ * @throws Exception
+ */
+ public void testLogcat() throws Exception {
+ // Clear logcat.
+ mDevice.executeAdbCommand("logcat", "-c");
+ // Start the APK and wait for it to complete.
+ mDevice.executeShellCommand(START_COMMAND);
+ // Dump logcat.
+ String logs = mDevice.executeAdbCommand("logcat", "-d", CLASS + ":I", "*:S");
+ // Search for string.
+ String testString = "";
+ Scanner in = new Scanner(logs);
+ while (in.hasNextLine()) {
+ String line = in.nextLine();
+ if(line.startsWith("I/"+CLASS)) {
+ testString = line.split(":")[1].trim();
+ }
+ }
+ // Assert the logged string matches the test string.
+ assertEquals("Incorrect test string", TEST_STRING, testString);
+ }
+}
diff --git a/libs/commonutil/src/com/android/cts/util/MeasureTime.java b/libs/commonutil/src/com/android/cts/util/MeasureTime.java
index c158228..fd22ef2 100644
--- a/libs/commonutil/src/com/android/cts/util/MeasureTime.java
+++ b/libs/commonutil/src/com/android/cts/util/MeasureTime.java
@@ -23,9 +23,9 @@
* @param count
* @param run
* @return array of time taken in each run in msec.
- * @throws IOException
+ * @throws Exception
*/
- public static double[] measure(int count, MeasureRun run) throws Exception {
+ public static double[] measure(int count, MeasureRun run) throws Exception {
double[] result = new double[count];
for (int i = 0; i < count; i++) {
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 9d28c34..5eaff9b 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -31,74 +31,13 @@
bug: 11352697
},
{
- name: "android.bionic.DEATHTEST#bzero_fortified",
- name: "android.bionic.DEATHTEST#bzero_fortified2",
- name: "android.bionic.DEATHTEST#memcpy_fortified",
- name: "android.bionic.DEATHTEST#memmove_fortified",
- name: "android.bionic.DEATHTEST#snprintf_fortified",
- name: "android.bionic.DEATHTEST#snprintf_fortified2",
- name: "android.bionic.DEATHTEST#sprintf2_fortified",
- name: "android.bionic.DEATHTEST#sprintf2_fortified2",
- name: "android.bionic.DEATHTEST#sprintf_fortified",
- name: "android.bionic.DEATHTEST#sprintf_fortified2",
- name: "android.bionic.DEATHTEST#strcat2_fortified2",
- name: "android.bionic.DEATHTEST#strcat_fortified",
- name: "android.bionic.DEATHTEST#strcat_fortified2",
- name: "android.bionic.DEATHTEST#strchr_fortified",
- name: "android.bionic.DEATHTEST#strchr_fortified2",
- name: "android.bionic.DEATHTEST#strcpy2_fortified",
- name: "android.bionic.DEATHTEST#strcpy2_fortified2",
- name: "android.bionic.DEATHTEST#strcpy3_fortified",
- name: "android.bionic.DEATHTEST#strcpy3_fortified2",
- name: "android.bionic.DEATHTEST#strcpy4_fortified",
- name: "android.bionic.DEATHTEST#strcpy_fortified",
- name: "android.bionic.DEATHTEST#strcpy_fortified2",
- name: "android.bionic.DEATHTEST#strlcat_fortified",
- name: "android.bionic.DEATHTEST#strlcat_fortified2",
- name: "android.bionic.DEATHTEST#strlcpy_fortified",
- name: "android.bionic.DEATHTEST#strlcpy_fortified2",
- name: "android.bionic.DEATHTEST#strlen_fortified",
- name: "android.bionic.DEATHTEST#strncat2_fortified",
- name: "android.bionic.DEATHTEST#strncat2_fortified2",
- name: "android.bionic.DEATHTEST#strncat3_fortified2",
- name: "android.bionic.DEATHTEST#strncat_fortified",
- name: "android.bionic.DEATHTEST#strncat_fortified2",
- name: "android.bionic.DEATHTEST#strncpy_fortified",
- name: "android.bionic.DEATHTEST#strncpy_fortified2",
- name: "android.bionic.DEATHTEST#strrchr_fortified",
- name: "android.bionic.DEATHTEST#strrchr_fortified2",
- name: "android.bionic.DEATHTEST#umask_fortified",
- name: "android.bionic.DEATHTEST#vsnprintf2_fortified",
- name: "android.bionic.DEATHTEST#vsnprintf2_fortified2",
- name: "android.bionic.DEATHTEST#vsnprintf_fortified",
- name: "android.bionic.DEATHTEST#vsnprintf_fortified2",
- name: "android.bionic.DEATHTEST#vsprintf2_fortified",
- name: "android.bionic.DEATHTEST#vsprintf2_fortified2",
- name: "android.bionic.DEATHTEST#vsprintf_fortified",
- name: "android.bionic.DEATHTEST#vsprintf_fortified2",
- name: "android.bionic.TEST_NAME#memcpy_chk_max_int_size",
- name: "android.bionic.TEST_NAME#strcat",
- name: "android.bionic.TEST_NAME#strcat2",
- name: "android.bionic.TEST_NAME#strcat_chk_max_int_size",
- name: "android.bionic.TEST_NAME#strcpy_chk_max_int_size",
- name: "android.bionic.TEST_NAME#strncat",
- name: "android.bionic.TEST_NAME#strncat2",
- name: "android.bionic.TEST_NAME#strncat3",
- name: "android.bionic.TEST_NAME#strncat4",
- name: "android.bionic.TEST_NAME#strncat5",
- name: "android.bionic.TEST_NAME#strncat6",
- name: "android.bionic.dlfcn#dladdr",
- name: "android.bionic.dlfcn#dladdr_invalid",
- name: "android.bionic.dlfcn#dlerror_concurrent",
- name: "android.bionic.dlfcn#dlopen_bad_flags",
- name: "android.bionic.dlfcn#dlopen_failure",
- name: "android.bionic.dlfcn#dlopen_library_with_only_gnu_hash",
- name: "android.bionic.dlfcn#dlsym_failures",
- name: "android.bionic.dlfcn#dlsym_in_self",
+ name: "android.bionic.DEATHTEST",
+ name: "android.bionic.TEST_NAME",
+ name: "android.bionic.dlfcn",
name: "android.bionic.math#isfinite",
name: "android.bionic.math#signbit",
- name: "android.bionic.stack_protector#same_guard_per_thread",
- name: "android.bionic.stack_unwinding_DeathTest#unwinding_through_signal_frame",
+ name: "android.bionic.stack_protector",
+ name: "android.bionic.stack_unwinding_DeathTest",
bug: 11119006
}
]
diff --git a/tests/tests/example/Android.mk b/tests/sample/Android.mk
old mode 100644
new mode 100755
similarity index 82%
rename from tests/tests/example/Android.mk
rename to tests/sample/Android.mk
index c6ef67b..e1a9408
--- a/tests/tests/example/Android.mk
+++ b/tests/sample/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 The Android Open Source Project
+# Copyright (C) 2014 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,9 +16,6 @@
include $(CLEAR_VARS)
-# Replace "Example" with your name.
-LOCAL_PACKAGE_NAME := CtsExampleTestCases
-
# Don't include this package in any target.
LOCAL_MODULE_TAGS := optional
@@ -28,10 +25,13 @@
# All tests should include android.test.runner.
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
LOCAL_SRC_FILES := $(call all-java-files-under, src)
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_PACKAGE_NAME := CtsSampleDeviceTestCases
+
LOCAL_SDK_VERSION := current
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/sample/AndroidManifest.xml b/tests/sample/AndroidManifest.xml
new file mode 100755
index 0000000..ae58f0a
--- /dev/null
+++ b/tests/sample/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.sample.cts">
+
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="android.sample.SampleDeviceActivity" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <!-- self-instrumenting test package. -->
+ <instrumentation
+ android:name="android.test.InstrumentationCtsTestRunner"
+ android:label="CTS sample tests"
+ android:targetPackage="android.sample.cts" />
+
+</manifest>
+
diff --git a/tests/sample/src/android/sample/SampleDeviceActivity.java b/tests/sample/src/android/sample/SampleDeviceActivity.java
new file mode 100644
index 0000000..8fd8fde
--- /dev/null
+++ b/tests/sample/src/android/sample/SampleDeviceActivity.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.sample;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Bundle;
+
+import java.lang.Override;
+
+/**
+ * A simple activity for using the SharedPreferences API.
+ */
+public class SampleDeviceActivity extends Activity {
+
+ private SharedPreferences mPreferences;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ // Get a reference to this context's shared preference.
+ mPreferences = getPreferences(Context.MODE_PRIVATE);
+ }
+
+ /**
+ * Saves the given key value pair to the shared preferences.
+ *
+ * @param key
+ * @param value
+ */
+ public void savePreference(String key, String value) {
+ // Get an editor to modify the preferences.
+ Editor editor = mPreferences.edit();
+ // Insert the key value pair.
+ editor.putString(key, value);
+ // Commit the changes - important.
+ editor.commit();
+ }
+
+ /**
+ * Looks up the given key in the shared preferences.
+ *
+ * @param key
+ * @return
+ */
+ public String getPreference(String key) {
+ return mPreferences.getString(key, null);
+ }
+
+ /**
+ * Deletes all entries in the shared preferences.
+ */
+ public void clearPreferences() {
+ // Get an editor to modify the preferences.
+ Editor editor = mPreferences.edit();
+ // Delete all entries.
+ editor.clear();
+ // Commit the changes - important.
+ editor.commit();
+ }
+
+}
diff --git a/tests/sample/src/android/sample/cts/SampleDeviceResultTest.java b/tests/sample/src/android/sample/cts/SampleDeviceResultTest.java
new file mode 100644
index 0000000..6bf883f
--- /dev/null
+++ b/tests/sample/src/android/sample/cts/SampleDeviceResultTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.sample.cts;
+
+import com.android.cts.util.MeasureRun;
+import com.android.cts.util.MeasureTime;
+import com.android.cts.util.ReportLog;
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+import com.android.cts.util.Stat;
+
+import android.cts.util.CtsAndroidTestCase;
+
+/**
+ * A simple compatibility test which includes results in the report.
+ *
+ * This test measures the time taken to run a workload and adds in the report.
+ */
+public class SampleDeviceResultTest extends CtsAndroidTestCase {
+
+ /**
+ * The number of times to repeat the test.
+ */
+ private static final int REPEAT = 5;
+
+ /**
+ * The input number for the factorial.
+ */
+ private static final int IN = 15;
+
+ /**
+ * The expected output number for the factorial.
+ */
+ private static final long OUT = 1307674368000L;
+
+ /**
+ * Measures the time taken to compute the factorial of 15 with a recursive method.
+ *
+ * @throws Exception
+ */
+ public void testFactorialRecursive() throws Exception {
+ runTest(new MeasureRun() {
+ @Override
+ public void run(int i) throws Exception {
+ // Compute the factorial and assert it is correct.
+ assertEquals("Incorrect result", OUT, factorialRecursive(IN));
+ }
+ });
+ }
+
+ /**
+ * Measures the time taken to compute the factorial of 15 with a iterative method.
+ *
+ * @throws Exception
+ */
+ public void testFactorialIterative() throws Exception {
+ runTest(new MeasureRun() {
+ @Override
+ public void run(int i) throws Exception {
+ // Compute the factorial and assert it is correct.
+ assertEquals("Incorrect result", OUT, factorialIterative(IN));
+ }
+ });
+ }
+
+ /**
+ * Computes the factorial of a number with a recursive method.
+ *
+ * @param num The number to compute the factorial of.
+ */
+ private static long factorialRecursive(int num) {
+ if (num <= 0) {
+ return 1;
+ }
+ return num * factorialRecursive(num - 1);
+ }
+
+ /**
+ * Computes the factorial of a number with a iterative method.
+ *
+ * @param num The number to compute the factorial of.
+ */
+ private static long factorialIterative(int num) {
+ long result = 1;
+ for (int i = 2; i <= num; i++) {
+ result *= i;
+ }
+ return result;
+ }
+
+ /**
+ * Runs the workload and records the result to the report log.
+ *
+ * @param workload
+ */
+ private void runTest(MeasureRun workload) throws Exception {
+ // MeasureTime runs the workload N times and records the time taken by each run.
+ double[] result = MeasureTime.measure(REPEAT, workload);
+ // Compute the stats.
+ Stat.StatResult stat = Stat.getStat(result);
+ // Get the report for this test and add the results to record.
+ ReportLog log = getReportLog();
+ log.printArray("Times", result, ResultType.LOWER_BETTER, ResultUnit.MS);
+ log.printValue("Min", stat.mMin, ResultType.LOWER_BETTER, ResultUnit.MS);
+ log.printValue("Max", stat.mMax, ResultType.LOWER_BETTER, ResultUnit.MS);
+ // Every report must have a summary,
+ log.printSummary("Average", stat.mAverage, ResultType.LOWER_BETTER, ResultUnit.MS);
+ }
+}
diff --git a/tests/sample/src/android/sample/cts/SampleDeviceTest.java b/tests/sample/src/android/sample/cts/SampleDeviceTest.java
new file mode 100644
index 0000000..13b7ea6
--- /dev/null
+++ b/tests/sample/src/android/sample/cts/SampleDeviceTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.sample.cts;
+
+import android.sample.SampleDeviceActivity;
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * A simple compatibility test which tests the SharedPreferences API.
+ *
+ * This test uses {@link android.test.ActivityInstrumentationTestCase2} to instrument the
+ * {@link android.sample.SampleDeviceActivity}.
+ */
+public class SampleDeviceTest extends ActivityInstrumentationTestCase2<SampleDeviceActivity> {
+
+ private static final String KEY = "foo";
+
+ private static final String VALUE = "bar";
+
+ /**
+ * A reference to the activity whose shared preferences are being tested.
+ */
+ private SampleDeviceActivity mActivity;
+
+ public SampleDeviceTest() {
+ super(SampleDeviceActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ // Start the activity and get a reference to it.
+ mActivity = getActivity();
+ // Wait for the UI Thread to become idle.
+ getInstrumentation().waitForIdleSync();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // Scrub the activity so it can be freed. The next time the setUp will create a new activity
+ // rather than reusing the old one.
+ mActivity = null;
+ super.tearDown();
+ }
+
+ /**
+ * Tests the SharedPreferences API.
+ *
+ * This inserts the key value pair and assert they can be retrieved. Then it clears the
+ * preferences and asserts they can no longer be retrieved.
+ *
+ * @throws Exception
+ */
+ public void testSharedPreferences() throws Exception {
+ // Save the key value pair to the preferences and assert they were saved.
+ mActivity.savePreference(KEY, VALUE);
+ assertEquals("Preferences were not saved", VALUE, mActivity.getPreference(KEY));
+
+ // Clear the shared preferences and assert the data was removed.
+ mActivity.clearPreferences();
+ assertNull("Preferences were not cleared", mActivity.getPreference(KEY));
+ }
+}
diff --git a/tests/tests/example/AndroidManifest.xml b/tests/tests/example/AndroidManifest.xml
deleted file mode 100644
index ba41cce..0000000
--- a/tests/tests/example/AndroidManifest.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<!-- Replace all the "example" stuff below with your package name, and
- remove this comment.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.cts.example">
-
- <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <!-- This is a self-instrumenting test package. -->
- <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
- android:targetPackage="com.android.cts.example"
- android:label="CTS tests of example component"/>
-
-</manifest>
-
diff --git a/tests/tests/example/src/android/example/Example.java b/tests/tests/example/src/android/example/Example.java
deleted file mode 100644
index bc22d9a..0000000
--- a/tests/tests/example/src/android/example/Example.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 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.example;
-
-/**
- * Example class being tested. In a real test, the classes to test would
- * live somewhere other than in the test package, but for the sake of
- * brevity, we include this one here instead.
- */
-public class Example {
- /**
- * Return the standard string indication of a successfuly blorting.
- *
- * @returns {@code "blort"}, always
- */
- public static String blort() {
- return "blort";
- }
-
- /**
- * Return the standard string indication of a successfuly zorching.
- *
- * @returns {@code "zorch"}, always
- */
- public static String zorch() {
- return "zorch";
- }
-}
diff --git a/tests/tests/example/src/android/example/cts/ExampleSecondaryTest.java b/tests/tests/example/src/android/example/cts/ExampleSecondaryTest.java
deleted file mode 100644
index d2b78dc..0000000
--- a/tests/tests/example/src/android/example/cts/ExampleSecondaryTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 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.example.cts;
-
-import android.example.Example;
-
-import junit.framework.TestCase;
-
-/**
- * Example test to demonstrate how tests work as well as to serve as a
- * smoke test for the CTS. This secondary test exists to demonstrate
- * that you may have more than one test class. Typically you will
- * separate your test classes by what class or major piece of
- * functionality is being tested.
- */
-public class ExampleSecondaryTest extends TestCase {
- /*
- * You can define standard JUnit setUp() and tearDown() methods here,
- * if needed.
- *
- * @Override protected void setUp() throws Exception { ... }
- * @Override protected void tearDown() throws Exception { ... }
- */
-
- /**
- * Test {@link Example#zorch}.
- */
- public void testZorch() {
- assertEquals("zorch", Example.zorch());
- }
-
- // Add more tests here.
-}
diff --git a/tests/tests/example/src/android/example/cts/ExampleTest.java b/tests/tests/example/src/android/example/cts/ExampleTest.java
deleted file mode 100644
index db907cc..0000000
--- a/tests/tests/example/src/android/example/cts/ExampleTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 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.example.cts;
-
-import android.example.Example;
-
-import junit.framework.TestCase;
-
-/**
- * Example test to demonstrate how tests work as well as to serve as
- * a smoke test for the CTS. (If the example test is "broken," then it
- * probably means that there's something fundamentally wrong with your
- * setup.)
- */
-public class ExampleTest extends TestCase {
- /*
- * You can define standard JUnit setUp() and tearDown() methods here,
- * if needed.
- *
- * @Override protected void setUp() throws Exception { ... }
- * @Override protected void tearDown() throws Exception { ... }
- */
-
- /**
- * Test {@link Example#blort}.
- */
- public void testBlort() {
- assertEquals("blort", Example.blort());
- }
-
- // Add more tests here.
-}
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
index c981db3..5ef710f 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
@@ -88,7 +88,7 @@
private int mMseMargin = 3 * (1 * 1);
// MSE margin for WebP Region-Decoding for 'Config.RGB_565' is little bigger.
- private int mMseMarginWebPConfigRgb565 = 5;
+ private int mMseMarginWebPConfigRgb565 = 8;
@Override
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCaptureResultTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCaptureResultTest.java
index 70fea28..f05111b 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCaptureResultTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCaptureResultTest.java
@@ -303,16 +303,16 @@
resultKeys.add(CaptureResult.LENS_STATE);
resultKeys.add(CaptureResult.NOISE_REDUCTION_MODE);
resultKeys.add(CaptureResult.REQUEST_FRAME_COUNT);
+ resultKeys.add(CaptureResult.REQUEST_PIPELINE_DEPTH);
resultKeys.add(CaptureResult.SCALER_CROP_REGION);
resultKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME);
resultKeys.add(CaptureResult.SENSOR_FRAME_DURATION);
resultKeys.add(CaptureResult.SENSOR_SENSITIVITY);
resultKeys.add(CaptureResult.SENSOR_TIMESTAMP);
resultKeys.add(CaptureResult.SENSOR_TEMPERATURE);
+ resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE);
resultKeys.add(CaptureResult.STATISTICS_FACE_DETECT_MODE);
resultKeys.add(CaptureResult.STATISTICS_LENS_SHADING_MAP);
- resultKeys.add(CaptureResult.STATISTICS_PREDICTED_COLOR_GAINS);
- resultKeys.add(CaptureResult.STATISTICS_PREDICTED_COLOR_TRANSFORM);
resultKeys.add(CaptureResult.STATISTICS_SCENE_FLICKER);
resultKeys.add(CaptureResult.TONEMAP_CURVE_BLUE);
resultKeys.add(CaptureResult.TONEMAP_CURVE_GREEN);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCharacteristicsTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCharacteristicsTest.java
index 09d5b90..d694104 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCharacteristicsTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCharacteristicsTest.java
@@ -563,6 +563,52 @@
}
}
+ public void testCameraCharacteristicsAndroidRequestPipelineMaxDepth() throws Exception {
+ String[] ids = mCameraManager.getCameraIdList();
+ for (int i = 0; i < ids.length; i++) {
+ CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+ assertNotNull(String.format("Can't get camera characteristics from: ID %s", ids[i]),
+ props);
+
+ {
+
+ assertNotNull("Invalid property: android.request.pipelineMaxDepth",
+ props.get(CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH));
+
+ List<Key<?>> allKeys = props.getKeys();
+ assertNotNull(String.format("Can't get camera characteristics keys from: ID %s",
+ ids[i], props));
+ assertTrue("Key not in keys list: android.request.pipelineMaxDepth", allKeys.contains(
+ CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH));
+
+ }
+
+ }
+ }
+
+ public void testCameraCharacteristicsAndroidRequestPartialResultCount() throws Exception {
+ String[] ids = mCameraManager.getCameraIdList();
+ for (int i = 0; i < ids.length; i++) {
+ CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+ assertNotNull(String.format("Can't get camera characteristics from: ID %s", ids[i]),
+ props);
+
+ {
+
+ assertNotNull("Invalid property: android.request.partialResultCount",
+ props.get(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT));
+
+ List<Key<?>> allKeys = props.getKeys();
+ assertNotNull(String.format("Can't get camera characteristics keys from: ID %s",
+ ids[i], props));
+ assertTrue("Key not in keys list: android.request.partialResultCount", allKeys.contains(
+ CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT));
+
+ }
+
+ }
+ }
+
public void testCameraCharacteristicsAndroidScalerAvailableFormats() throws Exception {
String[] ids = mCameraManager.getCameraIdList();
for (int i = 0; i < ids.length; i++) {
@@ -778,6 +824,33 @@
}
}
+ public void testCameraCharacteristicsAndroidSensorAvailableTestPatternModes() throws Exception {
+ String[] ids = mCameraManager.getCameraIdList();
+ for (int i = 0; i < ids.length; i++) {
+ CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+ assertNotNull(String.format("Can't get camera characteristics from: ID %s", ids[i]),
+ props);
+
+ Integer hwLevel = props.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+ assertNotNull("No hardware level reported! android.info.supportedHardwareLevel",
+ hwLevel);
+ if (hwLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+ {
+
+ assertNotNull("Invalid property: android.sensor.availableTestPatternModes",
+ props.get(CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES));
+
+ List<Key<?>> allKeys = props.getKeys();
+ assertNotNull(String.format("Can't get camera characteristics keys from: ID %s",
+ ids[i], props));
+ assertTrue("Key not in keys list: android.sensor.availableTestPatternModes", allKeys.contains(
+ CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES));
+
+ }
+
+ }
+ }
+
public void testCameraCharacteristicsAndroidSensorInfoActiveArraySize() throws Exception {
String[] ids = mCameraManager.getCameraIdList();
for (int i = 0; i < ids.length; i++) {
@@ -984,5 +1057,28 @@
}
}
+
+ public void testCameraCharacteristicsAndroidSyncMaxLatency() throws Exception {
+ String[] ids = mCameraManager.getCameraIdList();
+ for (int i = 0; i < ids.length; i++) {
+ CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+ assertNotNull(String.format("Can't get camera characteristics from: ID %s", ids[i]),
+ props);
+
+ {
+
+ assertNotNull("Invalid property: android.sync.maxLatency",
+ props.get(CameraCharacteristics.SYNC_MAX_LATENCY));
+
+ List<Key<?>> allKeys = props.getKeys();
+ assertNotNull(String.format("Can't get camera characteristics keys from: ID %s",
+ ids[i], props));
+ assertTrue("Key not in keys list: android.sync.maxLatency", allKeys.contains(
+ CameraCharacteristics.SYNC_MAX_LATENCY));
+
+ }
+
+ }
+ }
}
diff --git a/tests/tests/media/res/raw/video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz_id3v2.mp4 b/tests/tests/media/res/raw/video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz_id3v2.mp4
new file mode 100644
index 0000000..0902533
--- /dev/null
+++ b/tests/tests/media/res/raw/video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz_id3v2.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index b090e27..30c8370 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -70,4 +70,52 @@
assertNull("Writer was unexpected present",
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
}
+
+ public void testSetDataSourceNull() {
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+
+ try {
+ retriever.setDataSource((String)null);
+ fail("Expected IllegalArgumentException.");
+ } catch (IllegalArgumentException ex) {
+ // Expected, test passed.
+ }
+ }
+
+ public void testID3v2Metadata() {
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+
+ try {
+ Resources resources = getContext().getResources();
+ AssetFileDescriptor afd = resources.openRawResourceFd(
+ R.raw.video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz_id3v2);
+
+ retriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+
+ afd.close();
+ } catch (Exception e) {
+ fail("Unable to open file");
+ }
+
+ assertEquals("Title was other than expected",
+ "Title", retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
+
+ assertEquals("Artist was other than expected",
+ "UTF16LE エンディアン ",
+ retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST));
+
+ assertEquals("Album was other than expected",
+ "Test album",
+ retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM));
+
+ assertEquals("Track number was other than expected",
+ "10",
+ retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER));
+
+ assertEquals("Year was other than expected",
+ "2013", retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR));
+
+ assertNull("Writer was unexpectedly present",
+ retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
+ }
}
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 29fc2d7..27c7215 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -445,6 +445,8 @@
"/data/local/tmp/com.nuance.android.vsuite.vsuiteapp",
"/data/log",
"/data/logger",
+ "/data/logs",
+ "/data/logs/core",
"/data/lost+found",
"/data/misc",
"/data/misc/bluetooth",
diff --git a/tests/tests/print/AndroidManifest.xml b/tests/tests/print/AndroidManifest.xml
index 82715cb..4c94fd5 100644
--- a/tests/tests/print/AndroidManifest.xml
+++ b/tests/tests/print/AndroidManifest.xml
@@ -23,7 +23,7 @@
<uses-library android:name="android.test.runner"/>
- <activity android:name="android.print.cts.PrintDocumentAdapterContractActivity"/>
+ <activity android:name="android.print.cts.PrintDocumentActivity"/>
<service
android:name="android.print.cts.services.FirstPrintService"
diff --git a/tests/tests/print/src/android/print/cts/BasePrintTest.java b/tests/tests/print/src/android/print/cts/BasePrintTest.java
index c1973ca..d193bb0 100644
--- a/tests/tests/print/src/android/print/cts/BasePrintTest.java
+++ b/tests/tests/print/src/android/print/cts/BasePrintTest.java
@@ -71,7 +71,7 @@
protected static final String PRINT_JOB_NAME = "Test";
- private PrintDocumentAdapterContractActivity mActivity;
+ private PrintDocumentActivity mActivity;
private Locale mOldLocale;
@@ -79,6 +79,7 @@
private CallCounter mWriteCallCounter;
private CallCounter mFinishCallCounter;
private CallCounter mPrintJobQueuedCallCounter;
+ private CallCounter mDestroySessionCallCounter;
@Override
public void setUp() throws Exception {
@@ -107,6 +108,7 @@
mWriteCallCounter = new CallCounter();
mFinishCallCounter = new CallCounter();
mPrintJobQueuedCallCounter = new CallCounter();
+ mDestroySessionCallCounter = new CallCounter();
// Create the activity for the right locale.
createActivity();
@@ -159,12 +161,21 @@
mPrintJobQueuedCallCounter.call();
}
+ protected void onPrinterDiscoverySessionDestroyCalled() {
+ mDestroySessionCallCounter.call();
+ }
+
+ protected void waitForPrinterDiscoverySessionDestroyCallbackCalled() {
+ waitForCallbackCallCount(mDestroySessionCallCounter, 1,
+ "Did not get expected call to onDestroyPrinterDiscoverySession.");
+ }
+
protected void waitForServiceOnPrintJobQueuedCallbackCalled() {
waitForCallbackCallCount(mPrintJobQueuedCallCounter, 1,
"Did not get expected call to onPrintJobQueued.");
}
- protected void waitForAdapterCallbackFinish() {
+ protected void waitForAdapterFinishCallbackCalled() {
waitForCallbackCallCount(mFinishCallCounter, 1,
"Did not get expected call to finish.");
}
@@ -224,14 +235,14 @@
printButton.click();
}
- protected PrintDocumentAdapterContractActivity getActivity() {
+ protected PrintDocumentActivity getActivity() {
return mActivity;
}
private void createActivity() {
mActivity = launchActivity(
getInstrumentation().getTargetContext().getPackageName(),
- PrintDocumentAdapterContractActivity.class, null);
+ PrintDocumentActivity.class, null);
}
protected void clearPrintSpoolerData() throws Exception {
diff --git a/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java b/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
index cf28800..d3d5a4c 100644
--- a/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
+++ b/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
@@ -139,7 +139,7 @@
clickPrintButton();
// Wait for finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Wait for the print job.
waitForServiceOnPrintJobQueuedCallbackCalled();
@@ -239,7 +239,7 @@
clickPrintButton();
// Wait for finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Wait for the print job.
waitForServiceOnPrintJobQueuedCallbackCalled();
@@ -351,7 +351,7 @@
clickPrintButton();
// Wait for finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Wait for the print job.
waitForServiceOnPrintJobQueuedCallbackCalled();
@@ -439,7 +439,7 @@
UiDevice.getInstance().pressBack();
// Wait for finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(firstServiceCallbacks);
@@ -491,7 +491,7 @@
PrintAttributes.COLOR_MODE_COLOR)
.build();
PrinterInfo firstPrinter = new PrinterInfo.Builder(firstPrinterId,
- "First printer", PrinterInfo.STATUS_IDLE)
+ FIRST_PRINTER, PrinterInfo.STATUS_IDLE)
.setCapabilities(firstCapabilities)
.build();
printers.add(firstPrinter);
diff --git a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractActivity.java b/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
similarity index 92%
rename from tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractActivity.java
rename to tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
index eb80bb7..6a191a6 100644
--- a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractActivity.java
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
@@ -19,7 +19,7 @@
import android.app.Activity;
import android.os.Bundle;
-public class PrintDocumentAdapterContractActivity extends Activity {
+public class PrintDocumentActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
diff --git a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
index 64c225a..57eae3f 100644
--- a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
@@ -116,7 +116,7 @@
clickPrintButton();
// Wait for finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -220,7 +220,7 @@
UiDevice.getInstance().pressBack();
// Wait for finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -328,7 +328,7 @@
clickPrintButton();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -488,7 +488,7 @@
clickPrintButton();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -621,7 +621,7 @@
clickPrintButton();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -728,7 +728,7 @@
clickPrintButton();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -822,7 +822,7 @@
clickPrintButton();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -917,7 +917,7 @@
UiDevice.getInstance().pressBack();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -1001,7 +1001,7 @@
UiDevice.getInstance().pressBack();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -1067,7 +1067,7 @@
UiDevice.getInstance().pressBack();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -1143,7 +1143,7 @@
UiDevice.getInstance().pressBack();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -1224,7 +1224,7 @@
UiDevice.getInstance().pressBack();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -1289,7 +1289,7 @@
UiDevice.getInstance().pressBack();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
@@ -1362,7 +1362,7 @@
UiDevice.getInstance().pressBack();
// Wait for a finish.
- waitForAdapterCallbackFinish();
+ waitForAdapterFinishCallbackCalled();
// Verify the expected calls.
InOrder inOrder = inOrder(adapter);
diff --git a/tests/tests/print/src/android/print/cts/PrinterDiscoverySessionLifecycleTest.java b/tests/tests/print/src/android/print/cts/PrinterDiscoverySessionLifecycleTest.java
new file mode 100644
index 0000000..cb6a6d1
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/PrinterDiscoverySessionLifecycleTest.java
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.print.cts;
+
+import static org.mockito.Mockito.inOrder;
+
+import android.os.ParcelFileDescriptor;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentAdapter.LayoutResultCallback;
+import android.print.PrintDocumentAdapter.WriteResultCallback;
+import android.print.PrintDocumentInfo;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.print.cts.services.FirstPrintService;
+import android.print.cts.services.PrintServiceCallbacks;
+import android.print.cts.services.PrinterDiscoverySessionCallbacks;
+import android.print.cts.services.SecondPrintService;
+import android.print.cts.services.StubbablePrinterDiscoverySession;
+import android.printservice.PrintJob;
+import android.printservice.PrinterDiscoverySession;
+import android.support.test.uiautomator.UiDevice;
+
+import org.mockito.InOrder;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This test verifies that the system respects the {@link PrinterDiscoverySession}
+ * contract is respected.
+ */
+public class PrinterDiscoverySessionLifecycleTest extends BasePrintTest {
+ private static final String FIRST_PRINTER_NAME = "First printer";
+ private static final String SECOND_PRINTER_NAME = "Second printer";
+
+ private static final String FIRST_PRINTER_LOCAL_ID= "first_printer";
+ private static final String SECOND_PRINTER_LOCAL_ID = "second_printer";
+
+ public void testNormalLifecycle() throws Exception {
+ // Create the session callbacks that we will be checking.
+ final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
+ createFirstMockPrinterDiscoverySessionCallbacks();
+
+ // Create the service callbacks for the first print service.
+ PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+ new Answer<PrinterDiscoverySessionCallbacks>() {
+ @Override
+ public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+ return firstSessionCallbacks;
+ }
+ },
+ new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+ // We pretend the job is handled immediately.
+ printJob.complete();
+ return null;
+ }
+ }, null);
+
+ // Configure the print services.
+ FirstPrintService.setCallbacks(firstServiceCallbacks);
+ SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+ // Create a print adapter that respects the print contract.
+ PrintDocumentAdapter adapter = createMockPrintDocumentAdapter();
+
+ // Start printing.
+ print(adapter);
+
+ // Wait for write of the first page.
+ waitForWriteForAdapterCallback();
+
+ // Select the first printer.
+ selectPrinter(FIRST_PRINTER_NAME);
+
+ // Wait for layout as the printer has different capabilities.
+ waitForLayoutAdapterCallbackCount(2);
+
+ // Select the second printer (same capabilities as the other
+ // one so no layout should happen).
+ selectPrinter(SECOND_PRINTER_NAME);
+
+ // While the printer discovery session is still alive store the
+ // ids of printers as we want to make some assertions about them
+ // but only the print service can create printer ids which means
+ // that we need to get the created ones.
+ PrinterId firstPrinterId = getAddedPrinterIdForLocalId(firstSessionCallbacks,
+ FIRST_PRINTER_LOCAL_ID);
+ PrinterId secondPrinterId = getAddedPrinterIdForLocalId(firstSessionCallbacks,
+ SECOND_PRINTER_LOCAL_ID);
+ assertNotNull("Coundn't find printer:" + FIRST_PRINTER_LOCAL_ID, firstPrinterId);
+ assertNotNull("Coundn't find printer:" + SECOND_PRINTER_LOCAL_ID, secondPrinterId);
+
+ // Click the print button.
+ clickPrintButton();
+
+ // Wait for all print jobs to be handled after which the session destroyed.
+ waitForPrinterDiscoverySessionDestroyCallbackCalled();
+
+ // Verify the expected calls.
+ InOrder inOrder = inOrder(firstSessionCallbacks);
+
+ // We start discovery as the print dialog was up.
+ List<PrinterId> emptyPrinterIdList = Collections.emptyList();
+ inOrder.verify(firstSessionCallbacks).onStartPrinterDiscovery(
+ emptyPrinterIdList);
+
+ // We selected the first printer and now it should be tracked.
+ inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
+ firstPrinterId);
+
+ // We selected the second printer so the first should not be tracked.
+ inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
+ firstPrinterId);
+
+ // We selected the second printer and now it should be tracked.
+ inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
+ secondPrinterId);
+
+ // The print dialog went away so we first stop the printer tracking...
+ inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
+ secondPrinterId);
+
+ // ... next we stop printer discovery...
+ inOrder.verify(firstSessionCallbacks).onStopPrinterDiscovery();
+
+ // ... last the session is destroyed.
+ inOrder.verify(firstSessionCallbacks).onDestroy();
+ }
+
+ public void testStartPrinterDiscoveryWithHistoricalPrinters() throws Exception {
+ // Create the session callbacks that we will be checking.
+ final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
+ createFirstMockPrinterDiscoverySessionCallbacks();
+
+ // Create the service callbacks for the first print service.
+ PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+ new Answer<PrinterDiscoverySessionCallbacks>() {
+ @Override
+ public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+ return firstSessionCallbacks;
+ }
+ },
+ new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+ // We pretend the job is handled immediately.
+ printJob.complete();
+ return null;
+ }
+ }, null);
+
+ // Configure the print services.
+ FirstPrintService.setCallbacks(firstServiceCallbacks);
+ SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+ // Create a print adapter that respects the print contract.
+ PrintDocumentAdapter adapter = createMockPrintDocumentAdapter();
+
+ // Start printing.
+ print(adapter);
+
+ // Wait for write of the first page.
+ waitForWriteForAdapterCallback();
+
+ // Select the first printer.
+ selectPrinter(FIRST_PRINTER_NAME);
+
+ // Wait for a layout to finish - first layout was for the
+ // PDF printer, second for the first printer in preview mode.
+ waitForLayoutAdapterCallbackCount(2);
+
+ // While the printer discovery session is still alive store the
+ // ids of printer as we want to make some assertions about it
+ // but only the print service can create printer ids which means
+ // that we need to get the created one.
+ PrinterId firstPrinterId = getAddedPrinterIdForLocalId(
+ firstSessionCallbacks, FIRST_PRINTER_LOCAL_ID);
+
+ // Click the print button.
+ clickPrintButton();
+
+ // Wait for the print to complete.
+ waitForAdapterFinishCallbackCalled();
+
+ // Now print again as we want to confirm that the start
+ // printer discovery passes in the priority list.
+ print(adapter);
+
+ // Wait for a layout to finish - first layout was for the
+ // PDF printer, second for the first printer in preview mode,
+ // the third for the first printer in non-preview mode, and
+ // now a fourth for the PDF printer as we are printing again.
+ waitForLayoutAdapterCallbackCount(4);
+
+ // Cancel the printing.
+ UiDevice.getInstance().pressBack(); // wakes up the device.
+ UiDevice.getInstance().pressBack();
+
+ // Wait for all print jobs to be handled after which the session destroyed.
+ waitForPrinterDiscoverySessionDestroyCallbackCalled();
+
+ // Verify the expected calls.
+ InOrder inOrder = inOrder(firstSessionCallbacks);
+
+ // We start discovery as the print dialog was up.
+ List<PrinterId> priorityList = new ArrayList<PrinterId>();
+ priorityList.add(firstPrinterId);
+ inOrder.verify(firstSessionCallbacks).onStartPrinterDiscovery(
+ priorityList);
+
+ // We selected the first printer and now it should be tracked.
+ inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
+ firstPrinterId);
+
+ // We selected the second printer so the first should not be tracked.
+ inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
+ firstPrinterId);
+
+ // ...next we stop printer discovery...
+ inOrder.verify(firstSessionCallbacks).onStopPrinterDiscovery();
+
+ // ...last the session is destroyed.
+ inOrder.verify(firstSessionCallbacks).onDestroy();
+ }
+
+ private PrinterId getAddedPrinterIdForLocalId(
+ final PrinterDiscoverySessionCallbacks sessionCallbacks, String printerLocalId) {
+ final List<PrinterInfo> reportedPrinters = new ArrayList<PrinterInfo>();
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ // Grab the printer ids as only the service can create such.
+ StubbablePrinterDiscoverySession session = sessionCallbacks.getSession();
+ reportedPrinters.addAll(session.getPrinters());
+ }
+ });
+
+ final int reportedPrinterCount = reportedPrinters.size();
+ for (int i = 0; i < reportedPrinterCount; i++) {
+ PrinterInfo reportedPrinter = reportedPrinters.get(i);
+ String localId = reportedPrinter.getId().getLocalId();
+ if (printerLocalId.equals(localId)) {
+ return reportedPrinter.getId();
+ }
+ }
+
+ return null;
+ }
+
+ private PrintServiceCallbacks createSecondMockPrintServiceCallbacks() {
+ return createMockPrintServiceCallbacks(null, null, null);
+ }
+
+ private PrinterDiscoverySessionCallbacks createFirstMockPrinterDiscoverySessionCallbacks() {
+ return createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ // Get the session.
+ StubbablePrinterDiscoverySession session = ((PrinterDiscoverySessionCallbacks)
+ invocation.getMock()).getSession();
+
+ if (session.getPrinters().isEmpty()) {
+ List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+
+ // Add the first printer.
+ PrinterId firstPrinterId = session.getService().generatePrinterId(
+ FIRST_PRINTER_LOCAL_ID);
+ PrinterInfo firstPrinter = new PrinterInfo.Builder(firstPrinterId,
+ FIRST_PRINTER_NAME, PrinterInfo.STATUS_IDLE)
+ .build();
+ printers.add(firstPrinter);
+
+ // Add the first printer.
+ PrinterId secondPrinterId = session.getService().generatePrinterId(
+ SECOND_PRINTER_LOCAL_ID);
+ PrinterInfo secondPrinter = new PrinterInfo.Builder(secondPrinterId,
+ SECOND_PRINTER_NAME, PrinterInfo.STATUS_IDLE)
+ .build();
+ printers.add(secondPrinter);
+
+ session.addPrinters(printers);
+ }
+ return null;
+ }
+ }, null, null, new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ // Get the session.
+ StubbablePrinterDiscoverySession session = ((PrinterDiscoverySessionCallbacks)
+ invocation.getMock()).getSession();
+
+ PrinterId trackedPrinterId = (PrinterId) invocation.getArguments()[0];
+ List<PrinterInfo> reportedPrinters = session.getPrinters();
+
+ // We should be tracking a printer that we added.
+ PrinterInfo trackedPrinter = null;
+ final int reportedPrinterCount = reportedPrinters.size();
+ for (int i = 0; i < reportedPrinterCount; i++) {
+ PrinterInfo reportedPrinter = reportedPrinters.get(i);
+ if (reportedPrinter.getId().equals(trackedPrinterId)) {
+ trackedPrinter = reportedPrinter;
+ break;
+ }
+ }
+ assertNotNull("Can track only added printers", trackedPrinter);
+
+ // If the printer does not have capabilities reported add them.
+ if (trackedPrinter.getCapabilities() == null) {
+
+ // Add the capabilities to emulate lazy discovery.
+ // Same for each printer is fine for what we test.
+ PrinterCapabilitiesInfo capabilities =
+ new PrinterCapabilitiesInfo.Builder(trackedPrinterId)
+ .setMinMargins(new Margins(200, 200, 200, 200))
+ .addMediaSize(MediaSize.ISO_A4, true)
+ .addMediaSize(MediaSize.ISO_A5, false)
+ .addResolution(new Resolution("300x300", "300x300", 300, 300), true)
+ .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+ PrintAttributes.COLOR_MODE_COLOR)
+ .build();
+ PrinterInfo updatedPrinter = new PrinterInfo.Builder(trackedPrinter)
+ .setCapabilities(capabilities)
+ .build();
+
+ // Update the printer.
+ List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+ printers.add(updatedPrinter);
+ session.addPrinters(printers);
+ }
+
+ return null;
+ }
+ }, null, new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ // Take a note onDestroy was called.
+ onPrinterDiscoverySessionDestroyCalled();
+ return null;
+ }
+ });
+ }
+
+ public PrintDocumentAdapter createMockPrintDocumentAdapter() {
+ return createMockPrintDocumentAdapter(
+ new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
+ PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
+ .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+ .setPageCount(3)
+ .build();
+ callback.onLayoutFinished(info, false);
+ // Mark layout was called.
+ onLayoutCalled();
+ return null;
+ }
+ }, new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ Object[] args = invocation.getArguments();
+ PageRange[] pages = (PageRange[]) args[0];
+ ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+ WriteResultCallback callback = (WriteResultCallback) args[3];
+ fd.close();
+ callback.onWriteFinished(pages);
+ // Mark write was called.
+ onWriteCalled();
+ return null;
+ }
+ }, new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ // Mark finish was called.
+ onFinishCalled();
+ return null;
+ }
+ });
+ }
+}