Merge "Add a CTS case to catch non-recycleable view types bug" into mnc-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index f683840..9021921 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -62,7 +62,9 @@
     CtsKeySetSharedUserSigningBUpgradeB \
     CtsKeySetSigningABadUpgradeB \
     CtsKeySetSigningCBadAUpgradeAB \
-    CtsKeySetSigningANoDefUpgradeB
+    CtsKeySetSigningANoDefUpgradeB \
+    CtsKeySetSigningAUpgradeEcA \
+    CtsKeySetSigningEcAUpgradeA
 
 cts_support_packages := \
     CtsAccelerationTestStubs \
diff --git a/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-dsa-a.pk8 b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-dsa-a.pk8
new file mode 100644
index 0000000..ac0b0c1
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-dsa-a.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.pk8 b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.pk8
new file mode 100644
index 0000000..ec27be1
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.x509.pem b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.x509.pem
new file mode 100644
index 0000000..183691d
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.x509.pem
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBejCCAR+gAwIBAgIJAMsY4Fz5jr/IMAoGCCqGSM49BAMCMBkxFzAVBgNVBAMM
+DnVuaXRfdGVzdF9lY19hMB4XDTE1MDYwMTIxNDU1M1oXDTQyMTAxNzIxNDU1M1ow
+GTEXMBUGA1UEAwwOdW5pdF90ZXN0X2VjX2EwWTATBgcqhkjOPQIBBggqhkjOPQMB
+BwNCAAR8Q+7lg4KSOs2Be0XhFwlFCsiCCIh3iX2t6fE+V/MD+QBT1265hIyBKEH/
+oAsTpLy8FdGKLC0x+TwuCedui0SBo1AwTjAdBgNVHQ4EFgQUX4h7gPTgwQXorm0H
+7R12wN2yNrwwHwYDVR0jBBgwFoAUX4h7gPTgwQXorm0H7R12wN2yNrwwDAYDVR0T
+BAUwAwEB/zAKBggqhkjOPQQDAgNJADBGAiEA5kHO4aK20dwt81mCABAywD7Y6V1O
+vqoff9yIx3USW8oCIQDTzo8tbHuPc+i3vBsb5Uo1+4BE/pcOe/je6PGlRHG8rg==
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java
index 7f3737d..9637a6c 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java
@@ -76,6 +76,10 @@
             "CtsKeySetSigningCBadAUpgradeAB.apk";
     private static final String A_SIGNED_NO_B_B_UPGRADE =
             "CtsKeySetSigningANoDefUpgradeB.apk";
+    private static final String A_SIGNED_EC_A_UPGRADE =
+            "CtsKeySetSigningAUpgradeEcA.apk";
+    private static final String EC_A_SIGNED_A_UPGRADE =
+            "CtsKeySetSigningEcAUpgradeA.apk";
 
     /* package which defines the KEYSET_PERM_NAME signature permission */
     private static final String KEYSET_PERM_DEF_PKG =
@@ -486,4 +490,26 @@
         assertNotNull("Installation of apk with upgrade key referring to a bad public key succeeded!",
                 installResult);
     }
+
+    /*
+     * Check if an apk signed by RSA pub key can upgrade to apk signed by EC key.
+     */
+    public void testUpgradeKSRsaToEC() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, A_SIGNED_EC_A_UPGRADE,
+                EC_A_SIGNED_A_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from one signed by RSA key"
+                 + "to version signed by EC upgrade-key-set, Reason: %s", installResult),
+                 installResult);
+    }
+
+    /*
+     * Check if an apk signed by EC pub key can upgrade to apk signed by RSA key.
+     */
+    public void testUpgradeKSECToRSA() throws Exception {
+        String installResult = testPackageUpgrade(KEYSET_PKG, EC_A_SIGNED_A_UPGRADE,
+                A_SIGNED_EC_A_UPGRADE);
+        assertNull(String.format("failed to upgrade keyset app from one signed by EC key"
+                 + "to version signed by RSA upgrade-key-set, Reason: %s", installResult),
+                 installResult);
+    }
 }
diff --git a/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java b/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java
index fb8993c..14f215c 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentProvider/src/com/android/cts/documentprovider/MyDocumentsProvider.java
@@ -239,13 +239,16 @@
             new AsyncTask<Void, Void, Void>() {
                 @Override
                 protected Void doInBackground(Void... params) {
-                    try {
-                        final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
-                                pipe[0]);
-                        doc.contents = readFullyNoClose(is);
-                        is.close();
-                    } catch (IOException e) {
-                        Log.w(TAG, "Failed to stream", e);
+                    synchronized (doc) {
+                        try {
+                            final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
+                                    pipe[0]);
+                            doc.contents = readFullyNoClose(is);
+                            is.close();
+                            doc.notifyAll();
+                        } catch (IOException e) {
+                            Log.w(TAG, "Failed to stream", e);
+                        }
                     }
                     return null;
                 }
@@ -255,13 +258,20 @@
             new AsyncTask<Void, Void, Void>() {
                 @Override
                 protected Void doInBackground(Void... params) {
-                    try {
-                        final OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(
-                                pipe[1]);
-                        os.write(doc.contents);
-                        os.close();
-                    } catch (IOException e) {
-                        Log.w(TAG, "Failed to stream", e);
+                    synchronized (doc) {
+                        try {
+                            final OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(
+                                    pipe[1]);
+                            while (doc.contents == null) {
+                                doc.wait();
+                            }
+                            os.write(doc.contents);
+                            os.close();
+                        } catch (IOException e) {
+                            Log.w(TAG, "Failed to stream", e);
+                        } catch (InterruptedException e) {
+                            Log.w(TAG, "Interuppted", e);
+                        }
                     }
                     return null;
                 }
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
index 4d441de..79d053b 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
@@ -37,6 +37,18 @@
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
+#apks signed by cts-keyset-test-ec-a
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_PACKAGE_NAME := CtsKeySetSigningEcAUpgradeA
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
 #apks signed by cts-keyset-test-a and cts-keyset-test-b
 include $(CLEAR_VARS)
 
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk
new file mode 100644
index 0000000..3d0109a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk
@@ -0,0 +1,27 @@
+# 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)
+
+#apks signed by cts-keyset-test-a
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_PACKAGE_NAME := CtsKeySetSigningAUpgradeEcA
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uEcA/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/keysets/uEcA/AndroidManifest.xml
new file mode 100644
index 0000000..a84704a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/uEcA/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.keysets">
+    <application android:hasCode="false">
+    </application>
+    <key-sets>
+        <key-set android:name="EcA" >
+          <public-key android:name="keyEcA"
+                      android:value="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfEPu5YOCkjrNgXtF4RcJRQrIggiId4l9renxPlfzA/kAU9duuYSMgShB/6ALE6S8vBXRiiwtMfk8LgnnbotEgQ=="/>
+        </key-set>
+        <upgrade-key-set android:name="EcA"/>
+    </key-sets>
+</manifest>
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index b11248a..71bf6cf 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -313,12 +313,14 @@
 
         // create the notification to send
         final int notificationId = 1;
-        final Notification notification = new Notification();
-        notification.icon = android.R.drawable.stat_notify_call_mute;
-        notification.contentIntent = PendingIntent.getActivity(getActivity(), 0, new Intent(),
-                PendingIntent.FLAG_CANCEL_CURRENT);
-        notification.tickerText = message;
-        notification.setLatestEventInfo(getActivity(), "", "", notification.contentIntent);
+        final Notification notification = new Notification.Builder(getActivity())
+                .setSmallIcon(android.R.drawable.stat_notify_call_mute)
+                .setContentIntent(PendingIntent.getActivity(getActivity(), 0, new Intent(),
+                        PendingIntent.FLAG_CANCEL_CURRENT))
+                .setTicker(message)
+                .setContentTitle("")
+                .setContentText("")
+                .build();
 
         // create and populate the expected event
         final AccessibilityEvent expected = AccessibilityEvent.obtain();
diff --git a/tests/tests/app/AndroidManifest.xml b/tests/tests/app/AndroidManifest.xml
index 8e17396..d05648c 100644
--- a/tests/tests/app/AndroidManifest.xml
+++ b/tests/tests/app/AndroidManifest.xml
@@ -18,6 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.cts.app">
 
+    <uses-sdk android:minSdkVersion="11" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.BODY_SENSORS" />
     <application>
diff --git a/tests/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
index 23dac25..5781442 100644
--- a/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -100,9 +100,6 @@
     }
 
     private void sendNotification(final int id, final int icon) {
-        final Notification notification = new Notification(
-                icon, "No intent", System.currentTimeMillis());
-
         final Intent intent = new Intent(Intent.ACTION_MAIN, Threads.CONTENT_URI);
 
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
@@ -110,8 +107,13 @@
         intent.setAction(Intent.ACTION_MAIN);
 
         final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
-        notification.setLatestEventInfo(mContext, "notify#" + id, "This is #" + id
-                + "notification  ", pendingIntent);
+        final Notification notification = new Notification.Builder(mContext)
+                .setSmallIcon(icon)
+                .setWhen(System.currentTimeMillis())
+                .setContentTitle("notify#" + id)
+                .setContentText("This is #" + id + "notification  ")
+                .setContentIntent(pendingIntent)
+                .build();
         mNotificationManager.notify(id, notification);
 
         StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
diff --git a/tests/tests/app/src/android/app/cts/NotificationTest.java b/tests/tests/app/src/android/app/cts/NotificationTest.java
index c2f62c3..614d7f2 100644
--- a/tests/tests/app/src/android/app/cts/NotificationTest.java
+++ b/tests/tests/app/src/android/app/cts/NotificationTest.java
@@ -150,6 +150,22 @@
         assertNull(result.sound);
     }
 
+    public void testBuilder() {
+        final Intent intent = new Intent();
+        final PendingIntent contentIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+        mNotification = new Notification.Builder(mContext)
+                .setSmallIcon(1)
+                .setContentTitle(CONTENT_TITLE)
+                .setContentText(CONTENT_TEXT)
+                .setContentIntent(contentIntent)
+                .build();
+        assertEquals(CONTENT_TEXT, mNotification.extras.getString(Notification.EXTRA_TEXT));
+        assertEquals(CONTENT_TITLE, mNotification.extras.getString(Notification.EXTRA_TITLE));
+        assertEquals(1, mNotification.icon);
+        assertEquals(contentIntent, mNotification.contentIntent);
+        assertNotNull(mNotification.contentView);
+    }
+
     public void testSetLatestEventInfo() {
         mNotification = new Notification();
         mNotification.icon = 1;
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index 629e85e..8d96d91 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -1268,7 +1268,7 @@
 
         try {
             // start < context start
-            p.getOffsetForAdvance(string, 1, string.length(), 0, string.length(), false, 0.0f);
+            p.getOffsetForAdvance(string, 0, string.length(), 1, string.length(), false, 0.0f);
             fail("Should throw an IndexOutOfBoundsException.");
         } catch (IndexOutOfBoundsException e) {
         } catch (Exception e) {
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
index 452f0d0..0913152 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
@@ -16,6 +16,7 @@
 
 package android.graphics.drawable.cts;
 
+import android.view.Gravity;
 import com.android.cts.graphics.R;
 
 import org.xmlpull.v1.XmlPullParserException;
@@ -799,6 +800,611 @@
         assertEquals(1, constantState.getChangingConfigurations());
     }
 
+    @SuppressWarnings("deprecation")
+    public void testAddLayer() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        BitmapDrawable newDrawable = new BitmapDrawable();
+        int index = layerDrawable.addLayer(newDrawable);
+
+        final int numLayers = layerDrawable.getNumberOfLayers();
+        assertEquals(index, numLayers - 1);
+        assertEquals(newDrawable, layerDrawable.getDrawable(index));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetDrawable() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        final int numLayers = layerDrawable.getNumberOfLayers();
+        assertEquals(array[0], layerDrawable.getDrawable(0));
+        assertEquals(array[1], layerDrawable.getDrawable(1));
+        try {
+            assertEquals(null, layerDrawable.getDrawable(2));
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testFindIndexByLayerId() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setId(0, 10);
+        layerDrawable.setId(1, 20);
+
+        assertEquals(0, layerDrawable.findIndexByLayerId(10));
+        assertEquals(1, layerDrawable.findIndexByLayerId(20));
+        assertEquals(-1, layerDrawable.findIndexByLayerId(30));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetDrawable() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        BitmapDrawable newBitmapDrawable = new BitmapDrawable();
+        ColorDrawable newColorDrawable = new ColorDrawable(Color.GREEN);
+        layerDrawable.setDrawable(0, newColorDrawable);
+        layerDrawable.setDrawable(1, newBitmapDrawable);
+
+        final int numLayers = layerDrawable.getNumberOfLayers();
+        assertEquals(2, numLayers);
+        assertEquals(newColorDrawable, layerDrawable.getDrawable(0));
+        assertEquals(newBitmapDrawable, layerDrawable.getDrawable(1));
+        try {
+            assertEquals(null, layerDrawable.getDrawable(2));
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLeftPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(10, layerDrawable.getLeftPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetTopPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(11, layerDrawable.getTopPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetRightPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(20, layerDrawable.getRightPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetBottomPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(21, layerDrawable.getBottomPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetStartPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(-1, layerDrawable.getStartPadding());
+        layerDrawable.setPaddingRelative(10, 11, 20, 21);
+        assertEquals(10, layerDrawable.getStartPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetEndPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(-1, layerDrawable.getEndPadding());
+        layerDrawable.setPaddingRelative(10, 11, 20, 21);
+        assertEquals(20, layerDrawable.getEndPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(10, layerDrawable.getLeftPadding());
+        assertEquals(11, layerDrawable.getTopPadding());
+        assertEquals(20, layerDrawable.getRightPadding());
+        assertEquals(21, layerDrawable.getBottomPadding());
+        assertEquals(-1, layerDrawable.getStartPadding());
+        assertEquals(-1, layerDrawable.getEndPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetPaddingRelative() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPaddingRelative(10, 11, 20, 21);
+
+        assertEquals(10, layerDrawable.getStartPadding());
+        assertEquals(11, layerDrawable.getTopPadding());
+        assertEquals(20, layerDrawable.getEndPadding());
+        assertEquals(21, layerDrawable.getBottomPadding());
+        assertEquals(-1, layerDrawable.getLeftPadding());
+        assertEquals(-1, layerDrawable.getRightPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerGravity() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerGravity(0, Gravity.CENTER);
+        layerDrawable.setLayerGravity(1, Gravity.NO_GRAVITY);
+
+        try {
+            layerDrawable.setLayerGravity(2, Gravity.TOP);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        assertEquals(Gravity.CENTER, layerDrawable.getLayerGravity(0));
+        assertEquals(Gravity.NO_GRAVITY, layerDrawable.getLayerGravity(1));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerGravity() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerGravity(0, Gravity.CENTER);
+        layerDrawable.setLayerGravity(1, Gravity.NO_GRAVITY);
+
+        assertEquals(Gravity.CENTER, layerDrawable.getLayerGravity(0));
+        assertEquals(Gravity.NO_GRAVITY, layerDrawable.getLayerGravity(1));
+        try {
+            layerDrawable.getLayerGravity(2);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerWidth() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerWidth(0, 100);
+        layerDrawable.setLayerWidth(1, 200);
+
+        try {
+            layerDrawable.setLayerWidth(2, 300);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        assertEquals(100, layerDrawable.getLayerWidth(0));
+        assertEquals(200, layerDrawable.getLayerWidth(1));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerWidth() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerWidth(0, 100);
+        layerDrawable.setLayerWidth(1, 200);
+
+        assertEquals(100, layerDrawable.getLayerWidth(0));
+        assertEquals(200, layerDrawable.getLayerWidth(1));
+        try {
+            layerDrawable.getLayerWidth(2);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerHeight() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerHeight(0, 100);
+        layerDrawable.setLayerHeight(1, 200);
+
+        try {
+            layerDrawable.setLayerHeight(2, 300);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        assertEquals(100, layerDrawable.getLayerHeight(0));
+        assertEquals(200, layerDrawable.getLayerHeight(1));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerHeight() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerHeight(0, 100);
+        layerDrawable.setLayerHeight(1, 200);
+
+        assertEquals(100, layerDrawable.getLayerHeight(0));
+        assertEquals(200, layerDrawable.getLayerHeight(1));
+        try {
+            layerDrawable.getLayerHeight(2);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerSize() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerSize(0, 100, 200);
+        layerDrawable.setLayerSize(1, 300, 400);
+
+        try {
+            layerDrawable.setLayerSize(2, 500, 600);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        assertEquals(100, layerDrawable.getLayerWidth(0));
+        assertEquals(200, layerDrawable.getLayerHeight(0));
+        assertEquals(300, layerDrawable.getLayerWidth(1));
+        assertEquals(400, layerDrawable.getLayerHeight(1));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetRelative() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int start = 10;
+        int top = 20;
+        int end = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+        assertEquals(10, layerDrawable.getLayerInsetStart(0));
+        assertEquals(20, layerDrawable.getLayerInsetTop(0));
+        assertEquals(30, layerDrawable.getLayerInsetEnd(0));
+        assertEquals(40, layerDrawable.getLayerInsetBottom(0));
+        assertEquals(0, layerDrawable.getLayerInsetLeft(0));
+        assertEquals(0, layerDrawable.getLayerInsetRight(0));
+
+        // set bigger inset for layer 1
+        start += 10;
+        top += 10;
+        end += 10;
+        bottom += 10;
+        layerDrawable.setLayerInsetRelative(1, start, top, end, bottom);
+        assertEquals(layerDrawable.getDrawable(1).getIntrinsicWidth() + start + end,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(layerDrawable.getDrawable(1).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+
+
+        try {
+            layerDrawable.setLayerInsetRelative(-1, start, top, end, bottom);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetLeft() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
+                layerDrawable.getIntrinsicWidth());
+        left += 5;
+        layerDrawable.setLayerInsetLeft(0, left);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(left, layerDrawable.getLayerInsetLeft(0));
+
+        try {
+            layerDrawable.setLayerInsetLeft(1, left);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetLeft() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(left, layerDrawable.getLayerInsetLeft(0));
+        left += 5;
+        layerDrawable.setLayerInsetLeft(0, left);
+        assertEquals(left, layerDrawable.getLayerInsetLeft(0));
+
+        try {
+            layerDrawable.getLayerInsetLeft(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetTop() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+        top += 5;
+        layerDrawable.setLayerInsetTop(0, top);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+        assertEquals(top, layerDrawable.getLayerInsetTop(0));
+
+        try {
+            layerDrawable.setLayerInsetTop(1, top);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetTop() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(top, layerDrawable.getLayerInsetTop(0));
+        top += 5;
+        layerDrawable.setLayerInsetTop(0, top);
+        assertEquals(top, layerDrawable.getLayerInsetTop(0));
+
+        try {
+            layerDrawable.getLayerInsetTop(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetRight() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
+                layerDrawable.getIntrinsicWidth());
+        right += 5;
+        layerDrawable.setLayerInsetRight(0, right);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(right, layerDrawable.getLayerInsetRight(0));
+
+        try {
+            layerDrawable.setLayerInsetRight(1, right);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetRight() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(right, layerDrawable.getLayerInsetRight(0));
+        right += 5;
+        layerDrawable.setLayerInsetRight(0, right);
+        assertEquals(right, layerDrawable.getLayerInsetRight(0));
+
+        try {
+            layerDrawable.getLayerInsetRight(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetBottom() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+        bottom += 5;
+        layerDrawable.setLayerInsetBottom(0, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
+
+        try {
+            layerDrawable.setLayerInsetBottom(1, bottom);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetBottom() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
+        bottom += 5;
+        layerDrawable.setLayerInsetBottom(0, bottom);
+        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
+
+        try {
+            layerDrawable.getLayerInsetBottom(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetStart() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int start = 10;
+        int top = 20;
+        int end = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
+                layerDrawable.getIntrinsicWidth());
+        start += 5;
+        layerDrawable.setLayerInsetStart(0, start);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(start, layerDrawable.getLayerInsetStart(0));
+
+        try {
+            layerDrawable.setLayerInset(1, start, top, end, bottom);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetStart() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int start = 10;
+        int top = 20;
+        int end = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
+        assertEquals(start, layerDrawable.getLayerInsetStart(0));
+        start += 5;
+        layerDrawable.setLayerInsetStart(0, start);
+        assertEquals(start, layerDrawable.getLayerInsetStart(0));
+
+        try {
+            layerDrawable.getLayerInsetStart(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetEnd() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int start = 10;
+        int top = 20;
+        int end = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
+        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
+                layerDrawable.getIntrinsicWidth());
+        end += 5;
+        layerDrawable.setLayerInsetEnd(0, end);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
+
+        try {
+            layerDrawable.setLayerInsetEnd(1, end);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetEnd() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int start = 10;
+        int top = 20;
+        int end = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
+        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
+        end += 5;
+        layerDrawable.setLayerInsetEnd(0, end);
+        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
+
+        try {
+            layerDrawable.getLayerInsetEnd(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+
+
     private static class MockDrawable extends Drawable {
         private boolean mCalledSetDither = false;
         private boolean mCalledSetAlpha = false;
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index 9851ad8..7368376 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -763,12 +763,6 @@
 
             CamcorderProfile profile = CamcorderProfile.get(cameraId, profileId);
             Size videoSz = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
-            if (!mSupportedVideoSizes.contains(videoSz)) {
-                mCollector.addMessage("Video size " + videoSz.toString() + " for profile ID " +
-                        profileId + " must be one of the camera device supported video size!");
-                continue;
-            }
-
             Size maxPreviewSize = mOrderedPreviewSizes.get(0);
 
             if (mStaticInfo.isHardwareLevelLegacy() &&
@@ -778,6 +772,12 @@
                 continue;
             }
 
+            if (!mSupportedVideoSizes.contains(videoSz)) {
+                mCollector.addMessage("Video size " + videoSz.toString() + " for profile ID " +
+                        profileId + " must be one of the camera device supported video size!");
+                continue;
+            }
+
             // For LEGACY, find closest supported smaller or equal JPEG size to the current video
             // size; if no size is smaller than the video, pick the smallest JPEG size.  The assert
             // for video size above guarantees that for LIMITED or FULL, we select videoSz here.
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyGenParameterSpecTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyGenParameterSpecTest.java
new file mode 100644
index 0000000..a3e5d96
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyGenParameterSpecTest.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2015 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.keystore.cts;
+
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+import android.test.MoreAsserts;
+
+import junit.framework.TestCase;
+
+import java.math.BigInteger;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.util.Arrays;
+import java.util.Date;
+
+import javax.security.auth.x500.X500Principal;
+
+public class KeyGenParameterSpecTest extends TestCase {
+
+    private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
+    private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
+    private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
+    private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
+
+    public void testDefaults() {
+        // Set only the mandatory parameters and assert values returned by getters.
+
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                "arbitrary", KeyProperties.PURPOSE_ENCRYPT)
+                .build();
+
+        assertEquals("arbitrary", spec.getKeystoreAlias());
+        assertEquals(KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
+        assertNull(null, spec.getAlgorithmParameterSpec());
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getBlockModes()));
+        assertEquals(DEFAULT_CERT_NOT_BEFORE, spec.getCertificateNotBefore());
+        assertEquals(DEFAULT_CERT_NOT_AFTER, spec.getCertificateNotAfter());
+        assertEquals(DEFAULT_CERT_SERIAL_NUMBER, spec.getCertificateSerialNumber());
+        assertEquals(DEFAULT_CERT_SUBJECT, spec.getCertificateSubject());
+        assertFalse(spec.isDigestsSpecified());
+        try {
+            spec.getDigests();
+            fail();
+        } catch (IllegalStateException expected) {}
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getEncryptionPaddings()));
+        assertEquals(-1, spec.getKeySize());
+        assertNull(spec.getKeyValidityStart());
+        assertNull(spec.getKeyValidityForOriginationEnd());
+        assertNull(spec.getKeyValidityForConsumptionEnd());
+        assertTrue(spec.isRandomizedEncryptionRequired());
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getSignaturePaddings()));
+        assertFalse(spec.isUserAuthenticationRequired());
+        assertEquals(-1, spec.getUserAuthenticationValidityDurationSeconds());
+    }
+
+    public void testSettersReflectedInGetters() {
+        // Set all parameters to non-default values and then assert that getters reflect that.
+
+        Date certNotBeforeDate = new Date(System.currentTimeMillis());
+        Date certNotAfterDate = new Date(System.currentTimeMillis() + 12345678);
+        Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+        AlgorithmParameterSpec algSpecificParams = new ECGenParameterSpec("secp256r1");
+
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                "arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setAlgorithmParameterSpec(algSpecificParams)
+                .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
+                .setCertificateNotBefore(certNotBeforeDate)
+                .setCertificateNotAfter(certNotAfterDate)
+                .setCertificateSerialNumber(new BigInteger("13946146"))
+                .setCertificateSubject(new X500Principal("CN=test"))
+                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+                        KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                .setKeySize(1234)
+                .setKeyValidityStart(keyValidityStartDate)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setRandomizedEncryptionRequired(false)
+                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                .setUserAuthenticationRequired(true)
+                .setUserAuthenticationValidityDurationSeconds(12345)
+                .build();
+
+        assertEquals("arbitrary", spec.getKeystoreAlias());
+        assertEquals(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
+        assertSame(algSpecificParams, spec.getAlgorithmParameterSpec());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getBlockModes()),
+                KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC);
+        assertEquals(certNotBeforeDate, spec.getCertificateNotBefore());
+        assertEquals(certNotAfterDate, spec.getCertificateNotAfter());
+        assertEquals(new BigInteger("13946146"), spec.getCertificateSerialNumber());
+        assertEquals(new X500Principal("CN=test"), spec.getCertificateSubject());
+        assertTrue(spec.isDigestsSpecified());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getDigests()),
+                KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384);
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getEncryptionPaddings()),
+                KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7);
+        assertEquals(1234, spec.getKeySize());
+        assertEquals(keyValidityStartDate, spec.getKeyValidityStart());
+        assertEquals(keyValidityEndDateForOrigination, spec.getKeyValidityForOriginationEnd());
+        assertEquals(keyValidityEndDateForConsumption, spec.getKeyValidityForConsumptionEnd());
+        assertFalse(spec.isRandomizedEncryptionRequired());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getSignaturePaddings()),
+                KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
+        assertTrue(spec.isUserAuthenticationRequired());
+        assertEquals(12345, spec.getUserAuthenticationValidityDurationSeconds());
+    }
+
+    public void testNullAliasNotPermitted() {
+        try {
+            new KeyGenParameterSpec.Builder(null, KeyProperties.PURPOSE_ENCRYPT);
+            fail();
+        } catch (NullPointerException expected) {}
+    }
+
+    public void testEmptyAliasNotPermitted() {
+        try {
+            new KeyGenParameterSpec.Builder("", KeyProperties.PURPOSE_ENCRYPT);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+    }
+
+    public void testSetKeyValidityEndDateAppliesToBothEndDates() {
+        Date date = new Date(System.currentTimeMillis() + 555555);
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                "ignore", KeyProperties.PURPOSE_VERIFY)
+                .setKeyValidityEnd(date)
+                .build();
+        assertEquals(date, spec.getKeyValidityForOriginationEnd());
+        assertEquals(date, spec.getKeyValidityForConsumptionEnd());
+    }
+
+    public void testSetUserAuthenticationValidityDurationSecondsValidityCheck() {
+        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder("alias", 0);
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-2);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-100);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(Integer.MIN_VALUE);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        builder.setUserAuthenticationValidityDurationSeconds(-1);
+        builder.setUserAuthenticationValidityDurationSeconds(0);
+        builder.setUserAuthenticationValidityDurationSeconds(1);
+        builder.setUserAuthenticationValidityDurationSeconds(Integer.MAX_VALUE);
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-2);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+    }
+
+    public void testImmutabilityViaSetterParams() {
+        // Assert that all mutable parameters provided to setters are copied to ensure that values
+        // returned by getters never change.
+        String[] blockModes =
+                new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC};
+        String[] originalBlockModes = blockModes.clone();
+        Date certNotBeforeDate = new Date(System.currentTimeMillis());
+        Date originalCertNotBeforeDate = new Date(certNotBeforeDate.getTime());
+        Date certNotAfterDate = new Date(System.currentTimeMillis() + 12345678);
+        Date originalCertNotAfterDate = new Date(certNotAfterDate.getTime());
+        Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+        Date originalKeyValidityStartDate = new Date(keyValidityStartDate.getTime());
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+        Date originalKeyValidityEndDateForOrigination =
+                new Date(keyValidityEndDateForOrigination.getTime());
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+        Date originalKeyValidityEndDateForConsumption =
+                new Date(keyValidityEndDateForConsumption.getTime());
+        String[] digests = new String[] {KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512};
+        String[] originalDigests = digests.clone();
+        String[] encryptionPaddings = new String[] {
+                KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7};
+        String[] originalEncryptionPaddings = encryptionPaddings.clone();
+        String[] signaturePaddings = new String[] {
+                KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1};
+        String[] originalSignaturePaddings = signaturePaddings.clone();
+
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                "arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setBlockModes(blockModes)
+                .setCertificateNotBefore(certNotBeforeDate)
+                .setCertificateNotAfter(certNotAfterDate)
+                .setDigests(digests)
+                .setEncryptionPaddings(encryptionPaddings)
+                .setKeyValidityStart(keyValidityStartDate)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setSignaturePaddings(signaturePaddings)
+                .build();
+
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+        blockModes[0] = null;
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+        assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
+        certNotBeforeDate.setTime(1234567890L);
+        assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
+
+        assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
+        certNotAfterDate.setTime(1234567890L);
+        assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
+
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+        digests[1] = null;
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+        encryptionPaddings[0] = null;
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+        keyValidityStartDate.setTime(1234567890L);
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+        keyValidityEndDateForOrigination.setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+        keyValidityEndDateForConsumption.setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+        signaturePaddings[1] = null;
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+    }
+
+    public void testImmutabilityViaGetterReturnValues() {
+        // Assert that none of the mutable return values from getters modify the state of the spec.
+
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                "arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
+                .setCertificateNotBefore(new Date(System.currentTimeMillis()))
+                .setCertificateNotAfter(new Date(System.currentTimeMillis() + 12345678))
+                .setDigests(KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512)
+                .setEncryptionPaddings(
+                        KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+                        KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                .setKeyValidityStart(new Date(System.currentTimeMillis() - 2222222))
+                .setKeyValidityForOriginationEnd(new Date(System.currentTimeMillis() + 11111111))
+                .setKeyValidityForConsumptionEnd(new Date(System.currentTimeMillis() + 33333333))
+                .setSignaturePaddings(
+                        KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                .build();
+
+        String[] originalBlockModes = spec.getBlockModes().clone();
+        spec.getBlockModes()[0] = null;
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+        Date originalCertNotBeforeDate = (Date) spec.getCertificateNotBefore().clone();
+        spec.getCertificateNotBefore().setTime(1234567890L);
+        assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
+
+        Date originalCertNotAfterDate = (Date) spec.getCertificateNotAfter().clone();
+        spec.getCertificateNotAfter().setTime(1234567890L);
+        assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
+
+        String[] originalDigests = spec.getDigests().clone();
+        spec.getDigests()[0] = null;
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+        String[] originalEncryptionPaddings = spec.getEncryptionPaddings().clone();
+        spec.getEncryptionPaddings()[0] = null;
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+
+        Date originalKeyValidityStartDate = (Date) spec.getKeyValidityStart().clone();
+        spec.getKeyValidityStart().setTime(1234567890L);
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+        Date originalKeyValidityEndDateForOrigination =
+                (Date) spec.getKeyValidityForOriginationEnd().clone();
+        spec.getKeyValidityForOriginationEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+
+        Date originalKeyValidityEndDateForConsumption =
+                (Date) spec.getKeyValidityForConsumptionEnd().clone();
+        spec.getKeyValidityForConsumptionEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+
+        String[] originalSignaturePaddings = spec.getSignaturePaddings().clone();
+        spec.getSignaturePaddings()[0] = null;
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyInfoTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyInfoTest.java
new file mode 100644
index 0000000..2b1d6fc
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyInfoTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2015 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.keystore.cts;
+
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyInfo;
+import android.security.keystore.KeyProperties;
+
+import junit.framework.TestCase;
+
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.util.Arrays;
+import java.util.Date;
+
+public class KeyInfoTest extends TestCase {
+
+    public void testImmutabilityViaGetterReturnValues() throws Exception {
+        // Assert that none of the mutable return values from getters modify the state of the
+        // instance.
+
+        Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+
+        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
+        keyPairGenerator.initialize(new KeyGenParameterSpec.Builder(
+                KeyInfoTest.class.getSimpleName(),
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setKeySize(1024) // use smaller key size to speed the test up
+                .setKeyValidityStart(keyValidityStartDate)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
+                        KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
+                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PSS)
+                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+                .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
+                .build());
+        KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+        PrivateKey key = keyPair.getPrivate();
+        KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
+        KeyInfo info = keyFactory.getKeySpec(key, KeyInfo.class);
+
+        Date originalKeyValidityStartDate = (Date) info.getKeyValidityStart().clone();
+        info.getKeyValidityStart().setTime(1234567890L);
+        assertEquals(originalKeyValidityStartDate, info.getKeyValidityStart());
+
+        Date originalKeyValidityEndDateForOrigination =
+                (Date) info.getKeyValidityForOriginationEnd().clone();
+        info.getKeyValidityForOriginationEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                info.getKeyValidityForOriginationEnd());
+
+        Date originalKeyValidityEndDateForConsumption =
+                (Date) info.getKeyValidityForConsumptionEnd().clone();
+        info.getKeyValidityForConsumptionEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                info.getKeyValidityForConsumptionEnd());
+
+        String[] originalEncryptionPaddings = info.getEncryptionPaddings().clone();
+        info.getEncryptionPaddings()[0] = null;
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(info.getEncryptionPaddings()));
+
+        String[] originalSignaturePaddings = info.getSignaturePaddings().clone();
+        info.getSignaturePaddings()[0] = null;
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(info.getSignaturePaddings()));
+
+        String[] originalDigests = info.getDigests().clone();
+        info.getDigests()[0] = null;
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(info.getDigests()));
+
+        String[] originalBlockModes = info.getBlockModes().clone();
+        info.getBlockModes()[0] = null;
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(info.getBlockModes()));
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyProtectionTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyProtectionTest.java
new file mode 100644
index 0000000..ee24eed
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyProtectionTest.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2015 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.keystore.cts;
+
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.test.MoreAsserts;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Date;
+
+public class KeyProtectionTest extends TestCase {
+    public void testDefaults() {
+        // Set only the mandatory parameters and assert values returned by getters.
+
+        KeyProtection spec = new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
+                .build();
+
+        assertEquals(KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getBlockModes()));
+        assertFalse(spec.isDigestsSpecified());
+        try {
+            spec.getDigests();
+            fail();
+        } catch (IllegalStateException expected) {}
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getEncryptionPaddings()));
+        assertNull(spec.getKeyValidityStart());
+        assertNull(spec.getKeyValidityForOriginationEnd());
+        assertNull(spec.getKeyValidityForConsumptionEnd());
+        assertTrue(spec.isRandomizedEncryptionRequired());
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getSignaturePaddings()));
+        assertFalse(spec.isUserAuthenticationRequired());
+        assertEquals(-1, spec.getUserAuthenticationValidityDurationSeconds());
+    }
+
+    public void testSettersReflectedInGetters() {
+        // Set all parameters to non-default values and then assert that getters reflect that.
+
+        Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+
+        KeyProtection spec = new KeyProtection.Builder(
+                KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_VERIFY)
+                .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CTR)
+                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
+                        KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                .setKeyValidityStart(keyValidityStartDate)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setRandomizedEncryptionRequired(false)
+                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PSS)
+                .setUserAuthenticationRequired(true)
+                .setUserAuthenticationValidityDurationSeconds(123456)
+                .build();
+
+        assertEquals(
+                KeyProperties.PURPOSE_DECRYPT| KeyProperties.PURPOSE_VERIFY, spec.getPurposes());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getBlockModes()),
+                KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CTR);
+        assertTrue(spec.isDigestsSpecified());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getDigests()),
+                KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512);
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getEncryptionPaddings()),
+                KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1, KeyProperties.ENCRYPTION_PADDING_PKCS7);
+        assertEquals(keyValidityStartDate, spec.getKeyValidityStart());
+        assertEquals(keyValidityEndDateForOrigination, spec.getKeyValidityForOriginationEnd());
+        assertEquals(keyValidityEndDateForConsumption, spec.getKeyValidityForConsumptionEnd());
+        assertFalse(spec.isRandomizedEncryptionRequired());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getSignaturePaddings()),
+                KeyProperties.SIGNATURE_PADDING_RSA_PKCS1, KeyProperties.SIGNATURE_PADDING_RSA_PSS);
+        assertTrue(spec.isUserAuthenticationRequired());
+        assertEquals(123456, spec.getUserAuthenticationValidityDurationSeconds());
+    }
+
+    public void testSetKeyValidityEndDateAppliesToBothEndDates() {
+        Date date = new Date(System.currentTimeMillis() + 555555);
+        KeyProtection spec = new KeyProtection.Builder(
+                KeyProperties.PURPOSE_SIGN)
+                .setKeyValidityEnd(date)
+                .build();
+        assertEquals(date, spec.getKeyValidityForOriginationEnd());
+        assertEquals(date, spec.getKeyValidityForConsumptionEnd());
+    }
+
+    public void testSetUserAuthenticationValidityDurationSecondsValidityCheck() {
+        KeyProtection.Builder builder = new KeyProtection.Builder(0);
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-2);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-100);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(Integer.MIN_VALUE);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        builder.setUserAuthenticationValidityDurationSeconds(-1);
+        builder.setUserAuthenticationValidityDurationSeconds(0);
+        builder.setUserAuthenticationValidityDurationSeconds(1);
+        builder.setUserAuthenticationValidityDurationSeconds(Integer.MAX_VALUE);
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-2);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+    }
+
+    public void testImmutabilityViaSetterParams() {
+        // Assert that all mutable parameters provided to setters are copied to ensure that values
+        // returned by getters never change.
+        String[] blockModes =
+                new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC};
+        String[] originalBlockModes = blockModes.clone();
+        Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+        Date originalKeyValidityStartDate = new Date(keyValidityStartDate.getTime());
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+        Date originalKeyValidityEndDateForOrigination =
+                new Date(keyValidityEndDateForOrigination.getTime());
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+        Date originalKeyValidityEndDateForConsumption =
+                new Date(keyValidityEndDateForConsumption.getTime());
+        String[] digests = new String[] {KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512};
+        String[] originalDigests = digests.clone();
+        String[] encryptionPaddings = new String[] {
+                KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7};
+        String[] originalEncryptionPaddings = encryptionPaddings.clone();
+        String[] signaturePaddings = new String[] {
+                KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1};
+        String[] originalSignaturePaddings = signaturePaddings.clone();
+
+        KeyProtection spec = new KeyProtection.Builder(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setBlockModes(blockModes)
+                .setDigests(digests)
+                .setEncryptionPaddings(encryptionPaddings)
+                .setKeyValidityStart(keyValidityStartDate)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setSignaturePaddings(signaturePaddings)
+                .build();
+
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+        blockModes[0] = null;
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+        digests[1] = null;
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+        encryptionPaddings[0] = null;
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+        keyValidityStartDate.setTime(1234567890L);
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+        keyValidityEndDateForOrigination.setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+        keyValidityEndDateForConsumption.setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+        signaturePaddings[1] = null;
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+    }
+
+    public void testImmutabilityViaGetterReturnValues() {
+        // Assert that none of the mutable return values from getters modify the state of the spec.
+
+        KeyProtection spec = new KeyProtection.Builder(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
+                .setDigests(KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512)
+                .setEncryptionPaddings(
+                        KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+                        KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                .setKeyValidityStart(new Date(System.currentTimeMillis() - 2222222))
+                .setKeyValidityForOriginationEnd(new Date(System.currentTimeMillis() + 11111111))
+                .setKeyValidityForConsumptionEnd(new Date(System.currentTimeMillis() + 33333333))
+                .setSignaturePaddings(
+                        KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                .build();
+
+        String[] originalBlockModes = spec.getBlockModes().clone();
+        spec.getBlockModes()[0] = null;
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+        String[] originalDigests = spec.getDigests().clone();
+        spec.getDigests()[0] = null;
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+        String[] originalEncryptionPaddings = spec.getEncryptionPaddings().clone();
+        spec.getEncryptionPaddings()[0] = null;
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+
+        Date originalKeyValidityStartDate = (Date) spec.getKeyValidityStart().clone();
+        spec.getKeyValidityStart().setTime(1234567890L);
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+        Date originalKeyValidityEndDateForOrigination =
+                (Date) spec.getKeyValidityForOriginationEnd().clone();
+        spec.getKeyValidityForOriginationEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+
+        Date originalKeyValidityEndDateForConsumption =
+                (Date) spec.getKeyValidityForConsumptionEnd().clone();
+        spec.getKeyValidityForConsumptionEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+
+        String[] originalSignaturePaddings = spec.getSignaturePaddings().clone();
+        spec.getSignaturePaddings()[0] = null;
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+    }
+}
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index 7106385..6bef886 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -28,7 +28,6 @@
 		android_security_cts_LinuxRngTest.cpp \
 		android_security_cts_LoadEffectLibraryTest.cpp \
 		android_security_cts_NativeCodeTest.cpp \
-		android_security_cts_SeccompDeathTestService.cpp \
 		android_security_cts_SELinuxTest.cpp \
 		android_security_cts_MMapExecutableTest.cpp \
 		android_security_cts_AudioPolicyBinderTest.cpp
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index 424dbaf..1051a82 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -22,7 +22,6 @@
 extern int register_android_security_cts_LinuxRngTest(JNIEnv*);
 extern int register_android_security_cts_NativeCodeTest(JNIEnv*);
 extern int register_android_security_cts_LoadEffectLibraryTest(JNIEnv*);
-extern int register_android_security_cts_SeccompDeathTestService(JNIEnv*);
 extern int register_android_security_cts_SELinuxTest(JNIEnv*);
 extern int register_android_security_cts_MMapExecutableTest(JNIEnv* env);
 extern int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env);
@@ -50,10 +49,6 @@
         return JNI_ERR;
     }
 
-    if (register_android_security_cts_SeccompDeathTestService(env)) {
-        return JNI_ERR;
-    }
-
     if (register_android_security_cts_SELinuxTest(env)) {
         return JNI_ERR;
     }
diff --git a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
index 00765c6..350309b 100644
--- a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
@@ -34,6 +34,7 @@
 #include <errno.h>
 #include <inttypes.h>
 #include <linux/sysctl.h>
+#include <arpa/inet.h>
 
 /*
  * Returns true iff this device is vulnerable to CVE-2013-2094.
@@ -227,6 +228,28 @@
     return !vulnerable;
 }
 
+static jboolean android_security_cts_NativeCodeTest_doPingPongRootTest(JNIEnv*, jobject)
+{
+    int icmp_sock;
+    struct sockaddr sock_addr;
+
+    memset(&sock_addr, 0, sizeof(sock_addr));
+    icmp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
+    sock_addr.sa_family = AF_INET;
+
+    /* first connect */
+    connect(icmp_sock, &sock_addr, sizeof(sock_addr));
+
+    /* disconnect */
+    sock_addr.sa_family = AF_UNSPEC;
+    connect(icmp_sock, &sock_addr, sizeof(sock_addr));
+
+    /* second disconnect -> crash */
+    sock_addr.sa_family = AF_UNSPEC;
+    connect(icmp_sock, &sock_addr, sizeof(sock_addr));
+
+    return true;
+}
 
 static JNINativeMethod gMethods[] = {
     {  "doPerfEventTest", "()Z",
@@ -241,6 +264,8 @@
             (void *) android_security_cts_NativeCodeTest_doFutexTest },
     {  "doNvmapIocFromIdTest", "()Z",
             (void *) android_security_cts_NativeCodeTest_doNvmapIocFromIdTest },
+    {  "doPingPongRootTest", "()Z",
+            (void *) android_security_cts_NativeCodeTest_doPingPongRootTest },
 };
 
 int register_android_security_cts_NativeCodeTest(JNIEnv* env)
@@ -249,3 +274,4 @@
     return env->RegisterNatives(clazz, gMethods,
             sizeof(gMethods) / sizeof(JNINativeMethod));
 }
+
diff --git a/tests/tests/security/jni/android_security_cts_SeccompDeathTestService.cpp b/tests/tests/security/jni/android_security_cts_SeccompDeathTestService.cpp
deleted file mode 100644
index eb32521..0000000
--- a/tests/tests/security/jni/android_security_cts_SeccompDeathTestService.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <jni.h>
-#include <signal.h>
-#include <unistd.h>
-
-void android_security_cts_SeccompDeathTestService_testSigSysSelf(JNIEnv* env, jobject thiz)
-{
-    kill(getpid(), SIGSYS);
-}
-
-static JNINativeMethod methods[] = {
-    { "testSigSysSelf", "()V",
-        (void *)android_security_cts_SeccompDeathTestService_testSigSysSelf }
-};
-
-int register_android_security_cts_SeccompDeathTestService(JNIEnv* env) {
-    jclass clazz = env->FindClass("android/security/cts/SeccompDeathTestService");
-    return env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/src/android/security/cts/NativeCodeTest.java b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
index a2f8c09..ab41b4f 100644
--- a/tests/tests/security/src/android/security/cts/NativeCodeTest.java
+++ b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
@@ -58,6 +58,12 @@
                    doNvmapIocFromIdTest());
     }
 
+    public void testPingPongRoot() throws Exception {
+        assertTrue("Device is vulnerable to CVE-2015-3636, a vulnerability in the ping "
+                   + "socket implementation. Please apply the security patch at "
+                   + "https://github.com/torvalds/linux/commit/a134f083e79f",
+                   doPingPongRootTest());
+    }
     /**
      * Returns true iff this device is vulnerable to CVE-2013-2094.
      * A patch for CVE-2013-2094 can be found at
@@ -120,4 +126,18 @@
      * false if the device is vulnerable.
      */
     private static native boolean doCVE20141710Test();
+
+    /**
+     * CVE-2015-3636
+     *
+     * Returns true if the patch is applied, crashes the system otherwise.
+     *
+     * Detects if the following patch is present.
+     * https://github.com/torvalds/linux/commit/a134f083e79f
+     *
+     * Credit: Wen Xu and wushi of KeenTeam.
+     * http://seclists.org/oss-sec/2015/q2/333
+     */
+    private static native boolean doPingPongRootTest();
+
 }
diff --git a/tests/tests/security/src/android/security/cts/SeccompBpfTest.java b/tests/tests/security/src/android/security/cts/SeccompBpfTest.java
deleted file mode 100644
index b7d8f2e..0000000
--- a/tests/tests/security/src/android/security/cts/SeccompBpfTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.cts;
-
-import android.test.AndroidTestCase;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * Test for seccomp-bpf sandboxing technology. This makes use of the
- * SeccompDeathTestService to run sandboxing death tests out-of-process.
- */
-public class SeccompBpfTest extends AndroidTestCase implements ServiceConnection,
-       IBinder.DeathRecipient {
-    static final String TAG = "SeccompBpfTest";
-
-    /**
-     * Message sent from the SeccompDeathTestService before it runs a test.
-     */
-    static final int MSG_TEST_STARTED = 1;
-    /**
-     * Message sent from the SeccompDeathTestService after a test exits cleanly.
-     */
-    static final int MSG_TEST_ENDED_CLEAN = 2;
-
-    /**
-     * Dedicated thread used to receive messages from the SeccompDeathTestService.
-     */
-    final private HandlerThread mHandlerThread = new HandlerThread("SeccompBpfTest handler");
-    /**
-     * Messenger that runs on mHandlerThread.
-     */
-    private Messenger mMessenger;
-
-    /**
-     * Condition that blocks the test/instrumentation thread that runs the
-     * test cases, while the SeccompDeathTestService runs the test out-of-process.
-     */
-    final private ConditionVariable mCondition = new ConditionVariable();
-
-    /**
-     * The SeccompDeathTestService number to run.
-     */
-    private int mTestNumber = -1;
-
-    /**
-     * If the test has started.
-     */
-    private boolean mTestStarted = false;
-    /**
-     * If the test ended (either cleanly or with death).
-     */
-    private boolean mTestEnded = false;
-    /**
-     * If the test ended cleanly or died.
-     */
-    private boolean mTestDied = false;
-
-    public void testDeathTest() {
-        runDeathTest(SeccompDeathTestService.TEST_DEATH_TEST);
-        assertTrue(mTestDied);
-    }
-
-    public void testCleanTest() {
-        runDeathTest(SeccompDeathTestService.TEST_CLEAN_TEST);
-        assertFalse(mTestDied);
-    }
-
-    public void testSigSysSelf() {
-        runDeathTest(SeccompDeathTestService.TEST_SIGSYS_SELF);
-        assertTrue(mTestDied);
-    }
-
-    /**
-     * Runs a death test by its test number, which needs to match a value in
-     * SeccompDeathTestService.
-     *
-     * This blocks until the completion of the test, after which the test body
-     * can use mTestEnded/mTestDied to see if the test died.
-     */
-    public void runDeathTest(final int testNumber) {
-        mTestStarted = false;
-        mTestEnded = false;
-        mTestDied = false;
-
-        mTestNumber = testNumber;
-
-        Log.d(TAG, "Starting runDeathTest");
-        launchDeathTestService();
-        mCondition.block();
-
-        assertTrue(mTestStarted);
-        assertTrue(mTestEnded);
-    }
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mHandlerThread.start();
-        mMessenger = new Messenger(new Handler(mHandlerThread.getLooper()) {
-            @Override
-            public void handleMessage(Message msg) {
-                switch (msg.what) {
-                    case MSG_TEST_STARTED:
-                        onTestStarted();
-                        break;
-                    case MSG_TEST_ENDED_CLEAN:
-                        onTestEnded(false);
-                        break;
-                    default:
-                        super.handleMessage(msg);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        try {
-            mHandlerThread.quitSafely();
-        } finally {
-            super.tearDown();
-        }
-    }
-
-    private void launchDeathTestService() {
-        Log.d(TAG, "launchDeathTestService");
-        mCondition.close();
-
-        Intent intent = new Intent();
-        intent.setComponent(new ComponentName("com.android.cts.security", "android.security.cts.SeccompDeathTestService"));
-
-        if (!getContext().bindService(intent, this, Context.BIND_AUTO_CREATE)) {
-            mCondition.open();
-            fail("Failed to start DeathTestService");
-        }
-    }
-
-    @Override
-    public void onServiceConnected(ComponentName name, IBinder service) {
-        Log.d(TAG, "onServiceConnected");
-
-        Messenger remoteMessenger = new Messenger(service);
-        Message msg = Message.obtain(null, SeccompDeathTestService.MSG_RUN_TEST);
-        msg.getData().putBinder(SeccompDeathTestService.REPLY_BINDER_NAME, mMessenger.getBinder());
-        msg.getData().putInt(SeccompDeathTestService.RUN_TEST_IDENTIFIER, mTestNumber);
-
-        try {
-            service.linkToDeath(this, 0);
-            remoteMessenger.send(msg);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error setting up SeccompDeathTestService: " + e.getMessage());
-        }
-        Log.d(TAG, "Send MSG_TEST_START");
-    }
-
-    private void onTestStarted() {
-        Log.d(TAG, "onTestStarted");
-        mTestStarted = true;
-    }
-
-    @Override
-    public void onServiceDisconnected(ComponentName name) {
-        Log.d(TAG, "onServiceDisconnected");
-    }
-
-    @Override
-    public void binderDied() {
-        Log.d(TAG, "binderDied");
-        if (mTestEnded)
-            return;
-        onTestEnded(true);
-    }
-
-    private void onTestEnded(boolean died) {
-        Log.d(TAG, "onTestEnded, died=" + died);
-        mTestEnded = true;
-        mTestDied = died;
-        getContext().unbindService(this);
-        mCondition.open();
-    }
-}
diff --git a/tests/tests/security/src/android/security/cts/SeccompDeathTestService.java b/tests/tests/security/src/android/security/cts/SeccompDeathTestService.java
deleted file mode 100644
index c78ea35..0000000
--- a/tests/tests/security/src/android/security/cts/SeccompDeathTestService.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.cts;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * Service used to run tests for seccomp-bpf sandboxing. Since sandbox violations
- * result in process termination, they cannot be run from within the test case
- * itself. The SeccompBpfTest starts this service to run code out-of-process and
- * then observes when the Binder channel dies. If the test does not die, the
- * service reports back to the test that it exited cleanly.
- */
-public class SeccompDeathTestService extends Service {
-    static final String TAG = SeccompBpfTest.TAG;
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Message sent from SeccompBpfTest to run a test.
-     */
-    final static int MSG_RUN_TEST = 100;
-    /**
-     * In MSG_RUN_TEST, the test number to run.
-     */
-    final static String RUN_TEST_IDENTIFIER = "android.security.cts.SeccompDeathTestService.testID";
-    /**
-     * In MSG_RUN_TEST, the Binder on which to report clean death.
-     */
-    static final String REPLY_BINDER_NAME = "android.security.cts.SeccompBpfTest";
-
-    // Test numbers that map to test methods in this service.
-    final static int TEST_DEATH_TEST = 1;
-    final static int TEST_CLEAN_TEST = 2;
-    final static int TEST_SIGSYS_SELF = 3;
-
-    final private Messenger mMessenger = new Messenger(new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_RUN_TEST:
-                    runTest(msg);
-                    break;
-                default:
-                    super.handleMessage(msg);
-            }
-        }
-    });
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        Log.d(TAG, "onBind");
-        return mMessenger.getBinder();
-    }
-
-    private void runTest(Message msg) {
-        Log.d(TAG, "runTest");
-        IBinder harnessBinder = msg.getData().getBinder(REPLY_BINDER_NAME);
-        Messenger harness = new Messenger(harnessBinder);
-
-        try {
-            Log.d(TAG, "Send MSG_TEST_STARTED");
-            harness.send(Message.obtain(null, SeccompBpfTest.MSG_TEST_STARTED));
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to MSG_TEST_STARTED: " + e.getMessage());
-        }
-
-        demuxTest(msg.getData().getInt(RUN_TEST_IDENTIFIER));
-
-        try {
-            Log.d(TAG, "Send MSG_TEST_ENDED_CLEAN");
-            harness.send(Message.obtain(null, SeccompBpfTest.MSG_TEST_ENDED_CLEAN));
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to MSG_TEST_ENDED_CLEAN: " + e.getMessage());
-        }
-    }
-
-    private void demuxTest(int testNumber) {
-        switch (testNumber) {
-            case TEST_DEATH_TEST:
-                testDeath();
-                break;
-            case TEST_CLEAN_TEST:
-                break;
-            case TEST_SIGSYS_SELF:
-                testSigSysSelf();
-                break;
-            default:
-                throw new RuntimeException("Unknown test number " + testNumber);
-        }
-    }
-
-    public void testDeath() {
-        String s = null;
-        s.hashCode();
-    }
-
-    public native void testSigSysSelf();
-}
diff --git a/tests/tests/telecom/src/android/telecom/cts/DefaultDialerOperationsTest.java b/tests/tests/telecom/src/android/telecom/cts/DefaultDialerOperationsTest.java
index 1c6e9b1..b574a96 100644
--- a/tests/tests/telecom/src/android/telecom/cts/DefaultDialerOperationsTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/DefaultDialerOperationsTest.java
@@ -37,12 +37,23 @@
     private TelecomManager mTelecomManager;
     private PhoneAccountHandle mPhoneAccountHandle;
     private String mPreviousDefaultDialer = null;
+    private String mSystemDialer = null;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mContext = getInstrumentation().getContext();
+
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation());
+        // Reset the current dialer to the system dialer, to ensure that we start each test
+        // without being the default dialer.
+        mSystemDialer = TestUtils.getSystemDialer(getInstrumentation());
+        if (!TextUtils.isEmpty(mSystemDialer)) {
+            TestUtils.setDefaultDialer(getInstrumentation(), mSystemDialer);
+        }
         mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
         final List<PhoneAccountHandle> accounts = mTelecomManager.getCallCapablePhoneAccounts();
         if (accounts != null && !accounts.isEmpty()) {
@@ -53,18 +64,26 @@
     @Override
     protected void tearDown() throws Exception {
         if (!TextUtils.isEmpty(mPreviousDefaultDialer)) {
+            // Restore the default dialer to whatever the default dialer was before the tests
+            // were started. This may or may not be the system dialer.
             TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer);
         }
         super.tearDown();
     }
 
     public void testGetDefaultDialerPackage() throws Exception {
-        assertEquals(mPreviousDefaultDialer, mTelecomManager.getDefaultDialerPackage());
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        assertEquals(mSystemDialer, mTelecomManager.getDefaultDialerPackage());
         TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
         assertEquals(TestUtils.PACKAGE, mTelecomManager.getDefaultDialerPackage());
     }
 
     public void testVoicemailReadWritePermissions() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         try {
             mContext.getContentResolver().query(Voicemails.CONTENT_URI, null, null, null, null);
             fail("Reading voicemails should throw SecurityException if not default Dialer");
@@ -96,6 +115,9 @@
     }
 
     public void testSilenceRingerPermissions() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         try {
             mTelecomManager.silenceRinger();
             fail("TelecomManager.silenceRinger should throw SecurityException if not default "
@@ -110,6 +132,9 @@
 
     public void testCancelMissedCallsNotificationPermissions()
             throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         try {
             mTelecomManager.cancelMissedCallsNotification();
             fail("TelecomManager.cancelMissedCallsNotification should throw SecurityException if "
@@ -124,6 +149,9 @@
 
     public void testHandlePinMmPermissions()
             throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         try {
             mTelecomManager.handleMmi("0");
             fail("TelecomManager.handleMmi should throw SecurityException if not default dialer");
@@ -143,6 +171,9 @@
     }
 
     public void testGetAdnForPhoneAccountPermissions() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         try {
             mTelecomManager.getAdnUriForPhoneAccount(mPhoneAccountHandle);
             fail("TelecomManager.getAdnUriForPhoneAccount should throw SecurityException if "
@@ -156,6 +187,9 @@
     }
 
     public void testSetDefaultDialerNoDialIntent_notSupported() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         final PackageManager pm = mContext.getPackageManager();
         final ComponentName name = new ComponentName(mContext,
                 "android.telecom.cts.MockDialerActivity");
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index c72e3c2..ddc85a6 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -46,6 +46,8 @@
 
     private static final String COMMAND_GET_DEFAULT_DIALER = "telecom get-default-dialer";
 
+    private static final String COMMAND_GET_SYSTEM_DIALER = "telecom get-system-dialer";
+
     private static final String COMMAND_ENABLE = "telecom set-phone-account-enabled ";
 
     public static boolean shouldTestTelecom(Context context) {
@@ -65,6 +67,10 @@
         return executeShellCommand(instrumentation, COMMAND_GET_DEFAULT_DIALER);
     }
 
+    public static String getSystemDialer(Instrumentation instrumentation) throws Exception {
+        return executeShellCommand(instrumentation, COMMAND_GET_SYSTEM_DIALER);
+    }
+
     public static void enablePhoneAccount(Instrumentation instrumentation,
             PhoneAccountHandle handle) throws Exception {
         final ComponentName component = handle.getComponentName();
diff --git a/tests/tests/telecom2/src/android/telecom/cts/DefaultDialerOperationsNoPermissionsTest.java b/tests/tests/telecom2/src/android/telecom/cts/DefaultDialerOperationsNoPermissionsTest.java
index 4629992..86f850e 100644
--- a/tests/tests/telecom2/src/android/telecom/cts/DefaultDialerOperationsNoPermissionsTest.java
+++ b/tests/tests/telecom2/src/android/telecom/cts/DefaultDialerOperationsNoPermissionsTest.java
@@ -28,25 +28,40 @@
     private Context mContext;
     private TelecomManager mTelecomManager;
     private String mPreviousDefaultDialer = null;
+    private String mSystemDialer = null;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mContext = getInstrumentation().getContext();
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         TestUtils.PACKAGE = mContext.getPackageName();
         mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation());
+        // Reset the current dialer to the system dialer, to ensure that we start each test
+        // without being the default dialer.
+        mSystemDialer = TestUtils.getSystemDialer(getInstrumentation());
+        if (!TextUtils.isEmpty(mSystemDialer)) {
+            TestUtils.setDefaultDialer(getInstrumentation(), mSystemDialer);
+        }
         mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
     }
 
     @Override
     protected void tearDown() throws Exception {
         if (!TextUtils.isEmpty(mPreviousDefaultDialer)) {
+            // Restore the default dialer to whatever the default dialer was before the tests
+            // were started. This may or may not be the system dialer.
             TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer);
         }
         super.tearDown();
     }
 
     public void testShowInCallScreenPermissions() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
             @Override
             public void run() {
@@ -56,6 +71,9 @@
     }
 
     public void testGetCallCapableAccountsPermissions() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
             @Override
             public void run() {
@@ -65,6 +83,9 @@
     }
 
     public void testGetDefaultOutgoingPhoneAccount() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
             @Override
             public void run() {
@@ -74,6 +95,9 @@
     }
 
     public void testGetLine1Number() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
             @Override
             public void run() {
@@ -83,6 +107,9 @@
     }
 
     public void testGetVoicemailNumber() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
             @Override
             public void run() {
@@ -92,6 +119,9 @@
     }
 
     public void testIsInCall() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
         verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
             @Override
             public void run() {
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
index f0f977a..18aa23f 100644
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
@@ -22,6 +22,7 @@
 import android.telephony.CellLocation;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
 import android.net.ConnectivityManager;
 import android.test.InstrumentationTestCase;
@@ -40,6 +41,7 @@
     private boolean mOnMessageWaitingIndicatorChangedCalled;
     private boolean mOnServiceStateChangedCalled;
     private boolean mOnSignalStrengthChangedCalled;
+    private SignalStrength mSignalStrength;
     private TelephonyManager mTelephonyManager;
     private PhoneStateListener mListener;
     private final Object mLock = new Object();
@@ -152,6 +154,54 @@
         assertTrue(mOnSignalStrengthChangedCalled);
     }
 
+    public void testOnSignalStrengthsChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+                        synchronized(mLock) {
+                            mSignalStrength = signalStrength;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
+
+                Looper.loop();
+            }
+        });
+
+        assertTrue(mSignalStrength == null);
+        t.start();
+
+        synchronized (mLock) {
+            while(mSignalStrength == null) {
+                mLock.wait();
+            }
+        }
+        t.checkException();
+        assertTrue(mSignalStrength != null);
+
+        // Call SignalStrength methods to make sure they do not throw any exceptions
+        mSignalStrength.getCdmaDbm();
+        mSignalStrength.getCdmaEcio();
+        mSignalStrength.getEvdoDbm();
+        mSignalStrength.getEvdoEcio();
+        mSignalStrength.getEvdoSnr();
+        mSignalStrength.getGsmBitErrorRate();
+        mSignalStrength.getGsmSignalStrength();
+        mSignalStrength.isGsm();
+        mSignalStrength.getLevel();
+    }
+
     public void testOnMessageWaitingIndicatorChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index 2be1dcb..ce3fe78 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -160,7 +160,28 @@
         mTelephonyManager.getNeighboringCellInfo();
         mTelephonyManager.isNetworkRoaming();
         mTelephonyManager.getDeviceId();
+        mTelephonyManager.getDeviceId(mTelephonyManager.getDefaultSim());
         mTelephonyManager.getDeviceSoftwareVersion();
+        mTelephonyManager.getPhoneCount();
+    }
+
+    /**
+     * Tests that the phone count returned is valid.
+     */
+    public void testGetPhoneCount() {
+        int phoneCount = mTelephonyManager.getPhoneCount();
+        int phoneType = mTelephonyManager.getPhoneType();
+        switch (phoneType) {
+            case TelephonyManager.PHONE_TYPE_GSM:
+            case TelephonyManager.PHONE_TYPE_CDMA:
+                assertTrue("Phone count should be > 0", phoneCount > 0);
+                break;
+            case TelephonyManager.PHONE_TYPE_NONE:
+                assertTrue("Phone count should be 0", phoneCount == 0);
+                break;
+            default:
+                throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
+        }
     }
 
     /**
@@ -170,6 +191,24 @@
      */
     public void testGetDeviceId() {
         String deviceId = mTelephonyManager.getDeviceId();
+        verifyDeviceId(deviceId);
+    }
+
+    /**
+     * Tests that the device properly reports either a valid IMEI if
+     * GSM, a valid MEID or ESN if CDMA, or a valid MAC address if
+     * only a WiFi device.
+     */
+    public void testGetDeviceIdForSlotId() {
+        String deviceId = mTelephonyManager.getDeviceId(mTelephonyManager.getDefaultSim());
+        verifyDeviceId(deviceId);
+        // Also verify that no exception is thrown for any slot id (including invalid ones)
+        for (int i = -1; i <= mTelephonyManager.getPhoneCount(); i++) {
+            mTelephonyManager.getDeviceId(i);
+        }
+    }
+
+    private void verifyDeviceId(String deviceId) {
         int phoneType = mTelephonyManager.getPhoneType();
         switch (phoneType) {
             case TelephonyManager.PHONE_TYPE_GSM:
diff --git a/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java b/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
index 4895ca9..36b081c 100644
--- a/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
+++ b/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
@@ -18,10 +18,12 @@
 
 
 import android.test.AndroidTestCase;
+import android.text.Editable;
 import android.text.InputFilter;
 import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
+import android.text.TextWatcher;
 import android.text.style.StrikethroughSpan;
 import android.text.style.TabStopSpan;
 import android.text.style.UnderlineSpan;
@@ -596,4 +598,46 @@
             // expected exception
         }
     }
+
+    private static class MockTextWatcher implements TextWatcher {
+        private int mDepth = 0;
+
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            SpannableStringBuilder builder = (SpannableStringBuilder)s;
+            mDepth++;
+            assertEquals(mDepth, builder.getTextWatcherDepth());
+            mDepth--;
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+            SpannableStringBuilder builder = (SpannableStringBuilder)s;
+            mDepth++;
+            assertEquals(mDepth, builder.getTextWatcherDepth());
+            mDepth--;
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+            SpannableStringBuilder builder = (SpannableStringBuilder)s;
+            mDepth++;
+            assertEquals(mDepth, builder.getTextWatcherDepth());
+            if (mDepth <= builder.length()) {
+                // This will recursively call afterTextChanged.
+                builder.replace(mDepth - 1, mDepth, "a");
+            }
+            mDepth--;
+        }
+    }
+
+    public void testGetTextWatcherDepth() {
+        SpannableStringBuilder builder = new SpannableStringBuilder("hello");
+        builder.setSpan(new MockTextWatcher(), 0, builder.length(), 0);
+        assertEquals(0, builder.getTextWatcherDepth());
+        builder.replace(0, 1, "H");
+        assertEquals(0, builder.getTextWatcherDepth());
+        // MockTextWatcher replaces each character with 'a'.
+        assertEquals("aaaaa", builder.toString());
+    }
 }
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index ec02294..a52eabe 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -107,7 +107,8 @@
         Log.i(LOG_TAG, String.format("Checking user agent string %s", actualUserAgentString));
         final String patternString =
                 "Mozilla/5\\.0 \\(Linux;( U;)? Android ([^;]+);( (\\w+)-(\\w+);)?" +
-                "\\s?(.*)\\sBuild/(.+)\\) AppleWebKit/(\\d+)\\.(\\d+) \\(KHTML, like Gecko\\) " +
+                "\\s?(.*)\\sBuild/(.+); wv\\) AppleWebKit/(\\d+)\\.(\\d+) " +
+                "\\(KHTML, like Gecko\\) " +
                 "Version/\\d+\\.\\d+ Chrome/\\d+\\.\\d+\\.\\d+\\.\\d+( Mobile)? " +
                 "Safari/(\\d+)\\.(\\d+)";
         // Groups used:
diff --git a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
new file mode 100644
index 0000000..2dff4cb
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2015 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.widget.cts;
+
+import com.android.cts.widget.R;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.Gravity;
+import android.widget.PopupMenu;
+
+
+public class PopupMenuTest extends
+        ActivityInstrumentationTestCase2<MockPopupWindowCtsActivity> {
+    private Instrumentation mInstrumentation;
+    private Activity mActivity;
+
+    public PopupMenuTest() {
+        super("com.android.cts.widget", MockPopupWindowCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mActivity = getActivity();
+    }
+
+    public void testAccessGravity() {
+        PopupMenu popupMenu = new PopupMenu(mActivity,
+                mActivity.findViewById(R.id.anchor_middle_left));
+        assertEquals(Gravity.NO_GRAVITY, popupMenu.getGravity());
+        popupMenu.setGravity(Gravity.TOP);
+        assertEquals(Gravity.TOP, popupMenu.getGravity());
+    }
+
+    public void testOnDismissListener() {
+        final PopupMenu popupMenu = new PopupMenu(mActivity,
+                mActivity.findViewById(R.id.anchor_middle_left));
+        TestPopupDismissListener listener = new TestPopupDismissListener();
+        popupMenu.setOnDismissListener(listener);
+
+        mInstrumentation.runOnMainSync(new Runnable() {
+            public void run() {
+                popupMenu.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(0, listener.getDismissCount());
+
+        mInstrumentation.runOnMainSync(new Runnable() {
+            public void run() {
+                popupMenu.dismiss();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(1, listener.getDismissCount());
+
+        mInstrumentation.runOnMainSync(new Runnable() {
+            public void run() {
+                popupMenu.dismiss();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertEquals(1, listener.getDismissCount());
+    }
+
+    private class TestPopupDismissListener implements PopupMenu.OnDismissListener {
+        int mDismissCount;
+
+        @Override
+        public void onDismiss(PopupMenu menu) {
+            mDismissCount++;
+        }
+
+        int getDismissCount() {
+            return mDismissCount;
+        }
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/QuickContactBadgeTest.java b/tests/tests/widget/src/android/widget/cts/QuickContactBadgeTest.java
new file mode 100644
index 0000000..cfd61a2
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/QuickContactBadgeTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 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.widget.cts;
+
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Contacts;
+import android.test.InstrumentationTestCase;
+import android.test.UiThreadTest;
+import android.widget.QuickContactBadge;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class QuickContactBadgeTest extends InstrumentationTestCase {
+
+    @UiThreadTest
+    public void testPrioritizedMimetype() throws InterruptedException {
+        final String plainMimeType = "text/plain";
+        final Uri nonExistentContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 0);
+        final CountDownLatch latch = new CountDownLatch(1);
+        Context context = new ContextWrapper(getInstrumentation().getContext()) {
+            @Override
+            public void startActivity(Intent intent) {
+                testCallback(intent);
+            }
+
+            @Override
+            public void startActivityAsUser(Intent intent, UserHandle user) {
+                testCallback(intent);
+            }
+
+            @Override
+            public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
+                testCallback(intent);
+            }
+
+            private void testCallback(Intent intent) {
+                assertEquals(plainMimeType, intent.getStringExtra(
+                        ContactsContract.QuickContact.EXTRA_PRIORITIZED_MIMETYPE));
+                latch.countDown();
+            }
+        };
+
+        // Execute: create QuickContactBadge with a prioritized mimetype and click on it
+        QuickContactBadge badge = new QuickContactBadge(context);
+        badge.setPrioritizedMimeType(plainMimeType);
+        badge.assignContactUri(nonExistentContactUri);
+        badge.onClick(badge);
+
+        // Verify: the QuickContactBadge attempts to start an activity, and sets the
+        // prioritized mimetype. We don't know which method will be used to start the activity,
+        // so we check all options.
+        assertTrue(latch.await(1, TimeUnit.SECONDS));
+    }
+}
+