diff --git a/CtsBuild.mk b/CtsBuild.mk
index 6e57086..f6d0d5c 100644
--- a/CtsBuild.mk
+++ b/CtsBuild.mk
@@ -51,3 +51,7 @@
 define cts-get-test-xmls
 	$(foreach name,$(1),$(CTS_TESTCASES_OUT)/$(name).xml)
 endef
+
+define cts-get-executable-paths
+	$(foreach executable,$(1),$(CTS_TESTCASES_OUT)/$(executable))
+endef
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index dab7b67..e85109d 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -103,6 +103,7 @@
     CtsPermission2TestCases \
     CtsPreferenceTestCases \
     CtsPreference2TestCases \
+    CtsPrintTestCases \
     CtsProviderTestCases \
     CtsRenderscriptTestCases \
     CtsRenderscriptGraphicsTestCases \
@@ -124,7 +125,6 @@
 	$(cts_support_packages) \
 	$(cts_test_packages)
 
-
 # Host side only tests
 cts_host_libraries := \
     CtsHostUi \
@@ -134,18 +134,21 @@
     CtsMonkeyTestCases \
     CtsUsbTests
 
-
 # Native test executables that need to have associated test XMLs.
 cts_native_exes := \
 	NativeMediaTest_SL \
 	NativeMediaTest_XA \
-	bionic-unit-tests-cts \
+	bionic-unit-tests-cts
 
 cts_ui_tests := \
     CtsUiAutomatorTests
 
 cts_device_jars := \
-    CtsDeviceJank
+    CtsDeviceJank \
+    CtsPrintInstrument
+
+cts_device_executables := \
+    print-instrument
 
 # All the files that will end up under the repository/testcases
 # directory of the final CTS distribution.
@@ -153,7 +156,8 @@
     $(call cts-get-package-paths,$(cts_test_packages)) \
     $(call cts-get-native-paths,$(cts_native_exes)) \
     $(call cts-get-ui-lib-paths,$(cts_ui_tests)) \
-    $(call cts-get-ui-lib-paths,$(cts_device_jars))
+    $(call cts-get-ui-lib-paths,$(cts_device_jars)) \
+    $(call cts-get-executable-paths,$(cts_device_executables))
 
 # All the XMLs that will end up under the repository/testcases
 # and that need to be created before making the final CTS distribution.
@@ -162,6 +166,5 @@
     $(call cts-get-test-xmls,$(cts_native_exes)) \
     $(call cts-get-test-xmls,$(cts_ui_tests))
 
-
 # The following files will be placed in the tools directory of the CTS distribution
 CTS_TOOLS_LIST :=
\ No newline at end of file
diff --git a/tests/accessibility/AndroidManifest.xml b/tests/accessibility/AndroidManifest.xml
index 0d18cef..dde1de8 100644
--- a/tests/accessibility/AndroidManifest.xml
+++ b/tests/accessibility/AndroidManifest.xml
@@ -19,8 +19,6 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.view.accessibility.services">
 
-  <uses-permission android:name="android.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE"/>
-
   <application>
 
     <service android:name=".SpeakingAccessibilityService"
diff --git a/tests/print/Android.mk b/tests/print/Android.mk
new file mode 100644
index 0000000..fea7dc0
--- /dev/null
+++ b/tests/print/Android.mk
@@ -0,0 +1,36 @@
+# 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)
+
+##################################################
+# Build the print instrument library
+##################################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := CtsPrintInstrument
+LOCAL_SRC_FILES := $(call all-subdir-java-files) \
+    src/android/print/cts/IPrivilegedOperations.aidl
+LOCAL_MODULE_TAGS := optional
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_JAVA_LIBRARY)
+
+# Copy the shell script to run the print instrument Jar to the CTS out folder.
+$(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar : $(LOCAL_BUILT_MODULE) | $(ACP) 
+	$(copy-file-to-target)
+
+# Copy the built print instrument library Jar to the CTS out folder.
+$(CTS_TESTCASES_OUT)/print-instrument : $(LOCAL_PATH)/print-instrument | $(ACP)
+	$(copy-file-to-target)
+
diff --git a/tests/print/print-instrument b/tests/print/print-instrument
new file mode 100755
index 0000000..a79cb8a
--- /dev/null
+++ b/tests/print/print-instrument
@@ -0,0 +1,37 @@
+# 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.
+
+# Script to start "print-instrument" on the device
+#
+# The script sets up an alternative dalvik cache when running as
+# non-root. Jar files needs to be dexopt'd to run in Dalvik. For
+# plain jar files, this is done at first use. shell user does not
+# have write permission to default system Dalvik cache so we
+# redirect to an alternative cache.
+
+RUN_BASE=/data/local/tmp
+
+# If not running as root, use an alternative dex cache.
+if [ ${USER_ID} -ne 0 ]; then
+  tmp_cache=${RUN_BASE}/dalvik-cache
+  if [ ! -d ${tmp_cache} ]; then
+    mkdir -p ${tmp_cache}
+  fi
+  export ANDROID_DATA=${RUN_BASE}
+fi
+
+# Run print-instrument.
+export CLASSPATH=${RUN_BASE}/CtsPrintInstrument.jar
+
+exec app_process ${RUN_BASE} android.print.cts.PrintInstrument ${@}
diff --git a/tests/print/src/android/print/cts/IPrivilegedOperations.aidl b/tests/print/src/android/print/cts/IPrivilegedOperations.aidl
new file mode 100644
index 0000000..93c8c3e
--- /dev/null
+++ b/tests/print/src/android/print/cts/IPrivilegedOperations.aidl
@@ -0,0 +1,21 @@
+/*
+ * 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;
+
+interface IPrivilegedOperations {
+    boolean clearApplicationUserData(String packageName);
+}
diff --git a/tests/print/src/android/print/cts/PrintInstrument.java b/tests/print/src/android/print/cts/PrintInstrument.java
new file mode 100644
index 0000000..cd07410
--- /dev/null
+++ b/tests/print/src/android/print/cts/PrintInstrument.java
@@ -0,0 +1,279 @@
+/*
+ * 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 android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.app.IInstrumentationWatcher;
+import android.app.Instrumentation;
+import android.app.UiAutomationConnection;
+import android.content.ComponentName;
+import android.content.pm.IPackageDataObserver;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.AndroidException;
+import android.view.IWindowManager;
+
+import com.android.internal.os.BaseCommand;
+
+import java.io.PrintStream;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public final class PrintInstrument extends BaseCommand {
+
+    private static final String ARG_PRIVILEGED_OPS = "ARG_PRIVILEGED_OPS";
+
+    private IActivityManager mAm;
+
+    public static void main(String[] args) {
+        PrintInstrument instrumenter = new PrintInstrument();
+        instrumenter.run(args);
+    }
+
+    @Override
+    public void onRun() throws Exception {
+        mAm = ActivityManagerNative.getDefault();
+        if (mAm == null) {
+            System.err.println(NO_SYSTEM_ERROR_CODE);
+            throw new AndroidException("Can't connect to activity manager;"
+                    + " is the system running?");
+        }
+
+        String op = nextArgRequired();
+
+        if (op.equals("instrument")) {
+            runInstrument();
+        } else {
+            showError("Error: unknown command '" + op + "'");
+        }
+    }
+
+    @Override
+    public void onShowUsage(PrintStream out) {
+        /* do nothing */
+    }
+
+    @SuppressWarnings("deprecation")
+    private void runInstrument() throws Exception {
+        String profileFile = null;
+        boolean wait = false;
+        boolean rawMode = false;
+        boolean no_window_animation = false;
+        int userId = UserHandle.USER_CURRENT;
+        Bundle args = new Bundle();
+        String argKey = null, argValue = null;
+        IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+
+        String opt;
+        while ((opt=nextOption()) != null) {
+            if (opt.equals("-p")) {
+                profileFile = nextArgRequired();
+            } else if (opt.equals("-w")) {
+                wait = true;
+            } else if (opt.equals("-r")) {
+                rawMode = true;
+            } else if (opt.equals("-e")) {
+                argKey = nextArgRequired();
+                argValue = nextArgRequired();
+                args.putString(argKey, argValue);
+            } else if (opt.equals("--no_window_animation")
+                    || opt.equals("--no-window-animation")) {
+                no_window_animation = true;
+            } else if (opt.equals("--user")) {
+                userId = parseUserArg(nextArgRequired());
+            } else {
+                System.err.println("Error: Unknown option: " + opt);
+                return;
+            }
+        }
+
+        if (userId == UserHandle.USER_ALL) {
+            System.err.println("Error: Can't start instrumentation with user 'all'");
+            return;
+        }
+
+        String cnArg = nextArgRequired();
+        ComponentName cn = ComponentName.unflattenFromString(cnArg);
+        if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
+
+        InstrumentationWatcher watcher = null;
+        UiAutomationConnection connection = null;
+        if (wait) {
+            watcher = new InstrumentationWatcher();
+            watcher.setRawOutput(rawMode);
+            connection = new UiAutomationConnection();
+        }
+
+        float[] oldAnims = null;
+        if (no_window_animation) {
+            oldAnims = wm.getAnimationScales();
+            wm.setAnimationScale(0, 0.0f);
+            wm.setAnimationScale(1, 0.0f);
+        }
+
+        args.putIBinder(ARG_PRIVILEGED_OPS, new PrivilegedOperations(mAm));
+
+        if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId)) {
+            throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
+        }
+
+        if (watcher != null) {
+            if (!watcher.waitForFinish()) {
+                System.out.println("INSTRUMENTATION_ABORTED: System has crashed.");
+            }
+        }
+
+        if (oldAnims != null) {
+            wm.setAnimationScales(oldAnims);
+        }
+    }
+
+    private int parseUserArg(String arg) {
+        int userId;
+        if ("all".equals(arg)) {
+            userId = UserHandle.USER_ALL;
+        } else if ("current".equals(arg) || "cur".equals(arg)) {
+            userId = UserHandle.USER_CURRENT;
+        } else {
+            userId = Integer.parseInt(arg);
+        }
+        return userId;
+    }
+
+    private class InstrumentationWatcher extends IInstrumentationWatcher.Stub {
+        private boolean mFinished = false;
+        private boolean mRawMode = false;
+
+        /**
+         * Set or reset "raw mode".  In "raw mode", all bundles are dumped.  In "pretty mode",
+         * if a bundle includes Instrumentation.REPORT_KEY_STREAMRESULT, just print that.
+         * @param rawMode true for raw mode, false for pretty mode.
+         */
+        public void setRawOutput(boolean rawMode) {
+            mRawMode = rawMode;
+        }
+
+        @Override
+        public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) {
+            synchronized (this) {
+                // pretty printer mode?
+                String pretty = null;
+                if (!mRawMode && results != null) {
+                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
+                }
+                if (pretty != null) {
+                    System.out.print(pretty);
+                } else {
+                    if (results != null) {
+                        for (String key : results.keySet()) {
+                            System.out.println(
+                                    "INSTRUMENTATION_STATUS: " + key + "=" + results.get(key));
+                        }
+                    }
+                    System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode);
+                }
+                notifyAll();
+            }
+        }
+
+        @Override
+        public void instrumentationFinished(ComponentName name, int resultCode,
+                Bundle results) {
+            synchronized (this) {
+                // pretty printer mode?
+                String pretty = null;
+                if (!mRawMode && results != null) {
+                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
+                }
+                if (pretty != null) {
+                    System.out.println(pretty);
+                } else {
+                    if (results != null) {
+                        for (String key : results.keySet()) {
+                            System.out.println(
+                                    "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key));
+                        }
+                    }
+                    System.out.println("INSTRUMENTATION_CODE: " + resultCode);
+                }
+                mFinished = true;
+                notifyAll();
+            }
+        }
+
+        public boolean waitForFinish() {
+            synchronized (this) {
+                while (!mFinished) {
+                    try {
+                        if (!mAm.asBinder().pingBinder()) {
+                            return false;
+                        }
+                        wait(1000);
+                    } catch (InterruptedException e) {
+                        throw new IllegalStateException(e);
+                    }
+                }
+            }
+            return true;
+        }
+    }
+
+    private static final class PrivilegedOperations extends IPrivilegedOperations.Stub {
+        private final IActivityManager mAm;
+
+        public PrivilegedOperations(IActivityManager am) {
+            mAm = am;
+        }
+
+        @Override
+        public boolean clearApplicationUserData(final String clearedPackageName)
+                throws RemoteException {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                final AtomicBoolean success = new AtomicBoolean();
+                final CountDownLatch completionLacth = new CountDownLatch(1);
+
+                mAm.clearApplicationUserData(clearedPackageName,
+                        new IPackageDataObserver.Stub() {
+                            @Override
+                            public void onRemoveCompleted(String packageName, boolean succeeded) {
+                                if (clearedPackageName.equals(packageName) && succeeded) {
+                                    success.set(true);
+                                } else {
+                                    success.set(false);
+                                }
+                                completionLacth.countDown();
+                            }
+                }, UserHandle.USER_CURRENT);
+
+                try {
+                    completionLacth.await();
+                } catch (InterruptedException ie) {
+                    /* ignore */
+                }
+
+                return success.get();
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+    }
+}
diff --git a/tests/tests/print/Android.mk b/tests/tests/print/Android.mk
new file mode 100644
index 0000000..d9fcba6
--- /dev/null
+++ b/tests/tests/print/Android.mk
@@ -0,0 +1,33 @@
+# 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_MODULE_TAGS := optional
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    src/android/print/cts/IPrivilegedOperations.aidl
+
+LOCAL_PACKAGE_NAME := CtsPrintTestCases
+
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ctstestrunner ub-uiautomator
+
+# This test runner sets up/cleans up the device before/after running the tests.
+LOCAL_CTS_TEST_RUNNER := com.android.cts.tradefed.testtype.PrintTestRunner
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/print/AndroidManifest.xml b/tests/tests/print/AndroidManifest.xml
new file mode 100644
index 0000000..56b3233
--- /dev/null
+++ b/tests/tests/print/AndroidManifest.xml
@@ -0,0 +1,78 @@
+<?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="com.android.cts.print"
+        android:versionCode="1"
+        android:versionName="1">
+
+    <application android:allowBackup="false" >
+
+        <uses-library android:name="android.test.runner"/>
+
+        <activity android:name="android.print.cts.PrintDocumentAdapterContractActivity"/>
+
+        <service
+            android:name="android.print.cts.services.FirstPrintService"
+            android:permission="android.permission.BIND_PRINT_SERVICE">
+            <intent-filter>
+                <action android:name="android.printservice.PrintService" />
+            </intent-filter>
+            <meta-data
+               android:name="android.printservice"
+               android:resource="@xml/printservice">
+            </meta-data>
+        </service>
+
+        <service
+            android:name="android.print.cts.services.SecondPrintService"
+            android:permission="android.permission.BIND_PRINT_SERVICE">
+            <intent-filter>
+                <action android:name="android.printservice.PrintService" />
+            </intent-filter>
+            <meta-data
+               android:name="android.printservice"
+               android:resource="@xml/printservice">
+            </meta-data>
+        </service>
+
+        <activity
+            android:name="android.print.cts.services.SettingsActivity"
+            android:permission="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
+            android:exported="true">
+        </activity>
+
+        <activity
+            android:name="android.print.cts.services.AddPrintersActivity"
+            android:permission="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
+            android:exported="true">
+        </activity>
+
+        <activity
+            android:name="android.print.cts.services.CustomPrintOptionsActivity"
+            android:permission="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
+            android:exported="true">
+        </activity>
+
+  </application>
+
+  <instrumentation android:name="com.android.uiautomator.testrunner.UiAutomatorInstrumentationTestRunner"
+          android:targetPackage="com.android.cts.print"
+          android:label="Tests for the print APIs."/>
+
+</manifest>
diff --git a/tests/tests/print/res/values/strings.xml b/tests/tests/print/res/values/strings.xml
new file mode 100644
index 0000000..6d869e9
--- /dev/null
+++ b/tests/tests/print/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+
+<resources>
+
+    <string name="resolution_200x200">200x200</string>
+    <string name="resolution_300x300">300x300</string>
+    <string name="resolution_600x600">600x600</string>
+
+</resources>
diff --git a/tests/tests/print/res/xml/printservice.xml b/tests/tests/print/res/xml/printservice.xml
new file mode 100644
index 0000000..5579b81
--- /dev/null
+++ b/tests/tests/print/res/xml/printservice.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<print-service  xmlns:android="http://schemas.android.com/apk/res/android"
+     android:settingsActivity="android.print.services.SettingsActivity"
+     android:addPrintersActivity="android.print.services.AddPrintersActivity"
+     android:advancedPrintOptionsActivity="android.print.services.CustomPrintOptionsActivity"/>
diff --git a/tests/tests/print/src/android/print/cts/IPrivilegedOperations.aidl b/tests/tests/print/src/android/print/cts/IPrivilegedOperations.aidl
new file mode 100644
index 0000000..93c8c3e
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/IPrivilegedOperations.aidl
@@ -0,0 +1,21 @@
+/*
+ * 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;
+
+interface IPrivilegedOperations {
+    boolean clearApplicationUserData(String packageName);
+}
diff --git a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractActivity.java b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractActivity.java
new file mode 100644
index 0000000..eb80bb7
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractActivity.java
@@ -0,0 +1,28 @@
+/*
+ * 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 android.app.Activity;
+import android.os.Bundle;
+
+public class PrintDocumentAdapterContractActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
new file mode 100644
index 0000000..013c28c
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
@@ -0,0 +1,1767 @@
+/*
+ * 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.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;
+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.PrintManager;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.print.cts.services.FirstPrintService;
+import android.print.cts.services.SecondPrintService;
+import android.print.cts.services.StubPrintService;
+import android.printservice.PrintJob;
+import android.printservice.PrinterDiscoverySession;
+import android.util.DisplayMetrics;
+
+import com.android.uiautomator.core.UiDevice;
+import com.android.uiautomator.core.UiObject;
+import com.android.uiautomator.core.UiObjectNotFoundException;
+import com.android.uiautomator.core.UiSelector;
+import com.android.uiautomator.testrunner.UiAutomatorTestCase;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.mockito.InOrder;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+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 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();
+
+        // 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("Test")
+                        .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
+                        .build();
+                callback.onLayoutFinished(info, false);
+                layoutCallCounter.call();
+                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.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Select the second printer.
+        selectPrinter("Second printer");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 2);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // We selected the second printer which does not support the media
+        // size that was selected, so a new layout happens as the size changed.
+        // Since we passed false to the layout callback meaning that the content
+        // didn't change, there shouldn't be a next call to write.
+        PrintAttributes secondOldAttributes = firstNewAttributes;
+        PrintAttributes secondNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A3)
+                .setResolution(new Resolution("300x300", "300x300", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, secondOldAttributes, secondNewAttributes, true);
+
+        // When print is pressed we ask for a layout which is *not* for preview.
+        verifyLayoutCall(inOrder, adapter, secondNewAttributes, secondNewAttributes, false);
+
+        // When print is pressed we ask for all selected pages.
+        PageRange[] secondPages = new PageRange[] {PageRange.ALL_PAGES};
+        inOrder.verify(adapter).onWrite(eq(secondPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // 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("Test")
+                    .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                    .setPageCount(1)
+                    .build();
+                callback.onLayoutFinished(info, false);
+                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.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Cancel the printing.
+        UiDevice.getInstance().pressBack();
+
+        // Wait for finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // 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("Test")
+                    .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                    .setPageCount(1)
+                    .build();
+                callback.onLayoutFinished(info, false);
+                // Mark layout was called.
+                layoutCallCounter.call();
+                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.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Select the second printer.
+        selectPrinter("Second printer");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 2);
+
+        // Change the orientation.
+        changeOrientation("Landscape");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 3);
+
+        // Change the media size.
+        changeMediaSize("ISO A4");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 4);
+
+        // Change the color.
+        changeColor("Black & White");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 5);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // We selected the second printer which does not support the media
+        // size that was selected, so a new layout happens as the size changed.
+        // Since we passed false to the layout callback meaning that the content
+        // didn't change, there shouldn't be a next call to write.
+        PrintAttributes secondOldAttributes = firstNewAttributes;
+        PrintAttributes secondNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A3)
+                .setResolution(new Resolution("300x300", "300x300", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, secondOldAttributes, secondNewAttributes, true);
+
+        // We changed the orientation which triggers a layout. Since we passed
+        // false to the layout callback meaning that the content didn't change,
+        // there shouldn't be a next call to write.
+        PrintAttributes thirdOldAttributes = secondNewAttributes;
+        PrintAttributes thirdNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A3.asLandscape())
+                .setResolution(new Resolution("300x300", "300x300", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, thirdOldAttributes, thirdNewAttributes, true);
+
+        // We changed the media size which triggers a layout. Since we passed
+        // false to the layout callback meaning that the content didn't change,
+        // there shouldn't be a next call to write.
+        PrintAttributes fourthOldAttributes = thirdNewAttributes;
+        PrintAttributes fourthNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A4.asLandscape())
+                .setResolution(new Resolution("300x300", "300x300", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, fourthOldAttributes, fourthNewAttributes, true);
+
+        // We changed the color which triggers a layout. Since we passed
+        // false to the layout callback meaning that the content didn't change,
+        // there shouldn't be a next call to write.
+        PrintAttributes fifthOldAttributes = fourthNewAttributes;
+        PrintAttributes fifthNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A4.asLandscape())
+                .setResolution(new Resolution("300x300", "300x300", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_MONOCHROME)
+                .build();
+        verifyLayoutCall(inOrder, adapter, fifthOldAttributes, fifthNewAttributes, true);
+
+        // When print is pressed we ask for a layout which is *not* for preview.
+        verifyLayoutCall(inOrder, adapter, fifthNewAttributes, fifthNewAttributes, false);
+
+        // When print is pressed we ask for all selected pages.
+        PageRange[] secondPages = new PageRange[] {PageRange.ALL_PAGES};
+        inOrder.verify(adapter).onWrite(eq(secondPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // 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("Test")
+                    .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                    .setPageCount(1)
+                    .build();
+                callback.onLayoutFinished(info, false);
+                // Mark layout was called.
+                layoutCallCounter.call();
+                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.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Select the second printer.
+        selectPrinter("Second printer");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 2);
+
+        // Change the color.
+        changeColor("Black & White");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 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);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // We changed the printer and the new printer does not support the
+        // selected media size in which case the default media size of the
+        // printer is used resulting in a layout pass. Same for margins.
+        PrintAttributes secondOldAttributes = firstNewAttributes;
+        PrintAttributes secondNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A3)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(new Margins(0, 0, 0, 0))
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, secondOldAttributes, secondNewAttributes, true);
+
+        // We changed the printer and the new printer does not support the
+        // current color in which case the default color for the selected
+        // printer is used resulting in a layout pass.
+        PrintAttributes thirdOldAttributes = secondNewAttributes;
+        PrintAttributes thirdNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A3)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(new Margins(0, 0, 0, 0))
+                .setColorMode(PrintAttributes.COLOR_MODE_MONOCHROME)
+                .build();
+        verifyLayoutCall(inOrder, adapter, thirdOldAttributes, thirdNewAttributes, true);
+
+        // We changed the printer to one that does not support the current
+        // media size in which case we pick the default media size for the
+        // new printer which results in a layout pass. Same for color.
+        PrintAttributes fourthOldAttributes = thirdNewAttributes;
+        PrintAttributes fourthNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A4)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(new Margins(200, 200, 200, 200))
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, fourthOldAttributes, fourthNewAttributes, true);
+
+        // When print is pressed we ask for a layout which is *not* for preview.
+        verifyLayoutCall(inOrder, adapter, fourthNewAttributes, fourthNewAttributes, false);
+
+        // When print is pressed we ask for all selected pages.
+        PageRange[] secondPages = new PageRange[] {PageRange.ALL_PAGES};
+        inOrder.verify(adapter).onWrite(eq(secondPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // 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("Test")
+                        .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
+                        .build();
+                // The content changes after every layout.
+                callback.onLayoutFinished(info, true);
+                // Mark layout was called.
+                layoutCallCounter.call();
+                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.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Select the second printer.
+        selectPrinter("Second printer");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 2);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // We selected the second printer which does not support the media
+        // size that was selected, so a new layout happens as the size changed.
+        PrintAttributes secondOldAttributes = firstNewAttributes;
+        PrintAttributes secondNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A3)
+                .setResolution(new Resolution("300x300", "300x300", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, secondOldAttributes, secondNewAttributes, true);
+
+        // In the layout callback we reported that the content changed,
+        // so the previously written page has to be written again.
+        PageRange[] secondPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(secondPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // When print is pressed we ask for a layout which is *not* for preview.
+        verifyLayoutCall(inOrder, adapter, secondNewAttributes, secondNewAttributes, false);
+
+        // When print is pressed we ask for all selected pages.
+        PageRange[] thirdPages = new PageRange[] {PageRange.ALL_PAGES};
+        inOrder.verify(adapter).onWrite(eq(thirdPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // 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("Test")
+                        .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
+                        .build();
+                // The content changes after every layout.
+                callback.onLayoutFinished(info, false);
+                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.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Select the third printer.
+        selectPrinter("Third printer");
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // When print is pressed we ask for a layout which is *not* for preview.
+        verifyLayoutCall(inOrder, adapter, firstNewAttributes, firstNewAttributes, false);
+
+        // When print is pressed we ask for all selected pages.
+        PageRange[] thirdPages = new PageRange[] {PageRange.ALL_PAGES};
+        inOrder.verify(adapter).onWrite(eq(thirdPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // 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("Test")
+                        .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(3)
+                        .build();
+                callback.onLayoutFinished(info, false);
+                // Mark layout was called.
+                layoutCallCounter.call();
+                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.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Select the second printer.
+        selectPrinter("Second printer");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 2);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // We selected the second printer which does not support the media
+        // size that was selected, so a new layout happens as the size changed.
+        PrintAttributes secondOldAttributes = firstNewAttributes;
+        PrintAttributes secondNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A3)
+                .setResolution(new Resolution("300x300", "300x300", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, secondOldAttributes, secondNewAttributes, true);
+
+        // In the layout callback we reported that the content didn't change,
+        // and we wrote all pages in the write call while being asked only
+        // for the first page. Hence, all pages were written and they didn't
+        // change, therefore no subsequent write call should happen.
+
+        // When print is pressed we ask for a layout which is *not* for preview.
+        verifyLayoutCall(inOrder, adapter, secondNewAttributes, secondNewAttributes, false);
+
+        // In the layout callback we reported that the content didn't change,
+        // and we wrote all pages in the write call while being asked only
+        // for the first page. Hence, all pages were written and they didn't
+        // change, therefore no subsequent write call should happen.
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // Create a mock print adapter.
+        final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
+            new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                CancellationSignal cancellation = (CancellationSignal) invocation.getArguments()[2];
+                final LayoutResultCallback callback = (LayoutResultCallback) invocation
+                        .getArguments()[3];
+                cancellation.setOnCancelListener(new OnCancelListener() {
+                    @Override
+                    public void onCancel() {
+                        callback.onLayoutCancelled();
+                    }
+                });
+                layoutCallCounter.call();
+                return null;
+            }
+        }, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 1);
+
+        // Cancel printing.
+        UiDevice.getInstance().pressBack(); // wakes up the device.
+        UiDevice.getInstance().pressBack();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // 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("Test")
+                        .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
+                        .build();
+                callback.onLayoutFinished(info, false);
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                final ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                final CancellationSignal cancellation = (CancellationSignal) args[2];
+                final WriteResultCallback callback = (WriteResultCallback) args[3];
+                cancellation.setOnCancelListener(new OnCancelListener() {
+                    @Override
+                    public void onCancel() {
+                        try {
+                            fd.close();
+                        } catch (IOException ioe) {
+                            /* ignore */
+                        }
+                        callback.onWriteCancelled();
+                    }
+                });
+                // Mark write was called.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Cancel printing.
+        UiDevice.getInstance().pressBack(); // wakes up the device.
+        UiDevice.getInstance().pressBack();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // 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];
+                callback.onLayoutFailed(null);
+                // Mark layout was called.
+                layoutCallCounter.call();
+                return null;
+            }
+        }, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 1);
+
+        // Cancel printing.
+        UiDevice.getInstance().pressBack(); // wakes up the device.
+        UiDevice.getInstance().pressBack();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // No write as layout failed.
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // 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("Test")
+                        .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
+                        .build();
+                callback.onLayoutFinished(info, false);
+                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.onWriteFailed(null);
+                // Mark write was called.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Cancel printing.
+        UiDevice.getInstance().pressBack(); // wakes up the device.
+        UiDevice.getInstance().pressBack();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // 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("Test")
+                      .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
+                      .build();
+                callback.onLayoutFinished(info, false);
+                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();
+                // Write wrong pages.
+                callback.onWriteFinished(new PageRange[] {
+                        new PageRange(Integer.MAX_VALUE,Integer.MAX_VALUE)});
+                // Mark write was called.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Cancel printing.
+        UiDevice.getInstance().pressBack(); // wakes up the device.
+        UiDevice.getInstance().pressBack();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    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();
+
+        // Create a mock print adapter.
+        final PrintDocumentAdapter adapter = createMockPrintDocumentAdapter(
+            new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Break the contract and never call the callback.
+                // Mark layout called.
+                layoutCallCounter.call();
+                return null;
+            }
+        }, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(layoutCallCounter, 1);
+
+        // Cancel printing.
+        UiDevice.getInstance().pressBack(); // wakes up the device.
+        UiDevice.getInstance().pressBack();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    public void testEriteCallbackNotCalled() throws Exception {
+        // Configure the print services.
+        FirstPrintService.setImpl(new SimpleTwoPrintersService());
+        SecondPrintService.setImpl(null);
+
+        final CallCounter writeCallCounter = new CallCounter();
+        final CallCounter finishCallCounter = new CallCounter();
+
+        // 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("Test")
+                        .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(1)
+                        .build();
+                callback.onLayoutFinished(info, false);
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                fd.close();
+                // Break the contract and never call the callback.
+                // Mark write was called.
+                writeCallCounter.call();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                finishCallCounter.call();
+                return null;
+            }
+        });
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write.
+        waitForWriteForAdapterCallback(writeCallCounter);
+
+        // Cancel printing.
+        UiDevice.getInstance().pressBack(); // wakes up the device.
+        UiDevice.getInstance().pressBack();
+
+        // Wait for a finish.
+        waitForAdapterCallbackFinish(finishCallCounter);
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(adapter);
+
+        // Start is always called first.
+        inOrder.verify(adapter).onStart();
+
+        // Start is always followed by a layout. The PDF printer is selected if
+        // there are other printers but none of them was used.
+        PrintAttributes firstOldAttributes = new PrintAttributes.Builder().build();
+        PrintAttributes firstNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.NA_LETTER)
+                .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .build();
+        verifyLayoutCall(inOrder, adapter, firstOldAttributes, firstNewAttributes, true);
+
+        // We always ask for the first page for preview.
+        PageRange[] firstPages = new PageRange[] {new PageRange(0, 0)};
+        inOrder.verify(adapter).onWrite(eq(firstPages), any(ParcelFileDescriptor.class),
+                any(CancellationSignal.class), any(WriteResultCallback.class));
+
+        // Finish is always called last.
+        inOrder.verify(adapter).onFinish();
+
+        // No other call are expected.
+        verifyNoMoreInteractions(adapter);
+    }
+
+    private 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);
+            }
+        });
+    }
+
+    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++;
+            }
+        }
+
+        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/services/AddPrintersActivity.java b/tests/tests/print/src/android/print/cts/services/AddPrintersActivity.java
new file mode 100644
index 0000000..c72d6f9
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/services/AddPrintersActivity.java
@@ -0,0 +1,28 @@
+/*
+ * 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.app.Activity;
+import android.os.Bundle;
+
+public class AddPrintersActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/services/BasePrintService.java b/tests/tests/print/src/android/print/cts/services/BasePrintService.java
new file mode 100644
index 0000000..9d142d1
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/services/BasePrintService.java
@@ -0,0 +1,33 @@
+/*
+ * 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.printservice.PrintJob;
+import android.printservice.PrintService;
+import android.printservice.PrinterDiscoverySession;
+
+public abstract class BasePrintService extends PrintService {
+
+    @Override
+    public abstract PrinterDiscoverySession onCreatePrinterDiscoverySession();
+
+    @Override
+    public abstract void onRequestCancelPrintJob(PrintJob printJob);
+
+    @Override
+    public abstract void onPrintJobQueued(PrintJob printJob);
+}
diff --git a/tests/tests/print/src/android/print/cts/services/CustomPrintOptionsActivity.java b/tests/tests/print/src/android/print/cts/services/CustomPrintOptionsActivity.java
new file mode 100644
index 0000000..9d26d81
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/services/CustomPrintOptionsActivity.java
@@ -0,0 +1,28 @@
+/*
+ * 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.app.Activity;
+import android.os.Bundle;
+
+public class CustomPrintOptionsActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/services/FirstPrintService.java b/tests/tests/print/src/android/print/cts/services/FirstPrintService.java
new file mode 100644
index 0000000..5528a81
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/services/FirstPrintService.java
@@ -0,0 +1,42 @@
+/*
+ * 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.printservice.PrintService;
+
+public class FirstPrintService extends StubbablePrintService {
+
+    private static final Object sLock = new Object();
+
+    private static StubPrintService sImpl;
+
+    public static void setImpl(StubPrintService impl) {
+        synchronized (sLock) {
+            sImpl = impl;
+        }
+    }
+
+    @Override
+    protected BasePrintService getStub(PrintService host) {
+        synchronized (sLock) {
+            if (sImpl != null) {
+                sImpl.setHost(this);
+            }
+            return sImpl;
+        }
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/services/SecondPrintService.java b/tests/tests/print/src/android/print/cts/services/SecondPrintService.java
new file mode 100644
index 0000000..b5db7e9
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/services/SecondPrintService.java
@@ -0,0 +1,42 @@
+/*
+ * 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.printservice.PrintService;
+
+public class SecondPrintService extends StubbablePrintService {
+
+    private static final Object sLock = new Object();
+
+    private static StubPrintService sImpl;
+
+    public static void setImpl(StubPrintService impl) {
+        synchronized (sLock) {
+            sImpl = impl;
+        }
+    }
+
+    @Override
+    protected BasePrintService getStub(PrintService host) {
+        synchronized (sLock) {
+            if (sImpl != null) {
+                sImpl.setHost(this);
+            }
+            return sImpl;
+        }
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/services/SettingsActivity.java b/tests/tests/print/src/android/print/cts/services/SettingsActivity.java
new file mode 100644
index 0000000..eb23574
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/services/SettingsActivity.java
@@ -0,0 +1,28 @@
+/*
+ * 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.app.Activity;
+import android.os.Bundle;
+
+public class SettingsActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/tests/tests/print/src/android/print/cts/services/StubPrintService.java b/tests/tests/print/src/android/print/cts/services/StubPrintService.java
new file mode 100644
index 0000000..115ba5d
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/services/StubPrintService.java
@@ -0,0 +1,30 @@
+/*
+ * 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
new file mode 100644
index 0000000..73afd62
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/services/StubbablePrintService.java
@@ -0,0 +1,86 @@
+/*
+ * 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.PrintJob;
+import android.printservice.PrintService;
+import android.printservice.PrinterDiscoverySession;
+
+import java.util.List;
+
+public abstract class StubbablePrintService extends BasePrintService {
+
+    @Override
+    public PrinterDiscoverySession onCreatePrinterDiscoverySession() {
+        BasePrintService impl = getStub(this);
+        if (impl != null) {
+            return impl.onCreatePrinterDiscoverySession();
+        }
+        return new StubSession();
+    }
+
+    @Override
+    public void onRequestCancelPrintJob(PrintJob printJob) {
+        BasePrintService impl = getStub(this);
+        if (impl != null) {
+            impl.onRequestCancelPrintJob(printJob);
+        }
+    }
+
+    @Override
+    public void onPrintJobQueued(PrintJob printJob) {
+        BasePrintService impl = getStub(this);
+        if (impl != null) {
+            impl.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 */
+        }
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRemoteTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRemoteTestRunner.java
new file mode 100644
index 0000000..3d92eb3
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRemoteTestRunner.java
@@ -0,0 +1,277 @@
+/*
+ * 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 com.android.cts.tradefed.testtype;
+
+import com.android.ddmlib.AdbCommandRejectedException;
+import com.android.ddmlib.IShellEnabledDevice;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.TimeoutException;
+import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.ITestRunListener;
+import com.android.ddmlib.testrunner.InstrumentationResultParser;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.TimeUnit;
+
+public class PrintTestRemoteTestRunner implements IRemoteAndroidTestRunner {
+
+    private final String mPackageName;
+    private final String mRunnerName;
+    private IShellEnabledDevice mRemoteDevice;
+    // default to no timeout
+    private long mMaxTimeToOutputResponse = 0;
+    private TimeUnit mMaxTimeUnits = TimeUnit.MILLISECONDS;
+    private String mRunName = null;
+
+    /** map of name-value instrumentation argument pairs */
+    private Map<String, String> mArgMap;
+    private InstrumentationResultParser mParser;
+
+    private static final String LOG_TAG = "RemoteAndroidTest";
+    private static final String DEFAULT_RUNNER_NAME = "android.test.InstrumentationTestRunner";
+
+    private static final char CLASS_SEPARATOR = ',';
+    private static final char METHOD_SEPARATOR = '#';
+    private static final char RUNNER_SEPARATOR = '/';
+
+    // defined instrumentation argument names
+    private static final String CLASS_ARG_NAME = "class";
+    private static final String LOG_ARG_NAME = "log";
+    private static final String DEBUG_ARG_NAME = "debug";
+    private static final String COVERAGE_ARG_NAME = "coverage";
+    private static final String PACKAGE_ARG_NAME = "package";
+    private static final String SIZE_ARG_NAME = "size";
+
+    // This command starts a shell Java program (installed by this class)
+    // in the folder owned by the shell user. This app creates a proxy
+    // which does privileged operations such as wiping a package's user
+    // data and then starts the tests passing the proxy. This enables
+    // the tests to clear the print spooler data.
+    private static final String INSTRUMENTATION_COMMAND =
+            "chmod 755 /data/local/tmp/print-instrument && "
+            + "/data/local/tmp/print-instrument instrument -w -r %1$s %2$s";
+
+    /**
+     * Creates a remote Android test runner.
+     *
+     * @param packageName the Android application package that contains the
+     *            tests to run
+     * @param runnerName the instrumentation test runner to execute. If null,
+     *            will use default runner
+     * @param remoteDevice the Android device to execute tests on
+     */
+    public PrintTestRemoteTestRunner(String packageName, String runnerName,
+            IShellEnabledDevice remoteDevice) {
+
+        mPackageName = packageName;
+        mRunnerName = runnerName;
+        mRemoteDevice = remoteDevice;
+        mArgMap = new Hashtable<String, String>();
+    }
+
+    /**
+     * Alternate constructor. Uses default instrumentation runner.
+     *
+     * @param packageName the Android application package that contains the
+     *            tests to run
+     * @param remoteDevice the Android device to execute tests on
+     */
+    public PrintTestRemoteTestRunner(String packageName, IShellEnabledDevice remoteDevice) {
+        this(packageName, null, remoteDevice);
+    }
+
+    @Override
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    @Override
+    public String getRunnerName() {
+        if (mRunnerName == null) {
+            return DEFAULT_RUNNER_NAME;
+        }
+        return mRunnerName;
+    }
+
+    /**
+     * Returns the complete instrumentation component path.
+     */
+    private String getRunnerPath() {
+        return getPackageName() + RUNNER_SEPARATOR + getRunnerName();
+    }
+
+    @Override
+    public void setClassName(String className) {
+        addInstrumentationArg(CLASS_ARG_NAME, className);
+    }
+
+    @Override
+    public void setClassNames(String[] classNames) {
+        StringBuilder classArgBuilder = new StringBuilder();
+
+        for (int i = 0; i < classNames.length; i++) {
+            if (i != 0) {
+                classArgBuilder.append(CLASS_SEPARATOR);
+            }
+            classArgBuilder.append(classNames[i]);
+        }
+        setClassName(classArgBuilder.toString());
+    }
+
+    @Override
+    public void setMethodName(String className, String testName) {
+        setClassName(className + METHOD_SEPARATOR + testName);
+    }
+
+    @Override
+    public void setTestPackageName(String packageName) {
+        addInstrumentationArg(PACKAGE_ARG_NAME, packageName);
+    }
+
+    @Override
+    public void addInstrumentationArg(String name, String value) {
+        if (name == null || value == null) {
+            throw new IllegalArgumentException("name or value arguments cannot be null");
+        }
+        mArgMap.put(name, value);
+    }
+
+    @Override
+    public void removeInstrumentationArg(String name) {
+        if (name == null) {
+            throw new IllegalArgumentException("name argument cannot be null");
+        }
+        mArgMap.remove(name);
+    }
+
+    @Override
+    public void addBooleanArg(String name, boolean value) {
+        addInstrumentationArg(name, Boolean.toString(value));
+    }
+
+    @Override
+    public void setLogOnly(boolean logOnly) {
+        addBooleanArg(LOG_ARG_NAME, logOnly);
+    }
+
+    @Override
+    public void setDebug(boolean debug) {
+        addBooleanArg(DEBUG_ARG_NAME, debug);
+    }
+
+    @Override
+    public void setCoverage(boolean coverage) {
+        addBooleanArg(COVERAGE_ARG_NAME, coverage);
+    }
+
+    @Override
+    public void setTestSize(TestSize size) {
+        addInstrumentationArg(SIZE_ARG_NAME, ""/*size.getRunnerValue()*/);
+    }
+
+    @Override
+    public void setMaxtimeToOutputResponse(int maxTimeToOutputResponse) {
+        setMaxTimeToOutputResponse(maxTimeToOutputResponse, TimeUnit.MILLISECONDS);
+    }
+
+    @Override
+    public void setMaxTimeToOutputResponse(long maxTimeToOutputResponse, TimeUnit maxTimeUnits) {
+        mMaxTimeToOutputResponse = maxTimeToOutputResponse;
+        mMaxTimeUnits = maxTimeUnits;
+    }
+
+    @Override
+    public void setRunName(String runName) {
+        mRunName = runName;
+    }
+
+    @Override
+    public void run(ITestRunListener... listeners) throws TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
+        run(Arrays.asList(listeners));
+    }
+
+    @Override
+    public void run(Collection<ITestRunListener> listeners) throws TimeoutException,
+            AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
+        final String runCaseCommandStr = String.format(INSTRUMENTATION_COMMAND,
+              getArgsCommand(), getRunnerPath());
+        Log.i(LOG_TAG,
+                String.format("Running %1$s on %2$s", runCaseCommandStr, mRemoteDevice.getName()));
+        String runName = mRunName == null ? mPackageName : mRunName;
+        mParser = new InstrumentationResultParser(runName, listeners);
+
+        try {
+            mRemoteDevice.executeShellCommand(runCaseCommandStr, mParser, mMaxTimeToOutputResponse,
+                    mMaxTimeUnits);
+        } catch (IOException e) {
+            Log.w(LOG_TAG, String.format("IOException %1$s when running tests %2$s on %3$s",
+                    e.toString(), getPackageName(), mRemoteDevice.getName()));
+            // rely on parser to communicate results to listeners
+            mParser.handleTestRunFailed(e.toString());
+            throw e;
+        } catch (ShellCommandUnresponsiveException e) {
+            Log.w(LOG_TAG, String.format(
+                    "ShellCommandUnresponsiveException %1$s when running tests %2$s on %3$s",
+                    e.toString(), getPackageName(), mRemoteDevice.getName()));
+            mParser.handleTestRunFailed(String
+                    .format("Failed to receive adb shell test output within %1$d ms. "
+                            + "Test may have timed out, or adb connection to device became"
+                            + "unresponsive", mMaxTimeToOutputResponse));
+            throw e;
+        } catch (TimeoutException e) {
+            Log.w(LOG_TAG, String.format("TimeoutException when running tests %1$s on %2$s",
+                    getPackageName(), mRemoteDevice.getName()));
+            mParser.handleTestRunFailed(e.toString());
+            throw e;
+        } catch (AdbCommandRejectedException e) {
+            Log.w(LOG_TAG, String.format(
+                    "AdbCommandRejectedException %1$s when running tests %2$s on %3$s",
+                    e.toString(), getPackageName(), mRemoteDevice.getName()));
+            mParser.handleTestRunFailed(e.toString());
+            throw e;
+        }
+    }
+
+    @Override
+    public void cancel() {
+        if (mParser != null) {
+            mParser.cancel();
+        }
+    }
+
+    /**
+     * Returns the full instrumentation command line syntax for the provided
+     * instrumentation arguments. Returns an empty string if no arguments were
+     * specified.
+     */
+    private String getArgsCommand() {
+        StringBuilder commandBuilder = new StringBuilder();
+        for (Entry<String, String> argPair : mArgMap.entrySet()) {
+            final String argCmd = String.format(" -e %1$s %2$s", argPair.getKey(),
+                    argPair.getValue());
+            commandBuilder.append(argCmd);
+        }
+        return commandBuilder.toString();
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRunner.java
new file mode 100644
index 0000000..a7a6ccc
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRunner.java
@@ -0,0 +1,221 @@
+/*
+ * 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 com.android.cts.tradefed.testtype;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.tradefed.targetprep.SettingsToggler;
+import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner.TestSize;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IDeviceTest;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.util.StringEscapeUtils;
+
+import java.io.FileNotFoundException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Running the print tests requires modification of secure settings. Secure
+ * settings cannot be changed from device CTS tests since system signature
+ * permission is required. Such settings can be modified by the shell user,
+ * so a host side test driver is used for enabling these services, running
+ * the tests, and disabling the services.
+ */
+public class PrintTestRunner implements IBuildReceiver, IRemoteTest, IDeviceTest  {
+
+    private static final String PRINT_TEST_AND_SERVICES_APP_NAME =
+            "CtsPrintTestCases.apk";
+
+    private static final String PRINT_TESTS_PACKAGE_NAME =
+            "com.android.cts.print";
+
+    private static final String FIRST_PRINT_SERVICE_NAME =
+            "android.print.cts.services.FirstPrintService";
+
+    private static final String SECOND_PRINT_SERVICE_NAME =
+            "android.print.cts.services.SecondPrintService";
+
+    private static final String SHELL_USER_FOLDER = "data/local/tmp";
+
+    private static final String PRINT_INSTRUMENT_JAR = "CtsPrintInstrument.jar";
+
+    private static final String PRINT_INSTRUMENT_SCRIPT = "print-instrument";
+
+    private ITestDevice mDevice;
+
+    private CtsBuildHelper mCtsBuild;
+
+    private String mPackageName;
+    private String mRunnerName = "android.test.InstrumentationTestRunner";
+    private String mTestClassName;
+    private String mTestMethodName;
+    private String mTestPackageName;
+    private int mTestTimeout = 10 * 60 * 1000;  // 10 minutes
+    private String mTestSize;
+    private String mRunName = null;
+    private Map<String, String> mInstrArgMap = new HashMap<String, String>();
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    @Override
+    public void setDevice(ITestDevice device) {
+        mDevice = device;
+    }
+
+    @Override
+    public ITestDevice getDevice() {
+        return mDevice;
+    }
+
+    public void setPackageName(String packageName) {
+        mPackageName = packageName;
+    }
+
+    public void setRunnerName(String runnerName) {
+        mRunnerName = runnerName;
+    }
+
+    public void setClassName(String testClassName) {
+        mTestClassName = testClassName;
+    }
+
+    public void setMethodName(String testMethodName) {
+        mTestMethodName = StringEscapeUtils.escapeShell(testMethodName);
+    }
+
+    public void setTestPackageName(String testPackageName) {
+        mTestPackageName = testPackageName;
+    }
+
+    public void setTestSize(String size) {
+        mTestSize = size;
+    }
+
+    public void setRunName(String runName) {
+        mRunName = runName;
+    }
+
+    @Override
+    public void run(final ITestInvocationListener listener) throws DeviceNotAvailableException {
+        installShellProgramAndScriptFiles();
+        installTestsAndServicesApk();
+        enablePrintServices();
+        doRunTests(listener);
+        disablePrintServices();
+        uninstallTestsAndServicesApk();
+        uninstallShellProgramAndScriptFiles();
+    }
+
+    private void doRunTests(ITestInvocationListener listener)
+            throws DeviceNotAvailableException {
+        if (mPackageName == null) {
+            throw new IllegalArgumentException("package name has not been set");
+        }
+        if (mDevice == null) {
+            throw new IllegalArgumentException("Device has not been set");
+        }
+
+        IRemoteAndroidTestRunner runner =  new PrintTestRemoteTestRunner(mPackageName,
+                mRunnerName, mDevice.getIDevice());
+
+        if (mTestClassName != null) {
+            if (mTestMethodName != null) {
+                runner.setMethodName(mTestClassName, mTestMethodName);
+            } else {
+                runner.setClassName(mTestClassName);
+            }
+        } else if (mTestPackageName != null) {
+            runner.setTestPackageName(mTestPackageName);
+        }
+        if (mTestSize != null) {
+            runner.setTestSize(TestSize.getTestSize(mTestSize));
+        }
+        runner.setMaxTimeToOutputResponse(mTestTimeout, TimeUnit.MILLISECONDS);
+        if (mRunName != null) {
+            runner.setRunName(mRunName);
+        }
+        for (Map.Entry<String, String> argEntry : mInstrArgMap.entrySet()) {
+            runner.addInstrumentationArg(argEntry.getKey(), argEntry.getValue());
+        }
+
+        mDevice.runInstrumentationTests(runner, listener);
+    }
+
+    private void installShellProgramAndScriptFiles() throws DeviceNotAvailableException {
+        installFile(PRINT_INSTRUMENT_JAR);
+        installFile(PRINT_INSTRUMENT_SCRIPT);
+    }
+
+    private void installFile(String fileName) throws DeviceNotAvailableException {
+        try {
+            final boolean success = getDevice().pushFile(mCtsBuild.getTestApp(
+                    fileName), SHELL_USER_FOLDER + "/" + fileName);
+            if (!success) {
+                throw new IllegalArgumentException("Failed to install "
+                        + fileName + " on " + getDevice().getSerialNumber());
+           }
+        } catch (FileNotFoundException fnfe) {
+            throw new IllegalArgumentException("Cannot find file: " + fileName);
+        }
+    }
+
+    private void uninstallShellProgramAndScriptFiles() throws DeviceNotAvailableException {
+        getDevice().executeShellCommand("rm " + SHELL_USER_FOLDER + "/"
+                + PRINT_INSTRUMENT_JAR);
+        getDevice().executeShellCommand("rm " + SHELL_USER_FOLDER + "/"
+                + PRINT_INSTRUMENT_SCRIPT);
+    }
+
+    private void installTestsAndServicesApk() throws DeviceNotAvailableException {
+        try {
+            String installCode = getDevice().installPackage(mCtsBuild.getTestApp(
+                    PRINT_TEST_AND_SERVICES_APP_NAME), true);
+            if (installCode != null) {
+                throw new IllegalArgumentException("Failed to install "
+                        + PRINT_TEST_AND_SERVICES_APP_NAME + " on " + getDevice().getSerialNumber()
+                        + ". Reason: " + installCode);
+           }
+        } catch (FileNotFoundException fnfe) {
+            throw new IllegalArgumentException("Cannot find file: "
+                    + PRINT_TEST_AND_SERVICES_APP_NAME);
+        }
+    }
+
+    private void uninstallTestsAndServicesApk() throws DeviceNotAvailableException {
+        getDevice().uninstallPackage(PRINT_TESTS_PACKAGE_NAME);
+    }
+
+    private void enablePrintServices() throws DeviceNotAvailableException {
+        String enabledServicesValue = PRINT_TESTS_PACKAGE_NAME + "/" + FIRST_PRINT_SERVICE_NAME
+                + ":" + PRINT_TESTS_PACKAGE_NAME + "/" + SECOND_PRINT_SERVICE_NAME;
+        SettingsToggler.setSecureString(getDevice(), "enabled_print_services",
+                enabledServicesValue);
+    }
+
+    private void disablePrintServices() throws DeviceNotAvailableException {
+        SettingsToggler.setSecureString(getDevice(), "enabled_print_services", "");
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index 8ab5d18..994da0b 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -47,9 +47,11 @@
     public static final String WRAPPED_NATIVE_TEST = "wrappednative";
     public static final String VM_HOST_TEST = "vmHostTest";
     public static final String ACCESSIBILITY_TEST =
-        "com.android.cts.tradefed.testtype.AccessibilityTestRunner";
+            "com.android.cts.tradefed.testtype.AccessibilityTestRunner";
     public static final String ACCESSIBILITY_SERVICE_TEST =
-        "com.android.cts.tradefed.testtype.AccessibilityServiceTestRunner";
+            "com.android.cts.tradefed.testtype.AccessibilityServiceTestRunner";
+    public static final String PRINT_TEST =
+            "com.android.cts.tradefed.testtype.PrintTestRunner";
     public static final String DISPLAY_TEST =
             "com.android.cts.tradefed.testtype.DisplayTestRunner";
     public static final String UIAUTOMATOR_TEST = "uiAutomator";
@@ -61,7 +63,6 @@
     private String mAppNameSpace = null;
     private String mName = null;
     private String mRunner = null;
-    private boolean mIsVMHostTest = false;
     private String mTestType = null;
     private String mJarPath = null;
     private boolean mIsSignatureTest = false;
@@ -230,6 +231,9 @@
         } else if (ACCESSIBILITY_TEST.equals(mTestType)) {
             AccessibilityTestRunner test = new AccessibilityTestRunner();
             return setInstrumentationTest(test, testCaseDir);
+        } else if (PRINT_TEST.equals(mTestType)) {
+            PrintTestRunner test = new PrintTestRunner();
+            return setPrintTest(test, testCaseDir);
         } else if (ACCESSIBILITY_SERVICE_TEST.equals(mTestType)) {
             AccessibilityServiceTestRunner test = new AccessibilityServiceTestRunner();
             return setInstrumentationTest(test, testCaseDir);
@@ -270,6 +274,18 @@
         }
     }
 
+    private PrintTestRunner setPrintTest(PrintTestRunner printTest,
+            File testCaseDir) {
+        printTest.setRunName(getUri());
+        printTest.setPackageName(mAppNameSpace);
+        printTest.setRunnerName(mRunner);
+        printTest.setTestPackageName(mTestPackageName);
+        printTest.setClassName(mClassName);
+        printTest.setMethodName(mMethodName);
+        mDigest = generateDigest(testCaseDir, String.format("%s.apk", mName));
+        return printTest;
+    }
+
     /**
      * Populates given {@link InstrumentationApkTest} with data from the package xml.
      *
