Merge "Add new calllog fields to CTS test for Calls table"
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index e85109d..5fe6c5e 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -82,7 +82,6 @@
     CtsDreamsTestCases \
     CtsDrmTestCases \
     CtsEffectTestCases \
-    CtsExampleTestCases \
     CtsGestureTestCases \
     CtsGraphicsTestCases \
     CtsGraphics2TestCases \
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index b080b18..848c853 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -677,7 +677,7 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
             <meta-data android:name="test_required_features" android:value="android.hardware.sensor.gyroscope" />
-            <meta-data android:name="test_required_features" android:value="android.hardware.camera"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
         </activity>
         <activity
             android:name=".camera.fov.DetermineFovActivity"
@@ -805,6 +805,15 @@
             </intent-filter>
         </activity-alias>
 
+        <activity android:name=".sample.SampleTestActivity"
+                  android:label="@string/sample_framework_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_other" />
+        </activity>
+
         <activity android:name=".widget.WidgetTestActivity"
                 android:label="@string/widget_framework_test">
             <intent-filter>
diff --git a/apps/CtsVerifier/res/layout/pass_fail_sample.xml b/apps/CtsVerifier/res/layout/pass_fail_sample.xml
new file mode 100644
index 0000000..84d79ee
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/pass_fail_sample.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+    <Button android:id="@+id/sample_share_btn"
+            android:text="@string/share_button_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+    <include android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            layout="@layout/pass_fail_buttons" />
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 58f0103..e0e6dfc 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -412,6 +412,12 @@
     <!-- Magnetic Field -->
     <string name="snsr_mag_m_test">Magnetic Field Measurement Tests</string>
 
+    <!-- Strings for Sample Test Activities -->
+    <string name="share_button_text">Share</string>
+    <string name="sample_framework_test">Sample Framework Test</string>
+    <string name="sample_test">Sample Test</string>
+    <string name="sample_test_info">This test verifies that bluetooth sharing is working properly.\nThe test assumes the Device Under Test has bluetooth enabled and is already paired with a second device, also with bluetooth enabled.\nStart this test by clicking share, choose bluetooth from the options, and then select a device to share with.\nNote: This is a sample test, used to demonstrate how to write CTS Verifier tests, so just click pass.</string>
+
     <!-- Strings for SuidFilesActivity -->
     <string name="suid_files">SUID File Scanner</string>
     <string name="suid_files_info">This test will attempt to find unauthorized SUID binaries, but it is not comprehensive due to permission restrictions.\n\nAuthorized SUID binaries will appear green, while unauthorized SUID binaries will appear red.\n\nPress OK to start the scan...</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sample/SampleTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sample/SampleTestActivity.java
new file mode 100644
index 0000000..25f90d9
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sample/SampleTestActivity.java
@@ -0,0 +1,102 @@
+/*
+ * 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.verifier.sample;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+/**
+ * A sample CTS Verifier test case for testing file transfers using bluetooth sharing.
+ *
+ * This test assumes bluetooth is turned on and the device is already paired with a second device.
+ * Note: the second device need not be an Android device; it could be a laptop or desktop.
+ */
+public class SampleTestActivity extends PassFailButtons.Activity {
+
+    /**
+     * The name of the test file being transferred.
+     */
+    private static final String FILE_NAME = "test.txt";
+
+    /**
+     * The content of the test file being transferred.
+     */
+    private static final String TEST_STRING = "Sample Test String";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Setup the UI.
+        setContentView(R.layout.pass_fail_sample);
+        setPassFailButtonClickListeners();
+        setInfoResources(R.string.sample_test, R.string.sample_test_info, -1);
+        // Get the share button and attach the listener.
+        Button shareBtn = (Button) findViewById(R.id.sample_share_btn);
+        shareBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    createFileAndShare();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+    }
+
+    /**
+     * Creates a temporary file containing the test string and then issues the intent to share it.
+     *
+     * @throws Exception
+     */
+    private void createFileAndShare() throws Exception {
+        // Use the external cache directory so the file will be deleted when the app is uninstalled
+        // and the file can be accessed by other apps, such as the sharing app.
+        File dir = getExternalCacheDir ();
+        // Create the file with the given name.
+        File file = new File(dir, FILE_NAME);
+        FileOutputStream outputStream = null;
+        try {
+            // Write the test string to the test file.
+            outputStream = new FileOutputStream(file);
+            outputStream.write(TEST_STRING.getBytes());
+
+            // Create the share intent.
+            Intent intent = new Intent();
+            intent.setAction(Intent.ACTION_SEND);
+            intent.setType("text/plain");
+            intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
+            startActivity(intent);
+        } finally {
+            // Clean up.
+            if (outputStream != null) {
+                outputStream.close();
+            }
+        }
+
+    }
+}
diff --git a/build/test_package.mk b/build/test_package.mk
index 73f2a13..a0adb5f 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -36,12 +36,12 @@
 $(cts_package_xml): PRIVATE_PATH := $(LOCAL_PATH)
 $(cts_package_xml): PRIVATE_INSTRUMENTATION := $(LOCAL_INSTRUMENTATION_FOR)
 $(cts_package_xml): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
-ifneq ($(filter cts/suite/cts/%, $(LOCAL_PATH)),) # CTS
-PRIVATE_CTS_TEST_PACKAGE_NANE_ := com.android.cts.$(notdir $(LOCAL_PATH))
-else # CTS
-PRIVATE_CTS_TEST_PACKAGE_NANE_ := android.$(notdir $(LOCAL_PATH))
-endif # CTS
-$(cts_package_xml): PRIVATE_TEST_PACKAGE := $(PRIVATE_CTS_TEST_PACKAGE_NANE_)
+ifneq ($(filter cts/suite/cts/%, $(LOCAL_PATH)),)
+PRIVATE_CTS_TEST_PACKAGE_NAME_ := com.android.cts.$(notdir $(LOCAL_PATH))
+else
+PRIVATE_CTS_TEST_PACKAGE_NAME_ := android.$(notdir $(LOCAL_PATH))
+endif
+$(cts_package_xml): PRIVATE_TEST_PACKAGE := $(PRIVATE_CTS_TEST_PACKAGE_NAME_)
 $(cts_package_xml): PRIVATE_MANIFEST := $(LOCAL_PATH)/AndroidManifest.xml
 $(cts_package_xml): PRIVATE_TEST_TYPE := $(if $(LOCAL_CTS_TEST_RUNNER),$(LOCAL_CTS_TEST_RUNNER),'')
 $(cts_package_xml): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk $(CTS_EXPECTATIONS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
diff --git a/hostsidetests/sample/Android.mk b/hostsidetests/sample/Android.mk
new file mode 100644
index 0000000..1d3ddc8
--- /dev/null
+++ b/hostsidetests/sample/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := optional
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_MODULE := CtsSampleHostTestCases
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed ddmlib-prebuilt tradefed-prebuilt
+
+LOCAL_CTS_TEST_PACKAGE := android.host.sample
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/example/Android.mk b/hostsidetests/sample/app/Android.mk
similarity index 76%
copy from tests/tests/example/Android.mk
copy to hostsidetests/sample/app/Android.mk
index c6ef67b..4af45b9 100644
--- a/tests/tests/example/Android.mk
+++ b/hostsidetests/sample/app/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 The Android Open Source Project
+# Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -16,22 +16,16 @@
 
 include $(CLEAR_VARS)
 
-# Replace "Example" with your name.
-LOCAL_PACKAGE_NAME := CtsExampleTestCases
-
 # Don't include this package in any target.
 LOCAL_MODULE_TAGS := optional
 
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-# All tests should include android.test.runner.
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_PACKAGE_NAME := CtsSampleDeviceApp
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/sample/app/AndroidManifest.xml b/hostsidetests/sample/app/AndroidManifest.xml
new file mode 100755
index 0000000..c087435
--- /dev/null
+++ b/hostsidetests/sample/app/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.sample.app">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <application>
+        <activity android:name=".SampleDeviceActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
+
diff --git a/hostsidetests/sample/app/src/android/sample/app/SampleDeviceActivity.java b/hostsidetests/sample/app/src/android/sample/app/SampleDeviceActivity.java
new file mode 100644
index 0000000..d7efc0c
--- /dev/null
+++ b/hostsidetests/sample/app/src/android/sample/app/SampleDeviceActivity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.sample.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+/**
+ * A simple activity which logs to Logcat.
+ */
+public class SampleDeviceActivity extends Activity {
+
+    private static final String TAG = SampleDeviceActivity.class.getSimpleName();
+
+    /**
+     * The test string to log.
+     */
+    private static final String TEST_STRING = "SampleTestString";
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        // Log the test string to Logcat.
+        Log.i(TAG, TEST_STRING);
+    }
+
+}
diff --git a/hostsidetests/sample/src/android/sample/cts/SampleHostResultTest.java b/hostsidetests/sample/src/android/sample/cts/SampleHostResultTest.java
new file mode 100644
index 0000000..a3bc08f
--- /dev/null
+++ b/hostsidetests/sample/src/android/sample/cts/SampleHostResultTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.sample.cts;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.tradefed.util.HostReportLog;
+import com.android.cts.util.MeasureRun;
+import com.android.cts.util.MeasureTime;
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+import com.android.cts.util.ReportLog;
+import com.android.cts.util.Stat;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.IDevice;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.RunUtil;
+
+import java.io.File;
+import java.lang.Exception;
+
+/**
+ * Test to measure the transfer time of a file from the host to the device.
+ */
+public class SampleHostResultTest extends DeviceTestCase implements IBuildReceiver {
+
+    private static final String TAG = SampleHostResultTest.class.getSimpleName();
+
+    /**
+     * The number of times to repeat the test.
+     */
+    private static final int REPEAT = 5;
+
+    /**
+     * The name of the plan to transfer.
+     *
+     * In this case we will transfer the CTS.xml file.
+     */
+    private static final String PLAN_NAME = "CTS";
+
+    /**
+     * A reference to the build.
+     */
+    private CtsBuildHelper mBuild;
+
+    /**
+     * A reference to the device under test.
+     */
+    private ITestDevice mDevice;
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        // Get the build, this is used to access the APK.
+        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // Get the device, this gives a handle to run commands and install APKs.
+        mDevice = getDevice();
+    }
+
+    /**
+     * Measures the time taken to transfer a file to the device and then back.
+     *
+     * The workload is repeated several times and the report is populated with the result.
+     *
+     * @throws Exception
+     */
+    public void testTransferTime() throws Exception {
+        final ITestDevice device = mDevice;
+        // Get the external storage location and ensure its not null.
+        final String externalStorePath = mDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+        assertNotNull("External storage location no found", externalStorePath);
+        // Create the device side path where the file will be transfered.
+        final String devicePath = String.format("%s/%s", externalStorePath, "tmp_testPushPull.txt");
+        // Get the file from the build.
+        final File testFile = mBuild.getTestPlanFile(PLAN_NAME);
+        double[] result = MeasureTime.measure(REPEAT, new MeasureRun() {
+            @Override
+            public void prepare(int i) throws Exception {
+                device.executeShellCommand(String.format("rm %s", devicePath));
+            }
+            @Override
+            public void run(int i) throws Exception {
+                // Create a temporary file to compare with.
+                File tmpFile = FileUtil.createTempFile("tmp", "txt");
+                try {
+                    // Push the file across and ensure it exists.
+                    assertTrue("Could not push file", device.pushFile(testFile, devicePath));
+                    assertTrue("Unsuccessful transfer", device.doesFileExist(devicePath));
+                    // Pull the file back and ensure it is the same.
+                    assertTrue("Could not pull file", device.pullFile(devicePath, tmpFile));
+                    assertFilesAreEqual(testFile, tmpFile);
+                } finally {
+                    // Clean up.
+                    tmpFile.delete();
+                    device.executeShellCommand(String.format("rm %s", devicePath));
+                }
+            }
+        });
+        // Compute the stats.
+        Stat.StatResult stat = Stat.getStat(result);
+        // Get the report for this test and add the results to record.
+        HostReportLog report = new HostReportLog(mDevice.getSerialNumber(),
+                ReportLog.getClassMethodNames());
+        report.printArray("Times", result, ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.printValue("Min", stat.mMin, ResultType.LOWER_BETTER, ResultUnit.MS);
+        report.printValue("Max", stat.mMax, ResultType.LOWER_BETTER, ResultUnit.MS);
+        // Every report must have a summary,
+        report.printSummary("Average", stat.mAverage, ResultType.LOWER_BETTER, ResultUnit.MS);
+        // Send the report to Tradefed.
+        report.deliverReportToHost();
+    }
+
+    /**
+     * Asserts the two given files are equal using the diff utility.
+     *
+     * @throws Exception
+     */
+    private static void assertFilesAreEqual(File first, File second) throws Exception {
+        CommandResult result = RunUtil.getDefault().runTimedCmd(5000, "diff",
+                first.getAbsolutePath(), second.getAbsolutePath());
+        assertTrue("Diff failed to run", result.getStatus() == CommandStatus.SUCCESS);
+        assertTrue("Files are not equivalent", "".equals(result.getStdout()));
+    }
+
+}
diff --git a/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java b/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java
new file mode 100644
index 0000000..7ccde0e
--- /dev/null
+++ b/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.sample.cts;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.lang.String;
+import java.util.Scanner;
+
+/**
+ * Test to check the APK logs to Logcat.
+ *
+ * When this test builds, it also builds {@see android.sample.app.SampleDeviceActivity} into an APK
+ * which it then installs at runtime and starts. The activity simply prints a message to Logcat and
+ * then gets uninstalled.
+ */
+public class SampleHostTest extends DeviceTestCase implements IBuildReceiver {
+
+    /**
+     * The package name of the APK.
+     */
+    private static final String PACKAGE = "android.sample.app";
+
+    /**
+     * The file name of the APK.
+     */
+    private static final String APK = "CtsSampleDeviceApp.apk";
+
+    /**
+     * The class name of the main activity in the APK.
+     */
+    private static final String CLASS = "SampleDeviceActivity";
+
+    /**
+     * The command to launch the main activity.
+     */
+    private static final String START_COMMAND = String.format(
+            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE, PACKAGE, CLASS);
+
+    /**
+     * The test string to look for.
+     */
+    private static final String TEST_STRING = "SampleTestString";
+
+    /**
+     * A reference to the build.
+     */
+    private CtsBuildHelper mBuild;
+
+    /**
+     * A reference to the device under test.
+     */
+    private ITestDevice mDevice;
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        // Get the build, this is used to access the APK.
+        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // Get the device, this gives a handle to run commands and install APKs.
+        mDevice = getDevice();
+        // Remove any previously installed versions of this APK.
+        mDevice.uninstallPackage(PACKAGE);
+        // Get the APK from the build.
+        File app = mBuild.getTestApp(APK);
+        // Install the APK on the device.
+        mDevice.installPackage(app, false);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Remove the package once complete.
+        mDevice.uninstallPackage(PACKAGE);
+        super.tearDown();
+    }
+
+    /**
+     * Tests the string was successfully logged to Logcat from the activity.
+     *
+     * @throws Exception
+     */
+    public void testLogcat() throws Exception {
+        // Clear logcat.
+        mDevice.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        mDevice.executeShellCommand(START_COMMAND);
+        // Dump logcat.
+        String logs = mDevice.executeAdbCommand("logcat", "-d", CLASS + ":I", "*:S");
+        // Search for string.
+        String testString = "";
+        Scanner in = new Scanner(logs);
+        while (in.hasNextLine()) {
+            String line = in.nextLine();
+            if(line.startsWith("I/"+CLASS)) {
+                testString = line.split(":")[1].trim();
+            }
+        }
+        // Assert the logged string matches the test string.
+        assertEquals("Incorrect test string", TEST_STRING, testString);
+    }
+}
diff --git a/libs/commonutil/src/com/android/cts/util/MeasureTime.java b/libs/commonutil/src/com/android/cts/util/MeasureTime.java
index c158228..fd22ef2 100644
--- a/libs/commonutil/src/com/android/cts/util/MeasureTime.java
+++ b/libs/commonutil/src/com/android/cts/util/MeasureTime.java
@@ -23,9 +23,9 @@
      * @param count
      * @param run
      * @return array of time taken in each run in msec.
-     * @throws IOException
+     * @throws Exception
      */
-    public static double[] measure(int count, MeasureRun run)  throws Exception {
+    public static double[] measure(int count, MeasureRun run) throws Exception {
         double[] result = new double[count];
 
         for (int i = 0; i < count; i++) {
diff --git a/suite/audio_quality/test_description/dut_playback_sample.xml b/suite/audio_quality/test_description/dut_playback_sample.xml
new file mode 100644
index 0000000..f78209e
--- /dev/null
+++ b/suite/audio_quality/test_description/dut_playback_sample.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+
+<case name="dut_playback_sample" version="1.0" description="Sample test which check frequency of DUT's playback">
+	<setup>
+		<!-- prepare sound source id: to be used in output, sine 1000Hz, 4000ms long -->
+		<sound id="sound1" type="sin:32000:1000:4000" preload="1" />
+	</setup>
+	<action>
+		<sequential repeat="1" index="i">
+			<output device="DUT" id="sound1" gain="100" sync="start" waitforcompletion="0" />
+			<sequential repeat="1" index="j">
+				<!-- dummy recording to compensate for possible playback latency -->
+				<input device="host" id="dummy" gain="100" time="1000" sync="complete" />
+				<input device="host" id="host_in_$j" gain="100" time="2000" sync="complete" />
+			</sequential>
+		</sequential>
+		<sequential repeat="1" index="k">
+			<!-- input: host record, signal frequency in Hz, threshold, output: frequency calculated -->
+			<process method="script:playback_sample" input="id:host_in_$k,consti:1000,constf:5.0" output="val:freq_device_$k" />
+		</sequential>
+	</action>
+	<save file="host_in_.*" report="freq_device_.*" />
+</case>
diff --git a/suite/audio_quality/test_description/processing/playback_sample.py b/suite/audio_quality/test_description/processing/playback_sample.py
new file mode 100644
index 0000000..79e8d53
--- /dev/null
+++ b/suite/audio_quality/test_description/processing/playback_sample.py
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+
+# 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.
+
+from consts import *
+
+# Sample test for dut_playback_sample case
+# Input: host recording (mono),
+#        frequency of sine in Hz (i64)
+#        pass level threshold (double)
+# Output: device (double) frequency
+
+def playback_sample(inputData, inputTypes):
+    output = []
+    outputData = []
+    outputTypes = []
+    # basic sanity check
+    inputError = False
+    if (inputTypes[0] != TYPE_MONO):
+        inputError = True
+    if (inputTypes[1] != TYPE_I64):
+        inputError = True
+    if (inputTypes[2] != TYPE_DOUBLE):
+        inputError = True
+    if inputError:
+        output.append(RESULT_ERROR)
+        output.append(outputData)
+        output.append(outputTypes)
+        return output
+
+    hostRecording = inputData[0]
+    signalFrequency = inputData[1]
+    threshold = inputData[2]
+    samplingRate = 44100
+
+    freq = calc_freq(hostRecording, samplingRate)
+    print "Expected Freq ", signalFrequency, "Actual Freq ", freq, "Threshold % ", threshold
+    diff = abs(freq - signalFrequency)
+    if (diff < threshold):
+        output.append(RESULT_PASS)
+    else:
+        output.append(RESULT_OK)
+    outputData.append(freq)
+    outputTypes.append(TYPE_DOUBLE)
+    output.append(outputData)
+    output.append(outputTypes)
+    return output
+
+def calc_freq(recording, samplingRate):
+    #This would calculate the frequency of recording, but is skipped in this sample test for brevity
+    return 32000
\ No newline at end of file
diff --git a/tests/res/layout/inflater_override_theme_layout.xml b/tests/res/layout/inflater_override_theme_layout.xml
index 4440f7c..8c524ba 100644
--- a/tests/res/layout/inflater_override_theme_layout.xml
+++ b/tests/res/layout/inflater_override_theme_layout.xml
@@ -18,8 +18,8 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    theme="@style/Theme_OverrideOuter"
-    android:orientation="vertical" >
+    android:orientation="vertical"
+    android:theme="@style/Theme_OverrideOuter" >
 
     <View
         android:id="@+id/view_outer"
@@ -29,13 +29,19 @@
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        theme="@style/Theme_OverrideInner"
-        android:orientation="vertical" >
+        android:orientation="vertical"
+        android:theme="@style/Theme_OverrideInner" >
 
         <View
             android:id="@+id/view_inner"
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
+
+        <View
+            android:id="@+id/view_attr"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:theme="?attr/themeOverrideAttr" />
     </LinearLayout>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/tests/res/values/attrs.xml b/tests/res/values/attrs.xml
index 0525cae..404427d 100644
--- a/tests/res/values/attrs.xml
+++ b/tests/res/values/attrs.xml
@@ -127,4 +127,6 @@
     </declare-styleable>
     <!-- Integer used to uniquely identify theme overrides. -->
     <attr name="themeType" format="integer"/>
+    <!-- Theme reference used to override parent theme. -->
+    <attr name="themeOverrideAttr" format="reference"/>
 </resources>
diff --git a/tests/res/values/styles.xml b/tests/res/values/styles.xml
index 047e97c..daaed48 100644
--- a/tests/res/values/styles.xml
+++ b/tests/res/values/styles.xml
@@ -144,6 +144,11 @@
 
     <style name="Theme_OverrideInner">
         <item name="themeType">2</item>
+        <item name="themeOverrideAttr">@style/Theme_OverrideAttr</item>
+    </style>
+
+    <style name="Theme_OverrideAttr">
+        <item name="themeType">3</item>
     </style>
 
 </resources>
diff --git a/tests/tests/example/Android.mk b/tests/sample/Android.mk
old mode 100644
new mode 100755
similarity index 82%
rename from tests/tests/example/Android.mk
rename to tests/sample/Android.mk
index c6ef67b..e1a9408
--- a/tests/tests/example/Android.mk
+++ b/tests/sample/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 The Android Open Source Project
+# Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -16,9 +16,6 @@
 
 include $(CLEAR_VARS)
 
-# Replace "Example" with your name.
-LOCAL_PACKAGE_NAME := CtsExampleTestCases
-
 # Don't include this package in any target.
 LOCAL_MODULE_TAGS := optional
 
@@ -28,10 +25,13 @@
 # All tests should include android.test.runner.
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_PACKAGE_NAME := CtsSampleDeviceTestCases
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/sample/AndroidManifest.xml b/tests/sample/AndroidManifest.xml
new file mode 100755
index 0000000..ae58f0a
--- /dev/null
+++ b/tests/sample/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.sample.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:name="android.sample.SampleDeviceActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <!--  self-instrumenting test package. -->
+    <instrumentation
+        android:name="android.test.InstrumentationCtsTestRunner"
+        android:label="CTS sample tests"
+        android:targetPackage="android.sample.cts" />
+
+</manifest>
+
diff --git a/tests/sample/src/android/sample/SampleDeviceActivity.java b/tests/sample/src/android/sample/SampleDeviceActivity.java
new file mode 100644
index 0000000..8fd8fde
--- /dev/null
+++ b/tests/sample/src/android/sample/SampleDeviceActivity.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.sample;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Bundle;
+
+import java.lang.Override;
+
+/**
+ * A simple activity for using the SharedPreferences API.
+ */
+public class SampleDeviceActivity extends Activity {
+
+    private SharedPreferences mPreferences;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        // Get a reference to this context's shared preference.
+        mPreferences = getPreferences(Context.MODE_PRIVATE);
+    }
+
+    /**
+     * Saves the given key value pair to the shared preferences.
+     *
+     * @param key
+     * @param value
+     */
+    public void savePreference(String key, String value) {
+        // Get an editor to modify the preferences.
+        Editor editor = mPreferences.edit();
+        // Insert the key value pair.
+        editor.putString(key, value);
+        // Commit the changes - important.
+        editor.commit();
+    }
+
+    /**
+     * Looks up the given key in the shared preferences.
+     *
+     * @param key
+     * @return
+     */
+    public String getPreference(String key) {
+        return mPreferences.getString(key, null);
+    }
+
+    /**
+     * Deletes all entries in the shared preferences.
+     */
+    public void clearPreferences() {
+        // Get an editor to modify the preferences.
+        Editor editor = mPreferences.edit();
+        // Delete all entries.
+        editor.clear();
+        // Commit the changes - important.
+        editor.commit();
+    }
+
+}
diff --git a/tests/sample/src/android/sample/cts/SampleDeviceResultTest.java b/tests/sample/src/android/sample/cts/SampleDeviceResultTest.java
new file mode 100644
index 0000000..6bf883f
--- /dev/null
+++ b/tests/sample/src/android/sample/cts/SampleDeviceResultTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.sample.cts;
+
+import com.android.cts.util.MeasureRun;
+import com.android.cts.util.MeasureTime;
+import com.android.cts.util.ReportLog;
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+import com.android.cts.util.Stat;
+
+import android.cts.util.CtsAndroidTestCase;
+
+/**
+ * A simple compatibility test which includes results in the report.
+ *
+ * This test measures the time taken to run a workload and adds in the report.
+ */
+public class SampleDeviceResultTest extends CtsAndroidTestCase {
+
+    /**
+     * The number of times to repeat the test.
+     */
+    private static final int REPEAT = 5;
+
+    /**
+     * The input number for the factorial.
+     */
+    private static final int IN = 15;
+
+    /**
+     * The expected output number for the factorial.
+     */
+    private static final long OUT = 1307674368000L;
+
+    /**
+     * Measures the time taken to compute the factorial of 15 with a recursive method.
+     *
+     * @throws Exception
+     */
+    public void testFactorialRecursive() throws Exception {
+        runTest(new MeasureRun() {
+            @Override
+            public void run(int i) throws Exception {
+                // Compute the factorial and assert it is correct.
+                assertEquals("Incorrect result", OUT, factorialRecursive(IN));
+            }
+        });
+    }
+
+    /**
+     * Measures the time taken to compute the factorial of 15 with a iterative method.
+     *
+     * @throws Exception
+     */
+    public void testFactorialIterative() throws Exception {
+        runTest(new MeasureRun() {
+            @Override
+            public void run(int i) throws Exception {
+                // Compute the factorial and assert it is correct.
+                assertEquals("Incorrect result", OUT, factorialIterative(IN));
+            }
+        });
+    }
+
+    /**
+     * Computes the factorial of a number with a recursive method.
+     *
+     * @param num The number to compute the factorial of.
+     */
+    private static long factorialRecursive(int num) {
+        if (num <= 0) {
+            return 1;
+        }
+        return num * factorialRecursive(num - 1);
+    }
+
+    /**
+     * Computes the factorial of a number with a iterative method.
+     *
+     * @param num The number to compute the factorial of.
+     */
+    private static long factorialIterative(int num) {
+        long result = 1;
+        for (int i = 2; i <= num; i++) {
+            result *= i;
+        }
+        return result;
+    }
+
+    /**
+     * Runs the workload and records the result to the report log.
+     *
+     * @param workload
+     */
+    private void runTest(MeasureRun workload) throws Exception {
+        // MeasureTime runs the workload N times and records the time taken by each run.
+        double[] result = MeasureTime.measure(REPEAT, workload);
+        // Compute the stats.
+        Stat.StatResult stat = Stat.getStat(result);
+        // Get the report for this test and add the results to record.
+        ReportLog log = getReportLog();
+        log.printArray("Times", result, ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue("Min", stat.mMin, ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue("Max", stat.mMax, ResultType.LOWER_BETTER, ResultUnit.MS);
+        // Every report must have a summary,
+        log.printSummary("Average", stat.mAverage, ResultType.LOWER_BETTER, ResultUnit.MS);
+    }
+}
diff --git a/tests/sample/src/android/sample/cts/SampleDeviceTest.java b/tests/sample/src/android/sample/cts/SampleDeviceTest.java
new file mode 100644
index 0000000..13b7ea6
--- /dev/null
+++ b/tests/sample/src/android/sample/cts/SampleDeviceTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.sample.cts;
+
+import android.sample.SampleDeviceActivity;
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * A simple compatibility test which tests the SharedPreferences API.
+ *
+ * This test uses {@link android.test.ActivityInstrumentationTestCase2} to instrument the
+ * {@link android.sample.SampleDeviceActivity}.
+ */
+public class SampleDeviceTest extends ActivityInstrumentationTestCase2<SampleDeviceActivity> {
+
+    private static final String KEY = "foo";
+
+    private static final String VALUE = "bar";
+
+    /**
+     * A reference to the activity whose shared preferences are being tested.
+     */
+    private SampleDeviceActivity mActivity;
+
+    public SampleDeviceTest() {
+        super(SampleDeviceActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // Start the activity and get a reference to it.
+        mActivity = getActivity();
+        // Wait for the UI Thread to become idle.
+        getInstrumentation().waitForIdleSync();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Scrub the activity so it can be freed. The next time the setUp will create a new activity
+        // rather than reusing the old one.
+        mActivity = null;
+        super.tearDown();
+    }
+
+    /**
+     * Tests the SharedPreferences API.
+     *
+     * This inserts the key value pair and assert they can be retrieved. Then it clears the
+     * preferences and asserts they can no longer be retrieved.
+     *
+     * @throws Exception
+     */
+    public void testSharedPreferences() throws Exception {
+        // Save the key value pair to the preferences and assert they were saved.
+        mActivity.savePreference(KEY, VALUE);
+        assertEquals("Preferences were not saved", VALUE, mActivity.getPreference(KEY));
+
+        // Clear the shared preferences and assert the data was removed.
+        mActivity.clearPreferences();
+        assertNull("Preferences were not cleared", mActivity.getPreference(KEY));
+    }
+}
diff --git a/tests/tests/example/AndroidManifest.xml b/tests/tests/example/AndroidManifest.xml
deleted file mode 100644
index ba41cce..0000000
--- a/tests/tests/example/AndroidManifest.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<!-- Replace all the "example" stuff below with your package name, and
-     remove this comment.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.example">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <!-- This is a self-instrumenting test package. -->
-    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
-                     android:targetPackage="com.android.cts.example"
-                     android:label="CTS tests of example component"/>
-
-</manifest>
-
diff --git a/tests/tests/example/src/android/example/Example.java b/tests/tests/example/src/android/example/Example.java
deleted file mode 100644
index bc22d9a..0000000
--- a/tests/tests/example/src/android/example/Example.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.example;
-
-/**
- * Example class being tested. In a real test, the classes to test would
- * live somewhere other than in the test package, but for the sake of
- * brevity, we include this one here instead.
- */
-public class Example {
-    /**
-     * Return the standard string indication of a successfuly blorting.
-     *
-     * @returns {@code "blort"}, always
-     */
-    public static String blort() {
-        return "blort";
-    }
-
-    /**
-     * Return the standard string indication of a successfuly zorching.
-     *
-     * @returns {@code "zorch"}, always
-     */
-    public static String zorch() {
-        return "zorch";
-    }
-}
diff --git a/tests/tests/example/src/android/example/cts/ExampleSecondaryTest.java b/tests/tests/example/src/android/example/cts/ExampleSecondaryTest.java
deleted file mode 100644
index d2b78dc..0000000
--- a/tests/tests/example/src/android/example/cts/ExampleSecondaryTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.example.cts;
-
-import android.example.Example;
-
-import junit.framework.TestCase;
-
-/**
- * Example test to demonstrate how tests work as well as to serve as a
- * smoke test for the CTS. This secondary test exists to demonstrate
- * that you may have more than one test class. Typically you will
- * separate your test classes by what class or major piece of
- * functionality is being tested.
- */
-public class ExampleSecondaryTest extends TestCase {
-    /*
-     * You can define standard JUnit setUp() and tearDown() methods here,
-     * if needed.
-     *
-     * @Override protected void setUp() throws Exception { ... }
-     * @Override protected void tearDown() throws Exception { ... }
-     */
-
-    /**
-     * Test {@link Example#zorch}.
-     */
-    public void testZorch() {
-        assertEquals("zorch", Example.zorch());
-    }
-
-    // Add more tests here.
-}
diff --git a/tests/tests/example/src/android/example/cts/ExampleTest.java b/tests/tests/example/src/android/example/cts/ExampleTest.java
deleted file mode 100644
index db907cc..0000000
--- a/tests/tests/example/src/android/example/cts/ExampleTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.example.cts;
-
-import android.example.Example;
-
-import junit.framework.TestCase;
-
-/**
- * Example test to demonstrate how tests work as well as to serve as
- * a smoke test for the CTS. (If the example test is "broken," then it
- * probably means that there's something fundamentally wrong with your
- * setup.)
- */
-public class ExampleTest extends TestCase {
-    /*
-     * You can define standard JUnit setUp() and tearDown() methods here,
-     * if needed.
-     *
-     * @Override protected void setUp() throws Exception { ... }
-     * @Override protected void tearDown() throws Exception { ... }
-     */
-
-    /**
-     * Test {@link Example#blort}.
-     */
-    public void testBlort() {
-        assertEquals("blort", Example.blort());
-    }
-
-    // Add more tests here.
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCaptureResultTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCaptureResultTest.java
index 70fea28..f05111b 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCaptureResultTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCaptureResultTest.java
@@ -303,16 +303,16 @@
         resultKeys.add(CaptureResult.LENS_STATE);
         resultKeys.add(CaptureResult.NOISE_REDUCTION_MODE);
         resultKeys.add(CaptureResult.REQUEST_FRAME_COUNT);
+        resultKeys.add(CaptureResult.REQUEST_PIPELINE_DEPTH);
         resultKeys.add(CaptureResult.SCALER_CROP_REGION);
         resultKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME);
         resultKeys.add(CaptureResult.SENSOR_FRAME_DURATION);
         resultKeys.add(CaptureResult.SENSOR_SENSITIVITY);
         resultKeys.add(CaptureResult.SENSOR_TIMESTAMP);
         resultKeys.add(CaptureResult.SENSOR_TEMPERATURE);
+        resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE);
         resultKeys.add(CaptureResult.STATISTICS_FACE_DETECT_MODE);
         resultKeys.add(CaptureResult.STATISTICS_LENS_SHADING_MAP);
-        resultKeys.add(CaptureResult.STATISTICS_PREDICTED_COLOR_GAINS);
-        resultKeys.add(CaptureResult.STATISTICS_PREDICTED_COLOR_TRANSFORM);
         resultKeys.add(CaptureResult.STATISTICS_SCENE_FLICKER);
         resultKeys.add(CaptureResult.TONEMAP_CURVE_BLUE);
         resultKeys.add(CaptureResult.TONEMAP_CURVE_GREEN);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCharacteristicsTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCharacteristicsTest.java
index 09d5b90..d694104 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCharacteristicsTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraCharacteristicsTest.java
@@ -563,6 +563,52 @@
         }
     }
 
+    public void testCameraCharacteristicsAndroidRequestPipelineMaxDepth() throws Exception {
+        String[] ids = mCameraManager.getCameraIdList();
+        for (int i = 0; i < ids.length; i++) {
+            CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+            assertNotNull(String.format("Can't get camera characteristics from: ID %s", ids[i]),
+                                        props);
+
+            {
+
+                assertNotNull("Invalid property: android.request.pipelineMaxDepth",
+                        props.get(CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH));
+
+                List<Key<?>> allKeys = props.getKeys();
+                assertNotNull(String.format("Can't get camera characteristics keys from: ID %s",
+                        ids[i], props));
+                assertTrue("Key not in keys list: android.request.pipelineMaxDepth", allKeys.contains(
+                        CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH));
+
+            }
+
+        }
+    }
+
+    public void testCameraCharacteristicsAndroidRequestPartialResultCount() throws Exception {
+        String[] ids = mCameraManager.getCameraIdList();
+        for (int i = 0; i < ids.length; i++) {
+            CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+            assertNotNull(String.format("Can't get camera characteristics from: ID %s", ids[i]),
+                                        props);
+
+            {
+
+                assertNotNull("Invalid property: android.request.partialResultCount",
+                        props.get(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT));
+
+                List<Key<?>> allKeys = props.getKeys();
+                assertNotNull(String.format("Can't get camera characteristics keys from: ID %s",
+                        ids[i], props));
+                assertTrue("Key not in keys list: android.request.partialResultCount", allKeys.contains(
+                        CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT));
+
+            }
+
+        }
+    }
+
     public void testCameraCharacteristicsAndroidScalerAvailableFormats() throws Exception {
         String[] ids = mCameraManager.getCameraIdList();
         for (int i = 0; i < ids.length; i++) {
@@ -778,6 +824,33 @@
         }
     }
 
+    public void testCameraCharacteristicsAndroidSensorAvailableTestPatternModes() throws Exception {
+        String[] ids = mCameraManager.getCameraIdList();
+        for (int i = 0; i < ids.length; i++) {
+            CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+            assertNotNull(String.format("Can't get camera characteristics from: ID %s", ids[i]),
+                                        props);
+
+            Integer hwLevel = props.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+            assertNotNull("No hardware level reported! android.info.supportedHardwareLevel",
+                    hwLevel);
+            if (hwLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+            {
+
+                assertNotNull("Invalid property: android.sensor.availableTestPatternModes",
+                        props.get(CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES));
+
+                List<Key<?>> allKeys = props.getKeys();
+                assertNotNull(String.format("Can't get camera characteristics keys from: ID %s",
+                        ids[i], props));
+                assertTrue("Key not in keys list: android.sensor.availableTestPatternModes", allKeys.contains(
+                        CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES));
+
+            }
+
+        }
+    }
+
     public void testCameraCharacteristicsAndroidSensorInfoActiveArraySize() throws Exception {
         String[] ids = mCameraManager.getCameraIdList();
         for (int i = 0; i < ids.length; i++) {
@@ -984,5 +1057,28 @@
 
         }
     }
+
+    public void testCameraCharacteristicsAndroidSyncMaxLatency() throws Exception {
+        String[] ids = mCameraManager.getCameraIdList();
+        for (int i = 0; i < ids.length; i++) {
+            CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+            assertNotNull(String.format("Can't get camera characteristics from: ID %s", ids[i]),
+                                        props);
+
+            {
+
+                assertNotNull("Invalid property: android.sync.maxLatency",
+                        props.get(CameraCharacteristics.SYNC_MAX_LATENCY));
+
+                List<Key<?>> allKeys = props.getKeys();
+                assertNotNull(String.format("Can't get camera characteristics keys from: ID %s",
+                        ids[i], props));
+                assertTrue("Key not in keys list: android.sync.maxLatency", allKeys.contains(
+                        CameraCharacteristics.SYNC_MAX_LATENCY));
+
+            }
+
+        }
+    }
 }
 
diff --git a/tests/tests/media/res/raw/video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz_id3v2.mp4 b/tests/tests/media/res/raw/video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz_id3v2.mp4
new file mode 100644
index 0000000..0902533
--- /dev/null
+++ b/tests/tests/media/res/raw/video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz_id3v2.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index 9b1879a..12b98b5 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -446,10 +446,9 @@
     // Playback properties
     // ----------------------------------
 
-    // Test case 1: setStereoVolume() with max volume returns SUCCESS
-    public void testSetStereoVolumeMax() throws Exception {
+    // Common code for the testSetStereoVolume* and testSetVolume* tests
+    private void testSetVolumeCommon(String testName, float vol, boolean isStereo) throws Exception {
         // constants for test
-        final String TEST_NAME = "testSetStereoVolumeMax";
         final int TEST_SR = 22050;
         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
@@ -465,61 +464,35 @@
         track.write(data, OFFSET_DEFAULT, data.length);
         track.write(data, OFFSET_DEFAULT, data.length);
         track.play();
-        float maxVol = AudioTrack.getMaxVolume();
-        assertTrue(TEST_NAME, track.setStereoVolume(maxVol, maxVol) == AudioTrack.SUCCESS);
+        if (isStereo) {
+            // TODO to really test this, do a pan instead of using same value for left and right
+            assertTrue(testName, track.setStereoVolume(vol, vol) == AudioTrack.SUCCESS);
+        } else {
+            assertTrue(testName, track.setVolume(vol) == AudioTrack.SUCCESS);
+        }
         // -------- tear down --------------
         track.release();
     }
 
+    // Test case 1: setStereoVolume() with max volume returns SUCCESS
+    public void testSetStereoVolumeMax() throws Exception {
+        final String TEST_NAME = "testSetStereoVolumeMax";
+        float maxVol = AudioTrack.getMaxVolume();
+        testSetVolumeCommon(TEST_NAME, maxVol, true /*isStereo*/);
+    }
+
     // Test case 2: setStereoVolume() with min volume returns SUCCESS
     public void testSetStereoVolumeMin() throws Exception {
-        // constants for test
         final String TEST_NAME = "testSetStereoVolumeMin";
-        final int TEST_SR = 22050;
-        final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
-        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
-        final int TEST_MODE = AudioTrack.MODE_STREAM;
-        final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
-
-        // -------- initialization --------------
-        int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
-        AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
-                2 * minBuffSize, TEST_MODE);
-        byte data[] = new byte[minBuffSize];
-        // -------- test --------------
-        track.write(data, OFFSET_DEFAULT, data.length);
-        track.write(data, OFFSET_DEFAULT, data.length);
-        track.play();
         float minVol = AudioTrack.getMinVolume();
-        assertTrue(TEST_NAME, track.setStereoVolume(minVol, minVol) == AudioTrack.SUCCESS);
-        // -------- tear down --------------
-        track.release();
+        testSetVolumeCommon(TEST_NAME, minVol, true /*isStereo*/);
     }
 
     // Test case 3: setStereoVolume() with mid volume returns SUCCESS
     public void testSetStereoVolumeMid() throws Exception {
-        // constants for test
         final String TEST_NAME = "testSetStereoVolumeMid";
-        final int TEST_SR = 22050;
-        final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
-        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
-        final int TEST_MODE = AudioTrack.MODE_STREAM;
-        final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
-
-        // -------- initialization --------------
-        int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
-        AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
-                2 * minBuffSize, TEST_MODE);
-        byte data[] = new byte[minBuffSize];
-        // -------- test --------------
-
-        track.write(data, OFFSET_DEFAULT, data.length);
-        track.write(data, OFFSET_DEFAULT, data.length);
-        track.play();
         float midVol = (AudioTrack.getMaxVolume() - AudioTrack.getMinVolume()) / 2;
-        assertTrue(TEST_NAME, track.setStereoVolume(midVol, midVol) == AudioTrack.SUCCESS);
-        // -------- tear down --------------
-        track.release();
+        testSetVolumeCommon(TEST_NAME, midVol, true /*isStereo*/);
     }
 
     // Test case 4: setPlaybackRate() with half the content rate returns SUCCESS
@@ -644,6 +617,27 @@
         track.release();
     }
 
+    // Test case 9: setVolume() with max volume returns SUCCESS
+    public void testSetVolumeMax() throws Exception {
+        final String TEST_NAME = "testSetVolumeMax";
+        float maxVol = AudioTrack.getMaxVolume();
+        testSetVolumeCommon(TEST_NAME, maxVol, false /*isStereo*/);
+    }
+
+    // Test case 10: setVolume() with min volume returns SUCCESS
+    public void testSetVolumeMin() throws Exception {
+        final String TEST_NAME = "testSetVolumeMin";
+        float minVol = AudioTrack.getMinVolume();
+        testSetVolumeCommon(TEST_NAME, minVol, false /*isStereo*/);
+    }
+
+    // Test case 11: setVolume() with mid volume returns SUCCESS
+    public void testSetVolumeMid() throws Exception {
+        final String TEST_NAME = "testSetVolumeMid";
+        float midVol = (AudioTrack.getMaxVolume() - AudioTrack.getMinVolume()) / 2;
+        testSetVolumeCommon(TEST_NAME, midVol, false /*isStereo*/);
+    }
+
     // -----------------------------------------------------------------
     // Playback progress
     // ----------------------------------
diff --git a/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java b/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
index 0d83647..e74a64a 100644
--- a/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
+++ b/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
@@ -149,7 +149,8 @@
     /**
      * Tests editing of a video file with GL.
      */
-    private void videoEditTest() {
+    private void videoEditTest()
+            throws IOException {
         VideoChunks sourceChunks = new VideoChunks();
 
         if (!generateVideoFile(sourceChunks)) {
@@ -182,7 +183,8 @@
      *
      * @return true on success, false on "soft" failure
      */
-    private boolean generateVideoFile(VideoChunks output) {
+    private boolean generateVideoFile(VideoChunks output)
+            throws IOException {
         if (VERBOSE) Log.d(TAG, "generateVideoFile " + mWidth + "x" + mHeight);
         MediaCodec encoder = null;
         InputSurface inputSurface = null;
@@ -393,7 +395,8 @@
      * for output and a Surface for input, we can avoid issues with obscure formats and can
      * use a fragment shader to do transformations.
      */
-    private VideoChunks editVideoFile(VideoChunks inputData) {
+    private VideoChunks editVideoFile(VideoChunks inputData)
+            throws IOException {
         if (VERBOSE) Log.d(TAG, "editVideoFile " + mWidth + "x" + mHeight);
         VideoChunks outputData = new VideoChunks();
         MediaCodec decoder = null;
@@ -613,7 +616,8 @@
      * Checks the video file to see if the contents match our expectations.  We decode the
      * video to a Surface and check the pixels with GL.
      */
-    private void checkVideoFile(VideoChunks inputData) {
+    private void checkVideoFile(VideoChunks inputData)
+            throws IOException {
         OutputSurface surface = null;
         MediaCodec decoder = null;
 
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index eda4546..c4c8465 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -679,21 +679,25 @@
     }
 
     private static MediaCodec createDecoder(String mime) {
-        if (false) {
-            // change to force testing software codecs
-            if (mime.contains("avc")) {
-                return MediaCodec.createByCodecName("OMX.google.h264.decoder");
-            } else if (mime.contains("3gpp")) {
-                return MediaCodec.createByCodecName("OMX.google.h263.decoder");
-            } else if (mime.contains("mp4v")) {
-                return MediaCodec.createByCodecName("OMX.google.mpeg4.decoder");
-            } else if (mime.contains("vp8")) {
-                return MediaCodec.createByCodecName("OMX.google.vp8.decoder");
-            } else if (mime.contains("vp9")) {
-                return MediaCodec.createByCodecName("OMX.google.vp9.decoder");
+        try {
+            if (false) {
+                // change to force testing software codecs
+                if (mime.contains("avc")) {
+                    return MediaCodec.createByCodecName("OMX.google.h264.decoder");
+                } else if (mime.contains("3gpp")) {
+                    return MediaCodec.createByCodecName("OMX.google.h263.decoder");
+                } else if (mime.contains("mp4v")) {
+                    return MediaCodec.createByCodecName("OMX.google.mpeg4.decoder");
+                } else if (mime.contains("vp8")) {
+                    return MediaCodec.createByCodecName("OMX.google.vp8.decoder");
+                } else if (mime.contains("vp9")) {
+                    return MediaCodec.createByCodecName("OMX.google.vp9.decoder");
+                }
             }
+            return MediaCodec.createDecoderByType(mime);
+        } catch (Exception e) {
+            return null;
         }
-        return MediaCodec.createDecoderByType(mime);
     }
 
     // for video
@@ -1162,6 +1166,8 @@
         assertTrue("not an audio file", mime.startsWith("audio/"));
 
         codec = MediaCodec.createDecoderByType(mime);
+        assertNotNull("couldn't find codec " + mime, codec);
+
         codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
         codec.start();
         codecInputBuffers = codec.getInputBuffers();
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
index 9f76ddf..eb06eda 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
@@ -153,7 +153,7 @@
     /**
      * Prepares the encoder, decoder, and virtual display.
      */
-    private void encodeVirtualDisplayTest() {
+    private void encodeVirtualDisplayTest() throws IOException {
         MediaCodec encoder = null;
         MediaCodec decoder = null;
         OutputSurface outputSurface = null;
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index e9d0b5f..c2e59d4 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -187,8 +187,13 @@
     }
 
     private void testEncoder(String componentName, MediaFormat format) {
-        MediaCodec codec = MediaCodec.createByCodecName(componentName);
-
+        MediaCodec codec;
+        try {
+            codec = MediaCodec.createByCodecName(componentName);
+        } catch (Exception e) {
+            fail("codec '" + componentName + "' failed construction.");
+            return; /* does not get here, but avoids warning */
+        }
         try {
             codec.configure(
                     format,
@@ -196,9 +201,7 @@
                     null /* crypto */,
                     MediaCodec.CONFIGURE_FLAG_ENCODE);
         } catch (IllegalStateException e) {
-            Log.e(TAG, "codec '" + componentName + "' failed configuration.");
-
-            assertTrue("codec '" + componentName + "' failed configuration.", false);
+            fail("codec '" + componentName + "' failed configuration.");
         }
 
         codec.start();
diff --git a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
index 81296e4..264a76a 100644
--- a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
+++ b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
@@ -469,7 +469,8 @@
      * @param inputFormat the format of the stream to decode
      * @param surface into which to decode the frames
      */
-    private MediaCodec createVideoDecoder(MediaFormat inputFormat, Surface surface) {
+    private MediaCodec createVideoDecoder(MediaFormat inputFormat, Surface surface)
+            throws IOException {
         MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFor(inputFormat));
         decoder.configure(inputFormat, surface, null, 0);
         decoder.start();
@@ -489,7 +490,8 @@
     private MediaCodec createVideoEncoder(
             MediaCodecInfo codecInfo,
             MediaFormat format,
-            AtomicReference<Surface> surfaceReference) {
+            AtomicReference<Surface> surfaceReference)
+            throws IOException {
         MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
         encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
         // Must be called before start() is.
@@ -503,7 +505,8 @@
      *
      * @param inputFormat the format of the stream to decode
      */
-    private MediaCodec createAudioDecoder(MediaFormat inputFormat) {
+    private MediaCodec createAudioDecoder(MediaFormat inputFormat)
+            throws IOException {
         MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFor(inputFormat));
         decoder.configure(inputFormat, null, null, 0);
         decoder.start();
@@ -516,7 +519,8 @@
      * @param codecInfo of the codec to use
      * @param format of the stream to be produced
      */
-    private MediaCodec createAudioEncoder(MediaCodecInfo codecInfo, MediaFormat format) {
+    private MediaCodec createAudioEncoder(MediaCodecInfo codecInfo, MediaFormat format) 
+            throws IOException {
         MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
         encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
         encoder.start();
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
index 3428e86..9c07cf1 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
@@ -26,6 +26,7 @@
 import android.util.Log;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.List;
 import java.util.ArrayList;
 
@@ -56,7 +57,7 @@
 
     // Each component advertised by MediaCodecList should at least be
     // instantiate-able.
-    public void testComponentInstantiation() {
+    public void testComponentInstantiation() throws IOException {
         Log.d(TAG, "testComponentInstantiation");
 
         int codecCount = MediaCodecList.getCodecCount();
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index 86d03bf..ae14e6f 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -87,7 +87,11 @@
         format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
 
         try {
-            encoder = MediaCodec.createByCodecName(codecInfo.getName());
+            try {
+                encoder = MediaCodec.createByCodecName(codecInfo.getName());
+            } catch (IOException e) {
+                fail("failed to create codec " + codecInfo.getName());
+            }
             try {
                 surface = encoder.createInputSurface();
                 fail("createInputSurface should not work pre-configure");
@@ -132,7 +136,11 @@
         InputSurface inputSurface = null;
 
         try {
-            encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            try {
+                encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE + " encoder");
+            }
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             inputSurface = new InputSurface(encoder.createInputSurface());
             inputSurface.makeCurrent();
@@ -189,7 +197,11 @@
         InputSurface inputSurface = null;
 
         try {
-            encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            try {
+                encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE + " encoder");
+            }
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             inputSurface = new InputSurface(encoder.createInputSurface());
             inputSurface.makeCurrent();
@@ -231,7 +243,11 @@
         Surface surface = null;
 
         try {
-            encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            try {
+                encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE + " encoder");
+            }
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             surface = encoder.createInputSurface();
             encoder.start();
@@ -265,7 +281,11 @@
         Surface surface = null;
 
         try {
-            encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            try {
+                encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE + " encoder");
+            }
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             surface = encoder.createInputSurface();
             encoder.start();
@@ -415,11 +435,19 @@
         MediaCodec audioDecoderA = null;
         MediaCodec audioDecoderB = null;
         try {
-            audioDecoderA = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            try {
+                audioDecoderA = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            } catch (IOException e) {
+                fail("failed to create first " + MIME_TYPE_AUDIO + " decoder");
+            }
             audioDecoderA.configure(format, null, null, 0);
             audioDecoderA.start();
 
-            audioDecoderB = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            try {
+                audioDecoderB = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            } catch (IOException e) {
+                fail("failed to create second " + MIME_TYPE_AUDIO + " decoder");
+            }
             audioDecoderB.configure(format, null, null, 0);
             audioDecoderB.start();
         } finally {
@@ -457,11 +485,19 @@
         MediaCodec audioEncoder = null;
         MediaCodec audioDecoder = null;
         try {
-            audioEncoder = MediaCodec.createEncoderByType(MIME_TYPE_AUDIO);
+            try {
+                audioEncoder = MediaCodec.createEncoderByType(MIME_TYPE_AUDIO);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE_AUDIO + " encoder");
+            }
             audioEncoder.configure(encoderFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             audioEncoder.start();
 
-            audioDecoder = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            try {
+                audioDecoder = MediaCodec.createDecoderByType(MIME_TYPE_AUDIO);
+            } catch (IOException e) {
+                fail("failed to create " + MIME_TYPE_AUDIO + " decoder");
+            }
             audioDecoder.configure(decoderFormat, null, null, 0);
             audioDecoder.start();
         } finally {
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index b090e27..30c8370 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -70,4 +70,52 @@
         assertNull("Writer was unexpected present",
                 retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
     }
+
+    public void testSetDataSourceNull() {
+        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+
+        try {
+            retriever.setDataSource((String)null);
+            fail("Expected IllegalArgumentException.");
+        } catch (IllegalArgumentException ex) {
+            // Expected, test passed.
+        }
+    }
+
+    public void testID3v2Metadata() {
+        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+
+        try {
+            Resources resources = getContext().getResources();
+            AssetFileDescriptor afd = resources.openRawResourceFd(
+                    R.raw.video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz_id3v2);
+
+            retriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+
+            afd.close();
+        } catch (Exception e) {
+            fail("Unable to open file");
+        }
+
+        assertEquals("Title was other than expected",
+                "Title", retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
+
+        assertEquals("Artist was other than expected",
+                "UTF16LE エンディアン ",
+                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST));
+
+        assertEquals("Album was other than expected",
+                "Test album",
+                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM));
+
+        assertEquals("Track number was other than expected",
+                "10",
+                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER));
+
+        assertEquals("Year was other than expected",
+                "2013", retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR));
+
+        assertNull("Writer was unexpectedly present",
+                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
+    }
 }
diff --git a/tests/tests/net/Android.mk b/tests/tests/net/Android.mk
index 9647df1..1653335 100644
--- a/tests/tests/net/Android.mk
+++ b/tests/tests/net/Android.mk
@@ -30,7 +30,8 @@
 
 LOCAL_PACKAGE_NAME := CtsNetTestCases
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner \
+                               core-tests-support
 
 # uncomment when dalvik.annotation.Test* are removed or part of SDK
 #LOCAL_SDK_VERSION := current
diff --git a/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
index ceb74d1..cb8aeaf 100644
--- a/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
+++ b/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
@@ -28,6 +28,8 @@
 
 import dalvik.annotation.BrokenTest;
 
+import libcore.javax.net.ssl.SSLDefaultConfigurationAsserts;
+
 public class SSLCertificateSocketFactoryTest extends AndroidTestCase {
     private SSLCertificateSocketFactory mFactory;
     private int mTimeout;
@@ -39,6 +41,10 @@
         mFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(mTimeout);
     }
 
+    public void testDefaultConfiguration() throws Exception {
+        SSLDefaultConfigurationAsserts.assertSSLSocketFactory(mFactory);
+    }
+
     public void testAccessProperties() throws Exception {
         mFactory.getSupportedCipherSuites();
         mFactory.getDefaultCipherSuites();
diff --git a/tests/tests/print/AndroidManifest.xml b/tests/tests/print/AndroidManifest.xml
index 82715cb..4c94fd5 100644
--- a/tests/tests/print/AndroidManifest.xml
+++ b/tests/tests/print/AndroidManifest.xml
@@ -23,7 +23,7 @@
 
         <uses-library android:name="android.test.runner"/>
 
-        <activity android:name="android.print.cts.PrintDocumentAdapterContractActivity"/>
+        <activity android:name="android.print.cts.PrintDocumentActivity"/>
 
         <service
             android:name="android.print.cts.services.FirstPrintService"
diff --git a/tests/tests/print/src/android/print/cts/BasePrintTest.java b/tests/tests/print/src/android/print/cts/BasePrintTest.java
index c1973ca..d193bb0 100644
--- a/tests/tests/print/src/android/print/cts/BasePrintTest.java
+++ b/tests/tests/print/src/android/print/cts/BasePrintTest.java
@@ -71,7 +71,7 @@
 
     protected static final String PRINT_JOB_NAME = "Test";
 
-    private PrintDocumentAdapterContractActivity mActivity;
+    private PrintDocumentActivity mActivity;
 
     private Locale mOldLocale;
 
@@ -79,6 +79,7 @@
     private CallCounter mWriteCallCounter;
     private CallCounter mFinishCallCounter;
     private CallCounter mPrintJobQueuedCallCounter;
+    private CallCounter mDestroySessionCallCounter;
 
     @Override
     public void setUp() throws Exception {
@@ -107,6 +108,7 @@
         mWriteCallCounter = new CallCounter();
         mFinishCallCounter = new CallCounter();
         mPrintJobQueuedCallCounter = new CallCounter();
+        mDestroySessionCallCounter = new CallCounter();
 
         // Create the activity for the right locale.
         createActivity();
@@ -159,12 +161,21 @@
         mPrintJobQueuedCallCounter.call();
     }
 
+    protected void onPrinterDiscoverySessionDestroyCalled() {
+        mDestroySessionCallCounter.call();
+    }
+
+    protected void waitForPrinterDiscoverySessionDestroyCallbackCalled() {
+        waitForCallbackCallCount(mDestroySessionCallCounter, 1,
+                "Did not get expected call to onDestroyPrinterDiscoverySession.");
+    }
+
     protected void waitForServiceOnPrintJobQueuedCallbackCalled() {
         waitForCallbackCallCount(mPrintJobQueuedCallCounter, 1,
                 "Did not get expected call to onPrintJobQueued.");
     }
 
-    protected void waitForAdapterCallbackFinish() {
+    protected void waitForAdapterFinishCallbackCalled() {
         waitForCallbackCallCount(mFinishCallCounter, 1,
                 "Did not get expected call to finish.");
     }
@@ -224,14 +235,14 @@
         printButton.click();
     }
 
-    protected PrintDocumentAdapterContractActivity getActivity() {
+    protected PrintDocumentActivity getActivity() {
         return mActivity;
     }
 
     private void createActivity() {
         mActivity = launchActivity(
                 getInstrumentation().getTargetContext().getPackageName(),
-                PrintDocumentAdapterContractActivity.class, null);
+                PrintDocumentActivity.class, null);
     }
 
     protected void clearPrintSpoolerData() throws Exception {
diff --git a/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java b/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
index cf28800..d3d5a4c 100644
--- a/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
+++ b/tests/tests/print/src/android/print/cts/PageRangeAdjustmentTest.java
@@ -139,7 +139,7 @@
         clickPrintButton();
 
         // Wait for finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Wait for the print job.
         waitForServiceOnPrintJobQueuedCallbackCalled();
@@ -239,7 +239,7 @@
         clickPrintButton();
 
         // Wait for finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Wait for the print job.
         waitForServiceOnPrintJobQueuedCallbackCalled();
@@ -351,7 +351,7 @@
         clickPrintButton();
 
         // Wait for finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Wait for the print job.
         waitForServiceOnPrintJobQueuedCallbackCalled();
@@ -439,7 +439,7 @@
         UiDevice.getInstance().pressBack();
 
         // Wait for finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(firstServiceCallbacks);
@@ -491,7 +491,7 @@
                                 PrintAttributes.COLOR_MODE_COLOR)
                         .build();
                     PrinterInfo firstPrinter = new PrinterInfo.Builder(firstPrinterId,
-                            "First printer", PrinterInfo.STATUS_IDLE)
+                            FIRST_PRINTER, PrinterInfo.STATUS_IDLE)
                         .setCapabilities(firstCapabilities)
                         .build();
                     printers.add(firstPrinter);
diff --git a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractActivity.java b/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
similarity index 92%
rename from tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractActivity.java
rename to tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
index eb80bb7..6a191a6 100644
--- a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractActivity.java
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentActivity.java
@@ -19,7 +19,7 @@
 import android.app.Activity;
 import android.os.Bundle;
 
-public class PrintDocumentAdapterContractActivity extends Activity {
+public class PrintDocumentActivity extends Activity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
diff --git a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
index 64c225a..57eae3f 100644
--- a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
@@ -116,7 +116,7 @@
         clickPrintButton();
 
         // Wait for finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -220,7 +220,7 @@
         UiDevice.getInstance().pressBack();
 
         // Wait for finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -328,7 +328,7 @@
         clickPrintButton();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -488,7 +488,7 @@
         clickPrintButton();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -621,7 +621,7 @@
         clickPrintButton();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -728,7 +728,7 @@
         clickPrintButton();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -822,7 +822,7 @@
         clickPrintButton();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -917,7 +917,7 @@
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1001,7 +1001,7 @@
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1067,7 +1067,7 @@
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1143,7 +1143,7 @@
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1224,7 +1224,7 @@
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1289,7 +1289,7 @@
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
@@ -1362,7 +1362,7 @@
         UiDevice.getInstance().pressBack();
 
         // Wait for a finish.
-        waitForAdapterCallbackFinish();
+        waitForAdapterFinishCallbackCalled();
 
         // Verify the expected calls.
         InOrder inOrder = inOrder(adapter);
diff --git a/tests/tests/print/src/android/print/cts/PrinterDiscoverySessionLifecycleTest.java b/tests/tests/print/src/android/print/cts/PrinterDiscoverySessionLifecycleTest.java
new file mode 100644
index 0000000..cb6a6d1
--- /dev/null
+++ b/tests/tests/print/src/android/print/cts/PrinterDiscoverySessionLifecycleTest.java
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.print.cts;
+
+import static org.mockito.Mockito.inOrder;
+
+import android.os.ParcelFileDescriptor;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentAdapter.LayoutResultCallback;
+import android.print.PrintDocumentAdapter.WriteResultCallback;
+import android.print.PrintDocumentInfo;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.print.cts.services.FirstPrintService;
+import android.print.cts.services.PrintServiceCallbacks;
+import android.print.cts.services.PrinterDiscoverySessionCallbacks;
+import android.print.cts.services.SecondPrintService;
+import android.print.cts.services.StubbablePrinterDiscoverySession;
+import android.printservice.PrintJob;
+import android.printservice.PrinterDiscoverySession;
+import android.support.test.uiautomator.UiDevice;
+
+import org.mockito.InOrder;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This test verifies that the system respects the {@link PrinterDiscoverySession}
+ * contract is respected.
+ */
+public class PrinterDiscoverySessionLifecycleTest extends BasePrintTest {
+    private static final String FIRST_PRINTER_NAME = "First printer";
+    private static final String SECOND_PRINTER_NAME = "Second printer";
+
+    private static final String FIRST_PRINTER_LOCAL_ID= "first_printer";
+    private static final String SECOND_PRINTER_LOCAL_ID = "second_printer";
+
+    public void testNormalLifecycle() throws Exception {
+        // Create the session callbacks that we will be checking.
+        final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
+                createFirstMockPrinterDiscoverySessionCallbacks();
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                @Override
+                public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return firstSessionCallbacks;
+                    }
+                },
+                new Answer<Void>() {
+                @Override
+                public Void answer(InvocationOnMock invocation) {
+                    PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+                    // We pretend the job is handled immediately.
+                    printJob.complete();
+                    return null;
+                }
+            }, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+        // Create a print adapter that respects the print contract.
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter();
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write of the first page.
+        waitForWriteForAdapterCallback();
+
+        // Select the first printer.
+        selectPrinter(FIRST_PRINTER_NAME);
+
+        // Wait for layout as the printer has different capabilities.
+        waitForLayoutAdapterCallbackCount(2);
+
+        // Select the second printer (same capabilities as the other
+        // one so no layout should happen).
+        selectPrinter(SECOND_PRINTER_NAME);
+
+        // While the printer discovery session is still alive store the
+        // ids of printers as we want to make some assertions about them
+        // but only the print service can create printer ids which means
+        // that we need to get the created ones.
+        PrinterId firstPrinterId = getAddedPrinterIdForLocalId(firstSessionCallbacks,
+                FIRST_PRINTER_LOCAL_ID);
+        PrinterId secondPrinterId = getAddedPrinterIdForLocalId(firstSessionCallbacks,
+                SECOND_PRINTER_LOCAL_ID);
+        assertNotNull("Coundn't find printer:" + FIRST_PRINTER_LOCAL_ID, firstPrinterId);
+        assertNotNull("Coundn't find printer:" + SECOND_PRINTER_LOCAL_ID, secondPrinterId);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for all print jobs to be handled after which the session destroyed.
+        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(firstSessionCallbacks);
+
+        // We start discovery as the print dialog was up.
+        List<PrinterId> emptyPrinterIdList = Collections.emptyList();
+        inOrder.verify(firstSessionCallbacks).onStartPrinterDiscovery(
+                emptyPrinterIdList);
+
+        // We selected the first printer and now it should be tracked.
+        inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
+                firstPrinterId);
+
+        // We selected the second printer so the first should not be tracked.
+        inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
+                firstPrinterId);
+
+        // We selected the second printer and now it should be tracked.
+        inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
+                secondPrinterId);
+
+        // The print dialog went away so we first stop the printer tracking...
+        inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
+                secondPrinterId);
+
+        // ... next we stop printer discovery...
+        inOrder.verify(firstSessionCallbacks).onStopPrinterDiscovery();
+
+        // ... last the session is destroyed.
+        inOrder.verify(firstSessionCallbacks).onDestroy();
+    }
+
+    public void testStartPrinterDiscoveryWithHistoricalPrinters() throws Exception {
+        // Create the session callbacks that we will be checking.
+        final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
+                createFirstMockPrinterDiscoverySessionCallbacks();
+
+        // Create the service callbacks for the first print service.
+        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                @Override
+                public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return firstSessionCallbacks;
+                    }
+                },
+                new Answer<Void>() {
+                @Override
+                public Void answer(InvocationOnMock invocation) {
+                    PrintJob printJob = (PrintJob) invocation.getArguments()[0];
+                    // We pretend the job is handled immediately.
+                    printJob.complete();
+                    return null;
+                }
+            }, null);
+
+        // Configure the print services.
+        FirstPrintService.setCallbacks(firstServiceCallbacks);
+        SecondPrintService.setCallbacks(createSecondMockPrintServiceCallbacks());
+
+        // Create a print adapter that respects the print contract.
+        PrintDocumentAdapter adapter = createMockPrintDocumentAdapter();
+
+        // Start printing.
+        print(adapter);
+
+        // Wait for write of the first page.
+        waitForWriteForAdapterCallback();
+
+        // Select the first printer.
+        selectPrinter(FIRST_PRINTER_NAME);
+
+        // Wait for a layout to finish - first layout was for the
+        // PDF printer, second for the first printer in preview mode.
+        waitForLayoutAdapterCallbackCount(2);
+
+        // While the printer discovery session is still alive store the
+        // ids of printer as we want to make some assertions about it
+        // but only the print service can create printer ids which means
+        // that we need to get the created one.
+        PrinterId firstPrinterId = getAddedPrinterIdForLocalId(
+                firstSessionCallbacks, FIRST_PRINTER_LOCAL_ID);
+
+        // Click the print button.
+        clickPrintButton();
+
+        // Wait for the print to complete.
+        waitForAdapterFinishCallbackCalled();
+
+        // Now print again as we want to confirm that the start
+        // printer discovery passes in the priority list.
+        print(adapter);
+
+        // Wait for a layout to finish - first layout was for the
+        // PDF printer, second for the first printer in preview mode,
+        // the third for the first printer in non-preview mode, and
+        // now a fourth for the PDF printer as we are printing again.
+        waitForLayoutAdapterCallbackCount(4);
+
+        // Cancel the printing.
+        UiDevice.getInstance().pressBack(); // wakes up the device.
+        UiDevice.getInstance().pressBack();
+
+        // Wait for all print jobs to be handled after which the session destroyed.
+        waitForPrinterDiscoverySessionDestroyCallbackCalled();
+
+        // Verify the expected calls.
+        InOrder inOrder = inOrder(firstSessionCallbacks);
+
+        // We start discovery as the print dialog was up.
+        List<PrinterId> priorityList = new ArrayList<PrinterId>();
+        priorityList.add(firstPrinterId);
+        inOrder.verify(firstSessionCallbacks).onStartPrinterDiscovery(
+                priorityList);
+
+        // We selected the first printer and now it should be tracked.
+        inOrder.verify(firstSessionCallbacks).onStartPrinterStateTracking(
+                firstPrinterId);
+
+        // We selected the second printer so the first should not be tracked.
+        inOrder.verify(firstSessionCallbacks).onStopPrinterStateTracking(
+                firstPrinterId);
+
+        // ...next we stop printer discovery...
+        inOrder.verify(firstSessionCallbacks).onStopPrinterDiscovery();
+
+        // ...last the session is destroyed.
+        inOrder.verify(firstSessionCallbacks).onDestroy();
+    }
+
+    private PrinterId getAddedPrinterIdForLocalId(
+            final PrinterDiscoverySessionCallbacks sessionCallbacks, String printerLocalId) {
+        final List<PrinterInfo> reportedPrinters = new ArrayList<PrinterInfo>();
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // Grab the printer ids as only the service can create such.
+                StubbablePrinterDiscoverySession session = sessionCallbacks.getSession();
+                reportedPrinters.addAll(session.getPrinters());
+            }
+        });
+
+        final int reportedPrinterCount = reportedPrinters.size();
+        for (int i = 0; i < reportedPrinterCount; i++) {
+            PrinterInfo reportedPrinter = reportedPrinters.get(i);
+            String localId = reportedPrinter.getId().getLocalId();
+            if (printerLocalId.equals(localId)) {
+                return reportedPrinter.getId();
+            }
+        }
+
+        return null;
+    }
+
+    private PrintServiceCallbacks createSecondMockPrintServiceCallbacks() {
+        return createMockPrintServiceCallbacks(null, null, null);
+    }
+
+    private PrinterDiscoverySessionCallbacks createFirstMockPrinterDiscoverySessionCallbacks() {
+        return createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) {
+                // Get the session.
+                StubbablePrinterDiscoverySession session = ((PrinterDiscoverySessionCallbacks)
+                        invocation.getMock()).getSession();
+
+                if (session.getPrinters().isEmpty()) {
+                    List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+
+                    // Add the first printer.
+                    PrinterId firstPrinterId = session.getService().generatePrinterId(
+                            FIRST_PRINTER_LOCAL_ID);
+                    PrinterInfo firstPrinter = new PrinterInfo.Builder(firstPrinterId,
+                            FIRST_PRINTER_NAME, PrinterInfo.STATUS_IDLE)
+                        .build();
+                    printers.add(firstPrinter);
+
+                    // Add the first printer.
+                    PrinterId secondPrinterId = session.getService().generatePrinterId(
+                            SECOND_PRINTER_LOCAL_ID);
+                    PrinterInfo secondPrinter = new PrinterInfo.Builder(secondPrinterId,
+                            SECOND_PRINTER_NAME, PrinterInfo.STATUS_IDLE)
+                        .build();
+                    printers.add(secondPrinter);
+
+                    session.addPrinters(printers);
+                }
+                return null;
+            }
+        }, null, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Get the session.
+                StubbablePrinterDiscoverySession session = ((PrinterDiscoverySessionCallbacks)
+                        invocation.getMock()).getSession();
+
+                PrinterId trackedPrinterId = (PrinterId) invocation.getArguments()[0];
+                List<PrinterInfo> reportedPrinters = session.getPrinters();
+
+                // We should be tracking a printer that we added.
+                PrinterInfo trackedPrinter = null;
+                final int reportedPrinterCount = reportedPrinters.size();
+                for (int i = 0; i < reportedPrinterCount; i++) {
+                    PrinterInfo reportedPrinter = reportedPrinters.get(i);
+                    if (reportedPrinter.getId().equals(trackedPrinterId)) {
+                        trackedPrinter = reportedPrinter;
+                        break;
+                    }
+                }
+                assertNotNull("Can track only added printers", trackedPrinter);
+
+                // If the printer does not have capabilities reported add them.
+                if (trackedPrinter.getCapabilities() == null) {
+
+                    // Add the capabilities to emulate lazy discovery.
+                    // Same for each printer is fine for what we test.
+                    PrinterCapabilitiesInfo capabilities =
+                            new PrinterCapabilitiesInfo.Builder(trackedPrinterId)
+                        .setMinMargins(new Margins(200, 200, 200, 200))
+                        .addMediaSize(MediaSize.ISO_A4, true)
+                        .addMediaSize(MediaSize.ISO_A5, false)
+                        .addResolution(new Resolution("300x300", "300x300", 300, 300), true)
+                        .setColorModes(PrintAttributes.COLOR_MODE_COLOR,
+                                PrintAttributes.COLOR_MODE_COLOR)
+                        .build();
+                    PrinterInfo updatedPrinter = new PrinterInfo.Builder(trackedPrinter)
+                        .setCapabilities(capabilities)
+                        .build();
+
+                    // Update the printer.
+                    List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+                    printers.add(updatedPrinter);
+                    session.addPrinters(printers);
+                }
+
+                return null;
+            }
+        }, null, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Take a note onDestroy was called.
+                onPrinterDiscoverySessionDestroyCalled();
+                return null;
+            }
+        });
+    }
+
+    public PrintDocumentAdapter createMockPrintDocumentAdapter() {
+        return createMockPrintDocumentAdapter(
+            new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                LayoutResultCallback callback = (LayoutResultCallback) invocation.getArguments()[3];
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
+                        .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
+                        .setPageCount(3)
+                        .build();
+                callback.onLayoutFinished(info, false);
+                // Mark layout was called.
+                onLayoutCalled();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                PageRange[] pages = (PageRange[]) args[0];
+                ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
+                WriteResultCallback callback = (WriteResultCallback) args[3];
+                fd.close();
+                callback.onWriteFinished(pages);
+                // Mark write was called.
+                onWriteCalled();
+                return null;
+            }
+        }, new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // Mark finish was called.
+                onFinishCalled();
+                return null;
+            }
+        });
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_PinnedPositionsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_PinnedPositionsTest.java
new file mode 100644
index 0000000..2a8e806
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_PinnedPositionsTest.java
@@ -0,0 +1,489 @@
+/*
+ * Copyright (C) 2013 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.provider.cts;
+
+import static android.provider.cts.contacts.ContactUtil.newContentValues;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.PinnedPositions;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.cts.contacts.CommonDatabaseUtils;
+import android.provider.cts.contacts.ContactUtil;
+import android.provider.cts.contacts.DatabaseAsserts;
+import android.provider.cts.contacts.RawContactUtil;
+import android.test.AndroidTestCase;
+
+/**
+ * CTS tests for {@link android.provider.ContactsContract.PinnedPositions} API
+ */
+public class ContactsContract_PinnedPositionsTest extends AndroidTestCase {
+    private ContentResolver mResolver;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mResolver = getContext().getContentResolver();
+    }
+
+    /**
+     * Tests that the ContactsProvider automatically stars/unstars a pinned/unpinned contact if
+     * {@link PinnedPositions#STAR_WHEN_PINNING} boolean parameter is set to true, and that the
+     * values are correctly propogated to the contact's constituent raw contacts.
+     */
+    public void testPinnedPositionsUpdateForceStar() {
+        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        final int unpinned = PinnedPositions.UNPINNED;
+
+        assertValuesForContact(i1.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 0));
+        assertValuesForContact(i2.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 0));
+        assertValuesForContact(i3.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 0));
+        assertValuesForContact(i4.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 0));
+
+        assertValuesForRawContact(i1.mRawContactId, newContentValues(RawContacts.PINNED, unpinned));
+        assertValuesForRawContact(i2.mRawContactId, newContentValues(RawContacts.PINNED, unpinned));
+        assertValuesForRawContact(i3.mRawContactId, newContentValues(RawContacts.PINNED, unpinned));
+        assertValuesForRawContact(i4.mRawContactId, newContentValues(RawContacts.PINNED, unpinned));
+
+        final ContentValues values =
+                newContentValues(i1.mContactId, 1, i3.mContactId, 3, i4.mContactId, 2);
+        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
+                .appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").build(),
+                values, null, null);
+
+        // Pinning a contact should automatically star it if we specified the boolean parameter.
+        assertValuesForContact(i1.mContactId,
+                newContentValues(Contacts.PINNED, 1, Contacts.STARRED, 1));
+        assertValuesForContact(i2.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 0));
+        assertValuesForContact(i3.mContactId,
+                newContentValues(Contacts.PINNED, 3, Contacts.STARRED, 1));
+        assertValuesForContact(i4.mContactId,
+                newContentValues(Contacts.PINNED, 2, Contacts.STARRED, 1));
+
+        // Make sure the values are propagated to raw contacts.
+        assertValuesForRawContact(i1.mRawContactId, newContentValues(RawContacts.PINNED, 1));
+        assertValuesForRawContact(i2.mRawContactId, newContentValues(RawContacts.PINNED, unpinned));
+        assertValuesForRawContact(i3.mRawContactId, newContentValues(RawContacts.PINNED, 3));
+        assertValuesForRawContact(i4.mRawContactId, newContentValues(RawContacts.PINNED, 2));
+
+        final ContentValues unpin = newContentValues(i3.mContactId, unpinned);
+        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
+                .appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").build(),
+                unpin, null, null);
+
+        // Unpinning a contact should automatically unstar it.
+        assertValuesForContact(i1.mContactId,
+                newContentValues(Contacts.PINNED, 1, Contacts.STARRED, 1));
+        assertValuesForContact(i2.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 0));
+        assertValuesForContact(i3.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 0));
+        assertValuesForContact(i4.mContactId,
+                newContentValues(Contacts.PINNED, 2, Contacts.STARRED, 1));
+
+        assertValuesForRawContact(i1.mRawContactId,
+                newContentValues(RawContacts.PINNED, 1, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i2.mRawContactId,
+                newContentValues(RawContacts.PINNED, unpinned, RawContacts.STARRED, 0));
+        assertValuesForRawContact(i3.mRawContactId,
+                newContentValues(RawContacts.PINNED, unpinned, RawContacts.STARRED, 0));
+        assertValuesForRawContact(i4.mRawContactId,
+                newContentValues(RawContacts.PINNED, 2, RawContacts.STARRED, 1));
+
+        ContactUtil.delete(mResolver, i1.mContactId);
+        ContactUtil.delete(mResolver, i2.mContactId);
+        ContactUtil.delete(mResolver, i3.mContactId);
+        ContactUtil.delete(mResolver, i4.mContactId);
+    }
+
+    /**
+     * Tests that the ContactsProvider does not automatically star/unstar a pinned/unpinned contact
+     * if {@link PinnedPositions#STAR_WHEN_PINNING} boolean parameter not set to true or not
+     * provided.
+     */
+    public void testPinnedPositionsUpdateDontForceStar() {
+        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        final int unpinned = PinnedPositions.UNPINNED;
+
+        final ContentValues values =
+                newContentValues(i1.mContactId, 1, i3.mContactId, 3, i4.mContactId, 2);
+        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values, null, null);
+
+        // Pinning a contact should not automatically star it since we didn't specify the
+        // STAR_WHEN_PINNING boolean parameter.
+        assertValuesForContact(i1.mContactId,
+                newContentValues(Contacts.PINNED, 1, Contacts.STARRED, 0));
+        assertValuesForContact(i2.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 0));
+        assertValuesForContact(i3.mContactId,
+                newContentValues(Contacts.PINNED, 3, Contacts.STARRED, 0));
+        assertValuesForContact(i4.mContactId,
+                newContentValues(Contacts.PINNED, 2, Contacts.STARRED, 0));
+
+        // Make sure the values are propagated to raw contacts.
+        assertValuesForRawContact(i1.mRawContactId,
+                newContentValues(RawContacts.PINNED, 1, RawContacts.STARRED, 0));
+        assertValuesForRawContact(i2.mRawContactId,
+                newContentValues(RawContacts.PINNED, unpinned, RawContacts.STARRED, 0));
+        assertValuesForRawContact(i3.mRawContactId,
+                newContentValues(RawContacts.PINNED, 3, RawContacts.STARRED, 0));
+        assertValuesForRawContact(i4.mRawContactId,
+                newContentValues(RawContacts.PINNED, 2, RawContacts.STARRED, 0));
+
+        // Manually star contact 3.
+        assertEquals(1,
+                updateItemForContact(Contacts.CONTENT_URI, i3.mContactId, Contacts.STARRED, "1"));
+
+        // Check the third contact and raw contact is starred.
+        assertValuesForContact(i1.mContactId,
+                newContentValues(Contacts.PINNED, 1, Contacts.STARRED, 0));
+        assertValuesForContact(i2.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 0));
+        assertValuesForContact(i3.mContactId,
+                newContentValues(Contacts.PINNED, 3, Contacts.STARRED, 1));
+        assertValuesForContact(i4.mContactId,
+                newContentValues(Contacts.PINNED, 2, Contacts.STARRED, 0));
+
+        assertValuesForRawContact(i1.mRawContactId,
+                newContentValues(RawContacts.PINNED, 1, RawContacts.STARRED, 0));
+        assertValuesForRawContact(i2.mRawContactId,
+                newContentValues(RawContacts.PINNED, unpinned, RawContacts.STARRED, 0));
+        assertValuesForRawContact(i3.mRawContactId,
+                newContentValues(RawContacts.PINNED, 3, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i4.mRawContactId,
+                newContentValues(RawContacts.PINNED, 2, RawContacts.STARRED, 0));
+
+        final ContentValues unpin = newContentValues(i3.mContactId, unpinned);
+
+        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, unpin, null, null);
+
+        // Unpinning a contact should not automatically unstar it.
+        assertValuesForContact(i1.mContactId,
+                newContentValues(Contacts.PINNED, 1, Contacts.STARRED, 0));
+        assertValuesForContact(i2.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 0));
+        assertValuesForContact(i3.mContactId,
+                newContentValues(Contacts.PINNED, unpinned, Contacts.STARRED, 1));
+        assertValuesForContact(i4.mContactId,
+                newContentValues(Contacts.PINNED, 2, Contacts.STARRED, 0));
+
+        assertValuesForRawContact(i1.mRawContactId,
+                newContentValues(RawContacts.PINNED, 1, RawContacts.STARRED, 0));
+        assertValuesForRawContact(i2.mRawContactId,
+                newContentValues(RawContacts.PINNED, unpinned, RawContacts.STARRED, 0));
+        assertValuesForRawContact(i3.mRawContactId,
+                newContentValues(RawContacts.PINNED, unpinned, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i4.mRawContactId,
+                newContentValues(RawContacts.PINNED, 2, RawContacts.STARRED, 0));
+
+        ContactUtil.delete(mResolver, i1.mContactId);
+        ContactUtil.delete(mResolver, i2.mContactId);
+        ContactUtil.delete(mResolver, i3.mContactId);
+        ContactUtil.delete(mResolver, i4.mContactId);
+    }
+
+    /**
+     * Tests that updating the ContactsProvider with illegal pinned position correctly
+     * throws an IllegalArgumentException.
+     */
+    public void testPinnedPositionsUpdateIllegalValues() {
+        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        final int unpinned = PinnedPositions.UNPINNED;
+
+        assertValuesForContact(i1.mContactId, newContentValues(Contacts.PINNED, unpinned));
+        assertValuesForContact(i2.mContactId, newContentValues(Contacts.PINNED, unpinned));
+        assertValuesForContact(i3.mContactId, newContentValues(Contacts.PINNED, unpinned));
+        assertValuesForContact(i4.mContactId, newContentValues(Contacts.PINNED, unpinned));
+
+        // Unsupported string should throw an IllegalArgumentException.
+        final ContentValues values = newContentValues(i1.mContactId, 1, i3.mContactId, 3,
+                i4.mContactId, "undemotemeplease!");
+        try {
+            mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values, null, null);
+            fail("Pinned position must be an integer.");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        // Unsupported pinned position (e.g. float value) should throw an IllegalArgumentException.
+        final ContentValues values2 = newContentValues(i1.mContactId, "1.1");
+        try {
+            mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values2, null, null);
+            fail("Pinned position must be an integer");
+        } catch (IllegalArgumentException expected) {
+        }
+
+        // Nothing should have been changed.
+
+        assertValuesForContact(i1.mContactId, newContentValues(Contacts.PINNED, unpinned));
+        assertValuesForContact(i2.mContactId, newContentValues(Contacts.PINNED, unpinned));
+        assertValuesForContact(i3.mContactId, newContentValues(Contacts.PINNED, unpinned));
+        assertValuesForContact(i4.mContactId, newContentValues(Contacts.PINNED, unpinned));
+
+        assertValuesForRawContact(i1.mRawContactId, newContentValues(RawContacts.PINNED, unpinned));
+        assertValuesForRawContact(i2.mRawContactId, newContentValues(RawContacts.PINNED, unpinned));
+        assertValuesForRawContact(i3.mRawContactId, newContentValues(RawContacts.PINNED, unpinned));
+        assertValuesForRawContact(i4.mRawContactId, newContentValues(RawContacts.PINNED, unpinned));
+
+        ContactUtil.delete(mResolver, i1.mContactId);
+        ContactUtil.delete(mResolver, i2.mContactId);
+        ContactUtil.delete(mResolver, i3.mContactId);
+        ContactUtil.delete(mResolver, i4.mContactId);
+    }
+
+    /**
+     * Tests that pinned positions are correctly handled after the ContactsProvider aggregates
+     * and splits raw contacts.
+     */
+    public void testPinnedPositionsAfterJoinAndSplit() {
+        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i5 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i6 = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        final ContentValues values = newContentValues(i1.mContactId, 1, i2.mContactId, 2,
+                i3.mContactId, 3, i5.mContactId, 5, i6.mContactId, 6);
+        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
+                .appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").build(),
+                values, null, null);
+
+        // Aggregate raw contact 1 and 4 together.
+        ContactUtil.setAggregationException(mResolver, AggregationExceptions.TYPE_KEEP_TOGETHER,
+                i1.mRawContactId, i4.mRawContactId);
+
+        // If only one contact is pinned, the resulting contact should inherit the pinned position.
+        assertValuesForContact(i1.mContactId, newContentValues(Contacts.PINNED, 1));
+        assertValuesForContact(i2.mContactId, newContentValues(Contacts.PINNED, 2));
+        assertValuesForContact(i3.mContactId, newContentValues(Contacts.PINNED, 3));
+        assertValuesForContact(i5.mContactId, newContentValues(Contacts.PINNED, 5));
+        assertValuesForContact(i6.mContactId, newContentValues(Contacts.PINNED, 6));
+
+        assertValuesForRawContact(i1.mRawContactId,
+                newContentValues(RawContacts.PINNED, 1, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i2.mRawContactId,
+                newContentValues(RawContacts.PINNED, 2, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i3.mRawContactId,
+                newContentValues(RawContacts.PINNED, 3, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i4.mRawContactId,
+                newContentValues(RawContacts.PINNED, PinnedPositions.UNPINNED, RawContacts.STARRED,
+                        0));
+        assertValuesForRawContact(i5.mRawContactId,
+                newContentValues(RawContacts.PINNED, 5, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i6.mRawContactId,
+                newContentValues(RawContacts.PINNED, 6, RawContacts.STARRED, 1));
+
+        // Aggregate raw contact 2 and 3 together.
+        ContactUtil.setAggregationException(mResolver, AggregationExceptions.TYPE_KEEP_TOGETHER,
+                i2.mRawContactId, i3.mRawContactId);
+
+        // If both raw contacts are pinned, the resulting contact should inherit the lower
+        // pinned position.
+        assertValuesForContact(i1.mContactId, newContentValues(Contacts.PINNED, 1));
+        assertValuesForContact(i2.mContactId, newContentValues(Contacts.PINNED, 2));
+        assertValuesForContact(i5.mContactId, newContentValues(Contacts.PINNED, 5));
+        assertValuesForContact(i6.mContactId, newContentValues(Contacts.PINNED, 6));
+
+        assertValuesForRawContact(i1.mRawContactId, newContentValues(RawContacts.PINNED, 1));
+        assertValuesForRawContact(i2.mRawContactId, newContentValues(RawContacts.PINNED, 2));
+        assertValuesForRawContact(i3.mRawContactId, newContentValues(RawContacts.PINNED, 3));
+        assertValuesForRawContact(i4.mRawContactId,
+                newContentValues(RawContacts.PINNED, PinnedPositions.UNPINNED));
+        assertValuesForRawContact(i5.mRawContactId, newContentValues(RawContacts.PINNED, 5));
+        assertValuesForRawContact(i6.mRawContactId, newContentValues(RawContacts.PINNED, 6));
+
+        // Split the aggregated raw contacts.
+        ContactUtil.setAggregationException(mResolver, AggregationExceptions.TYPE_KEEP_SEPARATE,
+            i1.mRawContactId, i4.mRawContactId);
+
+        // Raw contacts should be unpinned after being split, but still starred.
+        assertValuesForRawContact(i1.mRawContactId,
+                newContentValues(RawContacts.PINNED, PinnedPositions.UNPINNED, RawContacts.STARRED,
+                        1));
+        assertValuesForRawContact(i2.mRawContactId,
+                newContentValues(RawContacts.PINNED, 2, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i3.mRawContactId,
+                newContentValues(RawContacts.PINNED, 3, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i4.mRawContactId,
+                newContentValues(RawContacts.PINNED, PinnedPositions.UNPINNED, RawContacts.STARRED,
+                        0));
+        assertValuesForRawContact(i5.mRawContactId,
+                newContentValues(RawContacts.PINNED, 5, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i6.mRawContactId,
+                newContentValues(RawContacts.PINNED, 6, RawContacts.STARRED, 1));
+
+        // Now demote contact 5.
+        final ContentValues cv = newContentValues(i5.mContactId, PinnedPositions.DEMOTED);
+        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().build(),
+                cv, null, null);
+
+        // Get new contact Ids for contacts composing of raw contacts 1 and 4 because they have
+        // changed.
+        final long cId1 = RawContactUtil.queryContactIdByRawContactId(mResolver, i1.mRawContactId);
+        final long cId4 = RawContactUtil.queryContactIdByRawContactId(mResolver, i4.mRawContactId);
+
+        assertValuesForContact(cId1, newContentValues(Contacts.PINNED, PinnedPositions.UNPINNED));
+        assertValuesForContact(i2.mContactId, newContentValues(Contacts.PINNED, 2));
+        assertValuesForContact(cId4, newContentValues(Contacts.PINNED, PinnedPositions.UNPINNED));
+        assertValuesForContact(i5.mContactId,
+                newContentValues(Contacts.PINNED, PinnedPositions.DEMOTED));
+        assertValuesForContact(i6.mContactId, newContentValues(Contacts.PINNED, 6));
+
+        // Aggregate contacts 5 and 6 together.
+        ContactUtil.setAggregationException(mResolver, AggregationExceptions.TYPE_KEEP_TOGETHER,
+                i5.mRawContactId, i6.mRawContactId);
+
+        // The resulting contact should have a pinned value of 6.
+        assertValuesForContact(cId1, newContentValues(Contacts.PINNED, PinnedPositions.UNPINNED));
+        assertValuesForContact(i2.mContactId, newContentValues(Contacts.PINNED, 2));
+        assertValuesForContact(cId4, newContentValues(Contacts.PINNED, PinnedPositions.UNPINNED));
+        assertValuesForContact(i5.mContactId, newContentValues(Contacts.PINNED, 6));
+
+        ContactUtil.delete(mResolver, cId1);
+        ContactUtil.delete(mResolver, i2.mContactId);
+        ContactUtil.delete(mResolver, cId4);
+        ContactUtil.delete(mResolver, i5.mContactId);
+    }
+
+    /**
+     * Tests that pinned positions are correctly handled for contacts that have been demoted
+     * or undemoted.
+     */
+    public void testPinnedPositionsAfterDemoteAndUndemote() {
+        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
+        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        final ContentValues values =
+                newContentValues(i1.mContactId, 0, i2.mContactId, PinnedPositions.DEMOTED);
+
+        // Pin contact 1 and demote contact 2.
+        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().
+                appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").
+                build(), values, null, null);
+
+        assertValuesForContact(i1.mContactId,
+                newContentValues(Contacts.PINNED, 0, Contacts.STARRED, 1));
+        assertValuesForContact(i2.mContactId,
+                newContentValues(Contacts.PINNED, PinnedPositions.DEMOTED, Contacts.STARRED, 0));
+
+        assertValuesForRawContact(i1.mRawContactId,
+                newContentValues(RawContacts.PINNED, 0, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i2.mRawContactId,
+                newContentValues(RawContacts.PINNED, PinnedPositions.DEMOTED, RawContacts.STARRED, 0));
+
+        // Now undemote both contacts.
+        final ContentValues values2 = newContentValues(i1.mContactId, PinnedPositions.UNDEMOTE,
+                i2.mContactId, PinnedPositions.UNDEMOTE);
+        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().
+                build(), values2, null, null);
+
+        // Contact 1 remains pinned at 0, while contact 2 becomes unpinned.
+        assertValuesForContact(i1.mContactId,
+                newContentValues(Contacts.PINNED, 0, Contacts.STARRED, 1));
+        assertValuesForContact(i2.mContactId,
+                newContentValues(Contacts.PINNED, PinnedPositions.UNPINNED, Contacts.STARRED, 0));
+
+        assertValuesForRawContact(i1.mRawContactId,
+                newContentValues(RawContacts.PINNED, 0, RawContacts.STARRED, 1));
+        assertValuesForRawContact(i2.mRawContactId,
+                newContentValues(RawContacts.PINNED, PinnedPositions.UNPINNED, RawContacts.STARRED,
+                        0));
+
+        ContactUtil.delete(mResolver, i1.mContactId);
+        ContactUtil.delete(mResolver, i2.mContactId);
+    }
+
+    /**
+     * Verifies that the stored values for the contact that corresponds to the given contactId
+     * contain the exact same name-value pairs in the given ContentValues.
+     *
+     * @param contactId Id of a valid contact in the contacts database.
+     * @param contentValues A valid ContentValues object.
+     */
+    private void assertValuesForContact(long contactId, ContentValues contentValues) {
+        DatabaseAsserts.assertStoredValuesInUriMatchExactly(mResolver, Contacts.CONTENT_URI.
+                buildUpon().appendEncodedPath(String.valueOf(contactId)).build(), contentValues);
+    }
+
+    /**
+     * Verifies that the stored values for the raw contact that corresponds to the given
+     * rawContactId contain the exact same name-value pairs in the given ContentValues.
+     *
+     * @param rawContactId Id of a valid contact in the contacts database
+     * @param contentValues A valid ContentValues object
+     */
+    private void assertValuesForRawContact(long rawContactId, ContentValues contentValues) {
+        DatabaseAsserts.assertStoredValuesInUriMatchExactly(mResolver, RawContacts.CONTENT_URI.
+                buildUpon().appendEncodedPath(String.valueOf(rawContactId)).build(), contentValues);
+    }
+
+    /**
+     * Updates the contacts provider for a contact or raw contact corresponding to the given
+     * contact with key-value pairs as specified in the provided string parameters. Throws an
+     * exception if the number of provided string parameters is not zero or non-even.
+     *
+     * @param uri base URI that the provided ID will be appended onto, in order to creating the
+     * resulting URI
+     * @param id id of the contact of raw contact to perform the update for
+     * @param extras an even number of string parameters that correspond to name-value pairs
+     *
+     * @return the number of rows that were updated
+     */
+    private int updateItemForContact(Uri uri, long id, String... extras) {
+        Uri itemUri = ContentUris.withAppendedId(uri, id);
+        return updateItemForUri(itemUri, extras);
+    }
+
+    /**
+     * Updates the contacts provider for the given YRU with key-value pairs as specified in the
+     * provided string parameters. Throws an exception if the number of provided string parameters
+     * is not zero or non-even.
+     *
+     * @param uri URI to perform the update for
+     * @param extras an even number of string parameters that correspond to name-value pairs
+     *
+     * @return the number of rows that were updated
+     */
+    private int updateItemForUri(Uri uri, String... extras) {
+        ContentValues values = new ContentValues();
+        CommonDatabaseUtils.extrasVarArgsToValues(values, extras);
+        return mResolver.update(uri, values, null, null);
+    }
+}
+
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/CommonDatabaseUtils.java b/tests/tests/provider/src/android/provider/cts/contacts/CommonDatabaseUtils.java
index 833de64..d89e06c 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/CommonDatabaseUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/CommonDatabaseUtils.java
@@ -16,8 +16,11 @@
 
 package android.provider.cts.contacts;
 
+import android.content.ContentValues;
 import android.database.Cursor;
 
+import junit.framework.Assert;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -67,4 +70,21 @@
             cursor.close();
         }
     }
+
+    /**
+     * Verifies that the number of string parameters is either zero or even, and inserts them
+     * into the provided ContentValues object as a set of name-value pairs. Throws an exception if
+     * the number of string parameters is odd, or a single null parameter was provided.
+     *
+     * @param values ContentValues object to insert name-value pairs into
+     * @param extras Zero or even number of string parameters
+     */
+    public static void extrasVarArgsToValues(ContentValues values, String... extras) {
+        Assert.assertNotNull(extras);
+        // Check that the number of provided string parameters is even.
+        Assert.assertEquals(0, extras.length % 2);
+        for (int i = 0; i < extras.length; i += 2) {
+            values.put(extras[i], extras[i + 1]);
+        }
+    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactUtil.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactUtil.java
index 2a53781..f6d67b9 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactUtil.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactUtil.java
@@ -22,6 +22,9 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.provider.ContactsContract;
+import android.provider.ContactsContract.AggregationExceptions;
+
+import junit.framework.Assert;
 
 /**
  * Convenience methods for operating on the Contacts table.
@@ -71,4 +74,64 @@
         }
         return CommonDatabaseUtils.NOT_FOUND;
     }
+
+    /**
+     * Verifies that the number of object parameters is either zero or even, inserts them
+     * into a new ContentValues object as a set of name-value pairs, and returns the newly created
+     * ContentValues object. Throws an exception if the number of string parameters is odd, or a
+     * single null parameter was provided.
+     *
+     * @param namesAndValues Zero or even number of object parameters to convert into name-value
+     * pairs
+     *
+     * @return newly created ContentValues containing the provided name-value pairs
+     */
+    public static ContentValues newContentValues(Object... namesAndValues) {
+        // Checks that the number of provided parameters is zero or even.
+        Assert.assertEquals(0, namesAndValues.length % 2);
+        final ContentValues contentValues = new ContentValues();
+        for (int i = 0; i < namesAndValues.length - 1; i += 2) {
+            Assert.assertNotNull(namesAndValues[i]);
+            final String name = namesAndValues[i].toString();
+            final Object value = namesAndValues[i + 1];
+            if (value == null) {
+                contentValues.putNull(name);
+            } else if (value instanceof String) {
+                contentValues.put(name, (String) value);
+            } else if (value instanceof Integer) {
+                contentValues.put(name, (Integer) value);
+            } else if (value instanceof Long) {
+                contentValues.put(name, (Long) value);
+            } else {
+                Assert.fail("Unsupported value type: " + value.getClass().getSimpleName() + " for "
+                    + " name: " + name);
+            }
+        }
+        return contentValues;
+    }
+
+    /**
+     * Updates the content resolver with two given raw contact ids and an aggregation type to
+     * manually trigger the forced aggregation, splitting of two raw contacts or specify that
+     * the provider should automatically decide whether or not to aggregate the two raw contacts.
+     *
+     * @param resolver ContentResolver from a valid context
+     * @param type One of the following aggregation exception types:
+     * {@link AggregationExceptions#TYPE_AUTOMATIC},
+     * {@link AggregationExceptions#TYPE_KEEP_SEPARATE},
+     * {@link AggregationExceptions#TYPE_KEEP_TOGETHER}
+     * @param rawContactId1 Id of the first raw contact
+     * @param rawContactId2 Id of the second raw contact
+     */
+    public static void setAggregationException(ContentResolver resolver, int type,
+        long rawContactId1, long rawContactId2) {
+        ContentValues values = new ContentValues();
+        values.put(AggregationExceptions.RAW_CONTACT_ID1, rawContactId1);
+        values.put(AggregationExceptions.RAW_CONTACT_ID2, rawContactId2);
+        values.put(AggregationExceptions.TYPE, type);
+        // Actually set the aggregation exception in the contacts database, and check that a
+        // single row was updated.
+        Assert.assertEquals(1, resolver.update(AggregationExceptions.CONTENT_URI, values, null,
+                  null));
+  }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationResize.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationResize.java
index b6d9a1a..68d7274 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/AllocationResize.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationResize.java
@@ -49,7 +49,7 @@
         mIn.copy1DRangeFrom(0, INPUTSIZE, inArray);
 
         try {
-            RSUtils.forEach(this, 0, mIn, mOut);
+            forEach(0, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ClearObjectTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ClearObjectTest.java
index 64deb33..e8a330a 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ClearObjectTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ClearObjectTest.java
@@ -66,7 +66,7 @@
         Allocation mOut = Allocation.createSized(mRS, Element.I32(mRS), ObjectNum);
         ms_clear.set_element(element);
         try {
-            RSUtils.forEach(this, TEST_ID_ELEMENT, mIn, mOut);
+            forEach(TEST_ID_ELEMENT, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         int[] tmpArray = new int[ObjectNum];
@@ -83,7 +83,7 @@
         ms_clear.set_type(type);
 
         try {
-            RSUtils.forEach(this, TEST_ID_TYPE, mIn, mOut);
+            forEach(TEST_ID_TYPE, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         int[] tmpArray = new int[ObjectNum];
@@ -99,7 +99,7 @@
         Allocation allocation = Allocation.createTyped(mRS, mIn.getType());
         ms_clear.set_allocation(allocation);
         try {
-            RSUtils.forEach(this, TEST_ID_ALLOCATION, mIn, mOut);
+            forEach(TEST_ID_ALLOCATION, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         int[] tmpArray = new int[ObjectNum];
@@ -115,7 +115,7 @@
         Allocation mIn = Allocation.createSized(mRS, Element.I32(mRS), ObjectNum);
         ms_clear.set_sampler(sampler);
         try {
-            RSUtils.forEach(this, TEST_ID_SAMPLER, mIn, mOut);
+            forEach(TEST_ID_SAMPLER, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         int[] tmpArray = new int[ObjectNum];
@@ -131,7 +131,7 @@
         Allocation mOut = Allocation.createSized(mRS, Element.I32(mRS), ObjectNum);
         ms_clear.set_script(script);
         try {
-            RSUtils.forEach(this, TEST_ID_SCRIPT, mIn, mOut);
+            forEach(TEST_ID_SCRIPT, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         int[] tmpArray = new int[ObjectNum];
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/GetElementAt.java b/tests/tests/renderscript/src/android/renderscript/cts/GetElementAt.java
index a9be1bc..babc1ef 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/GetElementAt.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/GetElementAt.java
@@ -62,7 +62,7 @@
         mOut = Allocation.createTyped(mRS, gIn.getType());
         script_x.set_gIn(gIn);
         try {
-            RSUtils.forEach(this, TEST_ID_X, mOut);
+            forEach(TEST_ID_X, mOut);
         } catch (RSRuntimeException e) {
         }
         mOut.copyTo(out);
@@ -83,7 +83,7 @@
         mOut = Allocation.createTyped(mRS, gIn.getType());
         script_xy.set_gIn(gIn);
         try {
-            RSUtils.forEach(this, TEST_ID_XY, mOut);
+            forEach(TEST_ID_XY, mOut);
         } catch (RSRuntimeException e) {
         }
         mOut.copyTo(out);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/InitTest.java b/tests/tests/renderscript/src/android/renderscript/cts/InitTest.java
index ef36927..848c192 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/InitTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/InitTest.java
@@ -46,7 +46,7 @@
         mIn.copy1DRangeFrom(0, INPUTSIZE, in);
 
         try {
-            RSUtils.forEach(this, 0, mIn, mOut);
+            forEach(0, mIn, mOut);
         } catch (RSRuntimeException e) {
         }
         mOut.copyTo(out);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java b/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java
index 09a2e94..ad3d078 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/PowTest.java
@@ -88,8 +88,8 @@
     }
 
     @Override
-    protected void fillRandom(long seed, int fact, int offset, float[] inArray, int rStride, int rSkip) {
-        RSUtils.genRandom(seed, 32, -16, inArray, rStride, rSkip);
+    protected void fillRandomFloats(long seed, int fact, int offset, float[] inArray) {
+        RSUtils.genRandomFloats(seed, 32, -16, inArray);
     }
 
     public void testPowF32() {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java b/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java
index c95a294..32308ce 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/PownTest.java
@@ -82,7 +82,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE];
-        RSUtils.genRandom(0x12345678, 32, 1, -16, n);
+        RSUtils.genRandomInts(0x12345678, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32.set_n1(nAlloc);
 
@@ -93,7 +93,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE];
-        RSUtils.genRandom(0x12345678, 32, 1, -16, n);
+        RSUtils.genRandomInts(0x12345678, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n1(nAlloc);
 
@@ -104,7 +104,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*2];
-        RSUtils.genRandom(0xacdef1, 32, 1, -16, n);
+        RSUtils.genRandomInts(0xacdef1, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32.set_n2(nAlloc);
 
@@ -115,7 +115,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*2];
-        RSUtils.genRandom(0xacdef1, 32, 1, -16, n);
+        RSUtils.genRandomInts(0xacdef1, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n2(nAlloc);
 
@@ -126,7 +126,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0xa123f1, 32, 1, -16, n, 4, 1);
+        RSUtils.genRandomInts(0xa123f1, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32.set_n3(nAlloc);
 
@@ -137,7 +137,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0xa123f1, 32, 1, -16, n, 4, 1);
+        RSUtils.genRandomInts(0xa123f1, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n3(nAlloc);
 
@@ -148,7 +148,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0x4323ca, 32, 1, -16, n);
+        RSUtils.genRandomInts(0x4323ca, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32.set_n4(nAlloc);
 
@@ -159,7 +159,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0x4323ca, 32, 1, -16, n);
+        RSUtils.genRandomInts(0x4323ca, 32, -16, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n4(nAlloc);
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java b/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java
index f10995b..cebbe24 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/PowrTest.java
@@ -88,8 +88,8 @@
     }
 
     @Override
-    protected void fillRandom(long seed, int fact, int offset, float[] inArray, int rStride, int rSkip) {
-        RSUtils.genRandom(seed, 64, 0, inArray, rStride, rSkip);
+    protected void fillRandomFloats(long seed, int fact, int offset, float[] inArray) {
+        RSUtils.genRandomFloats(seed, 64, 0, inArray);
     }
 
     public void testPowrF32() {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
index d68e628..d7759f1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
@@ -89,7 +89,7 @@
                                 int offset, int rStride, int rSkip, int refStride, int outStride,
                                 int inStride, int skip, int ulp) {
         float[] inArray = makeInArray(INPUTSIZE * inStride);
-        fillRandom(seed, fact, offset, inArray, rStride, rSkip);
+        fillRandomFloats(seed, fact, offset, inArray);
         float[] refArray = getRefArray(inArray, INPUTSIZE, inStride, skip);
 
         Allocation mAllocationIn = setInAlloc(inElement);
@@ -97,7 +97,7 @@
 
         Allocation mAllocationOut = setOutAlloc(outElement);
         try {
-            RSUtils.forEach(this, testid, mAllocationIn, mAllocationOut);
+            forEach(testid, mAllocationIn, mAllocationOut);
         } catch (RSRuntimeException e) {
             Log.e("RenderscriptCTS", "Caught RSRuntimeException: " +
                   e.getMessage());
@@ -173,8 +173,8 @@
         return new float[size];
     }
 
-    protected void fillRandom(long seed, int fact, int offset, float[] inArray, int rStride, int rSkip) {
-        RSUtils.genRandom(seed, fact, offset, inArray, rStride, rSkip);
+    protected void fillRandomFloats(long seed, int fact, int offset, float[] inArray) {
+        RSUtils.genRandomFloats(seed, fact, offset, inArray);
     }
 
     protected void fillInAlloc(Allocation mIn, float[] inArray) {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java b/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
index 8c81e3d..d3fb5d0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
@@ -27,65 +27,23 @@
  */
 public class RSUtils {
 
-    public static void genRandom(long seed, int factor, int offset, float array[]) {
+    /**
+     * Fills the array with random floats.  Values will be: offset + number between 0 and max.
+     */
+    public static void genRandomFloats(long seed, int max, int offset, float array[]) {
         Random r = new Random(seed);
         for (int i = 0; i < array.length; i++) {
-            array[i] = r.nextFloat() * factor + offset;
+            array[i] = r.nextFloat() * max + offset;
         }
     }
 
-    public static void genRandom(long seed, int factor, int offset, float array[],
-            int stride, int skip) {
-        Random r = new Random(seed);
-        for (int i = 0; i < array.length / stride; i++) {
-            for (int j = 0; j < stride; j++) {
-                if (j >= stride - skip)
-                    array[i * stride + j] = 0;
-                else
-                    array[i * stride + j] = r.nextFloat() * factor + offset;
-            }
-        }
-    }
-
-    public static void genRandom(long seed, int max, int factor, int offset, int array[]) {
+    /**
+     * Fills the array with random ints.  Values will be: offset + number between 0 and max (exclusive).
+     */
+    public static void genRandomInts(long seed, int max, int offset, int array[]) {
         Random r = new Random(seed);
         for (int i = 0; i < array.length; i++) {
-            array[i] = (r.nextInt(max) * factor + offset);
+            array[i] = (r.nextInt(max) + offset);
         }
     }
-
-    public static void genRandom(long seed, int factor, int offset, int array[],
-            int stride, int skip) {
-        Random r = new Random(seed);
-        for (int i = 0; i < array.length / stride; i++) {
-            for (int j = 0; j < stride; j++) {
-                if (j >= stride - skip)
-                    array[i * stride + j] = 0;
-                else
-                    array[i * stride + j] = r.nextInt() * factor + offset;
-            }
-        }
-    }
-
-    public static void genRandom(long seed, int max, int factor, int offset, int array[],
-            int stride, int skip) {
-        Random r = new Random(seed);
-        for (int i = 0; i < array.length / stride; i++) {
-            for (int j = 0; j < stride; j++) {
-                if (j >= stride - skip)
-                    array[i * stride + j] = 0;
-                else
-                    array[i * stride + j] = r.nextInt(max) * factor + offset;
-            }
-        }
-    }
-
-    public static void forEach(RSBaseCompute base, int testId, Allocation in) throws RSRuntimeException {
-        base.forEach(testId, in);
-    }
-
-    public static void forEach(RSBaseCompute base, int testId, Allocation in, Allocation out)
-            throws RSRuntimeException {
-        base.forEach(testId, in,out);
-    }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java
index 8301ad5..2c447bb 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RootnTest.java
@@ -80,7 +80,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE];
-        RSUtils.genRandom(0x12345678, 32, 1, 1, n);
+        RSUtils.genRandomInts(0x12345678, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32.set_n1(nAlloc);
 
@@ -91,7 +91,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE];
-        RSUtils.genRandom(0x12345678, 32, 1, 1, n);
+        RSUtils.genRandomInts(0x12345678, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n1(nAlloc);
 
@@ -103,7 +103,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*2];
-        RSUtils.genRandom(0xacdef1, 32, 1, 1, n);
+        RSUtils.genRandomInts(0xacdef1, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32.set_n2(nAlloc);
 
@@ -114,7 +114,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_2(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*2];
-        RSUtils.genRandom(0xacdef1, 32, 1, 1, n);
+        RSUtils.genRandomInts(0xacdef1, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n2(nAlloc);
 
@@ -126,7 +126,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0xa123f1, 32, 1, 1, n, 4, 1);
+        RSUtils.genRandomInts(0xa123f1, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32.set_n3(nAlloc);
 
@@ -137,7 +137,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_3(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0xa123f1, 32, 1, 1, n, 4, 1);
+        RSUtils.genRandomInts(0xa123f1, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n3(nAlloc);
 
@@ -148,7 +148,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0x4323ca, 32, 1, 1, n);
+        RSUtils.genRandomInts(0x4323ca, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32.set_n4(nAlloc);
 
@@ -159,7 +159,7 @@
         Allocation nAlloc = Allocation.createSized(mRS, Element.I32_4(mRS), INPUTSIZE);
 
         n = new int[INPUTSIZE*4];
-        RSUtils.genRandom(0x4323ca, 32, 1, 1, n);
+        RSUtils.genRandomInts(0x4323ca, 32, 1, n);
         nAlloc.copyFrom(n);
         script_f32_relaxed.set_n4(nAlloc);
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java b/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java
index 0b008a7..edff5b9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RsPackColorTo8888Test.java
@@ -72,10 +72,10 @@
         float[] inArray = new float[INPUTSIZE * 4];
         byte[] outArray = new byte[INPUTSIZE * 4];
         byte[] refArray = new byte[INPUTSIZE * 4];
-        RSUtils.genRandom(seed, 1, 0, inArray, 4, 1);
+        RSUtils.genRandomFloats(seed, 1, 0, inArray);
         mAllocationIn.copy1DRangeFrom(0, INPUTSIZE, inArray);
         try {
-            RSUtils.forEach(this, testId, mAllocationIn, mAllocationOut);
+            forEach(testId, mAllocationIn, mAllocationOut);
         } catch (RSRuntimeException e) {
         }
         mAllocationOut.copyTo(outArray);
@@ -99,10 +99,10 @@
         float[] inArray = new float[INPUTSIZE * 4];
         byte[] outArray = new byte[INPUTSIZE * 4];
         byte[] refArray = new byte[INPUTSIZE * 4];
-        RSUtils.genRandom(seed, 1, 0, inArray);
+        RSUtils.genRandomFloats(seed, 1, 0, inArray);
         mAllocationIn.copy1DRangeFrom(0, INPUTSIZE, inArray);
         try {
-            RSUtils.forEach(this, testId, mAllocationIn, mAllocationOut);
+            forEach(testId, mAllocationIn, mAllocationOut);
         } catch (RSRuntimeException e) {
         }
         mAllocationOut.copyTo(outArray);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RsUnpackColor8888Test.java b/tests/tests/renderscript/src/android/renderscript/cts/RsUnpackColor8888Test.java
index 4df1169..3ebbee1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RsUnpackColor8888Test.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RsUnpackColor8888Test.java
@@ -44,7 +44,7 @@
 
         mAllocationIn.copy1DRangeFrom(0, INPUTSIZE, inArray);
         try {
-            RSUtils.forEach(this, 0, mAllocationIn, mAllocationOut);
+            forEach(0, mAllocationIn, mAllocationOut);
         } catch (RSRuntimeException e) {
         }
         mAllocationOut.copyTo(outArray);
diff --git a/tests/tests/security/src/android/security/cts/CertificateTest.java b/tests/tests/security/src/android/security/cts/CertificateTest.java
index e6e2a2b..3db7aca 100644
--- a/tests/tests/security/src/android/security/cts/CertificateTest.java
+++ b/tests/tests/security/src/android/security/cts/CertificateTest.java
@@ -16,9 +16,10 @@
 
 package android.security.cts;
 
-import android.test.AndroidTestCase;
+import android.content.res.AssetManager;
+import android.test.InstrumentationTestCase;
 
-import java.io.FileInputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.KeyStore;
@@ -27,6 +28,7 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.Collections;
@@ -34,7 +36,7 @@
 import java.util.List;
 import java.util.Set;
 
-public class CertificateTest extends AndroidTestCase {
+public class CertificateTest extends InstrumentationTestCase {
 
     public void testNoRemovedCertificates() throws Exception {
         Set<String> expectedCertificates = new HashSet<String>(
@@ -45,16 +47,58 @@
     }
 
     /**
-     * {@see OEMCertificateWhitelist#OEM_CERTIFICATE_WHITELIST} for more information on this test.
+     * If you fail CTS as a result of adding a root CA that is not part of the Android root CA
+     * store, please see the following.
+     *
+     * First, this test exists because adding untrustworthy root CAs to a device has a very
+     * significant security impact. In the worst case, adding a rogue CA can permanently compromise
+     * the confidentiality and integrity of your users' network traffic. Because of this risk,
+     * adding new certificates should be done sparingly and as a last resort -- never as a first
+     * response or short term fix. Before attempting to modify this test, please consider whether
+     * adding a new certificate authority is in your users' best interests.
+     *
+     * Second, because the addition of a new root CA by an OEM can have such dire consequences for
+     * so many people it is imperative that it be done transparently and in the open. Any request to
+     * modify the certificate list used by this test must have a corresponding change in AOSP
+     * (one certificate per change) authored by the OEM in question and including:
+     *
+     *     - the certificate in question:
+     *       - The certificate must be in a file under
+     *         cts/tests/tests/security/assets/oem_cacerts, in PEM (Privacy-enhanced Electronic
+     *         Mail) format, with the textual representation of the certificate following the PEM
+     *         section.
+     *       - The file name must be in the format of <hash>.<n> where "hash" is the subject hash
+     *         produced by:
+     *           openssl x509 -in cert_file -subject_hash -noout
+     *         and the "n" is a unique integer identifier starting at 0 to deal with collisions.
+     *         See OpenSSL's c_rehash manpage for details.
+     *       - cts/tests/tests/security/tools/format_cert.sh helps meet the above requirements.
+     *
+     *     - information about who created and maintains both the certificate and the corresponding
+     *       keypair.
+     *
+     *     - information about what the certificate is to be used for and why the certificate is
+     *       appropriate for inclusion.
+     *
+     *     - a statement from the OEM indicating that they have sufficient confidence in the
+     *       security of the key, the security practices of the issuer, and the validity of the
+     *       intended use that they believe adding the certificate is not detrimental to the
+     *       security of the user.
+     *
+     * Finally, please note that this is not the usual process for adding root CAs to Android. If
+     * you have a certificate that you believe should be present on all Android devices, please file
+     * a public bug at https://code.google.com/p/android/issues/entry or http://b.android.com to
+     * seek resolution.
+     *
+     * For questions, comments, and code reviews please contact security@android.com.
      */
     public void testNoAddedCertificates() throws Exception {
-        Set<String> oemCertificateWhitelist = new HashSet<String>(
-                Arrays.asList(OEMCertificateWhitelist.OEM_CERTIFICATE_WHITELIST));
+        Set<String> oemWhitelistedCertificates = getOemWhitelistedCertificates();
         Set<String> expectedCertificates = new HashSet<String>(
                 Arrays.asList(CertificateData.CERTIFICATE_DATA));
         Set<String> deviceCertificates = getDeviceCertificates();
         deviceCertificates.removeAll(expectedCertificates);
-        deviceCertificates.removeAll(oemCertificateWhitelist);
+        deviceCertificates.removeAll(oemWhitelistedCertificates);
         assertEquals("Unknown CA certificates", Collections.EMPTY_SET, deviceCertificates);
     }
 
@@ -88,6 +132,30 @@
         return certificates;
     }
 
+    private static final String ASSETS_DIR_OEM_CERTS = "oem_cacerts";
+
+    private Set<String> getOemWhitelistedCertificates() throws Exception {
+        Set<String> certificates = new HashSet<String>();
+        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        AssetManager assetManager = getInstrumentation().getContext().getAssets();
+        for (String path : assetManager.list(ASSETS_DIR_OEM_CERTS)) {
+            File certAssetFile = new File(ASSETS_DIR_OEM_CERTS, path);
+            InputStream in = null;
+            try {
+                in = assetManager.open(certAssetFile.toString());
+                X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(in);
+                certificates.add(getFingerprint(certificate));
+            } catch (Exception e) {
+                throw new Exception("Failed to load certificate from asset: " + certAssetFile, e);
+            } finally {
+                if (in != null) {
+                    in.close();
+                }
+            }
+        }
+        return certificates;
+    }
+
     private String getFingerprint(X509Certificate certificate) throws CertificateEncodingException,
             NoSuchAlgorithmException {
         MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
diff --git a/tests/tests/security/src/android/security/cts/OEMCertificateWhitelist.java b/tests/tests/security/src/android/security/cts/OEMCertificateWhitelist.java
deleted file mode 100644
index 024c15f..0000000
--- a/tests/tests/security/src/android/security/cts/OEMCertificateWhitelist.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2013 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.security.cts;
-
-class OEMCertificateWhitelist {
-
-  /**
-   * If you fail CTS as a result of adding a root CA that is not part
-   * of the Android root CA store, please see the following.
-   *
-   * First, this test exists because adding untrustworthy root CAs
-   * to a device has a very significant security impact. In the worst
-   * case, adding a rogue CA to this list can permanently compromise
-   * the confidentiality and integrity of your users' network traffic.
-   * Because of this risk, adding new certificates should be done
-   * sparingly and as a last resort- never as a first response or
-   * short term fix. Before attempting to modify this test, please
-   * consider whether adding a new certificate authority is in your
-   * users' best interests.
-   *
-   * Second, because the addition of a new root CA by an OEM can have
-   * such dire consequences for so many people it is imperative that
-   * it be done transparently and in the open. Any request to modify
-   * this list must have a corresponding change in AOSP authored by
-   * the OEM in question and including:
-   *
-   *     - the certificate in question.
-   *
-   *     - information about who created and maintains
-   *       both the certificate and the corresponding keypair.
-   *
-   *     - information about what the certificate is to be used
-   *       for and why the certificate is appropriate for inclusion.
-   *
-   *     - a statement from the OEM indicating that they have
-   *       sufficient confidence in the security of the key, the
-   *       security practices of the issuer, and the validity
-   *       of the intended use that they believe adding the
-   *       certificate is not detrimental to the security of the
-   *       user.
-   *
-   * Finally, please note that this is not the usual process for
-   * adding root CAs to Android. If you have a certificate that you
-   * believe should be present on all Android devices, please file a
-   * public bug at https://code.google.com/p/android/issues/entry or
-   * http://b.android.com to seek resolution.
-   *
-   * For questions, comments, and code reviews please contact
-   * security@android.com.
-   */
-  static final String[] OEM_CERTIFICATE_WHITELIST = {};
-
-}
diff --git a/tests/tests/security/testeffect/Android.mk b/tests/tests/security/testeffect/Android.mk
index 49441c7..a7e3cac 100644
--- a/tests/tests/security/testeffect/Android.mk
+++ b/tests/tests/security/testeffect/Android.mk
@@ -22,7 +22,7 @@
 
 LOCAL_CFLAGS+= -O2 -fvisibility=hidden
 
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
 LOCAL_MODULE:= libctstesteffect
 
 LOCAL_C_INCLUDES := \
diff --git a/tests/tests/security/tools/format_cert.sh b/tests/tests/security/tools/format_cert.sh
new file mode 100755
index 0000000..94407a0
--- /dev/null
+++ b/tests/tests/security/tools/format_cert.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+# Outputs the provided certificate (PEM or DER) in a format used by CTS tests.
+# The format is PEM block, followed by the textual representation of the
+# certificate, followed by the SHA-1 fingerprint.
+
+# OpenSSL binary built from this Android source
+OPENSSL="$ANDROID_HOST_OUT/bin/openssl"
+if [ "$ANDROID_HOST_OUT" == "" ]; then
+  echo "Android build environment not set up"
+  echo
+  echo "Run the following from the root of the Android source tree:"
+  echo "  . build/envsetup.sh && lunch"
+  exit 1
+fi
+if [ ! -f "$OPENSSL" ]; then
+  echo "openssl binary not found"
+  echo
+  echo "Run 'mmm external/openssl' or 'make openssl' from the root of the" \
+      "Android source tree to build it."
+  exit 1
+fi
+
+# Input file containing the certificate in PEM or DER format
+in_file="$1"
+
+# Output file. If not specified, the file will be named <hash>.0 where "hash"
+# is the certificate's subject hash produced by:
+#   openssl x509 -in cert_file -subject_hash -noout
+out_file="$2"
+
+# Detect whether the input file is PEM or DER.
+in_form="pem"
+subject_hash=$("$OPENSSL" x509 -in "$in_file" -inform $in_form -subject_hash \
+    -noout 2>/dev/null)
+if [ "$?" != "0" ]; then
+  in_form="der"
+  subject_hash=$("$OPENSSL" x509 -in "$in_file" -inform $in_form -subject_hash \
+      -noout)
+  if [ "$?" != "0" ]; then
+    echo "Certificate file format is neither PEM nor DER"
+    exit 1
+  fi
+fi
+
+# Name the output file <hash>.0 if the name is not specified explicitly.
+if [ "$out_file" == "" ]; then
+  out_file="$subject_hash.0"
+  echo "Auto-generated output file name: $out_file"
+fi
+
+# Output the certificate in the target format
+"$OPENSSL" x509 -in "$in_file" -inform $in_form -outform pem > "$out_file" && \
+"$OPENSSL" x509 -in "$in_file" -inform $in_form -noout -text -fingerprint \
+    >> "$out_file"
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
index 3fc5b28..d96743c 100644
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
@@ -301,4 +301,29 @@
         assertTrue(PhoneNumberUtils.isWellFormedSmsAddress("+17005554141"));
         assertFalse(PhoneNumberUtils.isWellFormedSmsAddress("android"));
     }
+
+    public void testIsUriNumber() {
+        assertTrue(PhoneNumberUtils.isUriNumber("foo@google.com"));
+        assertTrue(PhoneNumberUtils.isUriNumber("xyz@zzz.org"));
+        assertFalse(PhoneNumberUtils.isUriNumber("+15103331245"));
+        assertFalse(PhoneNumberUtils.isUriNumber("+659231235"));
+    }
+
+    public void testGetUsernameFromUriNumber() {
+        assertEquals("john", PhoneNumberUtils.getUsernameFromUriNumber("john@myorg.com"));
+        assertEquals("tim_123", PhoneNumberUtils.getUsernameFromUriNumber("tim_123@zzz.org"));
+        assertEquals("5103331245", PhoneNumberUtils.getUsernameFromUriNumber("5103331245"));
+    }
+
+    public void testConvertAndStrip() {
+        // Untouched number.
+        assertEquals("123456789", PhoneNumberUtils.convertAndStrip("123456789"));
+        // Dashes should be stripped, legal separators (i.e. wild character remain untouched)
+        assertEquals("+15103331245*123", PhoneNumberUtils.convertAndStrip("+1-510-333-1245*123"));
+        // Arabic digits should be converted
+        assertEquals("5567861616", PhoneNumberUtils.convertAndStrip("٥‎٥‎٦‎٧‎٨‎٦‎١‎٦‎١‎٦‎"));
+        // Arabic digits converted and spaces stripped
+        assertEquals("5567861616", PhoneNumberUtils.convertAndStrip("٥‎ ٥‎٦‎ ٧‎ ٨‎ ٦‎ ١‎ ٦‎ ١‎ ٦‎"));
+
+    }
 }
diff --git a/tests/tests/util/src/android/util/cts/TypedValueTest.java b/tests/tests/util/src/android/util/cts/TypedValueTest.java
index 5cd7463..2ab91d9 100644
--- a/tests/tests/util/src/android/util/cts/TypedValueTest.java
+++ b/tests/tests/util/src/android/util/cts/TypedValueTest.java
@@ -205,16 +205,4 @@
 
         assertEquals(TypedValue.complexToDimension(10, dm), tv.getDimension(dm));
     }
-
-    public void testComplexToDimensionNoisy() {
-        DisplayMetrics dm = new DisplayMetrics();
-        dm.density = 1.1f;
-        dm.heightPixels = 100;
-        dm.scaledDensity = 2.1f;
-        dm.xdpi = 200f;
-        dm.ydpi = 300f;
-
-        assertEquals(TypedValue.complexToDimension(1, dm),
-                                 TypedValue.complexToDimensionNoisy(1, dm));
-    }
 }
diff --git a/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java b/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
index 66a86c3..f5247dd 100644
--- a/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
+++ b/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
@@ -43,20 +43,21 @@
 import android.widget.LinearLayout;
 
 public class LayoutInflaterTest extends AndroidTestCase {
-
     private LayoutInflater mLayoutInflater;
-    private Context mContext;
-    private final Factory mFactory = new Factory() {
-        public View onCreateView(String name, Context context,
-                AttributeSet attrs) {
 
+    @SuppressWarnings("hiding")
+    private Context mContext;
+
+    private final Factory mFactory = new Factory() {
+        @Override
+        public View onCreateView(String name, Context context, AttributeSet attrs) {
             return null;
         }
     };
     private boolean isOnLoadClass;
     private final Filter mFilter = new Filter() {
-
-        @SuppressWarnings("unchecked")
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        @Override
         public boolean onLoadClass(Class clazz) {
             isOnLoadClass = true;
             return true;
@@ -149,7 +150,8 @@
         mLayoutInflater = LayoutInflater.from(mContext);
         isOnLoadClass = false;
         mLayoutInflater.setFilter(new Filter() {
-            @SuppressWarnings("unchecked")
+            @SuppressWarnings({ "unchecked", "rawtypes" })
+            @Override
             public boolean onLoadClass(Class clazz) {
                 isOnLoadClass = true;
                 return false;
@@ -367,6 +369,7 @@
         View container = mLayoutInflater.inflate(R.layout.inflater_override_theme_layout, null);
         verifyThemeType(container, "view_outer", R.id.view_outer, 1);
         verifyThemeType(container, "view_inner", R.id.view_inner, 2);
+        verifyThemeType(container, "view_attr", R.id.view_attr, 3);
     }
 
     private void verifyThemeType(View container, String tag, int id, int type) {
@@ -376,7 +379,7 @@
         Theme theme = view.getContext().getTheme();
         boolean resolved = theme.resolveAttribute(R.attr.themeType, outValue, true);
         assertTrue("Resolved themeType for " + tag, resolved);
-        assertEquals(tag + " has themeType " + type, outValue.data, type);
+        assertEquals(tag + " has themeType " + type, type, outValue.data);
     }
 
     static class MockLayoutInflater extends LayoutInflater {
diff --git a/tools/tradefed-host/etc/cts-tradefed b/tools/tradefed-host/etc/cts-tradefed
index fb108b1..485740e 100755
--- a/tools/tradefed-host/etc/cts-tradefed
+++ b/tools/tradefed-host/etc/cts-tradefed
@@ -35,9 +35,9 @@
 checkPath java
 
 # check java version
-JAVA_VERSION=$(java -version 2>&1 | head -n 1 | grep '[ "]1\.6[\. "$$]')
+JAVA_VERSION=$(java -version 2>&1 | head -n 1 | grep '[ "]1\.[67][\. "$$]')
 if [ "${JAVA_VERSION}" == "" ]; then
-    echo "Wrong java version. 1.6 is required."
+    echo "Wrong java version. 1.6 or 1.7 is required."
     exit
 fi