Merge "Add test for android.media.AudioTrack.setVolume(float)"
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 b03d591..f05111b 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCaptureResultTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCaptureResultTest.java
@@ -274,6 +274,7 @@
         ArrayList<CameraMetadata.Key<?>> resultKeys = new ArrayList<CameraMetadata.Key<?>>();
         resultKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM);
         resultKeys.add(CaptureResult.COLOR_CORRECTION_GAINS);
+        resultKeys.add(CaptureResult.CONTROL_AE_MODE);
         resultKeys.add(CaptureResult.CONTROL_AE_REGIONS);
         resultKeys.add(CaptureResult.CONTROL_AF_MODE);
         resultKeys.add(CaptureResult.CONTROL_AF_REGIONS);
@@ -302,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 1b892ba..d694104 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCharacteristicsTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCharacteristicsTest.java
@@ -80,6 +80,29 @@
         }
     }
 
+    public void testCameraCharacteristicsAndroidControlAeAvailableModes() 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.control.aeAvailableModes",
+                        props.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_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.control.aeAvailableModes", allKeys.contains(
+                        CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES));
+
+            }
+
+        }
+    }
+
     public void testCameraCharacteristicsAndroidControlAeAvailableTargetFpsRanges() throws Exception {
         String[] ids = mCameraManager.getCameraIdList();
         for (int i = 0; i < ids.length; i++) {
@@ -540,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++) {
@@ -755,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++) {
@@ -961,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/DecodeEditEncodeTest.java b/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
index 0d83647..e74a64a 100644
--- a/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
+++ b/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
@@ -149,7 +149,8 @@
     /**
      * Tests editing of a video file with GL.
      */
-    private void videoEditTest() {
+    private void videoEditTest()
+            throws IOException {
         VideoChunks sourceChunks = new VideoChunks();
 
         if (!generateVideoFile(sourceChunks)) {
@@ -182,7 +183,8 @@
      *
      * @return true on success, false on "soft" failure
      */
-    private boolean generateVideoFile(VideoChunks output) {
+    private boolean generateVideoFile(VideoChunks output)
+            throws IOException {
         if (VERBOSE) Log.d(TAG, "generateVideoFile " + mWidth + "x" + mHeight);
         MediaCodec encoder = null;
         InputSurface inputSurface = null;
@@ -393,7 +395,8 @@
      * for output and a Surface for input, we can avoid issues with obscure formats and can
      * use a fragment shader to do transformations.
      */
-    private VideoChunks editVideoFile(VideoChunks inputData) {
+    private VideoChunks editVideoFile(VideoChunks inputData)
+            throws IOException {
         if (VERBOSE) Log.d(TAG, "editVideoFile " + mWidth + "x" + mHeight);
         VideoChunks outputData = new VideoChunks();
         MediaCodec decoder = null;
@@ -613,7 +616,8 @@
      * Checks the video file to see if the contents match our expectations.  We decode the
      * video to a Surface and check the pixels with GL.
      */
-    private void checkVideoFile(VideoChunks inputData) {
+    private void checkVideoFile(VideoChunks inputData)
+            throws IOException {
         OutputSurface surface = null;
         MediaCodec decoder = null;
 
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index eda4546..c4c8465 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -679,21 +679,25 @@
     }
 
     private static MediaCodec createDecoder(String mime) {
-        if (false) {
-            // change to force testing software codecs
-            if (mime.contains("avc")) {
-                return MediaCodec.createByCodecName("OMX.google.h264.decoder");
-            } else if (mime.contains("3gpp")) {
-                return MediaCodec.createByCodecName("OMX.google.h263.decoder");
-            } else if (mime.contains("mp4v")) {
-                return MediaCodec.createByCodecName("OMX.google.mpeg4.decoder");
-            } else if (mime.contains("vp8")) {
-                return MediaCodec.createByCodecName("OMX.google.vp8.decoder");
-            } else if (mime.contains("vp9")) {
-                return MediaCodec.createByCodecName("OMX.google.vp9.decoder");
+        try {
+            if (false) {
+                // change to force testing software codecs
+                if (mime.contains("avc")) {
+                    return MediaCodec.createByCodecName("OMX.google.h264.decoder");
+                } else if (mime.contains("3gpp")) {
+                    return MediaCodec.createByCodecName("OMX.google.h263.decoder");
+                } else if (mime.contains("mp4v")) {
+                    return MediaCodec.createByCodecName("OMX.google.mpeg4.decoder");
+                } else if (mime.contains("vp8")) {
+                    return MediaCodec.createByCodecName("OMX.google.vp8.decoder");
+                } else if (mime.contains("vp9")) {
+                    return MediaCodec.createByCodecName("OMX.google.vp9.decoder");
+                }
             }
+            return MediaCodec.createDecoderByType(mime);
+        } catch (Exception e) {
+            return null;
         }
-        return MediaCodec.createDecoderByType(mime);
     }
 
     // for video
@@ -1162,6 +1166,8 @@
         assertTrue("not an audio file", mime.startsWith("audio/"));
 
         codec = MediaCodec.createDecoderByType(mime);
+        assertNotNull("couldn't find codec " + mime, codec);
+
         codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
         codec.start();
         codecInputBuffers = codec.getInputBuffers();
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
index 9f76ddf..eb06eda 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
@@ -153,7 +153,7 @@
     /**
      * Prepares the encoder, decoder, and virtual display.
      */
-    private void encodeVirtualDisplayTest() {
+    private void encodeVirtualDisplayTest() throws IOException {
         MediaCodec encoder = null;
         MediaCodec decoder = null;
         OutputSurface outputSurface = null;
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index e9d0b5f..c2e59d4 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -187,8 +187,13 @@
     }
 
     private void testEncoder(String componentName, MediaFormat format) {
-        MediaCodec codec = MediaCodec.createByCodecName(componentName);
-
+        MediaCodec codec;
+        try {
+            codec = MediaCodec.createByCodecName(componentName);
+        } catch (Exception e) {
+            fail("codec '" + componentName + "' failed construction.");
+            return; /* does not get here, but avoids warning */
+        }
         try {
             codec.configure(
                     format,
@@ -196,9 +201,7 @@
                     null /* crypto */,
                     MediaCodec.CONFIGURE_FLAG_ENCODE);
         } catch (IllegalStateException e) {
-            Log.e(TAG, "codec '" + componentName + "' failed configuration.");
-
-            assertTrue("codec '" + componentName + "' failed configuration.", false);
+            fail("codec '" + componentName + "' failed configuration.");
         }
 
         codec.start();
diff --git a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
index 81296e4..264a76a 100644
--- a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
+++ b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
@@ -469,7 +469,8 @@
      * @param inputFormat the format of the stream to decode
      * @param surface into which to decode the frames
      */
-    private MediaCodec createVideoDecoder(MediaFormat inputFormat, Surface surface) {
+    private MediaCodec createVideoDecoder(MediaFormat inputFormat, Surface surface)
+            throws IOException {
         MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFor(inputFormat));
         decoder.configure(inputFormat, surface, null, 0);
         decoder.start();
@@ -489,7 +490,8 @@
     private MediaCodec createVideoEncoder(
             MediaCodecInfo codecInfo,
             MediaFormat format,
-            AtomicReference<Surface> surfaceReference) {
+            AtomicReference<Surface> surfaceReference)
+            throws IOException {
         MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
         encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
         // Must be called before start() is.
@@ -503,7 +505,8 @@
      *
      * @param inputFormat the format of the stream to decode
      */
-    private MediaCodec createAudioDecoder(MediaFormat inputFormat) {
+    private MediaCodec createAudioDecoder(MediaFormat inputFormat)
+            throws IOException {
         MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFor(inputFormat));
         decoder.configure(inputFormat, null, null, 0);
         decoder.start();
@@ -516,7 +519,8 @@
      * @param codecInfo of the codec to use
      * @param format of the stream to be produced
      */
-    private MediaCodec createAudioEncoder(MediaCodecInfo codecInfo, MediaFormat format) {
+    private MediaCodec createAudioEncoder(MediaCodecInfo codecInfo, MediaFormat format) 
+            throws IOException {
         MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
         encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
         encoder.start();
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
index 3428e86..9c07cf1 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
@@ -26,6 +26,7 @@
 import android.util.Log;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.List;
 import java.util.ArrayList;
 
@@ -56,7 +57,7 @@
 
     // Each component advertised by MediaCodecList should at least be
     // instantiate-able.
-    public void testComponentInstantiation() {
+    public void testComponentInstantiation() throws IOException {
         Log.d(TAG, "testComponentInstantiation");
 
         int codecCount = MediaCodecList.getCodecCount();
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index 86d03bf..ae14e6f 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -87,7 +87,11 @@
         format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
 
         try {
-            encoder = MediaCodec.createByCodecName(codecInfo.getName());
+            try {
+                encoder = MediaCodec.createByCodecName(codecInfo.getName());
+            } catch (IOException e) {
+                fail("failed to create codec " + codecInfo.getName());
+            }
             try {
                 surface = encoder.createInputSurface();
                 fail("createInputSurface should not work pre-configure");
@@ -132,7 +136,11 @@
         InputSurface inputSurface = null;
 
         try {
-            encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            try {
+                encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE + " encoder");
+            }
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             inputSurface = new InputSurface(encoder.createInputSurface());
             inputSurface.makeCurrent();
@@ -189,7 +197,11 @@
         InputSurface inputSurface = null;
 
         try {
-            encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            try {
+                encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE + " encoder");
+            }
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             inputSurface = new InputSurface(encoder.createInputSurface());
             inputSurface.makeCurrent();
@@ -231,7 +243,11 @@
         Surface surface = null;
 
         try {
-            encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            try {
+                encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE + " encoder");
+            }
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             surface = encoder.createInputSurface();
             encoder.start();
@@ -265,7 +281,11 @@
         Surface surface = null;
 
         try {
-            encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            try {
+                encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE + " encoder");
+            }
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             surface = encoder.createInputSurface();
             encoder.start();
@@ -415,11 +435,19 @@
         MediaCodec audioDecoderA = null;
         MediaCodec audioDecoderB = null;
         try {
-            audioDecoderA = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            try {
+                audioDecoderA = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            } catch (IOException e) {
+                fail("failed to create first " + MIME_TYPE_AUDIO + " decoder");
+            }
             audioDecoderA.configure(format, null, null, 0);
             audioDecoderA.start();
 
-            audioDecoderB = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            try {
+                audioDecoderB = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            } catch (IOException e) {
+                fail("failed to create second " + MIME_TYPE_AUDIO + " decoder");
+            }
             audioDecoderB.configure(format, null, null, 0);
             audioDecoderB.start();
         } finally {
@@ -457,11 +485,19 @@
         MediaCodec audioEncoder = null;
         MediaCodec audioDecoder = null;
         try {
-            audioEncoder = MediaCodec.createEncoderByType(MIME_TYPE_AUDIO);
+            try {
+                audioEncoder = MediaCodec.createEncoderByType(MIME_TYPE_AUDIO);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE_AUDIO + " encoder");
+            }
             audioEncoder.configure(encoderFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             audioEncoder.start();
 
-            audioDecoder = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            try {
+                audioDecoder = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE_AUDIO + " decoder");
+            }
             audioDecoder.configure(decoderFormat, null, null, 0);
             audioDecoder.start();
         } finally {
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/net/Android.mk b/tests/tests/net/Android.mk
index 9647df1..1653335 100644
--- a/tests/tests/net/Android.mk
+++ b/tests/tests/net/Android.mk
@@ -30,7 +30,8 @@
 
 LOCAL_PACKAGE_NAME := CtsNetTestCases
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner \
+                               core-tests-support
 
 # uncomment when dalvik.annotation.Test* are removed or part of SDK
 #LOCAL_SDK_VERSION := current
diff --git a/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
index ceb74d1..cb8aeaf 100644
--- a/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
+++ b/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
@@ -28,6 +28,8 @@
 
 import dalvik.annotation.BrokenTest;
 
+import libcore.javax.net.ssl.SSLDefaultConfigurationAsserts;
+
 public class SSLCertificateSocketFactoryTest extends AndroidTestCase {
     private SSLCertificateSocketFactory mFactory;
     private int mTimeout;
@@ -39,6 +41,10 @@
         mFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(mTimeout);
     }
 
+    public void testDefaultConfiguration() throws Exception {
+        SSLDefaultConfigurationAsserts.assertSSLSocketFactory(mFactory);
+    }
+
     public void testAccessProperties() throws Exception {
         mFactory.getSupportedCipherSuites();
         mFactory.getDefaultCipherSuites();
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 56b3233..4c94fd5 100644
--- a/tests/tests/print/AndroidManifest.xml
+++ b/tests/tests/print/AndroidManifest.xml
@@ -17,15 +17,13 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.print"
-        android:versionCode="1"
-        android:versionName="1">
+        package="com.android.cts.print">
 
     <application android:allowBackup="false" >
 
         <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"
@@ -71,7 +69,7 @@
 
   </application>
 
-  <instrumentation android:name="com.android.uiautomator.testrunner.UiAutomatorInstrumentationTestRunner"
+  <instrumentation android:name="android.support.test.uiautomator.UiAutomatorInstrumentationTestRunner"
           android:targetPackage="com.android.cts.print"
           android:label="Tests for the print APIs."/>
 
diff --git a/tests/tests/print/src/android/print/cts/BasePrintTest.java b/tests/tests/print/src/android/print/cts/BasePrintTest.java
new file mode 100644
index 0000000..d193bb0
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/BasePrintTest.java
@@ -0,0 +1,382 @@
+/*
+ * 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.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentAdapter.LayoutResultCallback;
+import android.print.PrintDocumentAdapter.WriteResultCallback;
+import android.print.PrintManager;
+import android.print.PrinterId;
+import android.print.cts.services.PrintServiceCallbacks;
+import android.print.cts.services.PrinterDiscoverySessionCallbacks;
+import android.print.cts.services.StubbablePrinterDiscoverySession;
+import android.printservice.PrintJob;
+import android.printservice.PrintService;
+import android.support.test.uiautomator.UiAutomatorTestCase;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiSelector;
+import android.util.DisplayMetrics;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.mockito.InOrder;
+import org.mockito.stubbing.Answer;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * This is the base class for print tests.
+ */
+public abstract class BasePrintTest extends UiAutomatorTestCase {
+
+    private static final long OPERATION_TIMEOUT = 10000;
+
+    private static final String ARG_PRIVILEGED_OPS = "ARG_PRIVILEGED_OPS";
+
+    private static final String PRINT_SPOOLER_PACKAGE_NAME = "com.android.printspooler";
+
+    protected static final String PRINT_JOB_NAME = "Test";
+
+    private PrintDocumentActivity mActivity;
+
+    private Locale mOldLocale;
+
+    private CallCounter mLayoutCallCounter;
+    private CallCounter mWriteCallCounter;
+    private CallCounter mFinishCallCounter;
+    private CallCounter mPrintJobQueuedCallCounter;
+    private CallCounter mDestroySessionCallCounter;
+
+    @Override
+    public void setUp() throws Exception {
+        // Make sure we start with a clean slate.
+        clearPrintSpoolerData();
+
+        // Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2
+        // Dexmaker is used by mockito.
+        System.setProperty("dexmaker.dexcache", getInstrumentation()
+                .getTargetContext().getCacheDir().getPath());
+
+        // Set to US locale.
+        Resources resources = getInstrumentation().getTargetContext().getResources();
+        Configuration oldConfiguration = resources.getConfiguration();
+        if (!oldConfiguration.locale.equals(Locale.US)) {
+            mOldLocale = oldConfiguration.locale;
+            DisplayMetrics displayMetrics = resources.getDisplayMetrics();
+            Configuration newConfiguration = new Configuration(oldConfiguration);
+            newConfiguration.locale = Locale.US;
+            resources.updateConfiguration(newConfiguration, displayMetrics);
+        }
+
+        // Initialize the latches.
+        mLayoutCallCounter = new CallCounter();
+        mFinishCallCounter = new CallCounter();
+        mWriteCallCounter = new CallCounter();
+        mFinishCallCounter = new CallCounter();
+        mPrintJobQueuedCallCounter = new CallCounter();
+        mDestroySessionCallCounter = new CallCounter();
+
+        // Create the activity for the right locale.
+        createActivity();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        // Done with the activity.
+        getActivity().finish();
+
+        // Restore the locale if needed.
+        if (mOldLocale != null) {
+            Resources resources = getInstrumentation().getTargetContext().getResources();
+            DisplayMetrics displayMetrics = resources.getDisplayMetrics();
+            Configuration newConfiguration = new Configuration(resources.getConfiguration());
+            newConfiguration.locale = mOldLocale;
+            mOldLocale = null;
+            resources.updateConfiguration(newConfiguration, displayMetrics);
+        }
+
+        // Make sure the spooler is cleaned.
+        clearPrintSpoolerData();
+    }
+
+    protected void print(final PrintDocumentAdapter adapter) {
+        // Initiate printing as if coming from the app.
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                PrintManager printManager = (PrintManager) getActivity()
+                        .getSystemService(Context.PRINT_SERVICE);
+                printManager.print("Print job", adapter, null);
+            }
+        });
+    }
+
+    protected void onLayoutCalled() {
+        mLayoutCallCounter.call();
+    }
+
+    protected void onWriteCalled() {
+        mWriteCallCounter.call();
+    }
+
+    protected void onFinishCalled() {
+        mFinishCallCounter.call();
+    }
+
+    protected void onPrintJobQueuedCalled() {
+        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 waitForAdapterFinishCallbackCalled() {
+        waitForCallbackCallCount(mFinishCallCounter, 1,
+                "Did not get expected call to finish.");
+    }
+
+    protected void waitForLayoutAdapterCallbackCount(int count) {
+        waitForCallbackCallCount(mLayoutCallCounter, count,
+                "Did not get expected call to layout.");
+    }
+
+    protected void waitForWriteForAdapterCallback() {
+        waitForCallbackCallCount(mWriteCallCounter, 1, "Did not get expected call to write.");
+    }
+
+    private void waitForCallbackCallCount(CallCounter counter, int count, String message) {
+        try {
+            counter.waitForCount(count, OPERATION_TIMEOUT);
+        } catch (TimeoutException te) {
+            fail(message);
+        }
+    }
+
+    protected void selectPrinter(String printerName) throws UiObjectNotFoundException {
+        UiObject destinationSpinner = new UiObject(new UiSelector().resourceId(
+                "com.android.printspooler:id/destination_spinner"));
+        destinationSpinner.click();
+        UiObject printerOption = new UiObject(new UiSelector().text(printerName));
+        printerOption.click();
+    }
+
+    protected void changeOrientation(String orientation) throws UiObjectNotFoundException {
+        UiObject orientationSpinner = new UiObject(new UiSelector().resourceId(
+                "com.android.printspooler:id/orientation_spinner"));
+        orientationSpinner.click();
+        UiObject orientationOption = new UiObject(new UiSelector().text(orientation));
+        orientationOption.click();
+    }
+
+    protected void changeMediaSize(String mediaSize) throws UiObjectNotFoundException {
+        UiObject mediaSizeSpinner = new UiObject(new UiSelector().resourceId(
+                "com.android.printspooler:id/paper_size_spinner"));
+        mediaSizeSpinner.click();
+        UiObject mediaSizeOption = new UiObject(new UiSelector().text(mediaSize));
+        mediaSizeOption.click();
+    }
+
+    protected void changeColor(String color) throws UiObjectNotFoundException {
+        UiObject colorSpinner = new UiObject(new UiSelector().resourceId(
+                "com.android.printspooler:id/color_spinner"));
+        colorSpinner.click();
+        UiObject colorOption = new UiObject(new UiSelector().text(color));
+        colorOption.click();
+    }
+
+    protected void clickPrintButton() throws UiObjectNotFoundException {
+        UiObject printButton = new UiObject(new UiSelector().resourceId(
+                "com.android.printspooler:id/print_button"));
+        printButton.click();
+    }
+
+    protected PrintDocumentActivity getActivity() {
+        return mActivity;
+    }
+
+    private void createActivity() {
+        mActivity = launchActivity(
+                getInstrumentation().getTargetContext().getPackageName(),
+                PrintDocumentActivity.class, null);
+    }
+
+    protected void clearPrintSpoolerData() throws Exception {
+        IPrivilegedOperations privilegedOps = IPrivilegedOperations.Stub.asInterface(
+                getParams().getBinder(ARG_PRIVILEGED_OPS));
+        privilegedOps.clearApplicationUserData(PRINT_SPOOLER_PACKAGE_NAME);
+    }
+
+    protected void verifyLayoutCall(InOrder inOrder, PrintDocumentAdapter mock,
+            PrintAttributes oldAttributes, PrintAttributes newAttributes,
+            final boolean forPreview) {
+        inOrder.verify(mock).onLayout(eq(oldAttributes), eq(newAttributes),
+                any(CancellationSignal.class), any(LayoutResultCallback.class), argThat(
+                        new BaseMatcher<Bundle>() {
+                            @Override
+                            public boolean matches(Object item) {
+                                Bundle bundle = (Bundle) item;
+                                return forPreview == bundle.getBoolean(
+                                        PrintDocumentAdapter.EXTRA_PRINT_PREVIEW);
+                            }
+
+                            @Override
+                            public void describeTo(Description description) {
+                                /* do nothing */
+                            }
+                        }));
+    }
+
+    protected PrintDocumentAdapter createMockPrintDocumentAdapter(Answer<Void> layoutAnswer,
+            Answer<Void> writeAnswer, Answer<Void> finishAnswer) {
+        // Create a mock print adapter.
+        PrintDocumentAdapter adapter = mock(PrintDocumentAdapter.class);
+        if (layoutAnswer != null) {
+            doAnswer(layoutAnswer).when(adapter).onLayout(any(PrintAttributes.class),
+                    any(PrintAttributes.class), any(CancellationSignal.class),
+                    any(LayoutResultCallback.class), any(Bundle.class));
+        }
+        if (writeAnswer != null) {
+            doAnswer(writeAnswer).when(adapter).onWrite(any(PageRange[].class),
+                    any(ParcelFileDescriptor.class), any(CancellationSignal.class),
+                    any(WriteResultCallback.class));
+        }
+        if (finishAnswer != null) {
+            doAnswer(finishAnswer).when(adapter).onFinish();
+        }
+        return adapter;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected PrinterDiscoverySessionCallbacks createMockPrinterDiscoverySessionCallbacks(
+            Answer<Void> onStartPrinterDiscovery, Answer<Void> onStopPrinterDiscovery,
+            Answer<Void> onValidatePrinters, Answer<Void> onStartPrinterStateTracking,
+            Answer<Void> onStopPrinterStateTracking, Answer<Void> onDestroy) {
+        PrinterDiscoverySessionCallbacks callbacks = mock(PrinterDiscoverySessionCallbacks.class);
+
+        doCallRealMethod().when(callbacks).setSession(any(StubbablePrinterDiscoverySession.class));
+        when(callbacks.getSession()).thenCallRealMethod();
+
+        if (onStartPrinterDiscovery != null) {
+            doAnswer(onStartPrinterDiscovery).when(callbacks).onStartPrinterDiscovery(
+                    any(List.class));
+        }
+        if (onStopPrinterDiscovery != null) {
+            doAnswer(onStopPrinterDiscovery).when(callbacks).onStopPrinterDiscovery();
+        }
+        if (onValidatePrinters != null) {
+            doAnswer(onValidatePrinters).when(callbacks).onValidatePrinters(
+                    any(List.class));
+        }
+        if (onStartPrinterStateTracking != null) {
+            doAnswer(onStartPrinterStateTracking).when(callbacks).onStartPrinterStateTracking(
+                    any(PrinterId.class));
+        }
+        if (onStopPrinterStateTracking != null) {
+            doAnswer(onStopPrinterStateTracking).when(callbacks).onStopPrinterStateTracking(
+                    any(PrinterId.class));
+        }
+        if (onDestroy != null) {
+            doAnswer(onDestroy).when(callbacks).onDestroy();
+        }
+
+        return callbacks;
+    }
+
+    protected PrintServiceCallbacks createMockPrintServiceCallbacks(
+            Answer<PrinterDiscoverySessionCallbacks> onCreatePrinterDiscoverySessionCallbacks,
+            Answer<Void> onPrintJobQueued, Answer<Void> onRequestCancelPrintJob) {
+        final PrintServiceCallbacks service = mock(PrintServiceCallbacks.class);
+
+        doCallRealMethod().when(service).setService(any(PrintService.class));
+        when(service.getService()).thenCallRealMethod();
+
+        if (onCreatePrinterDiscoverySessionCallbacks != null) {
+            doAnswer(onCreatePrinterDiscoverySessionCallbacks).when(service)
+                    .onCreatePrinterDiscoverySessionCallbacks();
+        }
+        if (onPrintJobQueued != null) {
+            doAnswer(onPrintJobQueued).when(service).onPrintJobQueued(any(PrintJob.class));
+        }
+        if (onRequestCancelPrintJob != null) {
+            doAnswer(onRequestCancelPrintJob).when(service).onRequestCancelPrintJob(
+                    any(PrintJob.class));
+        }
+
+        return service;
+    }
+
+    protected final class CallCounter {
+        private final Object mLock = new Object();
+
+        private int mCallCount;
+
+        public void call() {
+            synchronized (mLock) {
+                mCallCount++;
+            }
+        }
+
+        public void waitForCount(int count, long timeoutMIllis) throws TimeoutException {
+            synchronized (mLock) {
+                final long startTimeMillis = SystemClock.uptimeMillis();
+                while (mCallCount < count) {
+                    try {
+                        final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
+                        final long remainingTimeMillis = timeoutMIllis - elapsedTimeMillis;
+                        if (remainingTimeMillis <= 0) {
+                            throw new TimeoutException();
+                        }
+                        mLock.wait(timeoutMIllis);
+                    } catch (InterruptedException ie) {
+                        /* ignore */
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java b/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
new file mode 100644
index 0000000..d3d5a4c
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
@@ -0,0 +1,510 @@
+/*
+ * 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.Matchers.any;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+
+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.PrintService;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiSelector;
+
+import org.mockito.InOrder;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This test verifies that the system correctly adjust the
+ * page ranges to be printed depending whether the app gave
+ * the requested pages, more pages, etc.
+ */
+public class PageRangeAdjustmentTest extends BasePrintTest {
+
+    private static final String FIRST_PRINTER = "First printer";
+
+    public void testAllPagesWantedAndAllPagesWritten() throws Exception {
+        // Create a callback for the target print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+            new Answer<PrinterDiscoverySessionCallbacks>() {
+            @Override
+            public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                    return createMockFirstPrinterDiscoverySessionCallbacks();
+                }
+            },
+            new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) {
+                PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+                PageRange[] pages = printJob.getInfo().getPages();
+                assert(pages.length == 1 && PageRange.ALL_PAGES.equals(pages[0]));
+                printJob.complete();
+                onPrintJobQueuedCalled();
+                return null;
+            }
+        }, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+        // Create a mock print adapter.
+        final PrintDocumentAdapter adapter = 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;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback();
+
+        // Select the first printer.
+        selectPrinter(FIRST_PRINTER);
+
+        // Wait for layout as the printer has different capabilities.
+        waitForLayoutAdapterCallbackCount(2);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for finish.
+        waitForAdapterFinishCallbackCalled();
+
+        // Wait for the print job.
+        waitForServiceOnPrintJobQueuedCallbackCalled();
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(firstServiceCallbacks);
+
+        // We create a new session first.
+        inOrder.verify(firstServiceCallbacks)
+                .onCreatePrinterDiscoverySessionCallbacks();
+
+        // Next we wait for a call with the print job.
+        inOrder.verify(firstServiceCallbacks).onPrintJobQueued(
+                any(PrintJob.class));
+    }
+
+    public void testSomePagesWantedAndAllPagesWritten() throws Exception {
+        // Create a callback for the target print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+            new Answer<PrinterDiscoverySessionCallbacks>() {
+            @Override
+            public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                    return createMockFirstPrinterDiscoverySessionCallbacks();
+                }
+            },
+            new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) {
+                PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+                PageRange[] pages = printJob.getInfo().getPages();
+                // We always as for the first page for preview and in this
+                // case we write all, i.e. more that needed.
+                assertTrue(pages.length == 1 && pages[0].getStart() == 1
+                        && pages[0].getEnd() == 1);
+                printJob.complete();
+                onPrintJobQueuedCalled();
+                return null;
+            }
+        }, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+        // Create a mock print adapter.
+        final PrintDocumentAdapter adapter = 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();
+                ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                WriteResultCallback callback = (WriteResultCallback) args[3];
+                fd.close();
+                callback.onWriteFinished(new PageRange[] {PageRange.ALL_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;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback();
+
+        // Select the first printer.
+        selectPrinter(FIRST_PRINTER);
+
+        // Wait for layout as the printer has different capabilities.
+        waitForLayoutAdapterCallbackCount(2);
+
+        // Select only the second page.
+        selectPages("2");
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for finish.
+        waitForAdapterFinishCallbackCalled();
+
+        // Wait for the print job.
+        waitForServiceOnPrintJobQueuedCallbackCalled();
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(firstServiceCallbacks);
+
+        // We create a new session first.
+        inOrder.verify(firstServiceCallbacks)
+                .onCreatePrinterDiscoverySessionCallbacks();
+
+        // Next we wait for a call with the print job.
+        inOrder.verify(firstServiceCallbacks).onPrintJobQueued(
+                any(PrintJob.class));
+    }
+
+    public void testSomePagesWantedAndSomeMorePagesWritten() throws Exception {
+        // Create a callback for the target print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+            new Answer<PrinterDiscoverySessionCallbacks>() {
+            @Override
+            public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                    return createMockFirstPrinterDiscoverySessionCallbacks();
+                }
+            },
+            new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) {
+                PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+                PageRange[] pages = printJob.getInfo().getPages();
+                assert(pages.length == 1 && pages[0].getStart() == 1
+                        && pages[0].getEnd() == 2);
+                printJob.complete();
+                onPrintJobQueuedCalled();
+                return null;
+            }
+        }, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+        // Create a mock print adapter.
+        final PrintDocumentAdapter adapter = 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];
+                // We expect a single range as it is either the first page
+                // or the page we selected in the UI.
+                assertSame(pages.length, 1);
+                fd.close();
+
+                PageRange reqeustedPages = pages[0];
+                if (reqeustedPages.getStart() == reqeustedPages.getEnd()
+                        && reqeustedPages.getEnd() == 0) {
+                    // If asked for the first page, which is for preview
+                    // then write it...
+                    callback.onWriteFinished(pages);
+                } else {
+                    // otherwise write a page more that the one we selected.
+                    callback.onWriteFinished(new PageRange[] {new PageRange(2, 3)});
+                }
+                // 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;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback();
+
+        // Select the first printer.
+        selectPrinter(FIRST_PRINTER);
+
+        // Wait for layout as the printer has different capabilities.
+        waitForLayoutAdapterCallbackCount(2);
+
+        // Select only the third page.
+        selectPages("3");
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for finish.
+        waitForAdapterFinishCallbackCalled();
+
+        // Wait for the print job.
+        waitForServiceOnPrintJobQueuedCallbackCalled();
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(firstServiceCallbacks);
+
+        // We create a new session first.
+        inOrder.verify(firstServiceCallbacks)
+                .onCreatePrinterDiscoverySessionCallbacks();
+
+        // Next we wait for a call with the print job.
+        inOrder.verify(firstServiceCallbacks).onPrintJobQueued(
+                any(PrintJob.class));
+    }
+
+    public void testSomePagesWantedAndNotWritten() throws Exception {
+        // Create a callback for the target print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+            new Answer<PrinterDiscoverySessionCallbacks>() {
+            @Override
+            public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                    return createMockFirstPrinterDiscoverySessionCallbacks();
+                }
+            },
+            null, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+        // Create a mock print adapter.
+        final PrintDocumentAdapter adapter = 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];
+                assertSame(pages.length, 1);
+                fd.close();
+
+                // We should be asked for the first page...
+                assertSame(pages[0].getStart(), 0);
+                assertSame(pages[0].getEnd(), 0);
+
+                // ...just write a the wring page.
+                callback.onWriteFinished(new PageRange[] {new PageRange(1, 1)});
+
+                // 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;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback();
+
+        // Cancel printing.
+        UiDevice.getInstance().pressBack(); // wakes up the device.
+        UiDevice.getInstance().pressBack();
+
+        // Wait for finish.
+        waitForAdapterFinishCallbackCalled();
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(firstServiceCallbacks);
+
+        // We create a new session first.
+        inOrder.verify(firstServiceCallbacks)
+                .onCreatePrinterDiscoverySessionCallbacks();
+
+        // We should not receive a print job callback.
+        inOrder.verify(firstServiceCallbacks, never()).onPrintJobQueued(
+                any(PrintJob.class));
+    }
+
+    private void selectPages(String pages) throws UiObjectNotFoundException {
+        UiObject pagesSpinner = new UiObject(new UiSelector().resourceId(
+                "com.android.printspooler:id/range_options_spinner"));
+        pagesSpinner.click();
+
+        UiObject rangeOption = new UiObject(new UiSelector().text("Range"));
+        rangeOption.click();
+
+        UiObject pagesEditText = new UiObject(new UiSelector().resourceId(
+                "com.android.printspooler:id/page_range_edittext"));
+        pagesEditText.setText(pages);
+    }
+
+    private PrinterDiscoverySessionCallbacks createMockFirstPrinterDiscoverySessionCallbacks() {
+        return createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) {
+                PrinterDiscoverySessionCallbacks mock = (PrinterDiscoverySessionCallbacks)
+                        invocation.getMock();
+
+                StubbablePrinterDiscoverySession session = mock.getSession();
+                PrintService service = session.getService();
+
+                if (session.getPrinters().isEmpty()) {
+                          List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+
+                    // Add one printer.
+                    PrinterId firstPrinterId = service.generatePrinterId("first_printer");
+                    PrinterCapabilitiesInfo firstCapabilities =
+                            new PrinterCapabilitiesInfo.Builder(firstPrinterId)
+                        .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 firstPrinter = new PrinterInfo.Builder(firstPrinterId,
+                            FIRST_PRINTER, PrinterInfo.STATUS_IDLE)
+                        .setCapabilities(firstCapabilities)
+                        .build();
+                    printers.add(firstPrinter);
+
+                    session.addPrinters(printers);
+                }
+
+                return null;
+            }
+        }, null, null, null, null, null);
+    }
+
+    private PrintServiceCallbacks createSecondMockPrintServiceCallbacks() {
+        return createMockPrintServiceCallbacks(null, null, null);
+    }
+}
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 14a4ae1..57eae3f 100644
--- a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
@@ -17,21 +17,13 @@
 package android.print.cts;
 
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.CancellationSignal.OnCancelListener;
 import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
 import android.print.PageRange;
 import android.print.PrintAttributes;
 import android.print.PrintAttributes.Margins;
@@ -41,25 +33,18 @@
 import android.print.PrintDocumentAdapter.LayoutResultCallback;
 import android.print.PrintDocumentAdapter.WriteResultCallback;
 import android.print.PrintDocumentInfo;
-import android.print.PrintManager;
 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.StubPrintService;
+import android.print.cts.services.StubbablePrinterDiscoverySession;
 import android.printservice.PrintJob;
-import android.printservice.PrinterDiscoverySession;
-import android.util.DisplayMetrics;
-
-import android.support.test.uiautomator.UiAutomatorTestCase;
+import android.printservice.PrintService;
 import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.support.test.uiautomator.UiSelector;
 
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
 import org.mockito.InOrder;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
@@ -67,77 +52,17 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.TimeoutException;
 
 /**
  * This test verifies that the system respects the {@link PrintDocumentAdapter}
  * contract and invokes all callbacks as expected.
  */
-public class PrintDocumentAdapterContractTest extends UiAutomatorTestCase {
-
-    private static final long OPERATION_TIMEOUT = 10000;
-
-    private static final String ARG_PRIVILEGED_OPS = "ARG_PRIVILEGED_OPS";
-
-    private static final String PRINT_SPOOLER_PACKAGE_NAME = "com.android.printspooler";
-
-    private PrintDocumentAdapterContractActivity mActivity;
-
-    private Locale mOldLocale;
-
-    @Override
-    public void setUp() throws Exception {
-        // Make sure we start with a clean slate.
-        clearPrintSpoolerData();
-
-        // Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2
-        // Dexmaker is used by mockito.
-        System.setProperty("dexmaker.dexcache", getInstrumentation()
-                .getTargetContext().getCacheDir().getPath());
-
-        // Set to US locale.
-        Resources resources = getInstrumentation().getTargetContext().getResources();
-        Configuration oldConfiguration = resources.getConfiguration();
-        if (!oldConfiguration.locale.equals(Locale.US)) {
-            mOldLocale = oldConfiguration.locale;
-            DisplayMetrics displayMetrics = resources.getDisplayMetrics();
-            Configuration newConfiguration = new Configuration(oldConfiguration);
-            newConfiguration.locale = Locale.US;
-            resources.updateConfiguration(newConfiguration, displayMetrics);
-        }
-
-        // Create the activity for the right locale.
-        createActivity();
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        // Done with the activity.
-        getActivity().finish();
-
-        // Restore the locale if needed.
-        if (mOldLocale != null) {
-            Resources resources = getInstrumentation().getTargetContext().getResources();
-            DisplayMetrics displayMetrics = resources.getDisplayMetrics();
-            Configuration newConfiguration = new Configuration(resources.getConfiguration());
-            newConfiguration.locale = mOldLocale;
-            mOldLocale = null;
-            resources.updateConfiguration(newConfiguration, displayMetrics);
-        }
-
-        // Make sure the spooler is cleaned.
-        clearPrintSpoolerData();
-    }
+public class PrintDocumentAdapterContractTest extends BasePrintTest {
 
     public void testNoPrintOptionsOrPrinterChange() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter layoutCallCounter = new CallCounter();
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -145,11 +70,12 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
                         .build();
                 callback.onLayoutFinished(info, false);
-                layoutCallCounter.call();
+                // Mark layout was called.
+                onLayoutCalled();
                 return null;
             }
         }, new Answer<Void>() {
@@ -162,14 +88,14 @@
                 fd.close();
                 callback.onWriteFinished(pages);
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -178,19 +104,19 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Select the second printer.
         selectPrinter("Second printer");
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 2);
+        waitForLayoutAdapterCallbackCount(2);
 
         // Click the print button.
         clickPrintButton();
 
         // Wait for finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -244,11 +170,8 @@
 
     public void testNoPrintOptionsOrPrinterChangeCanceled() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -257,7 +180,7 @@
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback)
                         invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                     .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                     .setPageCount(1)
                     .build();
@@ -274,14 +197,14 @@
                 fd.close();
                 callback.onWriteFinished(pages);
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -290,13 +213,14 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Cancel the printing.
+        UiDevice.getInstance().pressBack(); // wakes up the device.
         UiDevice.getInstance().pressBack();
 
         // Wait for finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -329,12 +253,8 @@
 
     public void testPrintOptionsChangeAndNoPrinterChange() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter layoutCallCounter = new CallCounter();
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -343,13 +263,13 @@
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback)
                         invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                     .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                     .setPageCount(1)
                     .build();
                 callback.onLayoutFinished(info, false);
                 // Mark layout was called.
-                layoutCallCounter.call();
+                onLayoutCalled();
                 return null;
             }
         }, new Answer<Void>() {
@@ -362,14 +282,14 @@
                 fd.close();
                 callback.onWriteFinished(pages);
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -378,37 +298,37 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Select the second printer.
         selectPrinter("Second printer");
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 2);
+        waitForLayoutAdapterCallbackCount(2);
 
         // Change the orientation.
         changeOrientation("Landscape");
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 3);
+        waitForLayoutAdapterCallbackCount(3);
 
         // Change the media size.
         changeMediaSize("ISO A4");
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 4);
+        waitForLayoutAdapterCallbackCount(4);
 
         // Change the color.
         changeColor("Black & White");
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 5);
+        waitForLayoutAdapterCallbackCount(5);
 
         // Click the print button.
         clickPrintButton();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -498,12 +418,8 @@
 
     public void testPrintOptionsChangeAndPrinterChange() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter layoutCallCounter = new CallCounter();
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -512,13 +428,13 @@
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback)
                         invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                     .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                     .setPageCount(1)
                     .build();
                 callback.onLayoutFinished(info, false);
                 // Mark layout was called.
-                layoutCallCounter.call();
+                onLayoutCalled();
                 return null;
             }
         }, new Answer<Void>() {
@@ -531,14 +447,14 @@
                 fd.close();
                 callback.onWriteFinished(pages);
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -547,32 +463,32 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Select the second printer.
         selectPrinter("Second printer");
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 2);
+        waitForLayoutAdapterCallbackCount(2);
 
         // Change the color.
         changeColor("Black & White");
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 3);
+        waitForLayoutAdapterCallbackCount(3);
 
         // Change the printer to one which supports the current media size.
         // Select the second printer.
         selectPrinter("First printer");
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 4);
+        waitForLayoutAdapterCallbackCount(4);
 
         // Click the print button.
         clickPrintButton();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -649,12 +565,8 @@
     public void testPrintOptionsChangeAndNoPrinterChangeAndContentChange()
             throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter layoutCallCounter = new CallCounter();
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -662,13 +574,13 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
                         .build();
                 // The content changes after every layout.
                 callback.onLayoutFinished(info, true);
                 // Mark layout was called.
-                layoutCallCounter.call();
+                onLayoutCalled();
                 return null;
             }
         }, new Answer<Void>() {
@@ -681,14 +593,14 @@
                 fd.close();
                 callback.onWriteFinished(pages);
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -697,19 +609,19 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Select the second printer.
         selectPrinter("Second printer");
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 2);
+        waitForLayoutAdapterCallbackCount(2);
 
         // Click the print button.
         clickPrintButton();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -765,11 +677,8 @@
 
     public void testNewPrinterSupportsSelectedPrintOptions() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -777,7 +686,7 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
                         .build();
                 // The content changes after every layout.
@@ -794,14 +703,14 @@
                 fd.close();
                 callback.onWriteFinished(pages);
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -810,7 +719,7 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Select the third printer.
         selectPrinter("Third printer");
@@ -819,7 +728,7 @@
         clickPrintButton();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -859,12 +768,8 @@
 
     public void testNothingChangesAllPagesWrittenFirstTime() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter layoutCallCounter = new CallCounter();
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -872,12 +777,12 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(3)
                         .build();
                 callback.onLayoutFinished(info, false);
                 // Mark layout was called.
-                layoutCallCounter.call();
+                onLayoutCalled();
                 return null;
             }
         }, new Answer<Void>() {
@@ -889,14 +794,14 @@
                 fd.close();
                 callback.onWriteFinished(new PageRange[] {PageRange.ALL_PAGES});
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -905,19 +810,19 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Select the second printer.
         selectPrinter("Second printer");
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 2);
+        waitForLayoutAdapterCallbackCount(2);
 
         // Click the print button.
         clickPrintButton();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -972,11 +877,8 @@
 
     public void testCancelLongRunningLayout() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter layoutCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -992,14 +894,14 @@
                         callback.onLayoutCancelled();
                     }
                 });
-                layoutCallCounter.call();
+                onLayoutCalled();
                 return null;
             }
         }, null, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -1008,14 +910,14 @@
         print(adapter);
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 1);
+        waitForLayoutAdapterCallbackCount(1);
 
         // Cancel printing.
         UiDevice.getInstance().pressBack(); // wakes up the device.
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1042,11 +944,8 @@
 
     public void testCancelLongRunningWrite() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -1054,7 +953,7 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
                         .build();
                 callback.onLayoutFinished(info, false);
@@ -1079,14 +978,14 @@
                     }
                 });
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -1095,14 +994,14 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Cancel printing.
         UiDevice.getInstance().pressBack(); // wakes up the device.
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1134,11 +1033,8 @@
 
     public void testFailedLayout() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter layoutCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -1148,14 +1044,14 @@
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
                 callback.onLayoutFailed(null);
                 // Mark layout was called.
-                layoutCallCounter.call();
+                onLayoutCalled();
                 return null;
             }
         }, null, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -1164,14 +1060,14 @@
         print(adapter);
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 1);
+        waitForLayoutAdapterCallbackCount(1);
 
         // Cancel printing.
         UiDevice.getInstance().pressBack(); // wakes up the device.
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1200,11 +1096,8 @@
 
     public void testFailedWrite() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -1212,7 +1105,7 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
                         .build();
                 callback.onLayoutFinished(info, false);
@@ -1227,14 +1120,14 @@
                 fd.close();
                 callback.onWriteFailed(null);
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -1243,14 +1136,14 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Cancel printing.
         UiDevice.getInstance().pressBack(); // wakes up the device.
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1282,11 +1175,8 @@
 
     public void testRequestedPagesNotWritten() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -1294,7 +1184,7 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                       .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
                       .build();
                 callback.onLayoutFinished(info, false);
@@ -1311,14 +1201,14 @@
                 callback.onWriteFinished(new PageRange[] {
                         new PageRange(Integer.MAX_VALUE,Integer.MAX_VALUE)});
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -1327,14 +1217,14 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Cancel printing.
         UiDevice.getInstance().pressBack(); // wakes up the device.
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1366,11 +1256,8 @@
 
     public void testLayoutCallbackNotCalled() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter layoutCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -1379,14 +1266,14 @@
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Break the contract and never call the callback.
                 // Mark layout called.
-                layoutCallCounter.call();
+                onLayoutCalled();
                 return null;
             }
         }, null, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -1395,14 +1282,14 @@
         print(adapter);
 
         // Wait for layout.
-        waitForLayoutAdapterCallbackCount(layoutCallCounter, 1);
+        waitForLayoutAdapterCallbackCount(1);
 
         // Cancel printing.
         UiDevice.getInstance().pressBack(); // wakes up the device.
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1427,13 +1314,10 @@
         verifyNoMoreInteractions(adapter);
     }
 
-    public void testEriteCallbackNotCalled() throws Exception {
+    public void testWriteCallbackNotCalled() throws Exception {
         // Configure the print services.
-        FirstPrintService.setImpl(new SimpleTwoPrintersService());
-        SecondPrintService.setImpl(null);
-
-        final CallCounter writeCallCounter = new CallCounter();
-        final CallCounter finishCallCounter = new CallCounter();
+        FirstPrintService.setCallbacks(createFirstMockPrintServiceCallbacks());
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
 
         // Create a mock print adapter.
         final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
@@ -1441,7 +1325,7 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
-                PrintDocumentInfo info = new PrintDocumentInfo.Builder("Test")
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                         .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
                         .build();
                 callback.onLayoutFinished(info, false);
@@ -1455,14 +1339,14 @@
                 fd.close();
                 // Break the contract and never call the callback.
                 // Mark write was called.
-                writeCallCounter.call();
+                onWriteCalled();
                 return null;
             }
         }, new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 // Mark finish was called.
-                finishCallCounter.call();
+                onFinishCalled();
                 return null;
             }
         });
@@ -1471,14 +1355,14 @@
         print(adapter);
 
         // Wait for write.
-        waitForWriteForAdapterCallback(writeCallCounter);
+        waitForWriteForAdapterCallback();
 
         // Cancel printing.
         UiDevice.getInstance().pressBack(); // wakes up the device.
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish(finishCallCounter);
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1508,260 +1392,91 @@
         verifyNoMoreInteractions(adapter);
     }
 
-    private void print(final PrintDocumentAdapter adapter) {
-        // Initiate printing as if coming from the app.
-        getInstrumentation().runOnMainSync(new Runnable() {
+    private PrintServiceCallbacks createFirstMockPrintServiceCallbacks() {
+        final PrinterDiscoverySessionCallbacks callbacks =
+                createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
             @Override
-            public void run() {
-                PrintManager printManager = (PrintManager) getActivity()
-                        .getSystemService(Context.PRINT_SERVICE);
-                printManager.print("Print job", adapter, null);
+            public Void answer(InvocationOnMock invocation) {
+                PrinterDiscoverySessionCallbacks mock = (PrinterDiscoverySessionCallbacks)
+                        invocation.getMock();
+
+                StubbablePrinterDiscoverySession session = mock.getSession();
+                PrintService service = session.getService();
+
+                if (session.getPrinters().isEmpty()) {
+                    List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+
+                    // Add the first printer.
+                    PrinterId firstPrinterId = service.generatePrinterId("first_printer");
+                    PrinterCapabilitiesInfo firstCapabilities =
+                            new PrinterCapabilitiesInfo.Builder(firstPrinterId)
+                        .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 firstPrinter = new PrinterInfo.Builder(firstPrinterId,
+                            "First printer", PrinterInfo.STATUS_IDLE)
+                        .setCapabilities(firstCapabilities)
+                        .build();
+                    printers.add(firstPrinter);
+
+                    // Add the second printer.
+                    PrinterId secondPrinterId = service.generatePrinterId("second_printer");
+                    PrinterCapabilitiesInfo secondCapabilities =
+                            new PrinterCapabilitiesInfo.Builder(secondPrinterId)
+                        .addMediaSize(MediaSize.ISO_A3, true)
+                        .addMediaSize(MediaSize.ISO_A4, false)
+                        .addResolution(new Resolution("200x200", "200x200", 200, 200), true)
+                        .addResolution(new Resolution("300x300", "300x300", 300, 300), false)
+                        .setColorModes(PrintAttributes.COLOR_MODE_COLOR
+                                | PrintAttributes.COLOR_MODE_MONOCHROME,
+                                PrintAttributes.COLOR_MODE_MONOCHROME)
+                        .build();
+                    PrinterInfo secondPrinter = new PrinterInfo.Builder(secondPrinterId,
+                            "Second printer", PrinterInfo.STATUS_IDLE)
+                        .setCapabilities(secondCapabilities)
+                        .build();
+                    printers.add(secondPrinter);
+
+                    // Add the third printer.
+                    PrinterId thirdPrinterId = service.generatePrinterId("third_printer");
+                    PrinterCapabilitiesInfo thirdCapabilities =
+                            new PrinterCapabilitiesInfo.Builder(thirdPrinterId)
+                        .addMediaSize(MediaSize.NA_LETTER, true)
+                        .addResolution(new Resolution("300x300", "300x300", 300, 300), true)
+                        .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+                                PrintAttributes.COLOR_MODE_COLOR)
+                        .build();
+                    PrinterInfo thirdPrinter = new PrinterInfo.Builder(thirdPrinterId,
+                            "Third printer", PrinterInfo.STATUS_IDLE)
+                        .setCapabilities(thirdCapabilities)
+                        .build();
+                    printers.add(thirdPrinter);
+
+                    session.addPrinters(printers);
+                }
+                return null;
             }
-        });
-    }
-
-    private void waitForAdapterCallbackFinish(CallCounter counter) {
-        waitForCallbackCallCount(counter, 1, "Did not get expected call to finish.");
-    }
-
-    private void waitForLayoutAdapterCallbackCount(CallCounter counter, int count) {
-        waitForCallbackCallCount(counter, count, "Did not get expected call to layout.");
-    }
-
-    private void waitForWriteForAdapterCallback(CallCounter counter) {
-        waitForCallbackCallCount(counter, 1, "Did not get expected call to write.");
-    }
-
-    private void waitForCallbackCallCount(CallCounter counter, int count, String message) {
-        try {
-            counter.waitForCount(count, OPERATION_TIMEOUT);
-        } catch (TimeoutException te) {
-            fail(message);
-        }
-    }
-
-    private void selectPrinter(String printerName) throws UiObjectNotFoundException {
-        UiObject destinationSpinner = new UiObject(new UiSelector().resourceId(
-                "com.android.printspooler:id/destination_spinner"));
-        destinationSpinner.click();
-        UiObject printerOption = new UiObject(new UiSelector().text(printerName));
-        printerOption.click();
-    }
-
-    private void changeOrientation(String orientation) throws UiObjectNotFoundException {
-        UiObject orientationSpinner = new UiObject(new UiSelector().resourceId(
-                "com.android.printspooler:id/orientation_spinner"));
-        orientationSpinner.click();
-        UiObject orientationOption = new UiObject(new UiSelector().text(orientation));
-        orientationOption.click();
-    }
-
-    private void changeMediaSize(String mediaSize) throws UiObjectNotFoundException {
-        UiObject mediaSizeSpinner = new UiObject(new UiSelector().resourceId(
-                "com.android.printspooler:id/paper_size_spinner"));
-        mediaSizeSpinner.click();
-        UiObject mediaSizeOption = new UiObject(new UiSelector().text(mediaSize));
-        mediaSizeOption.click();
-    }
-
-    private void changeColor(String color) throws UiObjectNotFoundException {
-        UiObject colorSpinner = new UiObject(new UiSelector().resourceId(
-                "com.android.printspooler:id/color_spinner"));
-        colorSpinner.click();
-        UiObject colorOption = new UiObject(new UiSelector().text(color));
-        colorOption.click();
-    }
-
-    private void clickPrintButton() throws UiObjectNotFoundException {
-        UiObject printButton = new UiObject(new UiSelector().resourceId(
-                "com.android.printspooler:id/print_button"));
-        printButton.click();
-    }
-
-    private PrintDocumentAdapterContractActivity getActivity() {
-        return mActivity;
-    }
-
-    private void createActivity() {
-        mActivity = launchActivity(
-                getInstrumentation().getTargetContext().getPackageName(),
-                PrintDocumentAdapterContractActivity.class, null);
-    }
-
-    private void clearPrintSpoolerData() throws Exception {
-        IPrivilegedOperations privilegedOps = IPrivilegedOperations.Stub.asInterface(
-                getParams().getBinder(ARG_PRIVILEGED_OPS));
-        privilegedOps.clearApplicationUserData(PRINT_SPOOLER_PACKAGE_NAME);
-    }
-
-    private PrintDocumentAdapter createMockPrintDocumentAdapter(Answer<Void> layoutAnswer,
-            Answer<Void> writeAnswer, Answer<Void> finishAnswer) {
-        // Create a mock print adapter.
-        PrintDocumentAdapter adapter = mock(PrintDocumentAdapter.class);
-        if (layoutAnswer != null) {
-            doAnswer(layoutAnswer).when(adapter).onLayout(any(PrintAttributes.class),
-                    any(PrintAttributes.class), any(CancellationSignal.class),
-                    any(LayoutResultCallback.class), any(Bundle.class));
-        }
-        if (writeAnswer != null) {
-            doAnswer(writeAnswer).when(adapter).onWrite(any(PageRange[].class),
-                    any(ParcelFileDescriptor.class), any(CancellationSignal.class),
-                    any(WriteResultCallback.class));
-        }
-        if (finishAnswer != null) {
-            doAnswer(finishAnswer).when(adapter).onFinish();
-        }
-        return adapter;
-    }
-
-    static class SimpleTwoPrintersService extends StubPrintService {
-        @Override
-        public PrinterDiscoverySession onCreatePrinterDiscoverySession() {
-            return new PrinterDiscoverySession() {
-                @Override
-                public void onStartPrinterDiscovery(List<PrinterId> priorityList) {
-                    if (getPrinters().isEmpty()) {
-                        List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
-
-                        // Add the first printer.
-                        PrinterId firstPrinterId = getHost().generatePrinterId("first_printer");
-                        PrinterCapabilitiesInfo firstCapabilities =
-                                new PrinterCapabilitiesInfo.Builder(firstPrinterId)
-                            .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 firstPrinter = new PrinterInfo.Builder(firstPrinterId,
-                                "First printer", PrinterInfo.STATUS_IDLE)
-                            .setCapabilities(firstCapabilities)
-                            .build();
-                        printers.add(firstPrinter);
-
-                        // Add the second printer.
-                        PrinterId secondPrinterId = getHost().generatePrinterId("second_printer");
-                        PrinterCapabilitiesInfo secondCapabilities =
-                                new PrinterCapabilitiesInfo.Builder(secondPrinterId)
-                            .addMediaSize(MediaSize.ISO_A3, true)
-                            .addMediaSize(MediaSize.ISO_A4, false)
-                            .addResolution(new Resolution("200x200", "200x200", 200, 200), true)
-                            .addResolution(new Resolution("300x300", "300x300", 300, 300), false)
-                            .setColorModes(PrintAttributes.COLOR_MODE_COLOR
-                                    | PrintAttributes.COLOR_MODE_MONOCHROME,
-                                    PrintAttributes.COLOR_MODE_MONOCHROME)
-                            .build();
-                        PrinterInfo secondPrinter = new PrinterInfo.Builder(secondPrinterId,
-                                "Second printer", PrinterInfo.STATUS_IDLE)
-                            .setCapabilities(secondCapabilities)
-                            .build();
-                        printers.add(secondPrinter);
-
-                        // Add the third printer.
-                        PrinterId thirdPrinterId = getHost().generatePrinterId("third_printer");
-                        PrinterCapabilitiesInfo thirdCapabilities =
-                                new PrinterCapabilitiesInfo.Builder(thirdPrinterId)
-                            .addMediaSize(MediaSize.NA_LETTER, true)
-                            .addResolution(new Resolution("300x300", "300x300", 300, 300), true)
-                            .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
-                                    PrintAttributes.COLOR_MODE_COLOR)
-                            .build();
-                        PrinterInfo thirdPrinter = new PrinterInfo.Builder(thirdPrinterId,
-                                "Third printer", PrinterInfo.STATUS_IDLE)
-                            .setCapabilities(thirdCapabilities)
-                            .build();
-                        printers.add(thirdPrinter);
-
-                        addPrinters(printers);
-                    }
-                }
-
-                @Override
-                public void onStopPrinterDiscovery() {
-                    /* do nothing */
-                }
-
-                @Override
-                public void onValidatePrinters(List<PrinterId> printerIds) {
-                    /* do nothing */
-                }
-
-                @Override
-                public void onStartPrinterStateTracking(PrinterId printerId) {
-                    /* do nothing */
-                }
-
-                @Override
-                public void onStopPrinterStateTracking(PrinterId printerId) {
-                    /* do nothing */
-                }
-
-                @Override
-                public void onDestroy() {
-                    /* do nothing */
-                }
-            };
-        }
-
-        @Override
-        public void onRequestCancelPrintJob(PrintJob printJob) {
-            /* do nothing */
-        }
-
-        @Override
-        public void onPrintJobQueued(PrintJob printJob) {
-            /* do nothing */
-        }
-    }
-
-    private void verifyLayoutCall(InOrder inOrder, PrintDocumentAdapter mock,
-            PrintAttributes oldAttributes, PrintAttributes newAttributes,
-            final boolean forPreview) {
-        inOrder.verify(mock).onLayout(eq(oldAttributes), eq(newAttributes),
-                any(CancellationSignal.class), any(LayoutResultCallback.class), argThat(
-                        new BaseMatcher<Bundle>() {
-                            @Override
-                            public boolean matches(Object item) {
-                                Bundle bundle = (Bundle) item;
-                                return forPreview == bundle.getBoolean(
-                                        PrintDocumentAdapter.EXTRA_PRINT_PREVIEW);
-                            }
-
-                            @Override
-                            public void describeTo(Description description) {
-                                /* do nothing */
-                            }
-                        }));
-    }
-
-    private final class CallCounter {
-        private final Object mLock = new Object();
-
-        private int mCallCount;
-
-        public void call() {
-            synchronized (mLock) {
-                mCallCount++;
+        }, null, null, null, null, null);
+        return createMockPrintServiceCallbacks(new Answer<PrinterDiscoverySessionCallbacks>() {
+            @Override
+            public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                return callbacks;
             }
-        }
-
-        public void waitForCount(int count, long timeoutMIllis) throws TimeoutException {
-            synchronized (mLock) {
-                final long startTimeMillis = SystemClock.uptimeMillis();
-                while (mCallCount < count) {
-                    try {
-                        final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                        final long remainingTimeMillis = timeoutMIllis - elapsedTimeMillis;
-                        if (remainingTimeMillis <= 0) {
-                            throw new TimeoutException();
-                        }
-                        mLock.wait(timeoutMIllis);
-                    } catch (InterruptedException ie) {
-                        /* ignore */
-                    }
-                }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+                printJob.complete();
+                return null;
             }
-        }
+        }, null);
+    }
+
+    private PrintServiceCallbacks createSecondMockPrintServiceCallbacks() {
+        return createMockPrintServiceCallbacks(null, null, null);
     }
 }
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;
+            }
+        });
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/services/FirstPrintService.java b/tests/tests/print/src/android/print/cts/services/FirstPrintService.java
index 5528a81..a234de4 100644
--- a/tests/tests/print/src/android/print/cts/services/FirstPrintService.java
+++ b/tests/tests/print/src/android/print/cts/services/FirstPrintService.java
@@ -16,27 +16,25 @@
 
 package android.print.cts.services;
 
-import android.printservice.PrintService;
-
 public class FirstPrintService extends StubbablePrintService {
 
     private static final Object sLock = new Object();
 
-    private static StubPrintService sImpl;
+    private static PrintServiceCallbacks sCallbacks;
 
-    public static void setImpl(StubPrintService impl) {
+    public static void setCallbacks(PrintServiceCallbacks callbacks) {
         synchronized (sLock) {
-            sImpl = impl;
+            sCallbacks = callbacks;
         }
     }
 
     @Override
-    protected BasePrintService getStub(PrintService host) {
+    protected PrintServiceCallbacks getCallbacks() {
         synchronized (sLock) {
-            if (sImpl != null) {
-                sImpl.setHost(this);
+            if (sCallbacks != null) {
+                sCallbacks.setService(this);
             }
-            return sImpl;
+            return sCallbacks;
         }
     }
 }
diff --git a/tests/tests/print/src/android/print/cts/services/BasePrintService.java b/tests/tests/print/src/android/print/cts/services/PrintServiceCallbacks.java
similarity index 72%
rename from tests/tests/print/src/android/print/cts/services/BasePrintService.java
rename to tests/tests/print/src/android/print/cts/services/PrintServiceCallbacks.java
index 9d142d1..ff0245f 100644
--- a/tests/tests/print/src/android/print/cts/services/BasePrintService.java
+++ b/tests/tests/print/src/android/print/cts/services/PrintServiceCallbacks.java
@@ -18,16 +18,22 @@
 
 import android.printservice.PrintJob;
 import android.printservice.PrintService;
-import android.printservice.PrinterDiscoverySession;
 
-public abstract class BasePrintService extends PrintService {
+public abstract class PrintServiceCallbacks {
 
-    @Override
-    public abstract PrinterDiscoverySession onCreatePrinterDiscoverySession();
+    private PrintService mService;
 
-    @Override
+    public PrintService getService() {
+        return mService;
+    }
+
+    public void setService(PrintService service) {
+        mService = service;
+    }
+
+    public abstract PrinterDiscoverySessionCallbacks onCreatePrinterDiscoverySessionCallbacks();
+
     public abstract void onRequestCancelPrintJob(PrintJob printJob);
 
-    @Override
     public abstract void onPrintJobQueued(PrintJob printJob);
 }
diff --git a/tests/tests/print/src/android/print/cts/services/PrinterDiscoverySessionCallbacks.java b/tests/tests/print/src/android/print/cts/services/PrinterDiscoverySessionCallbacks.java
new file mode 100644
index 0000000..6b2c3a9
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/services/PrinterDiscoverySessionCallbacks.java
@@ -0,0 +1,46 @@
+/*
+ * 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.services;
+
+import android.print.PrinterId;
+
+import java.util.List;
+
+public abstract class PrinterDiscoverySessionCallbacks {
+
+    private StubbablePrinterDiscoverySession mSession;
+
+    public void setSession(StubbablePrinterDiscoverySession session) {
+        mSession = session;
+    }
+
+    public StubbablePrinterDiscoverySession getSession() {
+        return mSession;
+    }
+
+    public abstract void onStartPrinterDiscovery(List<PrinterId> priorityList);
+
+    public abstract void onStopPrinterDiscovery();
+
+    public abstract void onValidatePrinters(List<PrinterId> printerIds);
+
+    public abstract void onStartPrinterStateTracking(PrinterId printerId);
+
+    public abstract void onStopPrinterStateTracking(PrinterId printerId);
+
+    public abstract void onDestroy();
+}
diff --git a/tests/tests/print/src/android/print/cts/services/SecondPrintService.java b/tests/tests/print/src/android/print/cts/services/SecondPrintService.java
index b5db7e9..1029a8e 100644
--- a/tests/tests/print/src/android/print/cts/services/SecondPrintService.java
+++ b/tests/tests/print/src/android/print/cts/services/SecondPrintService.java
@@ -16,27 +16,25 @@
 
 package android.print.cts.services;
 
-import android.printservice.PrintService;
-
 public class SecondPrintService extends StubbablePrintService {
 
     private static final Object sLock = new Object();
 
-    private static StubPrintService sImpl;
+    private static PrintServiceCallbacks sCallbacks;
 
-    public static void setImpl(StubPrintService impl) {
+    public static void setCallbacks(PrintServiceCallbacks callbacks) {
         synchronized (sLock) {
-            sImpl = impl;
+            sCallbacks = callbacks;
         }
     }
 
     @Override
-    protected BasePrintService getStub(PrintService host) {
+    protected PrintServiceCallbacks getCallbacks() {
         synchronized (sLock) {
-            if (sImpl != null) {
-                sImpl.setHost(this);
+            if (sCallbacks != null) {
+                sCallbacks.setService(this);
             }
-            return sImpl;
+            return sCallbacks;
         }
     }
 }
diff --git a/tests/tests/print/src/android/print/cts/services/StubPrintService.java b/tests/tests/print/src/android/print/cts/services/StubPrintService.java
deleted file mode 100644
index 115ba5d..0000000
--- a/tests/tests/print/src/android/print/cts/services/StubPrintService.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.services;
-
-public abstract class StubPrintService extends BasePrintService {
-
-    private BasePrintService mHost;
-
-    public void setHost(BasePrintService host) {
-        mHost = host;
-    }
-
-    public BasePrintService getHost() {
-        return mHost;
-    }
-}
diff --git a/tests/tests/print/src/android/print/cts/services/StubbablePrintService.java b/tests/tests/print/src/android/print/cts/services/StubbablePrintService.java
index 73afd62..2686b41 100644
--- a/tests/tests/print/src/android/print/cts/services/StubbablePrintService.java
+++ b/tests/tests/print/src/android/print/cts/services/StubbablePrintService.java
@@ -16,71 +16,37 @@
 
 package android.print.cts.services;
 
-import android.print.PrinterId;
 import android.printservice.PrintJob;
 import android.printservice.PrintService;
 import android.printservice.PrinterDiscoverySession;
 
-import java.util.List;
-
-public abstract class StubbablePrintService extends BasePrintService {
+public abstract class StubbablePrintService extends PrintService {
 
     @Override
     public PrinterDiscoverySession onCreatePrinterDiscoverySession() {
-        BasePrintService impl = getStub(this);
-        if (impl != null) {
-            return impl.onCreatePrinterDiscoverySession();
+        PrintServiceCallbacks callbacks = getCallbacks();
+        if (callbacks != null) {
+            return new StubbablePrinterDiscoverySession(this,
+                    getCallbacks().onCreatePrinterDiscoverySessionCallbacks());
         }
-        return new StubSession();
+        return null;
     }
 
     @Override
     public void onRequestCancelPrintJob(PrintJob printJob) {
-        BasePrintService impl = getStub(this);
-        if (impl != null) {
-            impl.onRequestCancelPrintJob(printJob);
+        PrintServiceCallbacks callbacks = getCallbacks();
+        if (callbacks != null) {
+            callbacks.onRequestCancelPrintJob(printJob);
         }
     }
 
     @Override
     public void onPrintJobQueued(PrintJob printJob) {
-        BasePrintService impl = getStub(this);
-        if (impl != null) {
-            impl.onPrintJobQueued(printJob);
+        PrintServiceCallbacks callbacks = getCallbacks();
+        if (callbacks != null) {
+            callbacks.onPrintJobQueued(printJob);
         }
     }
 
-    protected abstract BasePrintService getStub(PrintService host);
-
-    private final class StubSession extends PrinterDiscoverySession {
-        @Override
-        public void onValidatePrinters(List<PrinterId> printerIds) {
-            /* do nothing */
-        }
-
-        @Override
-        public void onStopPrinterStateTracking(PrinterId printerId) {
-            /* do nothing */
-        }
-
-        @Override
-        public void onStopPrinterDiscovery() {
-            /* do nothing */
-        }
-
-        @Override
-        public void onStartPrinterStateTracking(PrinterId printerId) {
-            /* do nothing */
-        }
-
-        @Override
-        public void onStartPrinterDiscovery(List<PrinterId> priorityList) {
-            /* do nothing */
-        }
-
-        @Override
-        public void onDestroy() {
-            /* do nothing */
-        }
-    }
+    protected abstract PrintServiceCallbacks getCallbacks();
 }
diff --git a/tests/tests/print/src/android/print/cts/services/StubbablePrinterDiscoverySession.java b/tests/tests/print/src/android/print/cts/services/StubbablePrinterDiscoverySession.java
new file mode 100644
index 0000000..fdc2713
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/services/StubbablePrinterDiscoverySession.java
@@ -0,0 +1,83 @@
+/*
+ * 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.services;
+
+import android.print.PrinterId;
+import android.printservice.PrintService;
+import android.printservice.PrinterDiscoverySession;
+
+import java.util.List;
+
+public class StubbablePrinterDiscoverySession extends PrinterDiscoverySession {
+    private final PrintService mService;
+    private final PrinterDiscoverySessionCallbacks mCallbacks;
+
+    public StubbablePrinterDiscoverySession(PrintService service,
+            PrinterDiscoverySessionCallbacks callbacks) {
+        mService = service;
+        mCallbacks = callbacks;
+        if (mCallbacks != null) {
+            mCallbacks.setSession(this);
+        }
+    }
+
+    public PrintService getService() {
+        return mService;
+    }
+
+    @Override
+    public void onStartPrinterDiscovery(List<PrinterId> priorityList) {
+        if (mCallbacks != null) {
+            mCallbacks.onStartPrinterDiscovery(priorityList);
+        }
+    }
+
+    @Override
+    public void onStopPrinterDiscovery() {
+        if (mCallbacks != null) {
+            mCallbacks.onStopPrinterDiscovery();
+        }
+    }
+
+    @Override
+    public void onValidatePrinters(List<PrinterId> printerIds) {
+        if (mCallbacks != null) {
+            mCallbacks.onValidatePrinters(printerIds);
+        }
+    }
+
+    @Override
+    public void onStartPrinterStateTracking(PrinterId printerId) {
+        if (mCallbacks != null) {
+            mCallbacks.onStartPrinterStateTracking(printerId);
+        }
+    }
+
+    @Override
+    public void onStopPrinterStateTracking(PrinterId printerId) {
+        if (mCallbacks != null) {
+            mCallbacks.onStopPrinterStateTracking(printerId);
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        if (mCallbacks != null) {
+            mCallbacks.onDestroy();
+        }
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationResize.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationResize.java
index b6d9a1a..68d7274 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/AllocationResize.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationResize.java
@@ -49,7 +49,7 @@
         mIn.copy1DRangeFrom(0, INPUTSIZE, inArray);
 
         try {
-            RSUtils.forEach(this, 0, mIn, mOut);
+            forEach(0, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ClearObjectTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ClearObjectTest.java
index 64deb33..e8a330a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ClearObjectTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ClearObjectTest.java
@@ -66,7 +66,7 @@
         Allocation mOut = Allocation.createSized(mRS, Element.I32(mRS), ObjectNum);
         ms_clear.set_element(element);
         try {
-            RSUtils.forEach(this, TEST_ID_ELEMENT, mIn, mOut);
+            forEach(TEST_ID_ELEMENT, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         int[] tmpArray = new int[ObjectNum];
@@ -83,7 +83,7 @@
         ms_clear.set_type(type);
 
         try {
-            RSUtils.forEach(this, TEST_ID_TYPE, mIn, mOut);
+            forEach(TEST_ID_TYPE, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         int[] tmpArray = new int[ObjectNum];
@@ -99,7 +99,7 @@
         Allocation allocation = Allocation.createTyped(mRS, mIn.getType());
         ms_clear.set_allocation(allocation);
         try {
-            RSUtils.forEach(this, TEST_ID_ALLOCATION, mIn, mOut);
+            forEach(TEST_ID_ALLOCATION, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         int[] tmpArray = new int[ObjectNum];
@@ -115,7 +115,7 @@
         Allocation mIn = Allocation.createSized(mRS, Element.I32(mRS), ObjectNum);
         ms_clear.set_sampler(sampler);
         try {
-            RSUtils.forEach(this, TEST_ID_SAMPLER, mIn, mOut);
+            forEach(TEST_ID_SAMPLER, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         int[] tmpArray = new int[ObjectNum];
@@ -131,7 +131,7 @@
         Allocation mOut = Allocation.createSized(mRS, Element.I32(mRS), ObjectNum);
         ms_clear.set_script(script);
         try {
-            RSUtils.forEach(this, TEST_ID_SCRIPT, mIn, mOut);
+            forEach(TEST_ID_SCRIPT, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         int[] tmpArray = new int[ObjectNum];
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/GetElementAt.java b/tests/tests/renderscript/src/android/renderscript/cts/GetElementAt.java
index a9be1bc..babc1ef 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/GetElementAt.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/GetElementAt.java
@@ -62,7 +62,7 @@
         mOut = Allocation.createTyped(mRS, gIn.getType());
         script_x.set_gIn(gIn);
         try {
-            RSUtils.forEach(this, TEST_ID_X, mOut);
+            forEach(TEST_ID_X, mOut);
         } catch (RSRuntimeException e) {
         }
         mOut.copyTo(out);
@@ -83,7 +83,7 @@
         mOut = Allocation.createTyped(mRS, gIn.getType());
         script_xy.set_gIn(gIn);
         try {
-            RSUtils.forEach(this, TEST_ID_XY, mOut);
+            forEach(TEST_ID_XY, mOut);
         } catch (RSRuntimeException e) {
         }
         mOut.copyTo(out);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/InitTest.java b/tests/tests/renderscript/src/android/renderscript/cts/InitTest.java
index ef36927..848c192 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/InitTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/InitTest.java
@@ -46,7 +46,7 @@
         mIn.copy1DRangeFrom(0, INPUTSIZE, in);
 
         try {
-            RSUtils.forEach(this, 0, mIn, mOut);
+            forEach(0, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         mOut.copyTo(out);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java b/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java
index 09a2e94..ad3d078 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java
@@ -88,8 +88,8 @@
     }
 
     @Override
-    protected void fillRandom(long seed, int fact, int offset, float[] inArray, int rStride, int rSkip) {
-        RSUtils.genRandom(seed, 32, -16, inArray, rStride, rSkip);
+    protected void fillRandomFloats(long seed, int fact, int offset, float[] inArray) {
+        RSUtils.genRandomFloats(seed, 32, -16, inArray);
     }
 
     public void testPowF32() {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java b/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java
index c95a294..32308ce 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java
@@ -82,7 +82,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE];
-        RSUtils.genRandom(0x12345678, 32, 1, -16, n);
+        RSUtils.genRandomInts(0x12345678, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32.set_n1(nAlloc);
 
@@ -93,7 +93,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE];
-        RSUtils.genRandom(0x12345678, 32, 1, -16, n);
+        RSUtils.genRandomInts(0x12345678, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n1(nAlloc);
 
@@ -104,7 +104,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*2];
-        RSUtils.genRandom(0xacdef1, 32, 1, -16, n);
+        RSUtils.genRandomInts(0xacdef1, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32.set_n2(nAlloc);
 
@@ -115,7 +115,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*2];
-        RSUtils.genRandom(0xacdef1, 32, 1, -16, n);
+        RSUtils.genRandomInts(0xacdef1, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n2(nAlloc);
 
@@ -126,7 +126,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0xa123f1, 32, 1, -16, n, 4, 1);
+        RSUtils.genRandomInts(0xa123f1, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32.set_n3(nAlloc);
 
@@ -137,7 +137,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0xa123f1, 32, 1, -16, n, 4, 1);
+        RSUtils.genRandomInts(0xa123f1, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n3(nAlloc);
 
@@ -148,7 +148,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0x4323ca, 32, 1, -16, n);
+        RSUtils.genRandomInts(0x4323ca, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32.set_n4(nAlloc);
 
@@ -159,7 +159,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0x4323ca, 32, 1, -16, n);
+        RSUtils.genRandomInts(0x4323ca, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n4(nAlloc);
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java b/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java
index f10995b..cebbe24 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java
@@ -88,8 +88,8 @@
     }
 
     @Override
-    protected void fillRandom(long seed, int fact, int offset, float[] inArray, int rStride, int rSkip) {
-        RSUtils.genRandom(seed, 64, 0, inArray, rStride, rSkip);
+    protected void fillRandomFloats(long seed, int fact, int offset, float[] inArray) {
+        RSUtils.genRandomFloats(seed, 64, 0, inArray);
     }
 
     public void testPowrF32() {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
index d68e628..d7759f1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
@@ -89,7 +89,7 @@
                                 int offset, int rStride, int rSkip, int refStride, int outStride,
                                 int inStride, int skip, int ulp) {
         float[] inArray = makeInArray(INPUTSIZE * inStride);
-        fillRandom(seed, fact, offset, inArray, rStride, rSkip);
+        fillRandomFloats(seed, fact, offset, inArray);
         float[] refArray = getRefArray(inArray, INPUTSIZE, inStride, skip);
 
         Allocation mAllocationIn = setInAlloc(inElement);
@@ -97,7 +97,7 @@
 
         Allocation mAllocationOut = setOutAlloc(outElement);
         try {
-            RSUtils.forEach(this, testid, mAllocationIn, mAllocationOut);
+            forEach(testid, mAllocationIn, mAllocationOut);
         } catch (RSRuntimeException e) {
             Log.e("RenderscriptCTS", "Caught RSRuntimeException: " +
                   e.getMessage());
@@ -173,8 +173,8 @@
         return new float[size];
     }
 
-    protected void fillRandom(long seed, int fact, int offset, float[] inArray, int rStride, int rSkip) {
-        RSUtils.genRandom(seed, fact, offset, inArray, rStride, rSkip);
+    protected void fillRandomFloats(long seed, int fact, int offset, float[] inArray) {
+        RSUtils.genRandomFloats(seed, fact, offset, inArray);
     }
 
     protected void fillInAlloc(Allocation mIn, float[] inArray) {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java b/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
index 8c81e3d..d3fb5d0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
@@ -27,65 +27,23 @@
  */
 public class RSUtils {
 
-    public static void genRandom(long seed, int factor, int offset, float array[]) {
+    /**
+     * Fills the array with random floats.  Values will be: offset + number between 0 and max.
+     */
+    public static void genRandomFloats(long seed, int max, int offset, float array[]) {
         Random r = new Random(seed);
         for (int i = 0; i < array.length; i++) {
-            array[i] = r.nextFloat() * factor + offset;
+            array[i] = r.nextFloat() * max + offset;
         }
     }
 
-    public static void genRandom(long seed, int factor, int offset, float array[],
-            int stride, int skip) {
-        Random r = new Random(seed);
-        for (int i = 0; i < array.length / stride; i++) {
-            for (int j = 0; j < stride; j++) {
-                if (j >= stride - skip)
-                    array[i * stride + j] = 0;
-                else
-                    array[i * stride + j] = r.nextFloat() * factor + offset;
-            }
-        }
-    }
-
-    public static void genRandom(long seed, int max, int factor, int offset, int array[]) {
+    /**
+     * Fills the array with random ints.  Values will be: offset + number between 0 and max (exclusive).
+     */
+    public static void genRandomInts(long seed, int max, int offset, int array[]) {
         Random r = new Random(seed);
         for (int i = 0; i < array.length; i++) {
-            array[i] = (r.nextInt(max) * factor + offset);
+            array[i] = (r.nextInt(max) + offset);
         }
     }
-
-    public static void genRandom(long seed, int factor, int offset, int array[],
-            int stride, int skip) {
-        Random r = new Random(seed);
-        for (int i = 0; i < array.length / stride; i++) {
-            for (int j = 0; j < stride; j++) {
-                if (j >= stride - skip)
-                    array[i * stride + j] = 0;
-                else
-                    array[i * stride + j] = r.nextInt() * factor + offset;
-            }
-        }
-    }
-
-    public static void genRandom(long seed, int max, int factor, int offset, int array[],
-            int stride, int skip) {
-        Random r = new Random(seed);
-        for (int i = 0; i < array.length / stride; i++) {
-            for (int j = 0; j < stride; j++) {
-                if (j >= stride - skip)
-                    array[i * stride + j] = 0;
-                else
-                    array[i * stride + j] = r.nextInt(max) * factor + offset;
-            }
-        }
-    }
-
-    public static void forEach(RSBaseCompute base, int testId, Allocation in) throws RSRuntimeException {
-        base.forEach(testId, in);
-    }
-
-    public static void forEach(RSBaseCompute base, int testId, Allocation in, Allocation out)
-            throws RSRuntimeException {
-        base.forEach(testId, in,out);
-    }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java
index 8301ad5..2c447bb 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java
@@ -80,7 +80,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE];
-        RSUtils.genRandom(0x12345678, 32, 1, 1, n);
+        RSUtils.genRandomInts(0x12345678, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32.set_n1(nAlloc);
 
@@ -91,7 +91,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE];
-        RSUtils.genRandom(0x12345678, 32, 1, 1, n);
+        RSUtils.genRandomInts(0x12345678, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n1(nAlloc);
 
@@ -103,7 +103,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*2];
-        RSUtils.genRandom(0xacdef1, 32, 1, 1, n);
+        RSUtils.genRandomInts(0xacdef1, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32.set_n2(nAlloc);
 
@@ -114,7 +114,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*2];
-        RSUtils.genRandom(0xacdef1, 32, 1, 1, n);
+        RSUtils.genRandomInts(0xacdef1, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n2(nAlloc);
 
@@ -126,7 +126,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0xa123f1, 32, 1, 1, n, 4, 1);
+        RSUtils.genRandomInts(0xa123f1, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32.set_n3(nAlloc);
 
@@ -137,7 +137,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0xa123f1, 32, 1, 1, n, 4, 1);
+        RSUtils.genRandomInts(0xa123f1, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n3(nAlloc);
 
@@ -148,7 +148,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0x4323ca, 32, 1, 1, n);
+        RSUtils.genRandomInts(0x4323ca, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32.set_n4(nAlloc);
 
@@ -159,7 +159,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0x4323ca, 32, 1, 1, n);
+        RSUtils.genRandomInts(0x4323ca, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n4(nAlloc);
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java b/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java
index 0b008a7..edff5b9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java
@@ -72,10 +72,10 @@
         float[] inArray = new float[INPUTSIZE * 4];
         byte[] outArray = new byte[INPUTSIZE * 4];
         byte[] refArray = new byte[INPUTSIZE * 4];
-        RSUtils.genRandom(seed, 1, 0, inArray, 4, 1);
+        RSUtils.genRandomFloats(seed, 1, 0, inArray);
         mAllocationIn.copy1DRangeFrom(0, INPUTSIZE, inArray);
         try {
-            RSUtils.forEach(this, testId, mAllocationIn, mAllocationOut);
+            forEach(testId, mAllocationIn, mAllocationOut);
         } catch (RSRuntimeException e) {
         }
         mAllocationOut.copyTo(outArray);
@@ -99,10 +99,10 @@
         float[] inArray = new float[INPUTSIZE * 4];
         byte[] outArray = new byte[INPUTSIZE * 4];
         byte[] refArray = new byte[INPUTSIZE * 4];
-        RSUtils.genRandom(seed, 1, 0, inArray);
+        RSUtils.genRandomFloats(seed, 1, 0, inArray);
         mAllocationIn.copy1DRangeFrom(0, INPUTSIZE, inArray);
         try {
-            RSUtils.forEach(this, testId, mAllocationIn, mAllocationOut);
+            forEach(testId, mAllocationIn, mAllocationOut);
         } catch (RSRuntimeException e) {
         }
         mAllocationOut.copyTo(outArray);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RsUnpackColor8888Test.java b/tests/tests/renderscript/src/android/renderscript/cts/RsUnpackColor8888Test.java
index 4df1169..3ebbee1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RsUnpackColor8888Test.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RsUnpackColor8888Test.java
@@ -44,7 +44,7 @@
 
         mAllocationIn.copy1DRangeFrom(0, INPUTSIZE, inArray);
         try {
-            RSUtils.forEach(this, 0, mAllocationIn, mAllocationOut);
+            forEach(0, mAllocationIn, mAllocationOut);
         } catch (RSRuntimeException e) {
         }
         mAllocationOut.copyTo(outArray);
diff --git a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
index e56a7cf..1cc86ca 100644
--- a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
+++ b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
@@ -77,8 +77,7 @@
         sourcePath.add("./cts/tests/src");
         sourcePath.add("./cts/libs/commonutil/src");
         sourcePath.add("./cts/libs/deviceutil/src");
-        sourcePath.add("./frameworks/testing/uiautomator/library/testrunner-src");
-        sourcePath.add("./frameworks/testing/uiautomator_test_libraries/src");
+        sourcePath.add("./frameworks/uiautomator/src");
         sourcePath.add(sourceDir.toString());
         return join(sourcePath, ":");
     }