Merge "CTS tests for accessibility importance API"
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java
index 4b90d9a..99ecd0c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockConditionProvider.java
@@ -144,11 +144,6 @@
     }
 
     @Override
-    public void onRequestConditions(int relevance) {
-
-    }
-
-    @Override
     public void onSubscribe(Uri conditionId) {
         Log.d(TAG, "subscribed to " + conditionId);
         mSubscriptions.add(conditionId);
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
index 148d8a8..18b922e 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.java
@@ -19,6 +19,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.os.UserManager;
 import android.test.InstrumentationTestCase;
 
 /**
@@ -37,6 +38,7 @@
             PACKAGE_NAME, BasicAdminReceiver.class.getName());
 
     protected DevicePolicyManager mDevicePolicyManager;
+    protected UserManager mUserManager;
     protected Context mContext;
 
     @Override
@@ -44,10 +46,12 @@
         super.setUp();
         mContext = getInstrumentation().getContext();
 
-        mDevicePolicyManager = (DevicePolicyManager)
-            mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
         assertNotNull(mDevicePolicyManager);
 
+        mUserManager = mContext.getSystemService(UserManager.class);
+        assertNotNull(mUserManager);
+
         assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
         assertTrue("App is neither device nor profile owner",
                 mDevicePolicyManager.isProfileOwnerApp(PACKAGE_NAME) ||
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java
index 2fe0569..d70cd70 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.java
@@ -30,13 +30,12 @@
         mDevicePolicyManager = (DevicePolicyManager)
                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
         if (mDevicePolicyManager != null) {
-            removeActiveAdmin(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
             if (mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME)) {
                 mDevicePolicyManager.clearDeviceOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME);
             }
-            assertFalse(mDevicePolicyManager.isAdminActive(
-                    BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT));
             assertFalse(mDevicePolicyManager.isDeviceOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME));
+
+            Utils.removeActiveAdmin(getContext(), BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
         }
 
         super.tearDown();
@@ -46,13 +45,4 @@
     // side test once a test case is finished.
     public void testClearDeviceOwner() {
     }
-
-    private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
-        if (mDevicePolicyManager.isAdminActive(cn)) {
-            mDevicePolicyManager.removeActiveAdmin(cn);
-            for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
-                Thread.sleep(100);
-            }
-        }
-    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java
index d41166f..93f5d44 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearProfileOwnerTest.java
@@ -34,8 +34,9 @@
                 mDevicePolicyManager.clearProfileOwner(
                         BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
             }
-            removeActiveAdmin(BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
             assertFalse(mDevicePolicyManager.isProfileOwnerApp(BaseDeviceAdminTest.PACKAGE_NAME));
+
+            Utils.removeActiveAdmin(getContext(), BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT);
         }
 
         super.tearDown();
@@ -45,13 +46,4 @@
     // side test once a test case is finished.
     public void testClearProfileOwner() {
     }
-
-    private void removeActiveAdmin(ComponentName cn) throws InterruptedException {
-        if (mDevicePolicyManager.isAdminActive(cn)) {
-            mDevicePolicyManager.removeActiveAdmin(cn);
-            for (int i = 0; i < 1000 && mDevicePolicyManager.isAdminActive(cn); i++) {
-                Thread.sleep(100);
-            }
-        }
-    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/Utils.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/Utils.java
new file mode 100644
index 0000000..7390f76
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/Utils.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+
+import junit.framework.Assert;
+
+public class Utils {
+    private Utils() {
+    }
+
+    public static void removeActiveAdmin(Context context, ComponentName cn) throws Exception {
+        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+        if (dpm.isAdminActive(cn)) {
+            dpm.removeActiveAdmin(cn);
+            for (int i = 0; i < 1000 && dpm.isAdminActive(cn); i++) {
+                Thread.sleep(100);
+            }
+            Assert.assertFalse(dpm.isAdminActive(cn));
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java
new file mode 100644
index 0000000..a7d8110
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+
+import com.android.cts.deviceandprofileowner.BaseDeviceAdminTest;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public abstract class BaseUserRestrictionsTest extends BaseDeviceAdminTest {
+    protected static final String[] ALL_USER_RESTRICTIONS = new String[]{
+            UserManager.DISALLOW_CONFIG_WIFI,
+            UserManager.DISALLOW_MODIFY_ACCOUNTS,
+            UserManager.DISALLOW_INSTALL_APPS,
+            UserManager.DISALLOW_UNINSTALL_APPS,
+            UserManager.DISALLOW_SHARE_LOCATION,
+            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+            UserManager.DISALLOW_CONFIG_BLUETOOTH,
+            UserManager.DISALLOW_USB_FILE_TRANSFER,
+            UserManager.DISALLOW_CONFIG_CREDENTIALS,
+            UserManager.DISALLOW_REMOVE_USER,
+            UserManager.DISALLOW_DEBUGGING_FEATURES,
+            UserManager.DISALLOW_CONFIG_VPN,
+            UserManager.DISALLOW_CONFIG_TETHERING,
+            UserManager.DISALLOW_NETWORK_RESET,
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserManager.DISALLOW_ADD_USER,
+            UserManager.ENSURE_VERIFY_APPS,
+            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+            UserManager.DISALLOW_APPS_CONTROL,
+            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+            UserManager.DISALLOW_UNMUTE_MICROPHONE,
+            UserManager.DISALLOW_ADJUST_VOLUME,
+            UserManager.DISALLOW_OUTGOING_CALLS,
+            UserManager.DISALLOW_SMS,
+            UserManager.DISALLOW_FUN,
+            UserManager.DISALLOW_CREATE_WINDOWS,
+            UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
+            UserManager.DISALLOW_OUTGOING_BEAM,
+            UserManager.DISALLOW_SAFE_BOOT,
+            UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
+            UserManager.DISALLOW_DATA_ROAMING,
+            UserManager.DISALLOW_SET_USER_ICON
+    };
+
+    /**
+     * Restrictions that affect all users when DO sets.
+     */
+    protected static final String[] DO_GLOBAL_RESTRICTIONS = new String[] {
+            UserManager.DISALLOW_USB_FILE_TRANSFER,
+            UserManager.DISALLOW_CONFIG_TETHERING,
+            UserManager.DISALLOW_NETWORK_RESET,
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserManager.DISALLOW_ADD_USER,
+            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+            UserManager.DISALLOW_SMS,
+            UserManager.DISALLOW_FUN,
+            UserManager.DISALLOW_SAFE_BOOT,
+            UserManager.DISALLOW_CREATE_WINDOWS,
+            // UserManager.DISALLOW_DATA_ROAMING, // Not set during CTS
+
+            // PO can set them too, but when DO sets them, they're global.
+            UserManager.DISALLOW_ADJUST_VOLUME,
+            UserManager.DISALLOW_UNMUTE_MICROPHONE
+    };
+
+    public static final String[] HIDDEN_AND_PROHIBITED = new String[] {
+            "no_record_audio",
+            "no_wallpaper"
+    };
+
+    protected void assertLayeredRestriction(String restriction, boolean expected) {
+        assertEquals("Restriction " + restriction + ": expected=" + expected,
+                expected, mUserManager.hasUserRestriction(restriction));
+    }
+
+    protected void assertOwnerRestriction(String restriction, boolean expected) {
+        assertEquals("Restriction " + restriction + ": expected=" + expected,
+                expected, mDevicePolicyManager.getUserRestrictions(ADMIN_RECEIVER_COMPONENT)
+                        .getBoolean(restriction));
+    }
+
+    protected void assertRestrictions(Set<String> expected) {
+        for (String r : ALL_USER_RESTRICTIONS) {
+            assertLayeredRestriction(r, expected.contains(r));
+        }
+    }
+
+    /**
+     * Test that the given restriction can be set and cleared, then leave it set again.
+     */
+    protected void assertSetClearUserRestriction(String restriction) {
+        final boolean hadRestriction = mUserManager.hasUserRestriction(restriction);
+
+        assertOwnerRestriction(restriction, false);
+
+        // Set.  Shouldn't throw.
+        mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+
+        assertOwnerRestriction(restriction, true);
+        assertLayeredRestriction(restriction, true);
+
+        // Then clear.
+        assertClearUserRestriction(restriction);
+
+        assertLayeredRestriction(restriction, hadRestriction);
+
+        // Then set again.
+        mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+    }
+
+    /**
+     * Test that the given restriction can be cleared.  (and leave it cleared.)
+     */
+    protected void assertClearUserRestriction(String restriction) {
+        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+
+        assertOwnerRestriction(restriction, false);
+    }
+
+    /**
+     * Test that the given restriction *cannot* be set (or clear).
+     */
+    protected void assertCannotSetUserRestriction(String restriction) {
+        final boolean hadRestriction = mUserManager.hasUserRestriction(restriction);
+
+        assertOwnerRestriction(restriction, false);
+
+        // Set should fail.
+        try {
+            mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+            fail("Restriction=" + restriction);
+        } catch (SecurityException e) {
+            assertTrue("Restriction=" + restriction + " Message was: " + e.getMessage(),
+                    e.getMessage().contains("cannot set user restriction"));
+        }
+
+        // Shouldn't have changed.
+        assertOwnerRestriction(restriction, false);
+        assertLayeredRestriction(restriction, hadRestriction);
+
+        // Clear should fail too.
+        try {
+            mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
+            fail("Restriction=" + restriction);
+        } catch (SecurityException e) {
+            assertTrue("Restriction=" + restriction + " Message was: " + e.getMessage(),
+                    e.getMessage().contains("cannot set user restriction"));
+        }
+
+        // Shouldn't have changed.
+        assertOwnerRestriction(restriction, false);
+        assertLayeredRestriction(restriction, hadRestriction);
+    }
+
+    /** For {@link #testSetAllRestrictions} */
+    protected abstract String[] getAllowedRestrictions();
+
+    /** For {@link #testSetAllRestrictions} */
+    protected abstract String[] getDisallowedRestrictions();
+
+    /**
+     * Set only one restriction, and make sure only that's set, and then clear it.
+     */
+    public void testSetAllRestrictionsIndividually() {
+        for (String r : getAllowedRestrictions()) {
+            // Set it.
+            assertSetClearUserRestriction(r);
+
+            assertRestrictions(new HashSet<>(Arrays.asList(new String[]{r})));
+
+            // Then clear it.
+            assertClearUserRestriction(r);
+        }
+    }
+
+    /**
+     * Make sure all allowed restrictions can be set, and the others can't.
+     */
+    public void testSetAllRestrictions() {
+        for (String r : getAllowedRestrictions()) {
+            assertSetClearUserRestriction(r);
+        }
+        for (String r : getDisallowedRestrictions()) {
+            assertCannotSetUserRestriction(r);
+        }
+        for (String r : HIDDEN_AND_PROHIBITED) {
+            assertCannotSetUserRestriction(r);
+        }
+    }
+
+    /**
+     * Clear all allowed restrictions.
+     */
+    public void testClearAllRestrictions() {
+        for (String r : getAllowedRestrictions()) {
+            assertClearUserRestriction(r);
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/CheckNoOwnerRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/CheckNoOwnerRestrictionsTest.java
new file mode 100644
index 0000000..14e5f84
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/CheckNoOwnerRestrictionsTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+import android.test.AndroidTestCase;
+
+/**
+ * Used after after DO/PO are removed to make sure user restrictions set by them are no longer
+ * set.
+ */
+public class CheckNoOwnerRestrictionsTest extends AndroidTestCase {
+    public void testNoOwnerRestrictions() {
+        assertFalse(mContext.getSystemService(UserManager.class).hasUserRestriction(
+                UserManager.DISALLOW_UNMUTE_MICROPHONE));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
new file mode 100644
index 0000000..1ff9b6c
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+
+public class DeviceOwnerUserRestrictionsTest extends BaseUserRestrictionsTest {
+    public static final String[] ALLOWED = new String[] {
+            // UserManager.DISALLOW_CONFIG_WIFI, // Has unrecoverable side effects.
+            UserManager.DISALLOW_MODIFY_ACCOUNTS,
+            UserManager.DISALLOW_INSTALL_APPS,
+            UserManager.DISALLOW_UNINSTALL_APPS,
+            // UserManager.DISALLOW_SHARE_LOCATION, // Has unrecoverable side effects.
+            // UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, // Has unrecoverable side effects.
+            UserManager.DISALLOW_CONFIG_BLUETOOTH,
+            UserManager.DISALLOW_USB_FILE_TRANSFER,
+            UserManager.DISALLOW_CONFIG_CREDENTIALS,
+            UserManager.DISALLOW_REMOVE_USER,
+            // UserManager.DISALLOW_DEBUGGING_FEATURES, // Need for CTS
+            UserManager.DISALLOW_CONFIG_VPN,
+            UserManager.DISALLOW_CONFIG_TETHERING,
+            UserManager.DISALLOW_NETWORK_RESET,
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserManager.DISALLOW_ADD_USER,
+            // UserManager.ENSURE_VERIFY_APPS, // Has unrecoverable side effects.
+            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+            UserManager.DISALLOW_APPS_CONTROL,
+            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+            UserManager.DISALLOW_UNMUTE_MICROPHONE,
+            UserManager.DISALLOW_ADJUST_VOLUME,
+            UserManager.DISALLOW_OUTGOING_CALLS,
+            UserManager.DISALLOW_SMS,
+            UserManager.DISALLOW_FUN,
+            UserManager.DISALLOW_CREATE_WINDOWS,
+            UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
+            UserManager.DISALLOW_OUTGOING_BEAM,
+            UserManager.DISALLOW_SAFE_BOOT,
+            UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
+            // UserManager.DISALLOW_DATA_ROAMING, // Has unrecoverable side effects.
+            UserManager.DISALLOW_SET_USER_ICON
+    };
+
+    public static final String[] DISALLOWED = new String[] {
+            // DO can set all public restrictions.
+    };
+
+    @Override
+    protected String[] getAllowedRestrictions() {
+        return ALLOWED;
+    }
+
+    @Override
+    protected String[] getDisallowedRestrictions() {
+        return DISALLOWED;
+    }
+}
+
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/PrimaryProfileOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/PrimaryProfileOwnerUserRestrictionsTest.java
new file mode 100644
index 0000000..57c49cf
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/PrimaryProfileOwnerUserRestrictionsTest.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+public class PrimaryProfileOwnerUserRestrictionsTest extends BaseUserRestrictionsTest {
+    @Override
+    protected String[] getAllowedRestrictions() {
+        // PO on user-0 can set DO user restrictions too. (for now?)
+        return DeviceOwnerUserRestrictionsTest.ALLOWED;
+    }
+
+    @Override
+    protected String[] getDisallowedRestrictions() {
+        return DeviceOwnerUserRestrictionsTest.DISALLOWED;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
new file mode 100644
index 0000000..8cd56bf
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceandprofileowner.userrestrictions;
+
+import android.os.UserManager;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class SecondaryProfileOwnerUserRestrictionsTest extends BaseUserRestrictionsTest {
+    public static final String[] ALLOWED = new String[] {
+            // UserManager.DISALLOW_CONFIG_WIFI, // Has unrecoverable side effects.
+            UserManager.DISALLOW_MODIFY_ACCOUNTS,
+            UserManager.DISALLOW_INSTALL_APPS,
+            UserManager.DISALLOW_UNINSTALL_APPS,
+            // UserManager.DISALLOW_SHARE_LOCATION, // Has unrecoverable side effects.
+            // UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, // Has unrecoverable side effects.
+            UserManager.DISALLOW_CONFIG_BLUETOOTH,
+            UserManager.DISALLOW_CONFIG_CREDENTIALS,
+            UserManager.DISALLOW_REMOVE_USER,
+            // UserManager.DISALLOW_DEBUGGING_FEATURES, // Need for CTS
+            UserManager.DISALLOW_CONFIG_VPN,
+            // UserManager.ENSURE_VERIFY_APPS, // Has unrecoverable side effects.
+            UserManager.DISALLOW_APPS_CONTROL,
+            UserManager.DISALLOW_UNMUTE_MICROPHONE,
+            UserManager.DISALLOW_ADJUST_VOLUME,
+            UserManager.DISALLOW_OUTGOING_CALLS,
+            UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
+            UserManager.DISALLOW_OUTGOING_BEAM,
+            UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
+            UserManager.DISALLOW_SET_USER_ICON
+    };
+
+    public static final String[] DISALLOWED = new String[] {
+            UserManager.DISALLOW_USB_FILE_TRANSFER,
+            UserManager.DISALLOW_CONFIG_TETHERING,
+            UserManager.DISALLOW_NETWORK_RESET,
+            UserManager.DISALLOW_FACTORY_RESET,
+            UserManager.DISALLOW_ADD_USER,
+            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
+            UserManager.DISALLOW_SMS,
+            UserManager.DISALLOW_FUN,
+            UserManager.DISALLOW_SAFE_BOOT,
+            UserManager.DISALLOW_CREATE_WINDOWS,
+            UserManager.DISALLOW_DATA_ROAMING
+    };
+
+    @Override
+    protected String[] getAllowedRestrictions() {
+        return ALLOWED;
+    }
+
+    @Override
+    protected String[] getDisallowedRestrictions() {
+        return DISALLOWED;
+    }
+
+    /**
+     * This is called after DO setting all DO restrictions.  Global restrictions should be
+     * visible on other users.
+     */
+    public void testHasGlobalRestrictions() {
+        assertRestrictions(new HashSet<>(Arrays.asList(DO_GLOBAL_RESTRICTIONS)));
+    }
+
+    /**
+     * This is called after DO setting all DO restrictions, and PO setting all PO restrictions.
+     * All global + local restrictions should be visible.
+     */
+    public void testHasBothGlobalAndLocalRestrictions() {
+        final HashSet<String> expected = new HashSet<>();
+
+        // Should see all global ones from DO.
+        expected.addAll(Arrays.asList(DO_GLOBAL_RESTRICTIONS));
+
+        // Should also see all global ones from itself.
+        expected.addAll(Arrays.asList(ALLOWED));
+
+        assertRestrictions(expected);
+    }
+
+    /**
+     * This is called after DO setting all DO restrictions, and PO setting all PO restrictions,
+     * then DO clearing all restrictions.  Only PO restrictions should be set.
+     */
+    public void testLocalRestrictionsOnly() {
+        // Now should only see the ones that are set by this PO.
+        assertRestrictions(new HashSet<>(Arrays.asList(ALLOWED)));
+    }
+
+    /**
+     * Only the default restrictions should be set.
+     */
+    public void testDefaultRestrictionsOnly() {
+        final HashSet<String> expected = new HashSet<>(
+                // No restrictions.
+        );
+
+        assertRestrictions(expected);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceLoggingTest.java
new file mode 100644
index 0000000..642915f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceLoggingTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.deviceowner;
+
+import android.auditing.SecurityLog.SecurityEvent;
+import android.os.UserHandle;
+
+import java.util.List;
+
+public class DeviceLoggingTest extends BaseDeviceOwnerTest {
+
+    private static final String MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED =
+            "There should only be one user, managed by Device Owner";
+
+    /**
+     * Test: setting device logging can only be done if there's one user on the device.
+     */
+    public void testSetDeviceLoggingEnabledNotPossibleIfMoreThanOneUserPresent() {
+        try {
+            mDevicePolicyManager.setDeviceLoggingEnabled(getWho(), true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+        }
+    }
+
+    /**
+     * Test: retrieving device logs can only be done if there's one user on the device.
+     */
+    public void testRetrievingDeviceLogsNotPossibleIfMoreThanOneUserPresent() {
+        try {
+            mDevicePolicyManager.retrieveDeviceLogs(getWho());
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+        }
+    }
+
+    /**
+     * Test: retrieving previous device logs can only be done if there's one user on the device.
+     */
+    public void testRetrievingPreviousDeviceLogsNotPossibleIfMoreThanOneUserPresent() {
+        try {
+            mDevicePolicyManager.retrievePreviousDeviceLogs(getWho());
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+        }
+    }
+
+    /**
+     * Test: retrieving device logs should be rate limited - subsequent attempts should return null.
+     * TODO(mkarpinski): consider how we can test that the rate limiting is set to 2 hours.
+     */
+    public void testRetrievingDeviceLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval() {
+        List<SecurityEvent> logs = mDevicePolicyManager.retrieveDeviceLogs(getWho());
+        // if logs is null it means that that attempt was rate limited => test PASS
+        if (logs != null) {
+            assertNull(mDevicePolicyManager.retrieveDeviceLogs(getWho()));
+            assertNull(mDevicePolicyManager.retrieveDeviceLogs(getWho()));
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 450fbae..1114888 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -64,7 +64,13 @@
 
     private String mPackageVerifier;
     private HashSet<String> mAvailableFeatures;
+
+    /** Whether DPM is supported. */
     protected boolean mHasFeature;
+
+    /** Whether multi-user is supported. */
+    protected boolean mSupportsMultiUser;
+
     private ArrayList<Integer> mOriginalUsers;
 
     @Override
@@ -78,6 +84,8 @@
         assertNotNull(mCtsBuild);  // ensure build has been set before test is run.
         mHasFeature = getDevice().getApiLevel() >= 21 /* Build.VERSION_CODES.L */
                 && hasDeviceFeature("android.software.device_admin");
+        mSupportsMultiUser = getMaxNumberOfUsersSupported() > 1;
+
         // disable the package verifier to avoid the dialog when installing an app
         mPackageVerifier = getDevice().executeShellCommand(
                 "settings get global package_verifier_enable");
@@ -204,8 +212,11 @@
         stopUser(userId);
         String removeUserCommand = "pm remove-user " + userId;
         CLog.logAndDisplay(LogLevel.INFO, "starting command " + removeUserCommand);
+
+        String removeUserOutput = getDevice().executeShellCommand(removeUserCommand);
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + removeUserCommand + ": "
-                + getDevice().executeShellCommand(removeUserCommand));
+                + removeUserOutput);
+        assertTrue("Couldn't remove user", removeUserOutput.startsWith("Success:"));
     }
 
     protected void removeTestUsers() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 35c14d9..2d235f5 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -222,6 +222,29 @@
         assertEquals("Ephemeral flag must be set", FLAG_EPHEMERAL, flags & FLAG_EPHEMERAL);
     }
 
+    public void testDeviceLoggingWithTwoUsers() throws Exception {
+        if (!mHasFeature || getMaxNumberOfUsersSupported() < 2) {
+            return;
+        }
+        int userId = -1;
+        try {
+            userId = createUser();
+            executeDeviceTestMethod(".DeviceLoggingTest",
+                    "testSetDeviceLoggingEnabledNotPossibleIfMoreThanOneUserPresent");
+            executeDeviceTestMethod(".DeviceLoggingTest",
+                    "testRetrievingDeviceLogsNotPossibleIfMoreThanOneUserPresent");
+            executeDeviceTestMethod(".DeviceLoggingTest",
+                    "testRetrievingPreviousDeviceLogsNotPossibleIfMoreThanOneUserPresent");
+        } finally {
+            removeUser(userId);
+        }
+    }
+
+    public void testDeviceLoggingWithSingleUser() throws Exception {
+        executeDeviceTestMethod(".DeviceLoggingTest",
+                "testRetrievingDeviceLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval");
+    }
+
     public void testLockTask() throws Exception {
         try {
             installApp(INTENT_RECEIVER_APK);
@@ -273,7 +296,7 @@
 
     private void executeDeviceTestMethod(String className, String testName) throws Exception {
         assertTrue(runDeviceTestsAsUser(DEVICE_OWNER_PKG, className, testName,
-                /* deviceOwnerUserId */0));
+                /* deviceOwnerUserId */ 0));
     }
 
     private void executeDeviceOwnerTestAsUser(String testClassName, int userId) throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
new file mode 100644
index 0000000..beef986
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.devicepolicy;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public class UserRestrictionsTest extends BaseDevicePolicyTest {
+    private static final String DEVICE_ADMIN_PKG = "com.android.cts.deviceandprofileowner";
+    private static final String DEVICE_ADMIN_APK = "CtsDeviceAndProfileOwnerApp.apk";
+    private static final String ADMIN_RECEIVER_TEST_CLASS
+            = ".BaseDeviceAdminTest$BasicAdminReceiver";
+
+    private boolean mRemoveDeviceOwnerInTearDown;
+    private boolean mRemovePrimaryProfileOwnerInTearDown;
+    private int mDeviceOwnerUserId = USER_SYSTEM;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mRemoveDeviceOwnerInTearDown = false;
+        mRemovePrimaryProfileOwnerInTearDown = false;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            if (mRemoveDeviceOwnerInTearDown) {
+                assertTrue("Failed to clear device owner",
+                        runTests("ClearDeviceOwnerTest", mDeviceOwnerUserId));
+            }
+            if (mRemovePrimaryProfileOwnerInTearDown) {
+                assertTrue("Failed to clear profile owner",
+                        runTests("ClearProfileOwnerTest", mDeviceOwnerUserId));
+            }
+            assertTrue("Some user restrictions are still set",
+                    runTests("userrestrictions.CheckNoOwnerRestrictionsTest", mDeviceOwnerUserId));
+
+            // DO/PO might have set DISALLOW_REMOVE_USER, so it needs to be done after removing
+            // them.
+            removeTestUsers();
+        }
+        super.tearDown();
+    }
+
+    private boolean runTests(@Nonnull String className,
+            @Nullable String method, int userId) throws DeviceNotAvailableException {
+        return runDeviceTestsAsUser(DEVICE_ADMIN_PKG, "." + className, method, userId);
+    }
+
+    private boolean runTests(@Nonnull String className, int userId)
+            throws DeviceNotAvailableException {
+        return runTests(className, null, userId);
+    }
+
+    public void testUserRestrictions_deviceOwnerOnly() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installApp(DEVICE_ADMIN_APK);
+        assertTrue("Failed to set device owner",
+                setDeviceOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
+        mRemoveDeviceOwnerInTearDown = true;
+
+        runTests("userrestrictions.DeviceOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", mDeviceOwnerUserId);
+    }
+
+    public void testUserRestrictions_primaryProfileOwnerOnly() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        if (hasUserSplit()) {
+            // Can't set PO on user-0 in this mode.
+            return;
+        }
+
+        installApp(DEVICE_ADMIN_APK);
+        assertTrue("Failed to set profile owner",
+                setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        mDeviceOwnerUserId));
+        mRemovePrimaryProfileOwnerInTearDown = true;
+
+        runTests("userrestrictions.PrimaryProfileOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", mDeviceOwnerUserId);
+    }
+
+    public void testUserRestrictions_secondaryProfileOwnerOnly() throws Exception {
+        if (!mHasFeature || !mSupportsMultiUser) {
+            return;
+        }
+        final int secondaryUserId = createUser();
+
+        installAppAsUser(DEVICE_ADMIN_APK, secondaryUserId);
+        assertTrue("Failed to set profile owner",
+                setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        secondaryUserId));
+
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", secondaryUserId);
+    }
+
+    /**
+     * DO + PO combination.  Make sure global DO restrictions are visible on secondary users.
+     */
+    public void testUserRestrictions_layering() throws Exception {
+        if (!mHasFeature || !mSupportsMultiUser) {
+            return;
+        }
+        // Set DO
+        installApp(DEVICE_ADMIN_APK);
+        assertTrue("Failed to set device owner",
+                setDeviceOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
+        mRemoveDeviceOwnerInTearDown = true;
+
+        // Create another user and set PO.
+        final int secondaryUserId = createUser();
+
+        installAppAsUser(DEVICE_ADMIN_APK, secondaryUserId);
+        assertTrue("Failed to set profile owner",
+                setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        secondaryUserId));
+
+        // Let DO set all restrictions.
+        runTests("userrestrictions.DeviceOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", mDeviceOwnerUserId);
+
+        // Make sure the global restrictions are visible to secondary users.
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testHasGlobalRestrictions", secondaryUserId);
+
+        // Then let PO set all restrictions.
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", secondaryUserId);
+
+        // Make sure both local and global restrictions are visible on secondary users.
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testHasBothGlobalAndLocalRestrictions", secondaryUserId);
+
+        // Let DO clear all restrictions.
+        runTests("userrestrictions.DeviceOwnerUserRestrictionsTest",
+                "testClearAllRestrictions", mDeviceOwnerUserId);
+
+        // Now only PO restrictions should be set on the secondary user.
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testLocalRestrictionsOnly", secondaryUserId);
+    }
+
+    /**
+     * PO on user-0.  It can set DO restrictions too, but they shouldn't leak to other users.
+     */
+    public void testUserRestrictions_layering_profileOwnerNoLeaking() throws Exception {
+        if (!mHasFeature || !mSupportsMultiUser) {
+            return;
+        }
+        if (hasUserSplit()) {
+            // Can't set PO on user-0 in this mode.
+            return;
+        }
+        // Set DO on user 0
+        installApp(DEVICE_ADMIN_APK);
+        assertTrue("Failed to set device owner",
+                setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        mDeviceOwnerUserId));
+        mRemovePrimaryProfileOwnerInTearDown = true;
+
+        // Create another user and set PO.
+        final int secondaryUserId = createUser();
+
+        installAppAsUser(DEVICE_ADMIN_APK, secondaryUserId);
+        assertTrue("Failed to set profile owner",
+                setProfileOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                        secondaryUserId));
+
+        // Let user-0 PO sets all restrictions.
+        runTests("userrestrictions.PrimaryProfileOwnerUserRestrictionsTest",
+                "testSetAllRestrictions", mDeviceOwnerUserId);
+
+        // Secondary users shouldn't see any of them.
+        runTests("userrestrictions.SecondaryProfileOwnerUserRestrictionsTest",
+                "testDefaultRestrictionsOnly", secondaryUserId);
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/services/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
index 84bbd42..ed3cece 100755
--- a/hostsidetests/services/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
@@ -24,6 +24,11 @@
                 android:resizeable="true"
                 android:exported="true"
         />
+        <activity android:name=".DockedActivity"
+                android:resizeable="true"
+                android:exported="true"
+                android:taskAffinity="nobody.but.DockedActivity"
+        />
         <activity android:name=".NoRelaunchActivity"
                 android:resizeable="true"
                 android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java
index 97bc041..dbd92b5 100644
--- a/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/AutoEnterPipActivity.java
@@ -22,6 +22,6 @@
     @Override
     protected void onResume() {
         super.onResume();
-        enterPictureInPictureMode();
+        enterPictureInPicture();
     }
 }
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/DockedActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/DockedActivity.java
new file mode 100644
index 0000000..427fd29
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/DockedActivity.java
@@ -0,0 +1,22 @@
+/*
+ * 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.server.app;
+
+import android.app.Activity;
+
+public class DockedActivity extends Activity {
+}
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java
index b328a09..dba7cde 100644
--- a/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchPipOnPipActivity.java
@@ -20,8 +20,8 @@
 
 public class LaunchPipOnPipActivity extends Activity {
     @Override
-    public void onPictureInPictureModeChanged(boolean pictureInPictureMode) {
-        super.onPictureInPictureModeChanged(pictureInPictureMode);
+    public void onPictureInPictureChanged(boolean inPictureInPicture) {
+        super.onPictureInPictureChanged(inPictureInPicture);
         AlwaysFocusablePipActivity.launchAlwaysFocusablePipActivity(this);
     }
 }
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
index 731ff47..92be4b8 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
@@ -16,17 +16,23 @@
 
 package android.server.cts;
 
-import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
 
-import java.lang.Exception;
-import java.lang.String;
+import java.awt.Rectangle;
+
+import static com.android.ddmlib.Log.LogLevel.*;
 
 public class ActivityManagerDockedStackTests extends ActivityManagerTestBase {
 
     private static final String TEST_ACTIVITY_NAME = "TestActivity";
+    private static final String DOCKED_ACTIVITY_NAME = "DockedActivity";
     private static final String LAUNCH_TO_SIDE_ACTIVITY_NAME = "LaunchToSideActivity";
 
     private static final String AM_MOVE_TASK = "am stack movetask ";
+    private static final String AM_RESIZE_DOCKED_STACK = "am stack resize-docked-stack ";
+
+    private static final int TASK_SIZE = 600;
+    private static final int STACK_SIZE = 300;
 
     // TODO: Add test for non-resizeable activity.
 
@@ -140,6 +146,27 @@
         mDevice.executeShellCommand(cmd);
     }
 
+    public void testResizeDockedStack() throws Exception {
+        mDevice.executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
+        mDevice.executeShellCommand(getAmStartCmd(DOCKED_ACTIVITY_NAME));
+        mDevice.executeShellCommand(AM_MOVE_TASK + getActivityTaskId(DOCKED_ACTIVITY_NAME) + " "
+                + DOCKED_STACK_ID + " true");
+        mDevice.executeShellCommand(AM_RESIZE_DOCKED_STACK
+                + "0 0 " + STACK_SIZE + " " + STACK_SIZE
+                + " 0 0 " + TASK_SIZE + " " + TASK_SIZE);
+        mAmWmState.computeState(mDevice);
+        mAmWmState.assertSanity();
+        mAmWmState.assertContainsStack("Must contain docked stack", DOCKED_STACK_ID);
+        mAmWmState.assertContainsStack("Must contain fullscreen stack",
+                FULLSCREEN_WORKSPACE_STACK_ID);
+        assertEquals(new Rectangle(0, 0, STACK_SIZE, STACK_SIZE),
+                mAmWmState.getAmState().getStackById(DOCKED_STACK_ID).getBounds());
+        assertEquals(new Rectangle(0, 0, TASK_SIZE, TASK_SIZE),
+                mAmWmState.getAmState().getTaskByActivityName(DOCKED_ACTIVITY_NAME).getBounds());
+        mAmWmState.assertVisibility(DOCKED_ACTIVITY_NAME, true);
+        mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, true);
+    }
+
     private void launchActivityToSide(String activityName) throws Exception {
         mDevice.executeShellCommand(
                 getAmStartCmd(activityName) + " -f 0x20000000 --ez launch_to_the_side true");
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
index 785e487..88fcc97 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
@@ -77,11 +77,8 @@
         CLog.logAndDisplay(INFO, "==========After Docking========");
         final String newToken = getFocusedWindowToken(windowName, false);
 
-        if (relaunch) {
-            Assert.assertFalse("Window not replaced after relaunch.", oldToken.equals(newToken));
-        } else {
-            Assert.assertEquals("Window replaced without relaunch.", oldToken, newToken);
-        }
+        // For both relaunch and not relaunch case, we'd like the window to be kept.
+        Assert.assertEquals("Window replaced while docking.", oldToken, newToken);
     }
 
     private String getFocusedWindowToken(String windowName, boolean visibleOnly)
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
index 003d8e6..fcee898 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
@@ -174,6 +174,15 @@
         return false;
     }
 
+    ActivityStack getStackById(int stackId) {
+        for (ActivityStack stack : mStacks) {
+            if (stackId == stack.mStackId) {
+                return stack;
+            }
+        }
+        return null;
+    }
+
     List<ActivityStack> getStacks() {
         return new ArrayList(mStacks);
     }
@@ -195,6 +204,20 @@
         return false;
     }
 
+    ActivityTask getTaskByActivityName(String activityName) {
+        String fullName = ActivityManagerTestBase.getActivityComponentName(activityName);
+        for (ActivityStack stack : mStacks) {
+            for (ActivityTask task : stack.mTasks) {
+                for (Activity activity : task.mActivities) {
+                    if (activity.name.equals(fullName)) {
+                        return task;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
     static class ActivityStack extends ActivityContainer {
 
         private static final Pattern TASK_ID_PATTERN = Pattern.compile("Task id #(\\d+)");
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
index d0cd178..ceb2b63 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
@@ -187,7 +187,7 @@
                 "settings put system accelerometer_rotation " + rotation);
     }
 
-    private String runCommandAndPrintOutput(String command) throws DeviceNotAvailableException {
+    protected String runCommandAndPrintOutput(String command) throws DeviceNotAvailableException {
         final String output = mDevice.executeShellCommand(command);
         CLog.logAndDisplay(LogLevel.INFO, command);
         CLog.logAndDisplay(LogLevel.INFO, output);
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index fc9267a..17caccb 100644
--- a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -567,6 +567,58 @@
         }
     }
 
+    public void testSetDeviceLoggingEnabled_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testSetDeviceLoggingEnabled_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.setDeviceLoggingEnabled(mComponent, true);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testGetDeviceLoggingEnabled_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testGetDeviceLoggingEnabled_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.getDeviceLoggingEnabled(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testRetrieveDeviceLogs_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testRetrieveDeviceLogs_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.retrieveDeviceLogs(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
+    public void testRetrievePreviousDeviceLogs_failIfNotDeviceOwner() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testRetrievePreviousDeviceLogs_failIfNotDeviceOwner");
+            return;
+        }
+        try {
+            mDevicePolicyManager.retrievePreviousDeviceLogs(mComponent);
+            fail("did not throw expected SecurityException");
+        } catch (SecurityException e) {
+            assertDeviceOwnerMessage(e.getMessage());
+        }
+    }
+
     public void testCreateUser_failIfNotDeviceOwner() {
         if (!mDeviceAdmin) {
             Log.w(TAG, "Skipping testCreateUser_failIfNotDeviceOwner");
diff --git a/tests/app/src/android/app/cts/PipActivityTest.java b/tests/app/src/android/app/cts/PipActivityTest.java
index a553169..3f053cb 100644
--- a/tests/app/src/android/app/cts/PipActivityTest.java
+++ b/tests/app/src/android/app/cts/PipActivityTest.java
@@ -44,20 +44,20 @@
                 final boolean supportsPip =
                         mActivity.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
                 if (supportsPip) {
-                    mActivity.enterPictureInPictureMode();
-                    assertTrue(mActivity.inMultiWindowMode());
-                    assertTrue(mActivity.inPictureInPictureMode());
+                    mActivity.enterPictureInPicture();
+                    assertTrue(mActivity.inMultiWindow());
+                    assertTrue(mActivity.inPictureInPicture());
                 } else {
                     boolean pipSupportDisabled = false;
                     try {
-                        mActivity.enterPictureInPictureMode();
+                        mActivity.enterPictureInPicture();
                     } catch (IllegalStateException e) {
                         // Pip not supported
                         pipSupportDisabled = true;
                     }
                     assertTrue(pipSupportDisabled);
-                    assertFalse(mActivity.inMultiWindowMode());
-                    assertFalse(mActivity.inPictureInPictureMode());
+                    assertFalse(mActivity.inMultiWindow());
+                    assertFalse(mActivity.inPictureInPicture());
                 }
             }
         });
diff --git a/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java b/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
index 4f7f63e..e2908cd 100644
--- a/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
+++ b/tests/app/src/android/app/cts/PipNotResizeableActivityTest.java
@@ -42,7 +42,7 @@
                 public void run() {
                     boolean pipSupportDisabled = false;
                     try {
-                        mActivity.enterPictureInPictureMode();
+                        mActivity.enterPictureInPicture();
                     } catch (IllegalStateException e) {
                         // Pip not supported
                         pipSupportDisabled = true;
@@ -51,8 +51,8 @@
                         pipSupportDisabled = true;
                     }
                     assertTrue(pipSupportDisabled);
-                    assertFalse(mActivity.inMultiWindowMode());
-                    assertFalse(mActivity.inPictureInPictureMode());
+                    assertFalse(mActivity.inMultiWindow());
+                    assertFalse(mActivity.inPictureInPicture());
                 }
             });
             mInstrumentation.waitForIdleSync();
diff --git a/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java b/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
index 245421a..c9ce69c 100644
--- a/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
+++ b/tests/app/src/android/app/cts/PipNotSupportedActivityTest.java
@@ -42,7 +42,7 @@
             public void run() {
                 boolean pipSupportDisabled = false;
                 try {
-                    mActivity.enterPictureInPictureMode();
+                    mActivity.enterPictureInPicture();
                 } catch (IllegalStateException e) {
                     // Pip not supported
                     pipSupportDisabled = true;
@@ -51,8 +51,8 @@
                     pipSupportDisabled = true;
                 }
                 assertTrue(pipSupportDisabled);
-                assertFalse(mActivity.inMultiWindowMode());
-                assertFalse(mActivity.inPictureInPictureMode());
+                assertFalse(mActivity.inMultiWindow());
+                assertFalse(mActivity.inPictureInPicture());
             }
         });
         mInstrumentation.waitForIdleSync();
diff --git a/tests/camera/Android.mk b/tests/camera/Android.mk
index 62cdf25..4d653a6 100644
--- a/tests/camera/Android.mk
+++ b/tests/camera/Android.mk
@@ -20,6 +20,9 @@
 
 LOCAL_MODULE_TAGS := tests
 
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil \
 	ctstestrunner \
 	mockito-target \
diff --git a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
index 3826afd..4259882 100644
--- a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -261,6 +261,7 @@
                 }
 
                 ExifInterface exifInterface = new ExifInterface(filePath);
+                // Verify GPS data.
                 float[] latLong = new float[2];
                 assertTrue(exifInterface.getLatLong(latLong));
                 assertEquals(GPS_LATITUDE, latLong[0], GPS_DIFFERENCE_TOLERANCE);
@@ -270,6 +271,11 @@
                 assertEquals(GPS_TIMESTAMP,
                         exifInterface.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP));
 
+                // Verify the orientation.
+                assertEquals(ExifInterface.ORIENTATION_FLIP_VERTICAL,
+                        exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
+                                ExifInterface.ORIENTATION_UNDEFINED));
+
                 if (!VERBOSE) {
                     // Delete the captured DNG file.
                     File dngFile = new File(filePath);
diff --git a/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg b/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg
new file mode 100644
index 0000000..477cd3a
--- /dev/null
+++ b/tests/tests/media/res/raw/image_exif_byte_order_ii.jpg
Binary files differ
diff --git a/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg b/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg
new file mode 100644
index 0000000..78ac703
--- /dev/null
+++ b/tests/tests/media/res/raw/image_exif_byte_order_mm.jpg
Binary files differ
diff --git a/tests/tests/media/res/raw/lg_g4_iso_800.dng b/tests/tests/media/res/raw/lg_g4_iso_800.dng
new file mode 100644
index 0000000..5fcc720
--- /dev/null
+++ b/tests/tests/media/res/raw/lg_g4_iso_800.dng
Binary files differ
diff --git a/tests/tests/media/res/raw/okgoogle123_good.wav b/tests/tests/media/res/raw/okgoogle123_good.wav
new file mode 100644
index 0000000..ffd5a7f
--- /dev/null
+++ b/tests/tests/media/res/raw/okgoogle123_good.wav
Binary files differ
diff --git a/tests/tests/media/res/values/exifinterface.xml b/tests/tests/media/res/values/exifinterface.xml
new file mode 100644
index 0000000..8fc6adc
--- /dev/null
+++ b/tests/tests/media/res/values/exifinterface.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <array name="exifbyteorderii_jpg">
+        <item>true</item>
+        <item>512</item>
+        <item>288</item>
+        <item>false</item>
+        <item>0.0</item>
+        <item>0.0</item>
+        <item>0.0</item>
+        <item>SAMSUNG</item>
+        <item>SM-N900S</item>
+        <item>2.200</item>
+        <item>2016:01:29 18:32:27</item>
+        <item>0.033</item>
+        <item>0</item>
+        <item>413/100</item>
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item />
+        <item>480</item>
+        <item>640</item>
+        <item>50</item>
+        <item>6</item>
+        <item>0</item>
+    </array>
+    <array name="exifbyteordermm_jpg">
+        <item>false</item>
+        <item>0</item>
+        <item>0</item>
+        <item>true</item>
+        <item>0.0</item>
+        <item>0.0</item>
+        <item>0.0</item>
+        <item>LGE</item>
+        <item>Nexus 5</item>
+        <item>2.400</item>
+        <item>2016:01:29 15:44:58</item>
+        <item>0.017</item>
+        <item>0</item>
+        <item>3970/1000</item>
+        <item>0/1000</item>
+        <item>0</item>
+        <item>1970:01:01</item>
+        <item>0/1,0/1,0/10000</item>
+        <item>N</item>
+        <item>0/1,0/1,0/10000</item>
+        <item>E</item>
+        <item>GPS</item>
+        <item>00:00:00</item>
+        <item>176</item>
+        <item>144</item>
+        <item>146</item>
+        <item>0</item>
+        <item>0</item>
+    </array>
+    <array name="lg_g4_iso_800_dng">
+        <item>false</item>
+        <item>0</item>
+        <item>0</item>
+        <item>true</item>
+        <item>53.834507</item>
+        <item>10.69585</item>
+        <item>0.0</item>
+        <item>LGE</item>
+        <item>LG-H815</item>
+        <item>1.800</item>
+        <item>2015:11:12 16:46:18</item>
+        <item>0.0040</item>
+        <item>0.0</item>
+        <item>442/100</item>
+        <item>0/1</item>
+        <item>0</item>
+        <item>1970:01:17</item>
+        <item>53/1,50/1,423/100</item>
+        <item>N</item>
+        <item>10/1,41/1,4506/100</item>
+        <item>E</item>
+        <item />
+        <item>18:08:10</item>
+        <item>337</item>
+        <item>600</item>
+        <item>800</item>
+        <item>1</item>
+        <item />
+    </array>
+</resources>
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index c8cea22..50ea672 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -23,9 +23,12 @@
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecList;
 import android.media.MediaFormat;
+import android.media.MediaMuxer;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import java.io.File;
+import java.io.InputStream;
 import java.nio.BufferOverflowException;
 import java.nio.ByteBuffer;
 import java.util.LinkedList;
@@ -42,6 +45,20 @@
     private static final int kNumInputBytes = 512 * 1024;
     private static final long kTimeoutUs = 100;
 
+    // not all combinations are valid
+    private static final int MODE_SILENT = 0;
+    private static final int MODE_RANDOM = 1;
+    private static final int MODE_RESOURCE = 2;
+    private static final int MODE_QUIET = 4;
+    private static final int MODE_SILENTLEAD = 8;
+
+    /*
+     * Set this to true to save the encoding results to /data/local/tmp
+     * You will need to make /data/local/tmp writeable, run "setenforce 0",
+     * and remove files left from a previous run.
+     */
+    private static boolean sSaveResults = false;
+
     @Override
     public void setContext(Context context) {
         super.setContext(context);
@@ -172,13 +189,26 @@
 
     private int queueInputBuffer(
             MediaCodec codec, ByteBuffer[] inputBuffers, int index,
-            boolean random, boolean zeroLead) {
+            InputStream istream, int mode) {
         ByteBuffer buffer = inputBuffers[index];
         buffer.rewind();
         int size = buffer.limit();
 
-        if (random) {
-            if (zeroLead) {
+        if ((mode & MODE_RESOURCE) != 0 && istream != null) {
+            while (buffer.hasRemaining()) {
+                try {
+                    int next = istream.read();
+                    if (next < 0) {
+                        break;
+                    }
+                    buffer.put((byte) next);
+                } catch (Exception ex) {
+                    Log.i(TAG, "caught exception writing: " + ex);
+                    break;
+                }
+            }
+        } else if ((mode & MODE_RANDOM) != 0) {
+            if ((mode & MODE_SILENTLEAD) != 0) {
                 buffer.putInt(0);
                 buffer.putInt(0);
                 buffer.putInt(0);
@@ -186,6 +216,7 @@
             }
             while (true) {
                 try {
+                    int next = mRandom.nextInt();
                     buffer.putInt(mRandom.nextInt());
                 } catch (BufferOverflowException ex) {
                     break;
@@ -196,6 +227,15 @@
             buffer.put(zeroes);
         }
 
+        if ((mode & MODE_QUIET) != 0) {
+            int n = buffer.limit();
+            for (int i = 0; i < n; i += 2) {
+                short s = buffer.getShort(i);
+                s /= 8;
+                buffer.putShort(i, s);
+            }
+        }
+
         codec.queueInputBuffer(index, 0 /* offset */, size, 0 /* timeUs */, 0);
 
         return size;
@@ -224,17 +264,47 @@
     private void testEncoder(String componentName, MediaFormat format) {
         Log.i(TAG, "testEncoder " + componentName + "/" + format);
         // test with all zeroes/silence
-        testEncoder(componentName, format, false, 0, false);
+        testEncoder(componentName, format, 0, -1, MODE_SILENT);
+
+        // test with pcm input file
+        testEncoder(componentName, format, 0, R.raw.okgoogle123_good, MODE_RESOURCE);
+        testEncoder(componentName, format, 0, R.raw.okgoogle123_good, MODE_RESOURCE | MODE_QUIET);
 
         // test with random data, with and without a few leading zeroes
         for (int i = 0; i < mBadSeeds.length; i++) {
-            testEncoder(componentName, format, true, mBadSeeds[i], false);
-            testEncoder(componentName, format, true, mBadSeeds[i], true);
+            testEncoder(componentName, format, mBadSeeds[i], -1, MODE_RANDOM);
+            testEncoder(componentName, format, mBadSeeds[i], -1, MODE_RANDOM | MODE_SILENTLEAD);
         }
     }
 
-    private void testEncoder(String componentName, MediaFormat format, boolean random,
-            long startSeed, boolean zeroLead) {
+    private void testEncoder(String componentName, MediaFormat format,
+            long startSeed, int resid, int mode) {
+
+        int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+        int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+        int inBitrate = sampleRate * channelCount * 16;  // bit/sec
+        int outBitrate = format.getInteger(MediaFormat.KEY_BIT_RATE);
+
+        MediaMuxer muxer = null;
+        int muxidx = -1;
+        if (sSaveResults) {
+            try {
+                String outFile = "/data/local/tmp/transcoded-" + componentName + "-" + outBitrate +
+                        "-" + mode + "-" + startSeed + ".mp4";
+                new File("outFile").delete();
+                muxer = new MediaMuxer(outFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
+                muxidx = muxer.addTrack(format);
+                muxer.start();
+            } catch (Exception e) {
+                Log.i(TAG, "couldn't create muxer: " + e);
+            }
+        }
+
+        InputStream istream = null;
+        if ((mode & MODE_RESOURCE) != 0) {
+            istream = mContext.getResources().openRawResource(resid);
+        }
+
         mRandom.setSeed(startSeed);
         MediaCodec codec;
         try {
@@ -283,7 +353,7 @@
                         doneSubmittingInput = true;
                     } else {
                         int size = queueInputBuffer(
-                                codec, codecInputBuffers, index, random, zeroLead);
+                                codec, codecInputBuffers, index, istream, mode);
 
                         numBytesSubmitted += size;
 
@@ -302,6 +372,10 @@
             } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                 codecOutputBuffers = codec.getOutputBuffers();
             } else {
+                if (muxer != null) {
+                    muxer.writeSampleData(muxidx, codec.getOutputBuffer(index), info);
+                }
+
                 dequeueOutputBuffer(codec, codecOutputBuffers, index, info);
 
                 numBytesDequeued += info.size;
@@ -324,11 +398,6 @@
                     + "dequeued " + numBytesDequeued + " bytes.");
         }
 
-        int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
-        int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
-        int inBitrate = sampleRate * channelCount * 16;  // bit/sec
-        int outBitrate = format.getInteger(MediaFormat.KEY_BIT_RATE);
-
         float desiredRatio = (float)outBitrate / (float)inBitrate;
         float actualRatio = (float)numBytesDequeued / (float)numBytesSubmitted;
 
@@ -339,6 +408,11 @@
 
         codec.release();
         codec = null;
+        if (muxer != null) {
+            muxer.stop();
+            muxer.release();
+            muxer = null;
+        }
     }
 }
 
diff --git a/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
new file mode 100644
index 0000000..a51dd3d
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2016 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.media.cts;
+
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.ExifInterface;
+import android.os.Environment;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+public class ExifInterfaceTest extends AndroidTestCase {
+    private static final String TAG = ExifInterface.class.getSimpleName();
+    private static final boolean VERBOSE = false;  // lots of logging
+
+    private static final double DIFFERENCE_TOLERANCE = .0001;
+    private static final int BUFFER_SIZE = 32768;
+
+    // List of files.
+    private static final String EXIF_BYTE_ORDER_II_JPEG = "ExifByteOrderII.jpg";
+    private static final String EXIF_BYTE_ORDER_MM_JPEG = "ExifByteOrderMM.jpg";
+    private static final String LG_G4_ISO_800_DNG = "lg_g4_iso_800.dng";
+    private static final int[] IMAGE_RESOURCES = new int[] {
+            R.raw.image_exif_byte_order_ii,  R.raw.image_exif_byte_order_mm, R.raw.lg_g4_iso_800 };
+    private static final String[] IMAGE_FILENAMES = new String[] {
+            EXIF_BYTE_ORDER_II_JPEG, EXIF_BYTE_ORDER_MM_JPEG, LG_G4_ISO_800_DNG };
+
+    private static final String[] EXIF_TAGS = {
+            ExifInterface.TAG_MAKE,
+            ExifInterface.TAG_MODEL,
+            ExifInterface.TAG_APERTURE,
+            ExifInterface.TAG_DATETIME,
+            ExifInterface.TAG_EXPOSURE_TIME,
+            ExifInterface.TAG_FLASH,
+            ExifInterface.TAG_FOCAL_LENGTH,
+            ExifInterface.TAG_GPS_ALTITUDE,
+            ExifInterface.TAG_GPS_ALTITUDE_REF,
+            ExifInterface.TAG_GPS_DATESTAMP,
+            ExifInterface.TAG_GPS_LATITUDE,
+            ExifInterface.TAG_GPS_LATITUDE_REF,
+            ExifInterface.TAG_GPS_LONGITUDE,
+            ExifInterface.TAG_GPS_LONGITUDE_REF,
+            ExifInterface.TAG_GPS_PROCESSING_METHOD,
+            ExifInterface.TAG_GPS_TIMESTAMP,
+            ExifInterface.TAG_IMAGE_LENGTH,
+            ExifInterface.TAG_IMAGE_WIDTH,
+            ExifInterface.TAG_ISO,
+            ExifInterface.TAG_ORIENTATION,
+            ExifInterface.TAG_WHITE_BALANCE
+    };
+
+    private static class ExpectedValue {
+        // Thumbnail information.
+        public final boolean hasThumbnail;
+        public final int thumbnailWidth;
+        public final int thumbnailHeight;
+
+        // GPS information.
+        public final boolean hasLatLong;
+        public final float latitude;
+        public final float longitude;
+        public final float altitude;
+
+        // Values.
+        public final String make;
+        public final String model;
+        public final float aperture;
+        public final String datetime;
+        public final float exposureTime;
+        public final float flash;
+        public final String focalLength;
+        public final String gpsAltitude;
+        public final String gpsAltitudeRef;
+        public final String gpsDatestamp;
+        public final String gpsLatitude;
+        public final String gpsLatitudeRef;
+        public final String gpsLongitude;
+        public final String gpsLongitudeRef;
+        public final String gpsProcessingMethod;
+        public final String gpsTimestamp;
+        public final String imageLength;
+        public final String imageWidth;
+        public final String iso;
+        public final String whiteBalance;
+        public final String orientation;
+
+        private static String getString(TypedArray typedArray, int index) {
+            String stringValue = typedArray.getString(index);
+            if (stringValue == null || stringValue.equals("")) {
+                return null;
+            }
+            return stringValue.trim();
+        }
+
+        public ExpectedValue(TypedArray typedArray) {
+            // Reads thumbnail information.
+            hasThumbnail = typedArray.getBoolean(0, false);
+            thumbnailWidth = typedArray.getInt(1, 0);
+            thumbnailHeight = typedArray.getInt(2, 0);
+
+            // Reads GPS information.
+            hasLatLong = typedArray.getBoolean(3, false);
+            latitude = typedArray.getFloat(4, 0f);
+            longitude = typedArray.getFloat(5, 0f);
+            altitude = typedArray.getFloat(6, 0f);
+
+            // Read values.
+            make = getString(typedArray, 7);
+            model = getString(typedArray, 8);
+            aperture = typedArray.getFloat(9, 0f);
+            datetime = getString(typedArray, 10);
+            exposureTime = typedArray.getFloat(11, 0f);
+            flash = typedArray.getFloat(12, 0f);
+            focalLength = getString(typedArray, 13);
+            gpsAltitude = getString(typedArray, 14);
+            gpsAltitudeRef = getString(typedArray, 15);
+            gpsDatestamp = getString(typedArray, 16);
+            gpsLatitude = getString(typedArray, 17);
+            gpsLatitudeRef = getString(typedArray, 18);
+            gpsLongitude = getString(typedArray, 19);
+            gpsLongitudeRef = getString(typedArray, 20);
+            gpsProcessingMethod = getString(typedArray, 21);
+            gpsTimestamp = getString(typedArray, 22);
+            imageLength = getString(typedArray, 23);
+            imageWidth = getString(typedArray, 24);
+            iso = getString(typedArray, 25);
+            orientation = getString(typedArray, 26);
+            whiteBalance = getString(typedArray, 27);
+
+            typedArray.recycle();
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        byte[] buffer = new byte[BUFFER_SIZE];
+
+        for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+            String outputPath = new File(Environment.getExternalStorageDirectory(),
+                    IMAGE_FILENAMES[i]).getAbsolutePath();
+            try (InputStream inputStream = getContext().getResources().openRawResource(
+                    IMAGE_RESOURCES[i])) {
+                try (FileOutputStream outputStream = new FileOutputStream(outputPath)) {
+                    int amount;
+                    while ((amount = inputStream.read(buffer)) > 0) {
+                        outputStream.write(buffer, 0, amount);
+                    }
+                }
+            }
+        }
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+            String imageFilePath = new File(Environment.getExternalStorageDirectory(),
+                    IMAGE_FILENAMES[i]).getAbsolutePath();
+            File imageFile = new File(imageFilePath);
+            if (imageFile.exists()) {
+                imageFile.delete();
+            }
+        }
+
+        super.tearDown();
+    }
+
+    private void printExifTagsAndValues(String fileName, ExifInterface exifInterface) {
+        // Prints thumbnail information.
+        if (exifInterface.hasThumbnail()) {
+            byte[] thumbnailBytes = exifInterface.getThumbnail();
+            if (thumbnailBytes != null) {
+                Log.v(TAG, fileName + " Thumbnail size = " + thumbnailBytes.length);
+                Bitmap bitmap = BitmapFactory.decodeByteArray(
+                        thumbnailBytes, 0, thumbnailBytes.length);
+                if (bitmap == null) {
+                    Log.e(TAG, fileName + " Corrupted thumbnail!");
+                } else {
+                    Log.v(TAG, fileName + " Thumbnail size: " + bitmap.getWidth() + ", "
+                            + bitmap.getHeight());
+                }
+            } else {
+                Log.e(TAG, fileName + " Corrupted image (no thumbnail)");
+            }
+        } else {
+            if (exifInterface.getThumbnail() != null) {
+                Log.e(TAG, fileName + " Corrupted image (a thumbnail exists)");
+            } else {
+                Log.v(TAG, fileName + " No thumbnail");
+            }
+        }
+
+        // Prints GPS information.
+        Log.v(TAG, fileName + " Altitude = " + exifInterface.getAltitude(.0));
+
+        float[] latLong = new float[2];
+        if (exifInterface.getLatLong(latLong)) {
+            Log.v(TAG, fileName + " Latitude = " + latLong[0]);
+            Log.v(TAG, fileName + " Longitude = " + latLong[1]);
+        } else {
+            Log.v(TAG, fileName + "No latlong data");
+        }
+
+        // Prints values.
+        for (String tagKey : EXIF_TAGS) {
+            String tagValue = exifInterface.getAttribute(tagKey);
+            Log.v(TAG, fileName + "Key{" + tagKey + "} = '" + tagValue + "'");
+        }
+    }
+
+    private void compareFloatTag(ExifInterface exifInterface, String tag, float expectedValue) {
+        String stringValue = exifInterface.getAttribute(tag);
+        float floatValue = 0f;
+
+        if (stringValue != null) {
+            floatValue = Float.parseFloat(stringValue);
+        }
+
+        assertEquals(expectedValue, floatValue, DIFFERENCE_TOLERANCE);
+    }
+
+    private void compareStringTag(ExifInterface exifInterface, String tag, String expectedValue) {
+        String stringValue = exifInterface.getAttribute(tag);
+        if (stringValue != null) {
+            stringValue = stringValue.trim();
+        }
+
+        assertEquals(expectedValue, stringValue);
+    }
+
+    private void compareWithExpectedValue(ExifInterface exifInterface,
+            ExpectedValue expectedValue) {
+        // Checks a thumbnail image.
+        assertEquals(expectedValue.hasThumbnail, exifInterface.hasThumbnail());
+        if (expectedValue.hasThumbnail) {
+            byte[] thumbnailBytes = exifInterface.getThumbnail();
+            assertNotNull(thumbnailBytes);
+            Bitmap thumbnailBitmap =
+                    BitmapFactory.decodeByteArray(thumbnailBytes, 0, thumbnailBytes.length);
+            assertNotNull(thumbnailBitmap);
+            assertEquals(expectedValue.thumbnailWidth, thumbnailBitmap.getWidth());
+            assertEquals(expectedValue.thumbnailHeight, thumbnailBitmap.getHeight());
+        } else {
+            assertNull(exifInterface.getThumbnail());
+        }
+
+        // Checks GPS information.
+        float[] latLong = new float[2];
+        assertEquals(expectedValue.hasLatLong, exifInterface.getLatLong(latLong));
+        if (expectedValue.hasLatLong) {
+            assertEquals(expectedValue.latitude, latLong[0], DIFFERENCE_TOLERANCE);
+            assertEquals(expectedValue.longitude, latLong[1], DIFFERENCE_TOLERANCE);
+        }
+        assertEquals(expectedValue.altitude, exifInterface.getAltitude(.0), DIFFERENCE_TOLERANCE);
+
+        // Checks values.
+        compareStringTag(exifInterface, ExifInterface.TAG_MAKE, expectedValue.make);
+        compareStringTag(exifInterface, ExifInterface.TAG_MODEL, expectedValue.model);
+        compareFloatTag(exifInterface, ExifInterface.TAG_APERTURE, expectedValue.aperture);
+        compareStringTag(exifInterface, ExifInterface.TAG_DATETIME, expectedValue.datetime);
+        compareFloatTag(exifInterface, ExifInterface.TAG_EXPOSURE_TIME, expectedValue.exposureTime);
+        compareFloatTag(exifInterface, ExifInterface.TAG_FLASH, expectedValue.flash);
+        compareStringTag(exifInterface, ExifInterface.TAG_FOCAL_LENGTH, expectedValue.focalLength);
+        compareStringTag(exifInterface, ExifInterface.TAG_GPS_ALTITUDE, expectedValue.gpsAltitude);
+        compareStringTag(exifInterface, ExifInterface.TAG_GPS_ALTITUDE_REF,
+                expectedValue.gpsAltitudeRef);
+        compareStringTag(exifInterface, ExifInterface.TAG_GPS_DATESTAMP,
+                expectedValue.gpsDatestamp);
+        compareStringTag(exifInterface, ExifInterface.TAG_GPS_LATITUDE, expectedValue.gpsLatitude);
+        compareStringTag(exifInterface, ExifInterface.TAG_GPS_LATITUDE_REF,
+                expectedValue.gpsLatitudeRef);
+        compareStringTag(exifInterface, ExifInterface.TAG_GPS_LONGITUDE,
+                expectedValue.gpsLongitude);
+        compareStringTag(exifInterface, ExifInterface.TAG_GPS_LONGITUDE_REF,
+                expectedValue.gpsLongitudeRef);
+        compareStringTag(exifInterface, ExifInterface.TAG_GPS_PROCESSING_METHOD,
+                expectedValue.gpsProcessingMethod);
+        compareStringTag(exifInterface, ExifInterface.TAG_GPS_TIMESTAMP,
+                expectedValue.gpsTimestamp);
+        compareStringTag(exifInterface, ExifInterface.TAG_IMAGE_LENGTH, expectedValue.imageLength);
+        compareStringTag(exifInterface, ExifInterface.TAG_IMAGE_WIDTH, expectedValue.imageWidth);
+        compareStringTag(exifInterface, ExifInterface.TAG_ISO, expectedValue.iso);
+        compareStringTag(exifInterface, ExifInterface.TAG_ORIENTATION, expectedValue.orientation);
+        compareStringTag(exifInterface, ExifInterface.TAG_WHITE_BALANCE,
+                expectedValue.whiteBalance);
+    }
+
+    private void testExifInterface(String fileName, int typedArrayResourceId) throws IOException {
+        ExifInterface exifInterface = new ExifInterface(new File(Environment
+                .getExternalStorageDirectory(), fileName).getAbsolutePath());
+
+        assertNotNull(exifInterface);
+        if (VERBOSE) {
+            printExifTagsAndValues(fileName, exifInterface);
+        }
+
+        compareWithExpectedValue(exifInterface, new ExpectedValue(
+                getContext().getResources().obtainTypedArray(typedArrayResourceId)));
+    }
+
+    public void testReadExifDataFromExifByteOrderIIJpeg() throws Throwable {
+        testExifInterface(EXIF_BYTE_ORDER_II_JPEG, R.array.exifbyteorderii_jpg);
+    }
+
+    public void testReadExifDataFromExifByteOrderMMJpeg() throws Throwable {
+        testExifInterface(EXIF_BYTE_ORDER_MM_JPEG, R.array.exifbyteordermm_jpg);
+    }
+
+    public void testReadExifDataFromLgG4Iso800Dng() throws Throwable {
+        testExifInterface(LG_G4_ISO_800_DNG, R.array.lg_g4_iso_800_dng);
+    }
+}
diff --git a/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java b/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
index 93e6cf9..80aa68e 100644
--- a/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
@@ -25,7 +25,7 @@
 
 public class LocaleSpanTest extends TestCase {
 
-    public void testGetLocalesMain(@NonNull final LocaleList locales) {
+    private void checkGetLocales(@NonNull final LocaleList locales) {
         final LocaleSpan span = new LocaleSpan(locales);
         assertEquals(locales.getPrimary(), span.getLocale());
         assertEquals(locales, span.getLocales());
@@ -36,10 +36,10 @@
     }
 
     public void testGetLocales() {
-        testGetLocalesMain(LocaleList.getEmptyLocaleList());
-        testGetLocalesMain(LocaleList.forLanguageTags("en"));
-        testGetLocalesMain(LocaleList.forLanguageTags("en-GB,en"));
-        testGetLocalesMain(LocaleList.forLanguageTags("de-DE-u-co-phonebk,en-GB,en"));
+        checkGetLocales(LocaleList.getEmptyLocaleList());
+        checkGetLocales(LocaleList.forLanguageTags("en"));
+        checkGetLocales(LocaleList.forLanguageTags("en-GB,en"));
+        checkGetLocales(LocaleList.forLanguageTags("de-DE-u-co-phonebk,en-GB,en"));
     }
 
     public void testConstructorWithLocaleList() {
diff --git a/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java b/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java
index ec51216..ff5167c 100644
--- a/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/SuggestionSpanTest.java
@@ -48,7 +48,7 @@
         return original.toString();
     }
 
-    public void testGetLocaleObjectMain(final Locale locale) {
+    private void checkGetLocaleObject(final Locale locale) {
         final SuggestionSpan span = new SuggestionSpan(locale, new String[0],
                 SuggestionSpan.FLAG_AUTO_CORRECTION);
         // In the context of SuggestionSpan#getLocaleObject(), we do care only about subtags that
@@ -63,16 +63,16 @@
     }
 
     public void testGetLocaleObject() {
-        testGetLocaleObjectMain(Locale.forLanguageTag("en"));
-        testGetLocaleObjectMain(Locale.forLanguageTag("en-GB"));
-        testGetLocaleObjectMain(Locale.forLanguageTag("EN-GB"));
-        testGetLocaleObjectMain(Locale.forLanguageTag("en-gb"));
-        testGetLocaleObjectMain(Locale.forLanguageTag("En-gB"));
-        testGetLocaleObjectMain(Locale.forLanguageTag("und"));
-        testGetLocaleObjectMain(Locale.forLanguageTag("de-DE-u-co-phonebk"));
-        testGetLocaleObjectMain(Locale.forLanguageTag(""));
-        testGetLocaleObjectMain(null);
-        testGetLocaleObjectMain(new Locale(" an  ", " i n v a l i d ", "data"));
+        checkGetLocaleObject(Locale.forLanguageTag("en"));
+        checkGetLocaleObject(Locale.forLanguageTag("en-GB"));
+        checkGetLocaleObject(Locale.forLanguageTag("EN-GB"));
+        checkGetLocaleObject(Locale.forLanguageTag("en-gb"));
+        checkGetLocaleObject(Locale.forLanguageTag("En-gB"));
+        checkGetLocaleObject(Locale.forLanguageTag("und"));
+        checkGetLocaleObject(Locale.forLanguageTag("de-DE-u-co-phonebk"));
+        checkGetLocaleObject(Locale.forLanguageTag(""));
+        checkGetLocaleObject(null);
+        checkGetLocaleObject(new Locale(" an  ", " i n v a l i d ", "data"));
     }
 
     @NonNull
diff --git a/tests/tests/view/src/android/view/cts/WindowTest.java b/tests/tests/view/src/android/view/cts/WindowTest.java
index a897af4..0e67c3e 100644
--- a/tests/tests/view/src/android/view/cts/WindowTest.java
+++ b/tests/tests/view/src/android/view/cts/WindowTest.java
@@ -1046,7 +1046,7 @@
         }
 
         @Override
-        public void onMultiWindowModeChanged() {
+        public void onMultiWindowChanged() {
         }
 
         @Override