Merge "More lenient on playback start" into nyc-dev
diff --git a/OldCtsTestCaseList.mk b/OldCtsTestCaseList.mk
index ad572e1..185059e 100644
--- a/OldCtsTestCaseList.mk
+++ b/OldCtsTestCaseList.mk
@@ -48,6 +48,7 @@
     CtsSplitAppFeature \
     CtsTargetInstrumentationApp \
     CtsUsePermissionDiffCert \
+    CtsUsesLibraryApp \
     CtsWriteExternalStorageApp \
     CtsMultiUserStorageApp
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java
index 879916b..62e1701 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java
@@ -46,78 +46,78 @@
                     new Intent(this, ProtocolParamsReaderActivity.class), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_single_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_single_payment_reader),
                     SinglePaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_dual_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_dual_payment_reader),
                     DualPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_change_default_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_change_default_reader),
                     ChangeDefaultEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_foreground_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_foreground_payment_reader),
                     ForegroundPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_single_non_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_single_non_payment_reader),
                     SingleNonPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_dual_non_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_dual_non_payment_reader),
                     DualNonPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_conflicting_non_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_conflicting_non_payment_reader),
                     ConflictingNonPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_foreground_non_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_foreground_non_payment_reader),
                     ForegroundNonPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_throughput_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_throughput_reader),
                     ThroughputEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_tap_test_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_tap_test_reader),
                     TapTestEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_offhost_service_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_offhost_service_reader),
                     OffHostEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_on_and_offhost_service_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_on_and_offhost_service_reader),
                     OnAndOffHostEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_payment_dynamic_aids_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_payment_dynamic_aids_reader),
                     DynamicAidEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_large_num_aids_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_large_num_aids_reader),
                     LargeNumAidsEmulatorActivity.buildReaderIntent(this), null));
 
             NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
             CardEmulation cardEmulation = CardEmulation.getInstance(nfcAdapter);
             if (cardEmulation.supportsAidPrefixRegistration()) {
                 adapter.add(TestListItem.newTest(this, R.string.nfc_hce_payment_prefix_aids_reader,
-                        SimpleReaderActivity.class.getName(),
+                        getString(R.string.nfc_hce_payment_prefix_aids_reader),
                         PrefixPaymentEmulatorActivity.buildReaderIntent(this), null));
 
                 adapter.add(TestListItem.newTest(this, R.string.nfc_hce_payment_prefix_aids_reader_2,
-                        SimpleReaderActivity.class.getName(),
+                        getString(R.string.nfc_hce_payment_prefix_aids_reader_2),
                         PrefixPaymentEmulator2Activity.buildReaderIntent(this), null));
 
                 adapter.add(TestListItem.newTest(this, R.string.nfc_hce_other_prefix_aids_reader,
-                        SimpleReaderActivity.class.getName(),
+                        getString(R.string.nfc_hce_other_prefix_aids_reader),
                         DualNonPaymentPrefixEmulatorActivity.buildReaderIntent(this), null));
 
                 adapter.add(TestListItem.newTest(this, R.string.nfc_hce_other_conflicting_prefix_aids_reader,
-                        SimpleReaderActivity.class.getName(),
+                        getString(R.string.nfc_hce_other_conflicting_prefix_aids_reader),
                         ConflictingNonPaymentPrefixEmulatorActivity.buildReaderIntent(this), null));
             }
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java
index 638bc6f..4fab77a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java
@@ -37,6 +37,7 @@
     NfcAdapter mAdapter;
     CommandApdu[] mApdus;
     String[] mResponses;
+    String mLabel;
 
     TextView mTextView;
     Spinner mSpinner;
@@ -49,8 +50,8 @@
         setPassFailButtonClickListeners();
         getPassButton().setEnabled(false);
 
-        String label = getIntent().getStringExtra(EXTRA_LABEL);
-        setTitle(label);
+        mLabel = getIntent().getStringExtra(EXTRA_LABEL);
+        setTitle(mLabel);
 
         mAdapter = NfcAdapter.getDefaultAdapter(this);
         mTextView = (TextView) findViewById(R.id.text);
@@ -187,4 +188,9 @@
     @Override
     public void onNothingSelected(AdapterView<?> parent) {
     }
+
+    @Override
+    public String getTestId() {
+        return mLabel;
+    }
 }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
index 6c5e4a5..461bcd7 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
@@ -31,8 +31,9 @@
 public class PermissionsHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
     private static final String PKG = "com.android.cts.usepermission";
 
-    private static final String APK = "CtsUsePermissionApp.apk";
-    private static final String APK_COMPAT = "CtsUsePermissionAppCompat.apk";
+    private static final String APK_22 = "CtsUsePermissionApp22.apk";
+    private static final String APK_23 = "CtsUsePermissionApp23.apk";
+    private static final String APK_24 = "CtsUsePermissionApp24.apk";
 
     private IAbi mAbi;
     private IBuildInfo mCtsBuild;
@@ -67,9 +68,10 @@
     public void testFail() throws Exception {
         // Sanity check that remote failure is host failure
         assertNull(getDevice().installPackage(
-                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
         try {
-            runDeviceTests(PKG, ".UsePermissionTest", "testFail");
+            runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                    "testFail");
             fail("Expected remote failure");
         } catch (AssertionError expected) {
         }
@@ -78,82 +80,216 @@
     public void testKill() throws Exception {
         // Sanity check that remote kill is host failure
         assertNull(getDevice().installPackage(
-                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
         try {
-            runDeviceTests(PKG, ".UsePermissionTest", "testKill");
+            runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                    "testKill");
             fail("Expected remote failure");
         } catch (AssertionError expected) {
         }
     }
 
-    public void testDefault() throws Exception {
+    public void testCompatDefault22() throws Exception {
         assertNull(getDevice().installPackage(
-                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
-        runDeviceTests(PKG, ".UsePermissionTest", "testDefault");
-    }
-
-    public void testGranted() throws Exception {
-        assertNull(getDevice().installPackage(
-                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
-        grantPermission(PKG, "android.permission.READ_EXTERNAL_STORAGE");
-        grantPermission(PKG, "android.permission.WRITE_EXTERNAL_STORAGE");
-        runDeviceTests(PKG, ".UsePermissionTest", "testGranted");
-    }
-
-    public void testInteractiveGrant() throws Exception {
-        assertNull(getDevice().installPackage(
-                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
-        runDeviceTests(PKG, ".UsePermissionTest", "testInteractiveGrant");
-    }
-
-    public void testRuntimeGroupGrantSpecificity() throws Exception {
-        assertNull(getDevice().installPackage(
-                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
-        runDeviceTests(PKG, ".UsePermissionTest", "testRuntimeGroupGrantSpecificity");
-    }
-
-    public void testRuntimeGroupGrantExpansion() throws Exception {
-        assertNull(getDevice().installPackage(
-                MigrationHelper.getTestFile(mCtsBuild, APK), false, false));
-        runDeviceTests(PKG, ".UsePermissionTest", "testRuntimeGroupGrantExpansion");
-    }
-
-    public void testCompatDefault() throws Exception {
-        assertNull(getDevice().installPackage(MigrationHelper.getTestFile(mCtsBuild, APK_COMPAT),
+                MigrationHelper.getTestFile(mCtsBuild, APK_22),
                 false, false));
-        runDeviceTests(PKG, ".UsePermissionCompatTest", "testCompatDefault");
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest22",
+                "testCompatDefault");
     }
 
-    public void testCompatRevoked() throws Exception {
-        assertNull(getDevice().installPackage(MigrationHelper.getTestFile(mCtsBuild, APK_COMPAT),
+    public void testCompatRevoked22() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_22),
                 false, false));
-        setAppOps(PKG, "android:read_external_storage", "deny");
-        setAppOps(PKG, "android:write_external_storage", "deny");
-        runDeviceTests(PKG, ".UsePermissionCompatTest", "testCompatRevoked");
+        try {
+            runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest22",
+                    "testCompatRevoked_part1");
+            fail("App must be killed on a permission revoke");
+        } catch (AssertionError expected) {
+        }
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest22",
+                "testCompatRevoked_part2");
+    }
+
+    public void testNoRuntimePrompt22() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_22),
+                false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest22",
+                "testNoRuntimePrompt");
+    }
+
+    public void testDefault23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testDefault");
+    }
+
+    public void testGranted23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testGranted");
+    }
+
+    public void testInteractiveGrant23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testInteractiveGrant");
+    }
+
+    public void testRuntimeGroupGrantSpecificity23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testRuntimeGroupGrantSpecificity");
+    }
+
+    public void testRuntimeGroupGrantExpansion23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testRuntimeGroupGrantExpansion");
+    }
+
+    public void testCancelledPermissionRequest23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testCancelledPermissionRequest");
+    }
+
+    public void testRequestGrantedPermission23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testRequestGrantedPermission");
+    }
+
+    public void testDenialWithPrejudice23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testDenialWithPrejudice");
+    }
+
+    public void testRevokeAffectsWholeGroup23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        try {
+            runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23_part1",
+                    "testRevokeAffectsWholeGroup");
+        } catch (AssertionError expected) {
+        }
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23_part2",
+                "testRevokeAffectsWholeGroup");
+    }
+
+    public void testGrantPreviouslyRevokedWithPrejudiceShowsPrompt23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        try {
+            runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                    "testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part1");
+            fail("App must be killed on a permission revoke");
+        } catch (Throwable expected) {
+        }
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part2");
+    }
+
+    public void testRequestNonRuntimePermission23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testRequestNonRuntimePermission");
+    }
+
+    public void testRequestNonExistentPermission23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testRequestNonExistentPermission");
+    }
+
+    public void testRequestPermissionFromTwoGroups23() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testRequestPermissionFromTwoGroups");
+    }
+
+    public void testOnlyRequestedPermissionsGranted24() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_24), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest24",
+                "testOnlyRequestedPermissionsGranted");
+    }
+
+    public void testUpgradeKeepsPermissions() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_22), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest22",
+                "testAllPermissionsGrantedByDefault");
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), true, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testAllPermissionsGrantedOnUpgrade");
+    }
+
+    public void testNoDowngradePermissionModel() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        try {
+            assertNull(getDevice().installPackage(
+                    MigrationHelper.getTestFile(mCtsBuild, APK_22), true, false));
+            fail("Permission mode downgrade not allowed");
+        } catch (AssertionError expected) {
+        }
+    }
+
+    public void testNoResidualPermissionsOnUninstall() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testNoResidualPermissionsOnUninstall_part1");
+        assertNull(getDevice().uninstallPackage(PKG));
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testNoResidualPermissionsOnUninstall_part2");
+    }
+
+    public void testRevokePropagatedOnUpgradeOldToNewModel() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_22), false, false));
+        try {
+            runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest22",
+                    "testRevokePropagatedOnUpgradeOldToNewModel_part1");
+            fail("App must be killed on a permission revoke");
+        } catch (AssertionError expected) {
+        }
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), true, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testRevokePropagatedOnUpgradeOldToNewModel_part2");
+    }
+
+    public void testRevokePropagatedOnUpgradeNewToNewModel() throws Exception {
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), false, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testRevokePropagatedOnUpgradeNewToNewModel_part1");
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, APK_23), true, false));
+        runDeviceTests(PKG, "com.android.cts.usepermission.UsePermissionTest23",
+                "testRevokePropagatedOnUpgradeNewToNewModel_part2");
     }
 
     private void runDeviceTests(String packageName, String testClassName, String testMethodName)
             throws DeviceNotAvailableException {
         Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
     }
-
-    private void grantPermission(String pkg, String permission) throws Exception {
-        assertEmpty(getDevice().executeShellCommand("pm grant " + pkg + " " + permission));
-    }
-
-    private void revokePermission(String pkg, String permission) throws Exception {
-        assertEmpty(getDevice().executeShellCommand("pm revoke " + pkg + " " + permission));
-    }
-
-    private void setAppOps(String pkg, String op, String mode) throws Exception {
-        assertEmpty(getDevice().executeShellCommand("appops set " + pkg + " " + op + " " + mode));
-    }
-
-    private static void assertEmpty(String str) {
-        if (str == null || str.length() == 0) {
-            return;
-        } else {
-            fail("Expected empty string but found " + str);
-        }
-    }
 }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
new file mode 100644
index 0000000..b2b4476
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
@@ -0,0 +1,101 @@
+/*
+ * 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.appsecurity.cts;
+
+import com.android.compatibility.common.util.AbiUtils;
+import com.android.cts.migration.MigrationHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+/**
+ * Tests that verify intent filters.
+ */
+public class PrivilegedUpdateTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+    private static final String SHIM_PKG = "com.android.cts.priv.ctsshim";
+    /** Package name of the tests to be run */
+    private static final String TEST_PKG = "com.android.cts.privilegedupdate";
+
+    /** APK that contains the shim; to test upgrading */
+    private static final String SHIM_UPDATE_APK = "CtsShimPrivUpgradePrebuilt.apk";
+    /** APK that contains individual shim test cases */
+    private static final String TEST_APK = "CtsPrivilegedUpdateTests.apk";
+
+    private IAbi mAbi;
+    private IBuildInfo mCtsBuild;
+
+    @Override
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = buildInfo;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(mAbi);
+        assertNotNull(mCtsBuild);
+
+        getDevice().uninstallPackage(SHIM_PKG);
+        getDevice().uninstallPackage(TEST_PKG);
+
+        assertNull(getDevice().installPackage(
+                MigrationHelper.getTestFile(mCtsBuild, TEST_APK), false));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        getDevice().uninstallPackage(SHIM_PKG);
+        getDevice().uninstallPackage(TEST_PKG);
+    }
+
+    public void testSystemAppPriorities() throws Exception {
+        runDeviceTests(TEST_PKG, ".PrivilegedUpdateTest", "testSystemAppPriorities");
+    }
+
+    public void testPrivilegedAppPriorities() throws Exception {
+        runDeviceTests(TEST_PKG, ".PrivilegedUpdateTest", "testPrivilegedAppPriorities");
+    }
+
+    public void testPrivilegedAppUpgradePriorities() throws Exception {
+        getDevice().uninstallPackage(SHIM_PKG);
+        
+        try {
+            assertNull(getDevice().installPackage(
+                    MigrationHelper.getTestFile(mCtsBuild, SHIM_UPDATE_APK), true));
+            runDeviceTests(TEST_PKG, ".PrivilegedUpdateTest", "testPrivilegedAppUpgradePriorities");
+        } finally {
+            getDevice().uninstallPackage(SHIM_PKG);
+        }
+    }
+
+    private void runDeviceTests(String packageName, String testClassName, String testMethodName)
+            throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
index c528ad4..f5666d1 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
@@ -355,15 +355,22 @@
         }
     }
 
-    public static void assertMediaNoAccess(ContentResolver resolver) throws Exception {
+    public static void assertMediaNoAccess(ContentResolver resolver, boolean legacyApp)
+            throws Exception {
         final ContentValues values = new ContentValues();
         values.put(Images.Media.MIME_TYPE, "image/jpeg");
         values.put(Images.Media.DATA,
                 buildProbeFile(Environment.getExternalStorageDirectory()).getAbsolutePath());
 
         try {
-            resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
-            fail("Expected access to be blocked");
+            Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
+            if (legacyApp) {
+                // For legacy apps we do not crash - just make the operation do nothing
+                assertEquals(MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+                        .buildUpon().appendPath("0").build().toString(), uri.toString());
+            } else {
+                fail("Expected access to be blocked");
+            }
         } catch (Exception expected) {
         }
     }
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/Android.mk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/Android.mk
new file mode 100644
index 0000000..6d6e805
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/Android.mk
@@ -0,0 +1,67 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+###########################################################
+# Package w/ tests
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ctsdeviceutil ctstestrunner
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+LOCAL_PACKAGE_NAME := CtsPrivilegedUpdateTests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
+
+###########################################################
+# Variant: Privileged app upgrade
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CtsShimPrivUpgradePrebuilt
+LOCAL_MODULE_TAGS := tests
+#LOCAL_PRIVILEGED_MODULE := true
+LOCAL_MODULE_CLASS := APPS
+LOCAL_BUILT_MODULE_STEM := package.apk
+# Make sure the build system doesn't try to resign the APK
+LOCAL_CERTIFICATE := PRESIGNED
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_SRC_FILES := CtsShimPrivUpgrade.apk
+
+include $(BUILD_PREBUILT)
+
+# Add package to the set of APKs available to CTS
+# Unceremoneously ripped from cts/build/support_package.mk
+cts_support_apks :=
+$(foreach fp, $(ALL_MODULES.$(LOCAL_MODULE).BUILT_INSTALLED),\
+  $(eval pair := $(subst :,$(space),$(fp)))\
+  $(eval built := $(word 1,$(pair)))\
+  $(eval installed := $(CTS_TESTCASES_OUT)/$(notdir $(word 2,$(pair))))\
+  $(eval $(call copy-one-file, $(built), $(installed)))\
+  $(eval cts_support_apks += $(installed)))
+
+# Have the module name depend on the cts files; so the cts files get generated when you run mm/mmm/mma/mmma.
+$(my_register_name) : $(cts_support_apks)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/AndroidManifest.xml
similarity index 73%
rename from hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/AndroidManifest.xml
rename to hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/AndroidManifest.xml
index 253d85d..58f34b9 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<!-- 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.
@@ -15,13 +15,16 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.usepermission">
-    <application>
+        package="com.android.cts.privilegedupdate">
+
+    <application android:label="PrivilegedUpdateApp">
         <uses-library android:name="android.test.runner" />
-        <activity android:name=".MyActivity" />
+        <activity android:name=".MainActivity" />
     </application>
+
     <instrumentation
         android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.cts.usepermission" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+        android:targetPackage="com.android.cts.privilegedupdate" />
+
 </manifest>
+
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/CtsShimPrivUpgrade.apk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/CtsShimPrivUpgrade.apk
new file mode 100644
index 0000000..c71163d
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/CtsShimPrivUpgrade.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/src/com/android/cts/privilegedupdate/PrivilegedUpdateTest.java b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/src/com/android/cts/privilegedupdate/PrivilegedUpdateTest.java
new file mode 100644
index 0000000..7b92bea
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/src/com/android/cts/privilegedupdate/PrivilegedUpdateTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.intentfilter;
+
+import java.util.List;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Tests for intent filter.
+ */
+public class PrivilegedUpdateTest extends InstrumentationTestCase {
+    /** Package name of the privileged CTS shim */
+    private static final String PRIVILEGED_SHIM_PKG = "com.android.cts.priv.ctsshim";
+    /** Package name of the system CTS shim */
+    private static final String SYSTEM_SHIM_PKG = "com.android.cts.ctsshim";
+    /** Class name for the install tests */
+    private static final String INSTALL_CLASS = ".InstallPriority";
+
+    /**
+     * Tests the filter priorities for a system package are set correctly.
+     * <p>
+     * System packages can NOT obtain higher priorities for any action.
+     */
+    public void testSystemAppPriorities() throws Exception {
+        final ComponentName testComponent =
+                new ComponentName(SYSTEM_SHIM_PKG, SYSTEM_SHIM_PKG + INSTALL_CLASS);
+        assertFilterPriority(testComponent, Intent.ACTION_SEARCH, 0);
+        assertFilterPriority(testComponent, Intent.ACTION_VIEW, 0);
+        assertFilterPriority(testComponent, Intent.ACTION_SEND, 0);
+        assertFilterPriority(testComponent, Intent.ACTION_SEND_MULTIPLE, 0);
+        assertFilterPriority(testComponent, Intent.ACTION_SENDTO, 0);
+    }
+
+    /**
+     * Tests the filter priorities for a privileged package are set correctly.
+     * <p>
+     * Privileged packages can obtain higher priorities except for those on
+     * protected actions. 
+     */
+    public void testPrivilegedAppPriorities() throws Exception {
+        final ComponentName testComponent =
+                new ComponentName(PRIVILEGED_SHIM_PKG, PRIVILEGED_SHIM_PKG + INSTALL_CLASS);
+        assertFilterPriority(testComponent, Intent.ACTION_SEARCH, 100);
+        assertFilterPriority(testComponent, Intent.ACTION_VIEW, 0);
+        assertFilterPriority(testComponent, Intent.ACTION_SEND, 0);
+        assertFilterPriority(testComponent, Intent.ACTION_SEND_MULTIPLE, 0);
+        assertFilterPriority(testComponent, Intent.ACTION_SENDTO, 0);
+    }
+
+    /**
+     * Tests the filter priorities for a privileged package are set correctly after update.
+     * <p>
+     * Test various forms of filter equivalency [eg. action, category, scheme and host].
+     * Also, don't allow any filter obtain a higher priority than what was defined on
+     * system image.
+     */
+    public void testPrivilegedAppUpgradePriorities() throws Exception {
+        final ComponentName testComponent =
+                new ComponentName(PRIVILEGED_SHIM_PKG, PRIVILEGED_SHIM_PKG + INSTALL_CLASS);
+        assertFilterPriority(testComponent, Intent.ACTION_VIEW, 0);
+        assertFilterPriority(testComponent, Intent.ACTION_SEND, 0);
+        assertFilterPriority(testComponent, Intent.ACTION_SEND_MULTIPLE, 0);
+        assertFilterPriority(testComponent, Intent.ACTION_SENDTO, 0);
+
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeMatch"),
+                "com.android.cts.action.MATCH", 100);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeMatchMultiple"),
+                "com.android.cts.action.MATCH_MULTIPLE", 150);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeLowerPriority"),
+                "com.android.cts.action.LOWER_PRIORITY", 75);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeActionSubset"),
+                "com.android.cts.action.ACTION_SUB_2", 100);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeCategorySubset"),
+                "com.android.cts.action.CATEGORY_SUB", 100);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeSchemeSubset"),
+                "com.android.cts.action.SCHEME_SUB", "flubber:", 100);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeAuthoritySubset"),
+                "com.android.cts.action.AUTHORITY_SUB", 100);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeNewActivity"),
+                "com.android.cts.action.NEW_ACTIVITY", 0);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeNewAction"),
+                "com.android.cts.action.NEW_ACTION", 0);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeNewCategory"),
+                "com.android.cts.action.NEW_CATEGORY", 0);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeNewScheme"),
+                "com.android.cts.action.NEW_SCHEME", "zowie:", 0);
+        assertFilterPriority(
+                new ComponentName(PRIVILEGED_SHIM_PKG,
+                        PRIVILEGED_SHIM_PKG + ".UpgradeNewAuthority"),
+                "com.android.cts.action.NEW_AUTHORITY", 0);
+    }
+
+    private void assertFilterPriority(ComponentName component, String action, int priority) {
+        assertFilterPriority(component, action, null /*data*/, priority);
+    }
+    private void assertFilterPriority(
+            ComponentName component, String action, String data, int priority) {
+        final PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        final String className = component.getClassName();
+        final Intent intent = new Intent(action);
+        intent.setPackage(component.getPackageName());
+        if (data != null) {
+            intent.setData(Uri.parse(data));
+        }
+        final List<ResolveInfo> entries =
+                pm.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
+        assertNotNull(entries);
+        ResolveInfo foundInfo = null;
+        for (ResolveInfo ri : entries) {
+            if (ri.activityInfo.name.equals(className)) {
+                foundInfo = ri;
+                break;
+            }
+        }
+        assertTrue(action + "; didn't find class \"" + className + "\"", foundInfo != null);
+        assertEquals(action + "; wrong priority", priority, foundInfo.filter.getPriority());
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UsePermissionApp/AndroidManifest.xml
deleted file mode 100644
index ece4ebe..0000000
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.usepermission">
-    <application>
-        <uses-library android:name="android.test.runner" />
-        <activity android:name=".MyActivity" />
-    </application>
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.cts.usepermission" />
-
-    <!-- Note that WRITE_EXTERNAL_STORAGE implies READ_EXTERNAL_STORAGE;
-         this is a special case. -->
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <!-- Deliberately request WRITE_CONTACTS but *not* READ_CONTACTS -->
-    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
-
-    <!-- Request two different permissions within the same group -->
-    <uses-permission android:name="android.permission.SEND_SMS" />
-    <uses-permission android:name="android.permission.RECEIVE_SMS" />
-
-</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/UsePermissionTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/UsePermissionTest.java
deleted file mode 100644
index 8d3b976..0000000
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/UsePermissionTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * 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 com.android.cts.usepermission;
-
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand;
-
-import android.content.pm.PackageManager;
-import android.os.Environment;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiSelector;
-import android.test.InstrumentationTestCase;
-
-public class UsePermissionTest extends InstrumentationTestCase {
-    private static final String TAG = "UsePermissionTest";
-
-    private UiDevice mDevice;
-    private MyActivity mActivity;
-
-    public void testFail() throws Exception {
-        fail("Expected");
-    }
-
-    public void testKill() throws Exception {
-        android.os.Process.killProcess(android.os.Process.myPid());
-    }
-
-    public void testDefault() throws Exception {
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
-        // New permission model is denied by default
-        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE));
-        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-        assertDirNoAccess(Environment.getExternalStorageDirectory());
-        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
-        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver());
-    }
-
-    public void testGranted() throws Exception {
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
-        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE));
-        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
-        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
-        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
-    }
-
-    public void testInteractiveGrant() throws Exception {
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
-        // Start out without permission
-        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE));
-        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-        assertDirNoAccess(Environment.getExternalStorageDirectory());
-        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
-        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver());
-
-        // Go through normal grant flow
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
-                MyActivity.class, null);
-        mDevice.waitForIdle();
-
-        mActivity.requestPermissions(new String[] {
-                android.Manifest.permission.READ_EXTERNAL_STORAGE,
-                android.Manifest.permission.WRITE_EXTERNAL_STORAGE }, 42);
-        mDevice.waitForIdle();
-
-        new UiObject(new UiSelector()
-                .resourceId("com.android.packageinstaller:id/permission_allow_button")).click();
-        mDevice.waitForIdle();
-
-        MyActivity.Result result = mActivity.getResult();
-        assertEquals(42, result.requestCode);
-        assertEquals(android.Manifest.permission.READ_EXTERNAL_STORAGE, result.permissions[0]);
-        assertEquals(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, result.permissions[1]);
-        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
-        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[1]);
-
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
-        // We should have permission now!
-        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE));
-        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
-        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
-        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
-
-        mActivity.finish();
-    }
-
-    public void testRuntimeGroupGrantSpecificity() throws Exception {
-        // Start out without permission
-        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.WRITE_CONTACTS));
-        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.READ_CONTACTS));
-
-        // Go through normal grant flow
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
-                MyActivity.class, null);
-        mDevice.waitForIdle();
-
-        // request only one permission from the 'contacts' permission group
-        mActivity.requestPermissions(new String[] {
-                android.Manifest.permission.WRITE_CONTACTS }, 43);
-        mDevice.waitForIdle();
-
-        new UiObject(new UiSelector()
-                .resourceId("com.android.packageinstaller:id/permission_allow_button")).click();
-        mDevice.waitForIdle();
-
-        MyActivity.Result result = mActivity.getResult();
-        assertEquals(43, result.requestCode);
-        assertEquals(android.Manifest.permission.WRITE_CONTACTS, result.permissions[0]);
-        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
-
-        // We should have only the explicitly requested permission from this group
-        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.WRITE_CONTACTS));
-        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.READ_CONTACTS));
-
-        mActivity.finish();
-    }
-
-    public void testRuntimeGroupGrantExpansion() throws Exception {
-        // Start out without permission
-        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.RECEIVE_SMS));
-        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.SEND_SMS));
-
-        // Go through normal grant flow
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
-                MyActivity.class, null);
-        mDevice.waitForIdle();
-
-        // request only one permission from the 'SMS' permission group at runtime,
-        // but two from this group are <uses-permission> in the manifest
-        mActivity.requestPermissions(new String[] {
-                android.Manifest.permission.RECEIVE_SMS }, 44);
-        mDevice.waitForIdle();
-
-        new UiObject(new UiSelector()
-                .resourceId("com.android.packageinstaller:id/permission_allow_button")).click();
-        mDevice.waitForIdle();
-
-        MyActivity.Result result = mActivity.getResult();
-        assertEquals(44, result.requestCode);
-        assertEquals(android.Manifest.permission.RECEIVE_SMS, result.permissions[0]);
-        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
-
-        // We should now have been granted both of the permissions from this group
-        // that are mentioned in our manifest
-        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.RECEIVE_SMS));
-        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
-                .checkSelfPermission(android.Manifest.permission.SEND_SMS));
-
-        mActivity.finish();
-    }
-}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/Android.mk
similarity index 81%
copy from hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk
copy to hostsidetests/appsecurity/test-apps/UsePermissionApp22/Android.mk
index 4630f1f..9ee5921 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/Android.mk
@@ -19,13 +19,14 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ctsdeviceutil ctstestrunner ub-uiautomator
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-    ../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
+    ../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java \
+    ../UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionActivity.java \
+    ../UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
 
-LOCAL_PACKAGE_NAME := CtsUsePermissionApp
+LOCAL_PACKAGE_NAME := CtsUsePermissionApp22
 
 # tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/AndroidManifest.xml
new file mode 100644
index 0000000..ebb0cbf
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/AndroidManifest.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.usepermission">
+
+    <uses-sdk android:minSdkVersion="22" android:targetSdkVersion="22" />
+
+    <!-- Request two different permissions within the same group -->
+    <uses-permission android:name="android.permission.SEND_SMS" />
+    <uses-permission android:name="android.permission.RECEIVE_SMS" />
+
+    <!-- Contacts -->
+    <!-- Deliberately request WRITE_CONTACTS but *not* READ_CONTACTS -->
+    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
+
+    <!-- Calendar -->
+    <uses-permission android:name="android.permission.READ_CALENDAR"/>
+    <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
+
+    <!-- SMS -->
+    <uses-permission android:name="android.permission.SEND_SMS"/>
+    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
+    <uses-permission android:name="android.permission.READ_SMS"/>
+    <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH"/>
+    <uses-permission android:name="android.permission.RECEIVE_MMS"/>
+    <uses-permission android:name="android.permission.READ_CELL_BROADCASTS"/>
+
+    <!-- Storage -->
+    <!-- Special case: WRITE_EXTERNAL_STORAGE implies READ_EXTERNAL_STORAGE -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+
+    <!-- Location -->
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+
+    <!-- Phone -->
+    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <uses-permission android:name="android.permission.CALL_PHONE"/>
+    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
+    <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
+    <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL"/>
+    <uses-permission android:name="android.permission.USE_SIP"/>
+    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
+
+    <!-- Phone -->
+    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+
+    <!-- Camera -->
+    <uses-permission android:name="android.permission.CAMERA"/>
+
+    <!-- Body Sensors -->
+    <uses-permission android:name="android.permission.BODY_SENSORS"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:name=".BasePermissionActivity" />
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.usepermission" />
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
new file mode 100644
index 0000000..1478015
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
@@ -0,0 +1,172 @@
+/*
+ * 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 com.android.cts.usepermission;
+
+import static junit.framework.Assert.assertEquals;
+
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPaths;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand;
+import static junit.framework.Assert.assertTrue;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Environment;
+import android.os.Process;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.Arrays;
+
+/**
+ * Runtime permission behavior tests for apps targeting API 22
+ */
+public class UsePermissionTest22 extends BasePermissionsTest {
+    private static final int REQUEST_CODE_PERMISSIONS = 42;
+
+    @Test
+    public void testCompatDefault() throws Exception {
+        final Context context = getInstrumentation().getContext();
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        // Legacy permission model is granted by default
+        assertEquals(PackageManager.PERMISSION_GRANTED,
+                context.checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE,
+                        Process.myPid(), Process.myUid()));
+        assertEquals(PackageManager.PERMISSION_GRANTED,
+                context.checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
+                        Process.myPid(), Process.myUid()));
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
+        for (File path : getAllPackageSpecificPaths(context)) {
+            if (path != null) {
+                assertDirReadWriteAccess(path);
+            }
+        }
+        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
+    }
+
+    @Test
+    public void testCompatRevoked_part1() throws Exception {
+        // Revoke the permission
+        revokePermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, true);
+    }
+
+    @Test
+    public void testCompatRevoked_part2() throws Exception {
+        final Context context = getInstrumentation().getContext();
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        // Legacy permission model appears granted, but storage looks and
+        // behaves like it's ejected
+        assertEquals(PackageManager.PERMISSION_GRANTED,
+                context.checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE,
+                        Process.myPid(), Process.myUid()));
+        assertEquals(PackageManager.PERMISSION_GRANTED,
+                context.checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
+                        Process.myPid(), Process.myUid()));
+        assertEquals(Environment.MEDIA_UNMOUNTED, Environment.getExternalStorageState());
+
+        assertDirNoAccess(Environment.getExternalStorageDirectory());
+        for (File dir : getAllPackageSpecificPaths(context)) {
+            if (dir != null) {
+                assertDirNoAccess(dir);
+            }
+        }
+        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver(), true);
+
+        // Just to be sure, poke explicit path
+        assertDirNoAccess(new File(Environment.getExternalStorageDirectory(),
+                "/Android/data/" + getInstrumentation().getContext().getPackageName()));
+    }
+
+    @Test
+    public void testAllPermissionsGrantedByDefault() throws Exception {
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.SEND_SMS));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.RECEIVE_SMS));
+        // The APK does not request because of other tests Manifest.permission.READ_CONTACTS
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.SEND_SMS));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.RECEIVE_SMS));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_SMS));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.RECEIVE_WAP_PUSH));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.RECEIVE_MMS));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission("android.permission.READ_CELL_BROADCASTS"));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_PHONE_STATE));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.CALL_PHONE));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_CALL_LOG));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CALL_LOG));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.ADD_VOICEMAIL));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.USE_SIP));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.PROCESS_OUTGOING_CALLS));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.CAMERA));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.BODY_SENSORS));
+    }
+
+    @Test
+    public void testNoRuntimePrompt() throws Exception {
+        // Request the permission and do nothing
+        BasePermissionActivity.Result result = requestPermissions(
+                new String[] {Manifest.permission.SEND_SMS}, REQUEST_CODE_PERMISSIONS,
+                BasePermissionActivity.class, null);
+
+        // Expect the permission is not granted
+        assertEquals(REQUEST_CODE_PERMISSIONS, result.requestCode);
+        assertTrue(Arrays.equals(result.permissions, new String[0]));
+        assertTrue(Arrays.equals(result.grantResults, new int[0]));
+    }
+
+    @Test
+    public void testRevokePropagatedOnUpgradeOldToNewModel_part1() throws Exception {
+        // Revoke a permission
+        revokePermissions(new String[] {Manifest.permission.WRITE_CALENDAR}, true);
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/Android.mk
similarity index 94%
rename from hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk
rename to hostsidetests/appsecurity/test-apps/UsePermissionApp23/Android.mk
index 4630f1f..c8e05c5 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/Android.mk
@@ -19,13 +19,12 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ctsdeviceutil ctstestrunner ub-uiautomator
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     ../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
 
-LOCAL_PACKAGE_NAME := CtsUsePermissionApp
+LOCAL_PACKAGE_NAME := CtsUsePermissionApp23
 
 # tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/AndroidManifest.xml
new file mode 100644
index 0000000..71eadaa
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/AndroidManifest.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.usepermission">
+
+    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23" />
+
+    <!-- Request two different permissions within the same group -->
+    <uses-permission android:name="android.permission.SEND_SMS" />
+    <uses-permission android:name="android.permission.RECEIVE_SMS" />
+
+    <!-- Contacts -->
+    <!-- Deliberately request WRITE_CONTACTS but *not* READ_CONTACTS -->
+    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
+
+    <!-- Calendar -->
+    <uses-permission android:name="android.permission.READ_CALENDAR"/>
+    <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
+
+    <!-- SMS -->
+    <uses-permission android:name="android.permission.SEND_SMS"/>
+    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
+    <uses-permission android:name="android.permission.READ_SMS"/>
+    <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH"/>
+    <uses-permission android:name="android.permission.RECEIVE_MMS"/>
+    <uses-permission android:name="android.permission.READ_CELL_BROADCASTS"/>
+
+    <!-- Storage -->
+    <!-- Special case: WRITE_EXTERNAL_STORAGE implies READ_EXTERNAL_STORAGE -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+
+    <!-- Location -->
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+
+    <!-- Phone -->
+    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <uses-permission android:name="android.permission.CALL_PHONE"/>
+    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
+    <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
+    <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL"/>
+    <uses-permission android:name="android.permission.USE_SIP"/>
+    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
+
+    <!-- Phone -->
+    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+
+    <!-- Camera -->
+    <uses-permission android:name="android.permission.CAMERA"/>
+
+    <!-- Body Sensors -->
+    <uses-permission android:name="android.permission.BODY_SENSORS"/>
+
+    <application>
+        <activity android:name="com.android.cts.usepermission.BasePermissionActivity" />
+    </application>
+
+    <instrumentation
+            android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.cts.usepermission" />
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/MyActivity.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionActivity.java
similarity index 78%
rename from hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/MyActivity.java
rename to hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionActivity.java
index 5af3886..cacfa80 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/MyActivity.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionActivity.java
@@ -20,11 +20,15 @@
 import android.os.Bundle;
 import android.view.WindowManager;
 
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.TimeUnit;
 
-public class MyActivity extends Activity {
+public class BasePermissionActivity extends Activity {
+    private static final long OPERATION_TIMEOUT_MILLIS = 5000;
+
     private final SynchronousQueue<Result> mResult = new SynchronousQueue<>();
+    private final CountDownLatch mOnCreateSync = new CountDownLatch(1);
 
     public static class Result {
         public final int requestCode;
@@ -45,6 +49,8 @@
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+
+        mOnCreateSync.countDown();
     }
 
     @Override
@@ -57,9 +63,17 @@
         }
     }
 
+    public void waitForOnCreate() {
+        try {
+            mOnCreateSync.await(OPERATION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     public Result getResult() {
         try {
-            return mResult.take();
+            return mResult.poll(OPERATION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
         } catch (InterruptedException e) {
             throw new RuntimeException(e);
         }
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
new file mode 100644
index 0000000..5b7dfb6
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
@@ -0,0 +1,297 @@
+/*
+ * 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.usepermission;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiSelector;
+import android.util.ArrayMap;
+import android.widget.Switch;
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
+import java.util.Map;
+
+@RunWith(AndroidJUnit4.class)
+public abstract class BasePermissionsTest {
+    private static final String PLATFORM_PACKAGE_NAME = "android";
+
+    private static final long IDLE_TIMEOUT_MILLIS = 500;
+    private static final long GLOBAL_TIMEOUT_MILLIS = 5000;
+
+    private static Map<String, String> sPermissionToLabelResNameMap = new ArrayMap<>();
+    static {
+        // Contacts
+        sPermissionToLabelResNameMap.put(Manifest.permission.READ_CONTACTS,
+                "@android:string/permgrouplab_contacts");
+        sPermissionToLabelResNameMap.put(Manifest.permission.WRITE_CONTACTS,
+                "@android:string/permgrouplab_contacts");
+        // Calendar
+        sPermissionToLabelResNameMap.put(Manifest.permission.READ_CALENDAR,
+                "@android:string/permgrouplab_calendar");
+        sPermissionToLabelResNameMap.put(Manifest.permission.WRITE_CALENDAR,
+                "@android:string/permgrouplab_calendar");
+        // SMS
+        sPermissionToLabelResNameMap.put(Manifest.permission.SEND_SMS,
+                "@android:string/permgrouplab_sms");
+        sPermissionToLabelResNameMap.put(Manifest.permission.RECEIVE_SMS,
+                "@android:string/permgrouplab_sms");
+        sPermissionToLabelResNameMap.put(Manifest.permission.READ_SMS,
+                "@android:string/permgrouplab_sms");
+        sPermissionToLabelResNameMap.put(Manifest.permission.RECEIVE_WAP_PUSH,
+                "@android:string/permgrouplab_sms");
+        sPermissionToLabelResNameMap.put(Manifest.permission.RECEIVE_MMS,
+                "@android:string/permgrouplab_sms");
+        sPermissionToLabelResNameMap.put("android.permission.READ_CELL_BROADCASTS",
+                "@android:string/permgrouplab_sms");
+        // Storage
+        sPermissionToLabelResNameMap.put(Manifest.permission.READ_EXTERNAL_STORAGE,
+                "@android:string/permgrouplab_storage");
+        sPermissionToLabelResNameMap.put(Manifest.permission.WRITE_EXTERNAL_STORAGE,
+                "@android:string/permgrouplab_storage");
+        // Location
+        sPermissionToLabelResNameMap.put(Manifest.permission.ACCESS_FINE_LOCATION,
+                "@android:string/permgrouplab_location");
+        sPermissionToLabelResNameMap.put(Manifest.permission.ACCESS_COARSE_LOCATION,
+                "@android:string/permgrouplab_location");
+        // Phone
+        sPermissionToLabelResNameMap.put(Manifest.permission.READ_PHONE_STATE,
+                "@android:string/permgrouplab_phone");
+        sPermissionToLabelResNameMap.put(Manifest.permission.CALL_PHONE,
+                "@android:string/permgrouplab_phone");
+        sPermissionToLabelResNameMap.put("android.permission.ACCESS_IMS_CALL_SERVICE",
+                "@android:string/permgrouplab_phone");
+        sPermissionToLabelResNameMap.put(Manifest.permission.READ_CALL_LOG,
+                "@android:string/permgrouplab_phone");
+        sPermissionToLabelResNameMap.put(Manifest.permission.WRITE_CALL_LOG,
+                "@android:string/permgrouplab_phone");
+        sPermissionToLabelResNameMap.put(Manifest.permission.ADD_VOICEMAIL,
+                "@android:string/permgrouplab_phone");
+        sPermissionToLabelResNameMap.put(Manifest.permission.USE_SIP,
+                "@android:string/permgrouplab_phone");
+        sPermissionToLabelResNameMap.put(Manifest.permission.PROCESS_OUTGOING_CALLS,
+                "@android:string/permgrouplab_phone");
+        // Microphone
+        sPermissionToLabelResNameMap.put(Manifest.permission.RECORD_AUDIO,
+                "@android:string/permgrouplab_microphone");
+        // Camera
+        sPermissionToLabelResNameMap.put(Manifest.permission.CAMERA,
+                "@android:string/permgrouplab_camera");
+        // Body sensors
+        sPermissionToLabelResNameMap.put(Manifest.permission.BODY_SENSORS,
+                "@android:string/permgrouplab_sensors");
+    }
+
+    private Context mContext;
+    private Resources mPlatformResources;
+
+    protected static Instrumentation getInstrumentation() {
+        return InstrumentationRegistry.getInstrumentation();
+    }
+
+    protected static void assertPermissionRequestResult(BasePermissionActivity.Result result,
+            int requestCode, String[] permissions, boolean[] granted) {
+        assertEquals(requestCode, result.requestCode);
+        for (int i = 0; i < permissions.length; i++) {
+            assertEquals(permissions[i], result.permissions[i]);
+            assertEquals(granted[i] ? PackageManager.PERMISSION_GRANTED
+                    : PackageManager.PERMISSION_DENIED, result.grantResults[i]);
+
+        }
+    }
+
+    protected static UiDevice getUiDevice() {
+        return UiDevice.getInstance(getInstrumentation());
+    }
+
+    protected static Activity launchActivity(String packageName,
+            Class<?> clazz, Bundle extras) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClassName(packageName, clazz.getName());
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        if (extras != null) {
+            intent.putExtras(extras);
+        }
+        Activity activity = getInstrumentation().startActivitySync(intent);
+        getInstrumentation().waitForIdleSync();
+
+        return activity;
+    }
+
+    @Before
+    public void beforeTest() {
+        mContext = InstrumentationRegistry.getTargetContext();
+        try {
+            Context platformContext = mContext.createPackageContext(PLATFORM_PACKAGE_NAME, 0);
+            mPlatformResources = platformContext.getResources();
+        } catch (PackageManager.NameNotFoundException e) {
+            /* cannot happen */
+        }
+    }
+
+    protected BasePermissionActivity.Result requestPermissions(
+            String[] permissions, int requestCode, Class<?> clazz, Runnable postRequestAction)
+            throws Exception {
+        // Start an activity
+        BasePermissionActivity activity = (BasePermissionActivity) launchActivity(
+                getInstrumentation().getTargetContext().getPackageName(), clazz, null);
+
+        activity.waitForOnCreate();
+
+        // Request the permissions
+        activity.requestPermissions(permissions, requestCode);
+
+        // Define a more conservative idle criteria
+        getInstrumentation().getUiAutomation().waitForIdle(
+                IDLE_TIMEOUT_MILLIS, GLOBAL_TIMEOUT_MILLIS);
+
+        // Perform the post-request action
+        if (postRequestAction != null) {
+            postRequestAction.run();
+        }
+
+        BasePermissionActivity.Result result = activity.getResult();
+        activity.finish();
+        return result;
+    }
+
+    protected void clickAllowButton() throws Exception {
+        getUiDevice().findObject(new UiSelector().resourceId(
+                "com.android.packageinstaller:id/permission_allow_button")).click();
+    }
+
+    protected void clickDenyButton() throws Exception {
+        getUiDevice().findObject(new UiSelector().resourceId(
+                "com.android.packageinstaller:id/permission_deny_button")).click();
+    }
+
+    protected void clickDontAskAgainCheckbox() throws Exception {
+        getUiDevice().findObject(new UiSelector().resourceId(
+                "com.android.packageinstaller:id/do_not_ask_checkbox")).click();
+    }
+
+    protected void grantPermission(String permission) throws Exception {
+        grantPermissions(new String[]{permission});
+    }
+
+    protected void grantPermissions(String[] permissions) throws Exception {
+        setPermissionGrantState(permissions, true, false);
+    }
+
+    protected void revokePermission(String permission) throws Exception {
+        revokePermissions(new String[] {permission}, false);
+    }
+
+    protected void revokePermissions(String[] permissions, boolean legacyApp) throws Exception {
+        setPermissionGrantState(permissions, false, legacyApp);
+    }
+
+    private void setPermissionGrantState(String[] permissions, boolean granted,
+            boolean legacyApp) throws Exception {
+        getUiDevice().pressBack();
+        getUiDevice().waitForIdle();
+        getUiDevice().pressBack();
+        getUiDevice().waitForIdle();
+
+        // Open the app details settings
+        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
+        intent.setData(Uri.parse("package:" + mContext.getPackageName()));
+        mContext.startActivity(intent);
+
+        getUiDevice().waitForIdle();
+
+        // Open the permissions UI
+        UiObject permissionItem = getUiDevice().findObject(new UiSelector().text("Permissions"));
+        permissionItem.click();
+
+        getUiDevice().waitForIdle();
+
+        for (String permission : permissions) {
+            // Find the permission toggle
+            String permissionLabel = getPermissionLabel(permission);
+
+            UiObject2 toggleSwitch = null;
+            UiObject2 current = getUiDevice().findObject(By.text(permissionLabel));
+            Assert.assertNotNull("Permission should be present");
+
+            while (toggleSwitch == null) {
+                UiObject2 parent = current.getParent();
+                if (parent == null) {
+                    fail("Cannot find permission list item");
+                }
+                toggleSwitch = current.findObject(By.clazz(Switch.class));
+                current = parent;
+            }
+
+            final boolean wasGranted = toggleSwitch.isChecked();
+            if (granted != wasGranted) {
+                // Toggle the permission
+                toggleSwitch.click();
+
+                getUiDevice().waitForIdle();
+
+                if (wasGranted && legacyApp) {
+                    String packageName = getInstrumentation().getContext().getPackageManager()
+                            .getPermissionControllerPackageName();
+                    String resIdName = "com.android.packageinstaller"
+                            + ":string/grant_dialog_button_deny_anyway";
+                    Resources resources = getInstrumentation().getContext()
+                            .createPackageContext(packageName, 0).getResources();
+                    final int confirmResId = resources.getIdentifier(resIdName, null, null);
+                    String confirmTitle = resources.getString(confirmResId);
+                    UiObject denyAnyway = getUiDevice().findObject(new UiSelector()
+                            .text(confirmTitle.toUpperCase()));
+                    denyAnyway.click();
+
+                    getUiDevice().waitForIdle();
+                }
+            }
+        }
+
+        getUiDevice().pressBack();
+        getUiDevice().waitForIdle();
+        getUiDevice().pressBack();
+        getUiDevice().waitForIdle();
+    }
+
+    private String getPermissionLabel(String permission) throws Exception {
+        String labelResName = sPermissionToLabelResNameMap.get(permission);
+        assertNotNull("Unknown permisison " + permission, labelResName);
+        final int resourceId = mPlatformResources.getIdentifier(labelResName, null, null);
+        return mPlatformResources.getString(resourceId);
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
new file mode 100644
index 0000000..9908a45
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
@@ -0,0 +1,561 @@
+/*
+ * 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 com.android.cts.usepermission;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand;
+
+import android.Manifest;
+import android.content.pm.PackageManager;
+import android.os.Environment;
+import org.junit.Test;
+
+/**
+ * Runtime permission behavior tests for apps targeting API 23
+ */
+public class UsePermissionTest23 extends BasePermissionsTest {
+    private static final int REQUEST_CODE_PERMISSIONS = 42;
+
+    public void testFail() throws Exception {
+        fail("Expected");
+    }
+
+    @Test
+    public void testKill() throws Exception {
+        android.os.Process.killProcess(android.os.Process.myPid());
+    }
+
+    @Test
+    public void testDefault() throws Exception {
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        // New permission model is denied by default
+        assertAllPermissionsRevoked();
+
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+        assertDirNoAccess(Environment.getExternalStorageDirectory());
+        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
+        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver(), false);
+    }
+
+    @Test
+    public void testGranted() throws Exception {
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+        grantPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
+        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
+        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
+    }
+
+    @Test
+    public void testInteractiveGrant() throws Exception {
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        // Start out without permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+        assertDirNoAccess(Environment.getExternalStorageDirectory());
+        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
+        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver(), false);
+
+        // Go through normal grant flow
+        BasePermissionActivity.Result result = requestPermissions(new String[] {
+                Manifest.permission.READ_EXTERNAL_STORAGE,
+                Manifest.permission.WRITE_EXTERNAL_STORAGE},
+                REQUEST_CODE_PERMISSIONS,
+                BasePermissionActivity.class,
+                () -> {
+                    try {
+                        clickAllowButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        assertEquals(REQUEST_CODE_PERMISSIONS, result.requestCode);
+        assertEquals(Manifest.permission.READ_EXTERNAL_STORAGE, result.permissions[0]);
+        assertEquals(Manifest.permission.WRITE_EXTERNAL_STORAGE, result.permissions[1]);
+        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
+        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[1]);
+
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        // We should have permission now!
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
+        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
+        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
+    }
+
+    @Test
+    public void testRuntimeGroupGrantSpecificity() throws Exception {
+        // Start out without permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_CONTACTS));
+
+        String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
+
+        // request only one permission from the 'contacts' permission group
+        BasePermissionActivity.Result result = requestPermissions(permissions,
+                REQUEST_CODE_PERMISSIONS,
+                BasePermissionActivity.class,
+                () -> {
+                    try {
+                        clickAllowButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Expect the permission is granted
+        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
+                permissions, new boolean[] {true});
+
+        // Make sure no undeclared as used permissions are granted
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_CONTACTS));
+    }
+
+    @Test
+    public void testRuntimeGroupGrantExpansion() throws Exception {
+        // Start out without permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.RECEIVE_SMS));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.SEND_SMS));
+
+        String[] permissions = new String[] {Manifest.permission.RECEIVE_SMS};
+
+        // request only one permission from the 'SMS' permission group at runtime,
+        // but two from this group are <uses-permission> in the manifest
+        // request only one permission from the 'contacts' permission group
+        BasePermissionActivity.Result result = requestPermissions(permissions,
+                REQUEST_CODE_PERMISSIONS,
+                BasePermissionActivity.class,
+                () -> {
+                    try {
+                        clickAllowButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Expect the permission is granted
+        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
+                permissions, new boolean[] {true});
+
+        // We should now have been granted both of the permissions from this group.
+        // NOTE: This is undesired behavior which will be fixed for target API 24.
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.SEND_SMS));
+    }
+
+    @Test
+    public void testCancelledPermissionRequest() throws Exception {
+        // Make sure we don't have the permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
+
+        String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
+
+        // Request the permission and cancel the request
+        BasePermissionActivity.Result result = requestPermissions(permissions,
+                REQUEST_CODE_PERMISSIONS,
+                BasePermissionActivity.class,
+                () -> {
+                    try {
+                        clickDenyButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Expect the permission is not granted
+        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
+                permissions, new boolean[] {false});
+    }
+
+    @Test
+    public void testRequestGrantedPermission() throws Exception {
+        // Make sure we don't have the permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
+
+        String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
+
+        // Request the permission and allow it
+        BasePermissionActivity.Result firstResult = requestPermissions(permissions,
+                REQUEST_CODE_PERMISSIONS,
+                BasePermissionActivity.class, () -> {
+                    try {
+                        clickAllowButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Expect the permission is granted
+        assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS,
+                permissions, new boolean[] {true});
+
+        // Request the permission and do nothing
+        BasePermissionActivity.Result secondResult = requestPermissions(new String[] {
+                Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 1,
+                BasePermissionActivity.class, null);
+
+        // Expect the permission is granted
+        assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1,
+                permissions, new boolean[] {true});
+    }
+
+    @Test
+    public void testDenialWithPrejudice() throws Exception {
+        // Make sure we don't have the permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
+
+        String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
+
+        // Request the permission and deny it
+        BasePermissionActivity.Result firstResult = requestPermissions(
+                permissions, REQUEST_CODE_PERMISSIONS,
+                BasePermissionActivity.class, () -> {
+                    try {
+                        clickDenyButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Expect the permission is not granted
+        assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS,
+                permissions, new boolean[] {false});
+
+        // Request the permission and choose don't ask again
+        BasePermissionActivity.Result secondResult = requestPermissions(new String[] {
+                        Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 1,
+                BasePermissionActivity.class, () -> {
+                    try {
+                        clickDontAskAgainCheckbox();
+                        clickDenyButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Expect the permission is not granted
+        assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1,
+                permissions, new boolean[] {false});
+
+        // Request the permission and do nothing
+        BasePermissionActivity.Result thirdResult = requestPermissions(new String[] {
+                        Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 2,
+                BasePermissionActivity.class, null);
+
+        // Expect the permission is not granted
+        assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS + 2,
+                permissions, new boolean[] {false});
+    }
+
+    @Test
+    public void testRevokeAffectsWholeGroup_part1() throws Exception {
+        // Grant the group
+        grantPermission(Manifest.permission.READ_CALENDAR);
+
+        // Make sure we have the permissions
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
+
+        // Revoke the group
+        revokePermission(Manifest.permission.READ_CALENDAR);
+
+        // We just committed a suicide by revoking the permission. See part2 below...
+    }
+
+    public void testRevokeAffectsWholeGroup_part2() throws Exception {
+        // Make sure we don't have the permissions
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
+    }
+
+    @Test
+    public void testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part1() throws Exception {
+        // Make sure we don't have the permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
+
+        String[] permissions = new String[] {Manifest.permission.READ_CALENDAR};
+
+        // Request the permission and deny it
+        BasePermissionActivity.Result firstResult = requestPermissions(
+                permissions, REQUEST_CODE_PERMISSIONS,
+                BasePermissionActivity.class, () -> {
+                    try {
+                        clickDenyButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Expect the permission is not granted
+        assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS,
+                permissions, new boolean[] {false});
+
+        // Request the permission and choose don't ask again
+        BasePermissionActivity.Result secondResult = requestPermissions(new String[] {
+                        Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS + 1,
+                BasePermissionActivity.class, () -> {
+                    try {
+                        clickDontAskAgainCheckbox();
+                        clickDenyButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Expect the permission is not granted
+        assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1,
+                permissions, new boolean[] {false});
+
+        // Clear the denial with prejudice
+        grantPermission(Manifest.permission.READ_CALENDAR);
+        revokePermission(Manifest.permission.READ_CALENDAR);
+
+        // We just committed a suicide by revoking the permission. See part2 below...
+    }
+
+    @Test
+    public void testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part2() throws Exception {
+        // Make sure we don't have the permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
+
+        // Request the permission and allow it
+        BasePermissionActivity.Result thirdResult = requestPermissions(new String[] {
+                        Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS + 2,
+                BasePermissionActivity.class, () -> {
+                    try {
+                        clickAllowButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Make sure the permission is granted
+        assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS + 2,
+                new String[] {Manifest.permission.READ_CALENDAR}, new boolean[] {true});
+    }
+
+    @Test
+    public void testRequestNonRuntimePermission() throws Exception {
+        // Make sure we don't have the permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.BIND_PRINT_SERVICE));
+
+        String[] permissions = new String[] {Manifest.permission.BIND_PRINT_SERVICE};
+
+        // Request the permission and do nothing
+        BasePermissionActivity.Result result = requestPermissions(permissions,
+                REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, null);
+
+        // Expect the permission is not granted
+        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
+                permissions, new boolean[] {false});
+    }
+
+    @Test
+    public void testRequestNonExistentPermission() throws Exception {
+        // Make sure we don't have the permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission("permission.does.not.exist"));
+
+        String[] permissions = new String[] {"permission.does.not.exist"};
+
+        // Request the permission and do nothing
+        BasePermissionActivity.Result result = requestPermissions(permissions,
+                REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, null);
+
+        // Expect the permission is not granted
+        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
+                permissions, new boolean[] {false});
+    }
+
+    @Test
+    public void testRequestPermissionFromTwoGroups() throws Exception {
+        // Make sure we don't have the permissions
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
+
+        String[] permissions = new String[] {
+                Manifest.permission.WRITE_CONTACTS,
+                Manifest.permission.WRITE_CALENDAR
+        };
+
+        // Request the permission and do nothing
+        BasePermissionActivity.Result result = requestPermissions(permissions,
+                REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, () -> {
+            try {
+                clickAllowButton();
+                getUiDevice().waitForIdle();
+                clickAllowButton();
+                getUiDevice().waitForIdle();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
+
+        // Expect the permission is not granted
+        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
+                permissions, new boolean[] {true, true});
+    }
+
+    @Test
+    public void testNoResidualPermissionsOnUninstall_part1() throws Exception {
+        // Grant all permissions
+        grantPermissions(new String[] {
+                Manifest.permission.WRITE_CALENDAR,
+                Manifest.permission.WRITE_CONTACTS,
+                Manifest.permission.WRITE_EXTERNAL_STORAGE,
+                Manifest.permission.READ_SMS,
+                Manifest.permission.CALL_PHONE,
+                Manifest.permission.RECORD_AUDIO,
+                Manifest.permission.BODY_SENSORS,
+                Manifest.permission.ACCESS_COARSE_LOCATION,
+                Manifest.permission.CAMERA
+        });
+    }
+
+    @Test
+    public void testNoResidualPermissionsOnUninstall_part2() throws Exception {
+        // Make no permissions are granted after uninstalling and installing the app
+        assertAllPermissionsRevoked();
+    }
+
+    @Test
+    public void testRevokePropagatedOnUpgradeOldToNewModel_part2() throws Exception {
+        assertPermissionsGrantState(new String[] {Manifest.permission.WRITE_CALENDAR},
+                PackageManager.PERMISSION_DENIED);
+    }
+
+
+    public void testRevokePropagatedOnUpgradeNewToNewModel_part1() throws Exception {
+        // Make sure we don't have the permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
+
+        // Request the permission and allow it
+        BasePermissionActivity.Result thirdResult = requestPermissions(new String[] {
+                        Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS,
+                BasePermissionActivity.class, () -> {
+                    try {
+                        clickAllowButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Make sure the permission is granted
+        assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS,
+                new String[] {Manifest.permission.READ_CALENDAR}, new boolean[] {true});
+    }
+
+    public void testRevokePropagatedOnUpgradeNewToNewModel_part2() throws Exception {
+        // Make sure the permission is still granted after the upgrade
+        assertPermissionsGrantState(new String[] {Manifest.permission.READ_CALENDAR},
+                PackageManager.PERMISSION_GRANTED);
+        // Also make sure one of the not granted permissions is still not granted
+        assertPermissionsGrantState(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},
+                PackageManager.PERMISSION_DENIED);
+    }
+
+    private void assertAllPermissionsRevoked() {
+        assertAllPermissionsGrantState(PackageManager.PERMISSION_DENIED);
+    }
+
+    private void assertAllPermissionsGrantState(int grantState) {
+        assertPermissionsGrantState(new String[] {
+                Manifest.permission.SEND_SMS,
+                Manifest.permission.RECEIVE_SMS,
+                Manifest.permission.RECEIVE_WAP_PUSH,
+                Manifest.permission.RECEIVE_MMS,
+                Manifest.permission.READ_CALENDAR,
+                Manifest.permission.WRITE_CALENDAR,
+                Manifest.permission.WRITE_CONTACTS,
+                Manifest.permission.READ_EXTERNAL_STORAGE,
+                Manifest.permission.WRITE_EXTERNAL_STORAGE,
+                Manifest.permission.READ_SMS,
+                Manifest.permission.READ_PHONE_STATE,
+                Manifest.permission.READ_CALL_LOG,
+                Manifest.permission.WRITE_CALL_LOG,
+                Manifest.permission.ADD_VOICEMAIL,
+                Manifest.permission.CALL_PHONE,
+                Manifest.permission.USE_SIP,
+                Manifest.permission.PROCESS_OUTGOING_CALLS,
+                Manifest.permission.RECORD_AUDIO,
+                Manifest.permission.BODY_SENSORS,
+                Manifest.permission.ACCESS_FINE_LOCATION,
+                Manifest.permission.ACCESS_COARSE_LOCATION,
+                Manifest.permission.CAMERA,
+                Manifest.permission.BODY_SENSORS,
+                "android.permission.READ_CELL_BROADCASTS"
+        }, grantState);
+    }
+
+    private void assertPermissionsGrantState(String[] permissions, int grantState) {
+        for (String permission : permissions) {
+            assertEquals(grantState, getInstrumentation().getContext()
+                    .checkSelfPermission(permission));
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionApp24/Android.mk
similarity index 79%
copy from hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk
copy to hostsidetests/appsecurity/test-apps/UsePermissionApp24/Android.mk
index 4630f1f..d280372 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp24/Android.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2015 The Android Open Source Project
+# 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.
@@ -19,13 +19,13 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ctsdeviceutil ctstestrunner ub-uiautomator
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-    ../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
+    ../UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionActivity.java \
+    ../UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
 
-LOCAL_PACKAGE_NAME := CtsUsePermissionApp
+LOCAL_PACKAGE_NAME := CtsUsePermissionApp24
 
 # tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UsePermissionApp24/AndroidManifest.xml
similarity index 61%
copy from hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/AndroidManifest.xml
copy to hostsidetests/appsecurity/test-apps/UsePermissionApp24/AndroidManifest.xml
index 253d85d..64f3f34 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp24/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<!-- 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.
@@ -16,12 +16,17 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.cts.usepermission">
+
+    <!-- Request two different permissions within the same group -->
+    <uses-permission android:name="android.permission.SEND_SMS" />
+    <uses-permission android:name="android.permission.RECEIVE_SMS" />
+
     <application>
-        <uses-library android:name="android.test.runner" />
-        <activity android:name=".MyActivity" />
+        <activity android:name="com.android.cts.usepermission.BasePermissionActivity" />
     </application>
+
     <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.cts.usepermission" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+            android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.cts.usepermission" />
+
 </manifest>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp24/src/com/android/cts/usepermission/UsePermissionTest24.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp24/src/com/android/cts/usepermission/UsePermissionTest24.java
new file mode 100644
index 0000000..f87c67f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp24/src/com/android/cts/usepermission/UsePermissionTest24.java
@@ -0,0 +1,78 @@
+/*
+ * 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.usepermission;
+
+import android.Manifest;
+import android.content.pm.PackageManager;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+
+/**
+ * Runtime permission behavior tests for apps targeting API 24
+ */
+public class UsePermissionTest24 extends BasePermissionsTest {
+    private static final int REQUEST_CODE_PERMISSIONS = 42;
+
+    @Test
+    public void testOnlyRequestedPermissionsGranted() throws Exception {
+        // Start out without permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.RECEIVE_SMS));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.SEND_SMS));
+
+        String[] firstPermissions = new String[] {Manifest.permission.RECEIVE_SMS};
+
+        // Request only one permission and confirm
+        BasePermissionActivity.Result firstResult = requestPermissions(firstPermissions,
+                REQUEST_CODE_PERMISSIONS,
+                BasePermissionActivity.class,
+                () -> {
+                    try {
+                        clickAllowButton();
+                        getUiDevice().waitForIdle();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+
+        // Expect the permission is granted
+        assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS,
+                firstPermissions, new boolean[] {true});
+
+        // We should not have the other permission in the group
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.SEND_SMS));
+
+        String[] secondPermissions = new String[] {Manifest.permission.SEND_SMS};
+
+        // Request the other permission which should be auto-granted
+        BasePermissionActivity.Result secondResult = requestPermissions(secondPermissions,
+                REQUEST_CODE_PERMISSIONS + 1, BasePermissionActivity.class, null);
+
+        // Expect the permission is granted
+        assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1,
+                secondPermissions, new boolean[] {true});
+
+        // We now should have both permissions
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.RECEIVE_SMS));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(Manifest.permission.SEND_SMS));
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/Android.mk
deleted file mode 100644
index 8727c43..0000000
--- a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := 21
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ctsdeviceutil ctstestrunner ub-uiautomator
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-    ../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
-
-LOCAL_PACKAGE_NAME := CtsUsePermissionAppCompat
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
-
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/src/com/android/cts/usepermission/UsePermissionCompatTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/src/com/android/cts/usepermission/UsePermissionCompatTest.java
deleted file mode 100644
index 7f21d3400..0000000
--- a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/src/com/android/cts/usepermission/UsePermissionCompatTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 com.android.cts.usepermission;
-
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPaths;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Environment;
-import android.os.Process;
-import android.test.InstrumentationTestCase;
-
-import java.io.File;
-
-public class UsePermissionCompatTest extends InstrumentationTestCase {
-    private static final String TAG = "UsePermissionTest";
-
-    public void testCompatDefault() throws Exception {
-        final Context context = getInstrumentation().getContext();
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
-        // Legacy permission model is granted by default
-        assertEquals(PackageManager.PERMISSION_GRANTED,
-                context.checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE,
-                        Process.myPid(), Process.myUid()));
-        assertEquals(PackageManager.PERMISSION_GRANTED,
-                context.checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
-                        Process.myPid(), Process.myUid()));
-        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
-        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
-        for (File path : getAllPackageSpecificPaths(context)) {
-            if (path != null) {
-                assertDirReadWriteAccess(path);
-            }
-        }
-        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
-    }
-
-    public void testCompatRevoked() throws Exception {
-        final Context context = getInstrumentation().getContext();
-        logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
-        // Legacy permission model appears granted, but storage looks and
-        // behaves like it's ejected
-        assertEquals(PackageManager.PERMISSION_GRANTED,
-                context.checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE,
-                        Process.myPid(), Process.myUid()));
-        assertEquals(PackageManager.PERMISSION_GRANTED,
-                context.checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
-                        Process.myPid(), Process.myUid()));
-        assertEquals(Environment.MEDIA_UNMOUNTED, Environment.getExternalStorageState());
-        assertDirNoAccess(Environment.getExternalStorageDirectory());
-        for (File dir : getAllPackageSpecificPaths(context)) {
-            if (dir != null) {
-                assertDirNoAccess(dir);
-            }
-        }
-        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver());
-
-        // Just to be sure, poke explicit path
-        assertDirNoAccess(new File(Environment.getExternalStorageDirectory(),
-                "/Android/data/" + getInstrumentation().getContext().getPackageName()));
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ContactsTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ContactsTest.java
index 5a2b3fa..d9e56cb 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ContactsTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ContactsTest.java
@@ -41,6 +41,7 @@
 import android.provider.ContactsContract.PhoneLookup;
 import android.provider.ContactsContract.RawContacts;
 import android.test.AndroidTestCase;
+import android.util.Log;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileNotFoundException;
@@ -52,6 +53,8 @@
 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public class ContactsTest extends AndroidTestCase {
 
+    private static final String TAG = "ContactsTest";
+
     private static final String TEST_ACCOUNT_NAME = AccountAuthenticator.ACCOUNT_NAME;
     private static final String TEST_ACCOUNT_TYPE = AccountAuthenticator.ACCOUNT_TYPE;
     // details of a sample primary contact
@@ -79,6 +82,10 @@
     private static final String PRIMARY_DIRECTORY_CONTACT_NAME = "PrimaryDirectoryContact";
     private static final String MANAGED_DIRECTORY_CONTACT_NAME = "ManagedDirectoryContact";
 
+    // Retry directory query so we can make sure directory info in cp2 is updated
+    private static final int MAX_RETRY_DIRECTORY_QUERY = 10;
+    private static final int RETRY_DIRECTORY_QUERY_INTERVAL = 1000; // 1s
+
     private DevicePolicyManager mDevicePolicyManager;
     private ContentResolver mResolver;
 
@@ -502,48 +509,66 @@
 
     public void testGetDirectoryListInPrimaryProfile() {
         assertFalse(isManagedProfile());
-        final Cursor cursor = mResolver.query(Directory.ENTERPRISE_CONTENT_URI,
-                new String[]{
-                        Directory._ID,
-                        Directory.DISPLAY_NAME
-                }, null, null, null);
+        // As directory content in CP2 may not be updated, we will try 10 times to see if it's
+        // updated
+        for (int i = 0; i < MAX_RETRY_DIRECTORY_QUERY; i++) {
+            final Cursor cursor = mResolver.query(Directory.ENTERPRISE_CONTENT_URI,
+                    new String[]{
+                            Directory._ID,
+                            Directory.DISPLAY_NAME
+                    }, null, null, null);
 
-        boolean hasPrimaryDefault = false;
-        boolean hasPrimaryInvisible = false;
-        boolean hasManagedDefault = false;
-        boolean hasManagedInvisible = false;
-        boolean hasPrimaryDirectory = false;
-        boolean hasManagedDirectory = false;
+            boolean hasPrimaryDefault = false;
+            boolean hasPrimaryInvisible = false;
+            boolean hasManagedDefault = false;
+            boolean hasManagedInvisible = false;
+            boolean hasPrimaryDirectory = false;
+            boolean hasManagedDirectory = false;
 
-        while(cursor.moveToNext()) {
-            final long directoryId = cursor.getLong(0);
-            if (directoryId == Directory.DEFAULT) {
-                hasPrimaryDefault = true;
-            } else if (directoryId == Directory.LOCAL_INVISIBLE) {
-                hasPrimaryInvisible = true;
-            } else if (directoryId == Directory.ENTERPRISE_DEFAULT) {
-                hasManagedDefault = true;
-            } else if (directoryId == Directory.ENTERPRISE_LOCAL_INVISIBLE) {
-                hasManagedInvisible = true;
-            } else {
-                final String displayName = cursor.getString(1);
-                if (Directory.isEnterpriseDirectoryId(directoryId)
-                        && displayName.equals(MANAGED_DIRECTORY_NAME)) {
-                    hasManagedDirectory = true;
-                }
-                if (!Directory.isEnterpriseDirectoryId(directoryId)
-                        && displayName.equals(PRIMARY_DIRECTORY_NAME)) {
-                    hasPrimaryDirectory = true;
+            while(cursor.moveToNext()) {
+                final long directoryId = cursor.getLong(0);
+                if (directoryId == Directory.DEFAULT) {
+                    hasPrimaryDefault = true;
+                } else if (directoryId == Directory.LOCAL_INVISIBLE) {
+                    hasPrimaryInvisible = true;
+                } else if (directoryId == Directory.ENTERPRISE_DEFAULT) {
+                    hasManagedDefault = true;
+                } else if (directoryId == Directory.ENTERPRISE_LOCAL_INVISIBLE) {
+                    hasManagedInvisible = true;
+                } else {
+                    final String displayName = cursor.getString(1);
+                    if (Directory.isEnterpriseDirectoryId(directoryId)
+                            && displayName.equals(MANAGED_DIRECTORY_NAME)) {
+                        hasManagedDirectory = true;
+                    }
+                    if (!Directory.isEnterpriseDirectoryId(directoryId)
+                            && displayName.equals(PRIMARY_DIRECTORY_NAME)) {
+                        hasPrimaryDirectory = true;
+                    }
                 }
             }
+            cursor.close();
+
+            if (i + 1 == MAX_RETRY_DIRECTORY_QUERY) {
+                assertTrue(hasPrimaryDefault);
+                assertTrue(hasPrimaryInvisible);
+                assertTrue(hasManagedDefault);
+                assertTrue(hasManagedInvisible);
+                assertTrue(hasPrimaryDirectory);
+                assertTrue(hasManagedDirectory);
+            }
+            if (hasPrimaryDefault && hasPrimaryInvisible && hasManagedDefault
+                    && hasManagedInvisible && hasPrimaryDirectory && hasManagedDirectory) {
+                // Success
+                return;
+            } else {
+                // Failed, sleep and retry
+                try {
+                    Log.i(TAG, "Failed " + (i+1) + " times, retry");
+                    Thread.sleep(RETRY_DIRECTORY_QUERY_INTERVAL);
+                } catch (InterruptedException e) {}
+            }
         }
-        cursor.close();
-        assertTrue(hasPrimaryDefault);
-        assertTrue(hasPrimaryInvisible);
-        assertTrue(hasManagedDefault);
-        assertTrue(hasManagedInvisible);
-        assertTrue(hasPrimaryDirectory);
-        assertTrue(hasManagedDirectory);
     }
 
     public void testPrimaryProfileEnterpriseEmailLookup_canAccessPrimaryDirectories() {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 51f2457..e941b43 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -306,12 +306,18 @@
     }
 
     public void testSecurityLoggingWithSingleUser() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
         executeDeviceTestMethod(".SecurityLoggingTest",
                 "testRetrievingSecurityLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval");
         executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingAndDisablingSecurityLogging");
     }
 
     public void testLockTask() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
         try {
             installAppAsUser(INTENT_RECEIVER_APK, mPrimaryUserId);
             executeDeviceOwnerTest("LockTaskTest");
@@ -321,6 +327,9 @@
     }
 
     public void testSystemUpdatePolicy() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
         executeDeviceOwnerTest("SystemUpdatePolicyTest");
     }
 
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTestApi23.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTestApi23.java
index d94748d..914fe19 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTestApi23.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTestApi23.java
@@ -51,6 +51,9 @@
     }
 
     public void testDelegatedCertInstaller() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
         assertTrue("DelegatedCertInstaller failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
                 ".DelegatedCertInstallerTest", "testSetNotExistCertInstallerPackage",  mUserId));
     }
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java b/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
index da346ac..f1f24c9 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/WindowManagerState.java
@@ -384,7 +384,6 @@
         }
 
         private void extract(LinkedList<String> dump, Pattern[] exitPatterns) {
-
             while (!doneExtracting(dump, exitPatterns)) {
                 final String line = dump.pop().trim();
 
@@ -417,7 +416,7 @@
     static abstract class WindowContainer {
         protected static final Pattern sFullscreenPattern = Pattern.compile("mFullscreen=(\\S+)");
         protected static final Pattern sBoundsPattern =
-                Pattern.compile("mBounds=\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]");
+                Pattern.compile("mBounds=\\[(-?\\d+),(-?\\d+)\\]\\[(-?\\d+),(-?\\d+)\\]");
 
         protected boolean mFullscreen;
         protected Rectangle mBounds;
diff --git a/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java b/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
index b9ee987..ee44f8a 100644
--- a/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
+++ b/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
@@ -128,6 +128,12 @@
         setPictureListener(null);
         setWebChromeClient(null);
         setWebViewClient(null);
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mWebView.destroy();
+            }
+        });
     }
 
     /**
diff --git a/tests/JobScheduler/AndroidManifest.xml b/tests/JobScheduler/AndroidManifest.xml
index 2078978..876882f 100755
--- a/tests/JobScheduler/AndroidManifest.xml
+++ b/tests/JobScheduler/AndroidManifest.xml
@@ -23,12 +23,19 @@
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <application>
         <uses-library android:name="android.test.runner" />
 
         <service android:name="android.jobscheduler.MockJobService"
             android:permission="android.permission.BIND_JOB_SERVICE" />
+        <service android:name="android.jobscheduler.TriggerContentJobService"
+            android:permission="android.permission.BIND_JOB_SERVICE" />
+
+        <provider android:name="android.jobscheduler.DummyJobContentProvider"
+            android:authorities="android.jobscheduler.dummyprovider" android:multiprocess="false" />
     </application>
 
     <!--  self-instrumenting test package. -->
diff --git a/tests/JobScheduler/assets/violet.jpg b/tests/JobScheduler/assets/violet.jpg
new file mode 100644
index 0000000..7785dfd
--- /dev/null
+++ b/tests/JobScheduler/assets/violet.jpg
Binary files differ
diff --git a/tests/JobScheduler/src/android/jobscheduler/DummyJobContentProvider.java b/tests/JobScheduler/src/android/jobscheduler/DummyJobContentProvider.java
new file mode 100644
index 0000000..cc8cf21
--- /dev/null
+++ b/tests/JobScheduler/src/android/jobscheduler/DummyJobContentProvider.java
@@ -0,0 +1,167 @@
+/*
+ * 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.jobscheduler;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.net.Uri;
+
+/**
+ * Stub content provider used for generating content change reports
+ */
+public class DummyJobContentProvider extends ContentProvider {
+    private static final String DATABASE_NAME = "dummy.db";
+    private static final String NAME_VALUE_TABLE = "name_value";
+
+    private DatabaseHelper mDbHelper;
+    private static UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final int MATCH_NAME_VALUE      = 1;
+
+    public static final String AUTHORITY = "android.jobscheduler.dummyprovider";
+    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
+
+    public static final String _ID   = "_id";
+    public static final String NAME  = "name";
+    public static final String VALUE = "value";
+
+    static {
+        sMatcher.addURI(AUTHORITY, null, MATCH_NAME_VALUE);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#onCreate()
+     */
+    @Override
+    public boolean onCreate() {
+        mDbHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
+    private class DatabaseHelper extends SQLiteOpenHelper {
+        private static final int DATABASE_VERSION = 1;
+
+        DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            // create an empty name_value table
+            db.execSQL("CREATE TABLE " + NAME_VALUE_TABLE + " (" + _ID + " INTEGER PRIMARY KEY,"
+                    + NAME + " TEXT," + VALUE + " TEXT"+ ");");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#insert(android.net.Uri,
+     * android.content.ContentValues)
+     */
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        String tbName = getTableName(uri);
+        if (tbName == null) {
+            return null;
+        }
+        SQLiteDatabase db = mDbHelper.getWritableDatabase();
+        db.insert(tbName, VALUE, values);
+        getContext().getContentResolver().notifyChange(uri, null);
+        return uri;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#query(android.net.Uri,
+     * java.lang.String[], java.lang.String, java.lang.String[],
+     * java.lang.String)
+     */
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        String tbName = getTableName(uri);
+        if (tbName == null) {
+            return null;
+        }
+        SQLiteDatabase db = mDbHelper.getReadableDatabase();
+        Cursor c = db.query(tbName, projection, selection, selectionArgs, null, null, sortOrder);
+        c.setNotificationUri(getContext().getContentResolver(), uri);
+        return c;
+    }
+
+    private String getTableName(Uri uri) {
+        switch (sMatcher.match(uri)) {
+            case MATCH_NAME_VALUE:
+                return NAME_VALUE_TABLE;
+            default:
+                throw new UnsupportedOperationException();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#update(android.net.Uri,
+     * android.content.ContentValues, java.lang.String, java.lang.String[])
+     */
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        String tbName = getTableName(uri);
+        if (tbName == null) {
+            return 0;
+        }
+        SQLiteDatabase db = mDbHelper.getWritableDatabase();
+        int count = db.update(tbName, values, selection, selectionArgs);
+        getContext().getContentResolver().notifyChange(uri, null);
+        return count;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#delete(android.net.Uri,
+     * java.lang.String, java.lang.String[])
+     */
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        String tbName = getTableName(uri);
+        if (tbName == null) {
+            return 0;
+        }
+        SQLiteDatabase db = mDbHelper.getWritableDatabase();
+        int count = db.delete(tbName, selection, selectionArgs);
+        getContext().getContentResolver().notifyChange(uri, null);
+        return count;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.ContentProvider#getType(android.net.Uri)
+     */
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+}
diff --git a/tests/JobScheduler/src/android/jobscheduler/TriggerContentJobService.java b/tests/JobScheduler/src/android/jobscheduler/TriggerContentJobService.java
new file mode 100644
index 0000000..d87f1a7
--- /dev/null
+++ b/tests/JobScheduler/src/android/jobscheduler/TriggerContentJobService.java
@@ -0,0 +1,179 @@
+/*
+ * 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.jobscheduler;
+
+import android.annotation.TargetApi;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.Context;
+import android.os.Handler;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Handles callback from the framework {@link android.app.job.JobScheduler}. The behaviour of this
+ * class is configured through the static
+ * {@link TestEnvironment}.
+ */
+@TargetApi(21)
+public class TriggerContentJobService extends JobService {
+    private static final String TAG = "TriggerContentJobService";
+
+    /** Wait this long before timing out the test. */
+    private static final long DEFAULT_TIMEOUT_MILLIS = 30000L; // 30 seconds.
+
+    /** How long to delay before rescheduling the job each time we repeat. */
+    private static final long REPEAT_INTERVAL = 1000L; // 1 second.
+
+    JobInfo mRunningJobInfo;
+    JobParameters mRunningParams;
+
+    final Handler mHandler = new Handler();
+    final Runnable mWorker = new Runnable() {
+        @Override public void run() {
+            scheduleJob(TriggerContentJobService.this, mRunningJobInfo);
+            jobFinished(mRunningParams, false);
+        }
+    };
+
+    public static void scheduleJob(Context context, JobInfo jobInfo) {
+        JobScheduler js = context.getSystemService(JobScheduler.class);
+        js.schedule(jobInfo);
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.e(TAG, "Created test service.");
+    }
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        Log.i(TAG, "Test job executing: " + params.getJobId());
+
+        int mode = TestEnvironment.getTestEnvironment().getMode();
+        mRunningJobInfo = TestEnvironment.getTestEnvironment().getModeJobInfo();
+        TestEnvironment.getTestEnvironment().setMode(TestEnvironment.MODE_ONESHOT, null);
+        TestEnvironment.getTestEnvironment().notifyExecution(params);
+
+        if (mode == TestEnvironment.MODE_ONE_REPEAT) {
+            mRunningParams = params;
+            mHandler.postDelayed(mWorker, REPEAT_INTERVAL);
+            return true;
+        } else {
+            return false;  // No work to do.
+        }
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        return false;
+    }
+
+    /**
+     * Configures the expected behaviour for each test. This object is shared across consecutive
+     * tests, so to clear state each test is responsible for calling
+     * {@link TestEnvironment#setUp()}.
+     */
+    public static final class TestEnvironment {
+
+        private static TestEnvironment kTestEnvironment;
+        //public static final int INVALID_JOB_ID = -1;
+
+        private CountDownLatch mLatch;
+        private JobParameters mExecutedJobParameters;
+        private int mMode;
+        private JobInfo mModeJobInfo;
+
+        public static final int MODE_ONESHOT = 0;
+        public static final int MODE_ONE_REPEAT = 1;
+
+        public static TestEnvironment getTestEnvironment() {
+            if (kTestEnvironment == null) {
+                kTestEnvironment = new TestEnvironment();
+            }
+            return kTestEnvironment;
+        }
+
+        public JobParameters getLastJobParameters() {
+            return mExecutedJobParameters;
+        }
+
+        /**
+         * Block the test thread, waiting on the JobScheduler to execute some previously scheduled
+         * job on this service.
+         */
+        public boolean awaitExecution() throws InterruptedException {
+            final boolean executed = mLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+            return executed;
+        }
+
+        public void setMode(int mode, JobInfo jobInfo) {
+            synchronized (this) {
+                mMode = mode;
+                mModeJobInfo = jobInfo;
+            }
+        }
+
+        public int getMode() {
+            synchronized (this) {
+                return mMode;
+            }
+        }
+
+        public JobInfo getModeJobInfo() {
+            synchronized (this) {
+                return mModeJobInfo;
+            }
+        }
+
+        /**
+         * Block the test thread, expecting to timeout but still listening to ensure that no jobs
+         * land in the interim.
+         * @return True if the latch timed out waiting on an execution.
+         */
+        public boolean awaitTimeout() throws InterruptedException {
+            return !mLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        }
+
+        private void notifyExecution(JobParameters params) {
+            Log.d(TAG, "Job executed:" + params.getJobId());
+            mExecutedJobParameters = params;
+            mLatch.countDown();
+        }
+
+        public void setExpectedExecutions(int numExecutions) {
+            // For no executions expected, set count to 1 so we can still block for the timeout.
+            if (numExecutions == 0) {
+                mLatch = new CountDownLatch(1);
+            } else {
+                mLatch = new CountDownLatch(numExecutions);
+            }
+        }
+
+        /** Called in each testCase#setup */
+        public void setUp() {
+            mLatch = null;
+            mExecutedJobParameters = null;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java
index b9a498f..35903d7 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConstraintTest.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.jobscheduler.MockJobService;
+import android.jobscheduler.TriggerContentJobService;
 import android.test.AndroidTestCase;
 
 /**
@@ -35,14 +36,21 @@
     /** Environment that notifies of JobScheduler callbacks. */
     static MockJobService.TestEnvironment kTestEnvironment =
             MockJobService.TestEnvironment.getTestEnvironment();
+    static TriggerContentJobService.TestEnvironment kTriggerTestEnvironment =
+            TriggerContentJobService.TestEnvironment.getTestEnvironment();
     /** Handle for the service which receives the execution callbacks from the JobScheduler. */
     static ComponentName kJobServiceComponent;
+    static ComponentName kTriggerContentServiceComponent;
     JobScheduler mJobScheduler;
 
     @Override
     public void setUp() throws Exception {
+        super.setUp();
         kTestEnvironment.setUp();
+        kTriggerTestEnvironment.setUp();
         kJobServiceComponent = new ComponentName(getContext(), MockJobService.class);
+        kTriggerContentServiceComponent = new ComponentName(getContext(),
+                TriggerContentJobService.class);
         mJobScheduler = (JobScheduler) getContext().getSystemService(Context.JOB_SCHEDULER_SERVICE);
         mJobScheduler.cancelAll();
     }
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java
new file mode 100644
index 0000000..32959a0
--- /dev/null
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java
@@ -0,0 +1,394 @@
+/*
+ * 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.jobscheduler.cts;
+
+import android.annotation.TargetApi;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.jobscheduler.DummyJobContentProvider;
+import android.jobscheduler.TriggerContentJobService;
+import android.media.MediaScannerConnection;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.Process;
+import android.provider.MediaStore;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Schedules jobs that look for content URI changes and ensures they are triggered correctly.
+ */
+@TargetApi(23)
+public class TriggerContentTest extends ConstraintTest {
+    public static final int TRIGGER_CONTENT_JOB_ID = ConnectivityConstraintTest.class.hashCode();
+
+    // The root URI of the media provider, to monitor for generic changes to its content.
+    static final Uri MEDIA_URI = Uri.parse("content://" + MediaStore.AUTHORITY + "/");
+
+    // Media URI for all external media content.
+    static final Uri MEDIA_EXTERNAL_URI = Uri.parse("content://" + MediaStore.AUTHORITY
+            + "/external");
+
+    // Path segments for image-specific URIs in the provider.
+    static final List<String> EXTERNAL_PATH_SEGMENTS
+            = MediaStore.Images.Media.EXTERNAL_CONTENT_URI.getPathSegments();
+
+    // The columns we want to retrieve about a particular image.
+    static final String[] PROJECTION = new String[] {
+            MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATA
+    };
+    static final int PROJECTION_ID = 0;
+    static final int PROJECTION_DATA = 1;
+
+    // This is the external storage directory where cameras place pictures.
+    static final String DCIM_DIR = Environment.getExternalStoragePublicDirectory(
+            Environment.DIRECTORY_DCIM).getPath();
+
+    static final String PIC_1_NAME = "TriggerContentTest1_" + Process.myPid();
+    static final String PIC_2_NAME = "TriggerContentTest2_" + Process.myPid();
+
+    File[] mActiveFiles = new File[5];
+    Uri[] mActiveUris = new Uri[5];
+
+    static class MediaScanner implements MediaScannerConnection.OnScanCompletedListener {
+        private static final long DEFAULT_TIMEOUT_MILLIS = 1000L; // 1 second.
+
+        private CountDownLatch mLatch;
+        private String mScannedPath;
+        private Uri mScannedUri;
+
+        public boolean scan(Context context, String file, String mimeType)
+                throws InterruptedException {
+            mLatch = new CountDownLatch(1);
+            MediaScannerConnection.scanFile(context,
+                    new String[] { file.toString() }, new String[] { mimeType }, this);
+            return mLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        }
+
+        public String getScannedPath() {
+            synchronized (this) {
+                return mScannedPath;
+            }
+        }
+
+        public Uri getScannedUri() {
+            synchronized (this) {
+                return mScannedUri;
+            }
+        }
+
+        @Override public void onScanCompleted(String path, Uri uri) {
+            synchronized (this) {
+                mScannedPath = path;
+                mScannedUri = uri;
+                mLatch.countDown();
+            }
+        }
+    }
+
+    private void cleanupActive(int which) {
+        if (mActiveUris[which] != null) {
+            getContext().getContentResolver().delete(mActiveUris[which], null, null);
+            mActiveUris[which] = null;
+        }
+        if (mActiveFiles[which] != null) {
+            mActiveFiles[which].delete();
+            mActiveFiles[which] = null;
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        for (int i=0; i<mActiveFiles.length; i++) {
+            cleanupActive(i);
+        }
+    }
+
+    private JobInfo makeJobInfo(Uri uri, int flags) {
+        JobInfo.Builder builder = new JobInfo.Builder(TRIGGER_CONTENT_JOB_ID,
+                kTriggerContentServiceComponent);
+        builder.addTriggerContentUri(new JobInfo.TriggerContentUri(uri, flags));
+        // For testing purposes, react quickly.
+        builder.setTriggerContentUpdateDelay(500);
+        builder.setTriggerContentMaxDelay(500);
+        return builder.build();
+    }
+
+    private JobInfo makePhotosJobInfo() {
+        JobInfo.Builder builder = new JobInfo.Builder(TRIGGER_CONTENT_JOB_ID,
+                kTriggerContentServiceComponent);
+        // Look for specific changes to images in the provider.
+        builder.addTriggerContentUri(new JobInfo.TriggerContentUri(
+                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+                JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
+        // Also look for general reports of changes in the overall provider.
+        builder.addTriggerContentUri(new JobInfo.TriggerContentUri(MEDIA_URI, 0));
+        // For testing purposes, react quickly.
+        builder.setTriggerContentUpdateDelay(500);
+        builder.setTriggerContentMaxDelay(500);
+        return builder.build();
+    }
+
+    public static void copyToFileOrThrow(InputStream inputStream, File destFile)
+            throws IOException {
+        if (destFile.exists()) {
+            destFile.delete();
+        }
+        FileOutputStream out = new FileOutputStream(destFile);
+        try {
+            byte[] buffer = new byte[4096];
+            int bytesRead;
+            while ((bytesRead = inputStream.read(buffer)) >= 0) {
+                out.write(buffer, 0, bytesRead);
+            }
+        } finally {
+            out.flush();
+            try {
+                out.getFD().sync();
+            } catch (IOException e) {
+            }
+            out.close();
+            inputStream.close();
+        }
+    }
+
+    public Uri createAndAddImage(File destFile, InputStream image) throws IOException,
+            InterruptedException {
+        copyToFileOrThrow(image, destFile);
+        MediaScanner scanner = new MediaScanner();
+        boolean success = scanner.scan(getContext(), destFile.toString(), "image/jpeg");
+        if (success) {
+            return scanner.getScannedUri();
+        }
+        return null;
+    }
+
+    public Uri makeActiveFile(int which, File file, InputStream source) throws IOException,
+                InterruptedException {
+        mActiveFiles[which] = file;
+        mActiveUris[which] = createAndAddImage(file, source);
+        return mActiveUris[which];
+    }
+
+    private void assertUriArrayLength(int length, Uri[] uris) {
+        if (uris.length != length) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Expected ");
+            sb.append(length);
+            sb.append(" URI, got ");
+            sb.append(uris.length);
+            if (uris.length > 0) {
+                sb.append(": ");
+                for (int i=0; i<uris.length; i++) {
+                    if (i > 0) {
+                        sb.append(", ");
+                    }
+                    sb.append(uris[i]);
+                }
+            }
+            fail(sb.toString());
+        }
+    }
+
+    private void assertHasUri(Uri wanted, Uri[] uris) {
+        for (int i=0; i<uris.length; i++) {
+            if (wanted.equals(uris[i])) {
+                return;
+            }
+        }
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("Don't have uri ");
+        sb.append(wanted);
+        sb.append(" in: ");
+        for (int i=0; i<uris.length; i++) {
+            if (i > 0) {
+                sb.append(", ");
+            }
+            sb.append(uris[i]);
+        }
+        fail(sb.toString());
+    }
+
+    public void testDescendantsObserver() throws Exception {
+        String base = "content://" + DummyJobContentProvider.AUTHORITY + "/root";
+        Uri uribase = Uri.parse(base);
+        Uri uri1 = Uri.parse(base + "/sub1");
+        Uri uri2 = Uri.parse(base + "/sub2");
+
+        // Start watching.
+        JobInfo triggerJob = makeJobInfo(uribase,
+                JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS);
+        kTriggerTestEnvironment.setExpectedExecutions(1);
+        kTriggerTestEnvironment.setMode(TriggerContentJobService.TestEnvironment.MODE_ONE_REPEAT,
+                triggerJob);
+        mJobScheduler.schedule(triggerJob);
+
+        // Report changes.
+        getContext().getContentResolver().notifyChange(uribase, null, 0);
+        getContext().getContentResolver().notifyChange(uri1, null, 0);
+
+        // Wait and check results
+        boolean executed = kTriggerTestEnvironment.awaitExecution();
+        kTriggerTestEnvironment.setExpectedExecutions(1);
+        assertTrue("Timed out waiting for trigger content.", executed);
+        JobParameters params = kTriggerTestEnvironment.getLastJobParameters();
+        Uri[] uris = params.getTriggeredContentUris();
+        assertUriArrayLength(2, uris);
+        assertHasUri(uribase, uris);
+        assertHasUri(uri1, uris);
+        String[] auths = params.getTriggeredContentAuthorities();
+        assertEquals(1, auths.length);
+        assertEquals(DummyJobContentProvider.AUTHORITY, auths[0]);
+
+        // Report more changes, this time not letting it see the top-level change
+        getContext().getContentResolver().notifyChange(uribase, null,
+                ContentResolver.NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS);
+        getContext().getContentResolver().notifyChange(uri2, null, 0);
+
+        // Wait for the job to wake up and verify it saw the change.
+        executed = kTriggerTestEnvironment.awaitExecution();
+        assertTrue("Timed out waiting for trigger content.", executed);
+        params = kTriggerTestEnvironment.getLastJobParameters();
+        uris = params.getTriggeredContentUris();
+        assertUriArrayLength(1, uris);
+        assertEquals(uri2, uris[0]);
+        auths = params.getTriggeredContentAuthorities();
+        assertEquals(1, auths.length);
+        assertEquals(DummyJobContentProvider.AUTHORITY, auths[0]);
+    }
+
+    public void testNonDescendantsObserver() throws Exception {
+        String base = "content://" + DummyJobContentProvider.AUTHORITY + "/root";
+        Uri uribase = Uri.parse(base);
+        Uri uri1 = Uri.parse(base + "/sub1");
+        Uri uri2 = Uri.parse(base + "/sub2");
+
+        // Start watching.
+        JobInfo triggerJob = makeJobInfo(uribase, 0);
+        kTriggerTestEnvironment.setExpectedExecutions(1);
+        kTriggerTestEnvironment.setMode(TriggerContentJobService.TestEnvironment.MODE_ONE_REPEAT,
+                triggerJob);
+        mJobScheduler.schedule(triggerJob);
+
+        // Report changes.
+        getContext().getContentResolver().notifyChange(uribase, null, 0);
+        getContext().getContentResolver().notifyChange(uri1, null, 0);
+
+        // Wait and check results
+        boolean executed = kTriggerTestEnvironment.awaitExecution();
+        kTriggerTestEnvironment.setExpectedExecutions(1);
+        assertTrue("Timed out waiting for trigger content.", executed);
+        JobParameters params = kTriggerTestEnvironment.getLastJobParameters();
+        Uri[] uris = params.getTriggeredContentUris();
+        assertUriArrayLength(1, uris);
+        assertEquals(uribase, uris[0]);
+        String[] auths = params.getTriggeredContentAuthorities();
+        assertEquals(1, auths.length);
+        assertEquals(DummyJobContentProvider.AUTHORITY, auths[0]);
+
+        // Report more changes, this time not letting it see the top-level change
+        getContext().getContentResolver().notifyChange(uribase, null,
+                ContentResolver.NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS);
+        getContext().getContentResolver().notifyChange(uri2, null, 0);
+
+        // Wait for the job to wake up and verify it saw the change.
+        executed = kTriggerTestEnvironment.awaitExecution();
+        assertTrue("Timed out waiting for trigger content.", executed);
+        params = kTriggerTestEnvironment.getLastJobParameters();
+        uris = params.getTriggeredContentUris();
+        assertUriArrayLength(1, uris);
+        assertEquals(uribase, uris[0]);
+        auths = params.getTriggeredContentAuthorities();
+        assertEquals(1, auths.length);
+        assertEquals(DummyJobContentProvider.AUTHORITY, auths[0]);
+    }
+
+    public void testPhotoAdded() throws Exception {
+        JobInfo triggerJob = makePhotosJobInfo();
+
+        kTriggerTestEnvironment.setExpectedExecutions(1);
+        kTriggerTestEnvironment.setMode(TriggerContentJobService.TestEnvironment.MODE_ONE_REPEAT,
+                triggerJob);
+        mJobScheduler.schedule(triggerJob);
+
+        // Create a file that our job should see.
+        makeActiveFile(0, new File(DCIM_DIR, PIC_1_NAME),
+                getContext().getResources().getAssets().open("violet.jpg"));
+        assertNotNull(mActiveUris[0]);
+
+        // Wait for the job to wake up with the change and verify it.
+        boolean executed = kTriggerTestEnvironment.awaitExecution();
+        kTriggerTestEnvironment.setExpectedExecutions(1);
+        assertTrue("Timed out waiting for trigger content.", executed);
+        JobParameters params = kTriggerTestEnvironment.getLastJobParameters();
+        Uri[] uris = params.getTriggeredContentUris();
+        assertUriArrayLength(1, uris);
+        assertEquals(mActiveUris[0], uris[0]);
+        String[] auths = params.getTriggeredContentAuthorities();
+        assertEquals(1, auths.length);
+        assertEquals(MediaStore.AUTHORITY, auths[0]);
+
+        // While the job is still running, create another file it should see.
+        // (This tests that it will see changes that happen before the next job
+        // is scheduled.)
+        makeActiveFile(1, new File(DCIM_DIR, PIC_2_NAME),
+                getContext().getResources().getAssets().open("violet.jpg"));
+        assertNotNull(mActiveUris[1]);
+
+        // Wait for the job to wake up and verify it saw the change.
+        executed = kTriggerTestEnvironment.awaitExecution();
+        assertTrue("Timed out waiting for trigger content.", executed);
+        params = kTriggerTestEnvironment.getLastJobParameters();
+        uris = params.getTriggeredContentUris();
+        assertUriArrayLength(1, uris);
+        assertEquals(mActiveUris[1], uris[0]);
+        auths = params.getTriggeredContentAuthorities();
+        assertEquals(1, auths.length);
+        assertEquals(MediaStore.AUTHORITY, auths[0]);
+
+        // Schedule a new job to look at what we see when deleting the files.
+        kTriggerTestEnvironment.setExpectedExecutions(1);
+        kTriggerTestEnvironment.setMode(TriggerContentJobService.TestEnvironment.MODE_ONESHOT,
+                triggerJob);
+        mJobScheduler.schedule(triggerJob);
+
+        // Delete the files.  Note that this will result in a general change, not for specific URIs.
+        cleanupActive(0);
+        cleanupActive(1);
+
+        // Wait for the job to wake up and verify it saw the change.
+        executed = kTriggerTestEnvironment.awaitExecution();
+        assertTrue("Timed out waiting for trigger content.", executed);
+        params = kTriggerTestEnvironment.getLastJobParameters();
+        uris = params.getTriggeredContentUris();
+        assertUriArrayLength(1, uris);
+        assertEquals(MEDIA_EXTERNAL_URI, uris[0]);
+        auths = params.getTriggeredContentAuthorities();
+        assertEquals(1, auths.length);
+        assertEquals(MediaStore.AUTHORITY, auths[0]);
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
index df48a61..c413d01 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
@@ -16,12 +16,14 @@
 
 import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.GestureDescription;
+import android.content.res.Resources;
 import android.graphics.Matrix;
 import android.graphics.Path;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
+import android.util.DisplayMetrics;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -305,17 +307,21 @@
                 StubMagnificationAccessibilityService.enableSelf(this);
         android.accessibilityservice.AccessibilityService.MagnificationController
                 magnificationController = magnificationService.getMagnificationController();
+        final Resources res = getInstrumentation().getTargetContext().getResources();
+        final DisplayMetrics metrics = res.getDisplayMetrics();
         try {
             // Magnify screen by 2x from upper left corner
             final AtomicBoolean setScale = new AtomicBoolean();
-            final AtomicBoolean setCenter = new AtomicBoolean();
             final float magnificationFactor = 2.0f;
+            // Center to have (0,0) in the upper-left corner
+            final float centerX = metrics.widthPixels / (2.0f * magnificationFactor) - 1.0f;
+            final float centerY = metrics.heightPixels / (2.0f * magnificationFactor) - 1.0f;
             magnificationService.runOnServiceSync(() -> {
                         setScale.set(magnificationController.setScale(magnificationFactor, false));
-                        setCenter.set(magnificationController.setCenter(0, 0, false));
+                        // Make sure the upper right corner is on the screen
+                        magnificationController.setCenter(centerX, centerY, false);
                     });
             assertTrue("Failed to set scale", setScale.get());
-            assertTrue("Failed to set center", setCenter.get());
 
             GestureDescription click = createClick((int) (clickX * magnificationFactor),
                     (int) (clickY * magnificationFactor));
diff --git a/tests/browser/AndroidTest.xml b/tests/browser/AndroidTest.xml
index 49c93fc..511e769 100644
--- a/tests/browser/AndroidTest.xml
+++ b/tests/browser/AndroidTest.xml
@@ -21,5 +21,7 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.browser.cts" />
         <option name="runtime-hint" value="4m14s" />
+        <!-- test-timeout unit is ms, value = 60 min -->
+        <option name="test-timeout" value="3600000" />
     </test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/tests/core/runner/src/com/android/cts/core/runner/AndroidJUnitRunnerConstants.java b/tests/core/runner/src/com/android/cts/core/runner/AndroidJUnitRunnerConstants.java
index c6c8504..8875c13 100644
--- a/tests/core/runner/src/com/android/cts/core/runner/AndroidJUnitRunnerConstants.java
+++ b/tests/core/runner/src/com/android/cts/core/runner/AndroidJUnitRunnerConstants.java
@@ -48,6 +48,25 @@
     String ARGUMENT_TEST_CLASS = "class";
 
     /**
+     * A comma separated list of the names of test classes not to run
+     */
+    String ARGUMENT_NOT_TEST_CLASS = "notClass";
+
+    /**
+     * A comma separated list of the names of test packages to run.
+     *
+     * <p>The equivalent constant in {@code InstrumentationTestRunner} is hidden and so not
+     * available
+     * through the public API.
+     */
+    String ARGUMENT_TEST_PACKAGE = "package";
+
+    /**
+     * A comma separated list of the names of test packages not to run.
+     */
+    String ARGUMENT_NOT_TEST_PACKAGE = "notPackage";
+
+    /**
      * Log the results as if the tests were executed but don't actually run the tests.
      *
      * <p>The equivalent constant in {@code InstrumentationTestRunner} is private.
diff --git a/tests/core/runner/src/com/android/cts/core/runner/CoreTestRunner.java b/tests/core/runner/src/com/android/cts/core/runner/CoreTestRunner.java
index 13af39a..58f34c3 100644
--- a/tests/core/runner/src/com/android/cts/core/runner/CoreTestRunner.java
+++ b/tests/core/runner/src/com/android/cts/core/runner/CoreTestRunner.java
@@ -36,6 +36,7 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.HashSet;
 import javax.annotation.Nullable;
 import org.junit.runner.Computer;
 import org.junit.runner.JUnitCore;
@@ -53,8 +54,11 @@
 import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_COUNT;
 import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_DEBUG;
 import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_LOG_ONLY;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_NOT_TEST_CLASS;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_NOT_TEST_PACKAGE;
 import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_TEST_CLASS;
 import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_TEST_FILE;
+import static com.android.cts.core.runner.AndroidJUnitRunnerConstants.ARGUMENT_TEST_PACKAGE;
 
 /**
  * A drop-in replacement for AndroidJUnitTestRunner, which understands the same arguments, and has
@@ -129,12 +133,12 @@
 
         // The test can be run specifying a list of tests to run, or as cts-tradefed does it,
         // by passing a fileName with a test to run on each line.
-        List<String> testNameList;
+        Set<String> testNameSet = new HashSet<>();
         String arg;
         if ((arg = args.getString(ARGUMENT_TEST_FILE)) != null) {
             // The tests are specified in a file.
             try {
-                testNameList = readTestsFromFile(arg);
+                testNameSet.addAll(readTestsFromFile(arg));
             } catch (IOException err) {
                 finish(Activity.RESULT_CANCELED, new Bundle());
                 return;
@@ -142,25 +146,46 @@
         } else if ((arg = args.getString(ARGUMENT_TEST_CLASS)) != null) {
             // The tests are specified in a String passed in the bundle.
             String[] tests = arg.split(",");
-            testNameList = Arrays.asList(tests);
-        } else {
-            // null means the runner should run all tests.
-            testNameList = null;
+            testNameSet.addAll(Arrays.asList(tests));
         }
 
-        if (testNameList == null) {
-            List<String> roots = getRootClassNames(args);
-            if (roots == null) {
-                // Find all test classes
-                testList = getAllTestClasses();
-            } else {
-                testList = TestList.rootList(roots);
-            }
-
-        } else {
-            testList = TestList.exclusiveList(testNameList);
+        Set<String> notTestNameSet = new HashSet<>();
+        if ((arg = args.getString(ARGUMENT_NOT_TEST_CLASS)) != null) {
+            // The classes are specified in a String passed in the bundle
+            String[] tests = arg.split(",");
+            notTestNameSet.addAll(Arrays.asList(tests));
         }
 
+        Set<String> packageNameSet = new HashSet<>();
+        if ((arg = args.getString(ARGUMENT_TEST_PACKAGE)) != null) {
+            // The packages are specified in a String passed in the bundle
+            String[] packages = arg.split(",");
+            packageNameSet.addAll(Arrays.asList(packages));
+        }
+
+        Set<String> notPackageNameSet = new HashSet<>();
+        if ((arg = args.getString(ARGUMENT_NOT_TEST_PACKAGE)) != null) {
+            // The packages are specified in a String passed in the bundle
+            String[] packages = arg.split(",");
+            notPackageNameSet.addAll(Arrays.asList(packages));
+        }
+
+        List<String> roots = getRootClassNames(args);
+        if (roots == null) {
+            // Find all test classes
+            Collection<Class<?>> classes = TestClassFinder.getClasses(
+                Collections.singletonList(getContext().getPackageCodePath()),
+                getClass().getClassLoader());
+            testList = new TestList(classes);
+        } else {
+            testList = TestList.rootList(roots);
+        }
+
+        testList.addIncludeTestPackages(packageNameSet);
+        testList.addExcludeTestPackages(notPackageNameSet);
+        testList.addIncludeTests(testNameSet);
+        testList.addExcludeTests(notTestNameSet);
+
         listenerClasses = new ArrayList<>();
         String listenerArg = args.getString(ARGUMENT_CORE_LISTENER);
         if (listenerArg != null) {
@@ -282,13 +307,4 @@
             throw err;
         }
     }
-
-    private TestList getAllTestClasses() {
-        Collection<Class<?>> classes = TestClassFinder.getClasses(
-                Collections.singletonList(getContext().getPackageCodePath()),
-                getClass().getClassLoader());
-
-        return TestList.classList(classes);
-    }
-
 }
diff --git a/tests/core/runner/src/com/android/cts/core/runner/TestList.java b/tests/core/runner/src/com/android/cts/core/runner/TestList.java
index 4008d69..9d97501 100644
--- a/tests/core/runner/src/com/android/cts/core/runner/TestList.java
+++ b/tests/core/runner/src/com/android/cts/core/runner/TestList.java
@@ -18,6 +18,7 @@
 import android.util.Log;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -28,33 +29,21 @@
  */
 class TestList {
 
-    /**
-     * The names of the set of tests to run, if null then all tests should be run.
-     */
-    @Nullable
-    private final Set<String> testsToRun;
+    /** The set of test pacakges to run */
+    private final Set<String> mIncludedPackages = new HashSet<>();
 
+    /** The set of test packages not to run */
+    private final Set<String> mExcludedPackages = new HashSet<>();
+
+    /** The set of tests (classes or methods) to run */
+    private final Set<String> mIncludedTests = new HashSet<>();
+
+    /** The set of tests (classes or methods) not to run */
+    private final Set<String> mExcludedTests = new HashSet<>();
+
+    /** The list of all test classes to run (without filtering applied)*/
     private final Collection<Class<?>> classesToRun;
 
-    public static TestList exclusiveList(List<String> testNameList) {
-        Set<String> classNamesToRun = new LinkedHashSet<>();
-        Set<String> testsToRun = new LinkedHashSet<>(testNameList);
-
-        for (String testName : testNameList) {
-            int index = testName.indexOf('#');
-            String className;
-            if (index == -1) {
-                className = testName;
-            } else {
-                className = testName.substring(0, index);
-            }
-            classNamesToRun.add(className);
-        }
-
-        Log.d(CoreTestRunner.TAG, "Running only the following tests: " + testsToRun);
-        return new TestList(getClasses(classNamesToRun), testsToRun);
-    }
-
     public static TestList rootList(List<String> rootList) {
 
         // Run from the root test class.
@@ -63,7 +52,7 @@
 
         List<Class<?>> classesToRun1 = getClasses(classNamesToRun);
 
-        return new TestList(classesToRun1, null);
+        return new TestList(classesToRun1);
     }
 
     private static List<Class<?>> getClasses(Set<String> classNames) {
@@ -79,19 +68,29 @@
         return classesToRun;
     }
 
-    public static TestList classList(Collection<Class<?>> classes) {
-        return new TestList(classes, null);
-    }
-
     /**
      * @param classes The list of classes to run.
-     * @param testsToRun The exclusive set of tests to run or null if all tests reachable from the
      */
-    private TestList(Collection<Class<?>> classes, Set<String> testsToRun) {
-        this.testsToRun = testsToRun;
+    public TestList(Collection<Class<?>> classes) {
         this.classesToRun = classes;
     }
 
+    public void addIncludeTestPackages(Set<String> packageNameSet) {
+        mIncludedPackages.addAll(packageNameSet);
+    }
+
+    public void addExcludeTestPackages(Set<String> packageNameSet) {
+        mExcludedPackages.addAll(packageNameSet);
+    }
+
+    public void addIncludeTests(Set<String> testNameSet) {
+        mIncludedTests.addAll(testNameSet);
+    }
+
+    public void addExcludeTests(Set<String> testNameSet) {
+        mExcludedTests.addAll(testNameSet);
+    }
+
     /**
      * Return all the classes to run.
      */
@@ -103,8 +102,36 @@
      * Return true if the test with the specified name should be run, false otherwise.
      */
     public boolean shouldRunTest(String testName) {
-        // If the tests aren't explicitly provided then run all tests by
-        // default, otherwise run only those tests explicitly listed by name.
-        return testsToRun == null || testsToRun.contains(testName);
+
+        int index = testName.indexOf('#');
+        String className;
+        if (index == -1) {
+            className = testName;
+        } else {
+            className = testName.substring(0, index);
+        }
+        try {
+            Class<?> testClass = Class.forName(className);
+            Package testPackage = testClass.getPackage();
+            String testPackageName = "";
+            if (testPackage != null) {
+                testPackageName = testPackage.getName();
+            }
+
+            boolean include =
+                    (mIncludedPackages.isEmpty() || mIncludedPackages.contains(testPackageName)) &&
+                    (mIncludedTests.isEmpty() || mIncludedTests.contains(className) ||
+                            mIncludedTests.contains(testName));
+
+            boolean exclude =
+                    mExcludedPackages.contains(testPackageName) ||
+                    mExcludedTests.contains(className) ||
+                    mExcludedTests.contains(testName);
+
+            return include && !exclude;
+        } catch (ClassNotFoundException e) {
+            Log.w("Could not load class '" + className, e);
+            return false;
+        }
     }
 }
diff --git a/tests/inputmethod/Android.mk b/tests/inputmethod/Android.mk
deleted file mode 100644
index 3a90fa9..0000000
--- a/tests/inputmethod/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsInputMethodTestCases
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner android-support-test
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/inputmethod/AndroidManifest.xml b/tests/inputmethod/AndroidManifest.xml
deleted file mode 100644
index 038b164..0000000
--- a/tests/inputmethod/AndroidManifest.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-    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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.inputmethod.cts">
-
-    <application >
-        <uses-library android:name="android.test.runner"/>
-
-        <activity android:name="android.inputmethod.cts.TestActivity" />
-        <service android:name="android.inputmethod.cts.MockInputMethodService"
-                 android:permission="android.permission.BIND_INPUT_METHOD">
-            <intent-filter>
-                <action android:name="android.view.InputMethod" />
-            </intent-filter>
-            <meta-data android:name="android.view.im" android:resource="@xml/method" />
-        </service>
-    </application>
-
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.inputmethod.cts"
-                     android:label="Tests for the InputMethod APIs."/>
-
-</manifest>
diff --git a/tests/inputmethod/AndroidTest.xml b/tests/inputmethod/AndroidTest.xml
deleted file mode 100644
index 3a52042..0000000
--- a/tests/inputmethod/AndroidTest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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.
--->
-<configuration description="Config for CTS Input test cases">
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsInputMethodTestCases.apk" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.inputmethod.cts" />
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/tests/inputmethod/res/xml/method.xml b/tests/inputmethod/res/xml/method.xml
deleted file mode 100644
index fc2ec95..0000000
--- a/tests/inputmethod/res/xml/method.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-    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.
--->
-
-<input-method xmlns:android="http://schemas.android.com/apk/res/android"
-              android:isDefault="True">
-    <subtype android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" />
-</input-method>
diff --git a/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTest.java b/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTest.java
deleted file mode 100644
index c68d448..0000000
--- a/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.inputmethod.cts;
-
-import android.annotation.NonNull;
-import android.content.pm.PackageManager;
-import android.os.IBinder;
-import android.inputmethodservice.InputMethodService;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.inputmethod.InputMethodManager;
-
-import java.util.List;
-
-public class InputMethodServiceTest extends InstrumentationTestCase {
-    private String mTestImeId;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mTestImeId = getInstrumentation().getContext().getPackageName() +
-                "/" + MockInputMethodService.class.getName();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * Ensures that the IME with {@code imeId} is not enabled.
-     *
-     * This method ensures that no IME with {@code imeId} is enabled. If the given IME is currently
-     * in use, switches to another IME first. Then, if the given IME is enabled, disables it.
-     */
-    private void ensureImeNotEnabled(@NonNull final String imeId) {
-        final String currentImeId =
-                InputMethodServiceTestUtil.getCurrentImeId(getInstrumentation());
-        if (currentImeId.equals(imeId)) {
-            // Requested IME is already used. This typically happens if the previous test case is
-            // not finished gracefully. In this case, selects another IME.
-            String otherImeCandidate = null;
-            final List<String> enabledImes =
-                    InputMethodServiceTestUtil.getEnabledImeIds(getInstrumentation());
-            for (final String enabledIme : enabledImes) {
-                if (!enabledIme.equals(imeId)) {
-                    otherImeCandidate = imeId;
-                    break;
-                }
-            }
-            if (otherImeCandidate == null) {
-                // When PackageManager.hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS)
-                // returns true, this case must not happen.
-                throw new IllegalStateException(
-                        "No other IME is available. Unable to continue tests.");
-            }
-            assertTrue(InputMethodServiceTestUtil.setIme(getInstrumentation(), otherImeCandidate));
-        }
-
-        if (InputMethodServiceTestUtil.isImeEnabled(getInstrumentation(), imeId)) {
-            assertTrue(InputMethodServiceTestUtil.disableIme(getInstrumentation(), imeId));
-        }
-    }
-
-    /**
-     * Asserts the given service is not running.
-     */
-    private void assertServiceNotRunning() {
-        assertTrue(MockInputMethodService.getInstance() == null ||
-                MockInputMethodService.getInstance().getCallCount("onCreate") == 0);
-    }
-
-    /**
-     * This test checks the following APIs.
-     * <ul>
-     *   <li>{@link InputMethodManager#getEnabledInputMethodList()}</li>
-     *   <li>{@link InputMethodManager#getInputMethodList()}</li>
-     *   <li>{@link InputMethodManager#setInputMethod(IBinder, String)}</li>
-     *   <li>{@link InputMethodService#onCreate()}</li>
-     *   <li>{@link InputMethodService#onDestroy()}</li>
-     * </ul>
-     */
-    @MediumTest
-    public void testCreateAndDestroy() {
-        if (!getInstrumentation().getContext().getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_INPUT_METHODS)) {
-            // The "input method" system feature is not supported on this device.
-            return;
-        }
-
-        // Clear the counter in the mock service, since it might have been used in a previous test.
-        MockInputMethodService.resetCounter();
-
-        ensureImeNotEnabled(mTestImeId);
-
-        final String ImeIdToRestore =
-                InputMethodServiceTestUtil.getCurrentImeId(getInstrumentation());
-        MockInputMethodService service = MockInputMethodService.getInstance();
-        assertServiceNotRunning();
-
-        try {
-            // Enable test IME.
-            assertTrue(InputMethodServiceTestUtil.enableIme(getInstrumentation(), mTestImeId));
-            service = MockInputMethodService.getInstance();
-            assertServiceNotRunning();
-
-            // Select test IME.
-            assertTrue(InputMethodServiceTestUtil.setIme(getInstrumentation(), mTestImeId));
-            service = MockInputMethodService.getInstance();
-            assertNotNull(service);
-            assertEquals(1, MockInputMethodService.getCallCount("<init>"));
-            assertEquals(1, MockInputMethodService.getCallCount("onCreate"));
-        } finally {
-            // Restores IMEs to original one.
-            InputMethodServiceTestUtil.setIme(getInstrumentation(), ImeIdToRestore);
-            InputMethodServiceTestUtil.disableIme(getInstrumentation(), mTestImeId);
-            assertEquals(1, MockInputMethodService.getCallCount("onDestroy"));
-        }
-    }
-}
diff --git a/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTestUtil.java b/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTestUtil.java
deleted file mode 100644
index aa46c38..0000000
--- a/tests/inputmethod/src/android/inputmethod/cts/InputMethodServiceTestUtil.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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.inputmethod.cts;
-
-import android.annotation.NonNull;
-import android.app.Instrumentation;
-import android.app.UiAutomation;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Utility functions for testing of input method stuff.
- */
-public final class InputMethodServiceTestUtil {
-    private static final String TAG = InputMethodServiceTestUtil.class.getSimpleName();
-
-    // Prevents this from being instantiated.
-    private InputMethodServiceTestUtil() {}
-
-    @NonNull
-    private static String executeShellCommand(final UiAutomation uiAutomation, final String[] cmd) {
-        final String flattenCmd = TextUtils.join(" ", cmd);
-        List<String> output = new ArrayList<>();
-
-        try (final ParcelFileDescriptor fd = uiAutomation.executeShellCommand(flattenCmd);
-             final FileReader fr = new FileReader(fd.getFileDescriptor());
-             final BufferedReader br = new BufferedReader(fr)) {
-
-            String line;
-            while ((line = br.readLine()) != null) {
-                output.add(line);
-            }
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-
-        // The output from the "ime" command should be only one line.
-        if (output.size() != 1) {
-            throw new IllegalStateException(
-                    "The output from 'ime' command should be one line, but it outputs multiples: " +
-                    TextUtils.join("\n", output));
-        }
-        return output.get(0);
-    }
-
-    @NonNull
-    public static String getCurrentImeId(final Instrumentation inst) {
-        return Settings.Secure.getString(inst.getContext().getContentResolver(),
-                Settings.Secure.DEFAULT_INPUT_METHOD);
-    }
-
-    public static boolean isImeEnabled(final Instrumentation inst, final String imeId) {
-        final List<String> enabledImes = getEnabledImeIds(inst);
-        return enabledImes.contains(imeId);
-    }
-
-    @NonNull
-    public static List<String> getEnabledImeIds(final Instrumentation inst) {
-        InputMethodManager imm = (InputMethodManager) inst.getContext().getSystemService(
-                Context.INPUT_METHOD_SERVICE);
-        final List<InputMethodInfo> enabledImes = imm.getEnabledInputMethodList();
-        List<String> result = new ArrayList<>();
-        for (final InputMethodInfo enabledIme : enabledImes) {
-            result.add(enabledIme.getId());
-        }
-        return result;
-    }
-
-    /**
-     * Puts the specified IME into the available input method list.
-     *
-     * This operation will be done synchronously in "ime" command using
-     * {@link com.android.server.InputMethodManagerService#setInputMethodEnabled(String, boolean)},
-     * which is synchronous.
-     *
-     * @param imeId IME ID to be enabled.
-     * @return {@code true} if the target IME gets enabled successfully. {@code false} if failed.
-     */
-    public static boolean enableIme(final Instrumentation inst, final String imeId) {
-        // Needs to check the output message from the checking command, since executeShellCommand()
-        // does not pass the exit status code back to the test.
-        final String output = executeShellCommand(
-                inst.getUiAutomation(), new String[]{"ime", "enable", imeId});
-        final String expectedOutput = "Input method " + imeId + ": now enabled";
-        if (!output.equals(expectedOutput)) {
-            Log.e(TAG, "Unexpected output message. Expected: " + expectedOutput +
-                    ", Actual: " + output);
-            return false;
-        }
-
-        final InputMethodManager imm = (InputMethodManager) inst.getContext().getSystemService(
-                Context.INPUT_METHOD_SERVICE);
-        final List<InputMethodInfo> enabledInputMethods = imm.getEnabledInputMethodList();
-        for (final InputMethodInfo imi : enabledInputMethods) {
-            if (imi.getId().equals(imeId))
-                return true;
-        }
-
-        Log.e(TAG, "Failed to enable the given IME (IME ID: " + imeId + ").");
-        return false;
-    }
-
-    /**
-     * Removes the specified IME from the available input method list.
-     *
-     * This operation will {@code @NonNull} final be done synchronously in "ime" command using
-     * {@link com.android.server.InputMethodManagerService#setInputMethodEnabled(String, boolean)},
-     * which is synchronous.
-     *
-     * @param imeId IME ID to be disabled.
-     * @return {@code true} if the target IME gets disabled successfully. {@code false} if failed.
-     */
-    public static boolean disableIme(final Instrumentation inst, final String imeId) {
-        // Needs to check the output message from the checking command, since executeShellCommand()
-        // does not pass the exit status code back to the test.
-        final String output = executeShellCommand(
-                inst.getUiAutomation(), new String[]{"ime", "disable", imeId});
-        final String expectedOutput = "Input method " + imeId + ": now disabled";
-        if (!output.equals(expectedOutput)) {
-            Log.w(TAG, "Unexpected output message. Expected: " + expectedOutput +
-                    ", Actual: " + output);
-            return false;
-        }
-
-        final InputMethodManager imm = (InputMethodManager) inst.getContext().getSystemService(
-                Context.INPUT_METHOD_SERVICE);
-        final List<InputMethodInfo> enabledInputMethods = imm.getEnabledInputMethodList();
-        for (final InputMethodInfo imi : enabledInputMethods) {
-            if (imi.getId().equals(imeId)) {
-                Log.e(TAG, "Failed to disable the given IME (IME ID: " + imeId + ").");
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Switches to the specified IME.
-     *
-     * This operation will be done synchronously in the "ime" command using
-     * {@link InputMethodManager#setInputMethod(IBinder, String)}, which is synchronous.
-     *
-     * @param imeId IME ID to be switched to.
-     * @return {@code true} if the target IME gets active successfully. {@code false} if failed.
-     */
-    public static boolean setIme(final Instrumentation inst, final String imeId) {
-        // Needs to check the output message from the checking command, since executeShellCommand()
-        // does not pass the exit status code back to the test.
-        final String output = executeShellCommand(
-                inst.getUiAutomation(), new String[]{"ime", "set", imeId});
-        final String expectedOutput = "Input method " + imeId + " selected";
-        if (!output.equals(expectedOutput)) {
-            Log.w(TAG, "Unexpected output message. Expected: " + expectedOutput +  ", Actual: " +
-                    output);
-            return false;
-        }
-
-        final String currentImeId = getCurrentImeId(inst);
-        if (!TextUtils.equals(currentImeId, imeId)) {
-            Log.e(TAG, "Failed to switch the current IME. Expected: " + imeId +  ", Actual: " +
-                    currentImeId);
-            return false;
-        }
-
-        return true;
-    }
-}
diff --git a/tests/inputmethod/src/android/inputmethod/cts/MockInputMethodService.java b/tests/inputmethod/src/android/inputmethod/cts/MockInputMethodService.java
deleted file mode 100644
index 12b80a5..0000000
--- a/tests/inputmethod/src/android/inputmethod/cts/MockInputMethodService.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.inputmethod.cts;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.inputmethodservice.InputMethodService;
-
-import java.util.HashMap;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * A mock implementation of {@link InputMethodService} for testing purpose.
- */
-public class MockInputMethodService extends InputMethodService {
-    private static AtomicReference<MockInputMethodService> sCurrentInstance =
-            new AtomicReference<>();
-    private static final HashMap<String, Integer> mCallCounter = new HashMap<>();
-
-    /**
-     * @return The instance of {@code MockInputMethodService}. If the service has not been created
-     * yet or already been destroyed, returns {@code null}.
-     */
-    @Nullable
-    public static MockInputMethodService getInstance() {
-        return sCurrentInstance.get();
-    }
-
-    public static void resetCounter() {
-        synchronized (mCallCounter) {
-            mCallCounter.clear();
-        }
-    }
-
-    private static void incrementCallCount(@NonNull final String methodName) {
-        synchronized (mCallCounter) {
-            if (!mCallCounter.containsKey(methodName)) {
-                mCallCounter.put(methodName, 0);
-            }
-            mCallCounter.put(methodName, mCallCounter.get(methodName) + 1);
-        }
-    }
-
-    public static int getCallCount(@NonNull final String methodName) {
-        synchronized (mCallCounter) {
-            if (!mCallCounter.containsKey(methodName)) {
-                return 0;
-            }
-            return mCallCounter.get(methodName);
-        }
-    }
-
-    public MockInputMethodService() {
-        incrementCallCount("<init>");
-    }
-
-    @Override
-    public void onCreate() {
-        if (!sCurrentInstance.compareAndSet(null, this)) {
-            throw new IllegalStateException("New MockInputMethodService instance is being created "
-                    + "before the existing instance is destroyed.");
-        }
-
-        super.onCreate();
-        incrementCallCount("onCreate");
-    }
-
-    @Override
-    public void onDestroy() {
-        sCurrentInstance.lazySet(null);
-        super.onDestroy();
-        incrementCallCount("onDestroy");
-    }
-}
-
diff --git a/tests/tests/bluetooth/AndroidManifest.xml b/tests/tests/bluetooth/AndroidManifest.xml
index 3c751d7..45718a3 100644
--- a/tests/tests/bluetooth/AndroidManifest.xml
+++ b/tests/tests/bluetooth/AndroidManifest.xml
@@ -21,6 +21,7 @@
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
index bc819c1..fd1c7d2 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
@@ -63,11 +63,14 @@
 
     private BluetoothAdapter mBluetoothAdapter;
     private BluetoothLeScanner mScanner;
+    // Whether location is on before running the tests.
+    private boolean mLocationOn;
 
     @Override
     public void setUp() {
-        if (!isBleSupported())
+        if (!isBleSupported()) {
             return;
+        }
         BluetoothManager manager = (BluetoothManager) mContext.getSystemService(
                 Context.BLUETOOTH_SERVICE);
         mBluetoothAdapter = manager.getAdapter();
@@ -78,6 +81,17 @@
             sleep(3000);
         }
         mScanner = mBluetoothAdapter.getBluetoothLeScanner();
+        mLocationOn = TestUtils.isLocationOn(getContext());
+        if (!mLocationOn) {
+            TestUtils.enableLocation(getContext());
+        }
+    }
+
+    @Override
+    public void tearDown() {
+        if (!mLocationOn) {
+            TestUtils.disableLocation(getContext());
+        }
     }
 
     /**
@@ -85,8 +99,9 @@
      */
     @MediumTest
     public void testBasicBleScan() {
-        if (!isBleSupported())
+        if (!isBleSupported()) {
             return;
+        }
         long scanStartMillis = SystemClock.elapsedRealtime();
         Collection<ScanResult> scanResults = scan();
         long scanEndMillis = SystemClock.elapsedRealtime();
@@ -100,8 +115,9 @@
      */
     @MediumTest
     public void testScanFilter() {
-        if (!isBleSupported())
+        if (!isBleSupported()) {
             return;
+        }
 
         List<ScanFilter> filters = new ArrayList<ScanFilter>();
         ScanFilter filter = createScanFilter();
@@ -140,13 +156,13 @@
         Map<ParcelUuid, byte[]> serviceData = record.getServiceData();
         if (serviceData != null && !serviceData.isEmpty()) {
             ParcelUuid uuid = serviceData.keySet().iterator().next();
-            return new ScanFilter.Builder().setServiceData(uuid, new byte[] { 0 },
-                    new byte[] { 0 }).build();
+            return new ScanFilter.Builder().setServiceData(uuid, new byte[]{0},
+                    new byte[]{0}).build();
         }
         SparseArray<byte[]> manufacturerSpecificData = record.getManufacturerSpecificData();
         if (manufacturerSpecificData != null && manufacturerSpecificData.size() > 0) {
             return new ScanFilter.Builder().setManufacturerData(manufacturerSpecificData.keyAt(0),
-                    new byte[] { 0 }, new byte[] { 0 }).build();
+                    new byte[]{0}, new byte[]{0}).build();
         }
         List<ParcelUuid> serviceUuids = record.getServiceUuids();
         if (serviceUuids != null && !serviceUuids.isEmpty()) {
@@ -160,15 +176,16 @@
      */
     @MediumTest
     public void testOpportunisticScan() {
-        if (!isBleSupported())
+        if (!isBleSupported()) {
             return;
+        }
         ScanSettings opportunisticScanSettings = new ScanSettings.Builder()
                 .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC)
                 .build();
         BleScanCallback emptyScanCallback = new BleScanCallback();
 
         // No scans are really started with opportunistic scans only.
-        mScanner.startScan(Collections.<ScanFilter> emptyList(), opportunisticScanSettings,
+        mScanner.startScan(Collections.<ScanFilter>emptyList(), opportunisticScanSettings,
                 emptyScanCallback);
         sleep(SCAN_DURATION_MILLIS);
         assertTrue(emptyScanCallback.getScanResults().isEmpty());
@@ -213,7 +230,7 @@
                 .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                 .setReportDelay(BATCH_SCAN_REPORT_DELAY_MILLIS).build();
         BleScanCallback batchScanCallback = new BleScanCallback();
-        mScanner.startScan(Collections.<ScanFilter> emptyList(), batchScanSettings,
+        mScanner.startScan(Collections.<ScanFilter>emptyList(), batchScanSettings,
                 batchScanCallback);
         sleep(SCAN_DURATION_MILLIS);
         mScanner.flushPendingScanResults(batchScanCallback);
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/TestUtils.java b/tests/tests/bluetooth/src/android/bluetooth/cts/TestUtils.java
index 7c5db9e..327a2b8 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/TestUtils.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/TestUtils.java
@@ -17,6 +17,8 @@
 package android.bluetooth.cts;
 
 import android.bluetooth.le.ScanRecord;
+import android.content.Context;
+import android.provider.Settings;
 
 import junit.framework.Assert;
 
@@ -36,18 +38,57 @@
         Class<?> scanRecordClass = ScanRecord.class;
         try {
             Method method = scanRecordClass.getDeclaredMethod("parseFromBytes", byte[].class);
-            return (ScanRecord)method.invoke(null, bytes);
+            return (ScanRecord) method.invoke(null, bytes);
         } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException
                 | InvocationTargetException e) {
             return null;
         }
     }
 
-    // Assert two byte arrays are equal.
+    /**
+     * Assert two byte arrays are equal.
+     */
     static void assertArrayEquals(byte[] expected, byte[] actual) {
         if (!Arrays.equals(expected, actual)) {
             Assert.fail("expected:<" + Arrays.toString(expected) +
                     "> but was:<" + Arrays.toString(actual) + ">");
         }
     }
-}
+
+    /**
+     * Get current location mode settings.
+     */
+    static int getLocationMode(Context context) {
+        return Settings.Secure.getInt(context.getContentResolver(),
+                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
+    }
+
+    /**
+     * Set location settings mode.
+     */
+    static void setLocationMode(Context context, int mode) {
+        Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE,
+                mode);
+    }
+
+    /**
+     * Return true if location is on.
+     */
+    static boolean isLocationOn(Context context) {
+        return getLocationMode(context) != Settings.Secure.LOCATION_MODE_OFF;
+    }
+
+    /**
+     * Enable location and set the mode to GPS only.
+     */
+    static void enableLocation(Context context) {
+        setLocationMode(context, Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
+    }
+
+    /**
+     * Disable location.
+     */
+    static void disableLocation(Context context) {
+        setLocationMode(context, Settings.Secure.LOCATION_MODE_OFF);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java b/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java
index b2a90f2..5750963 100644
--- a/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java
+++ b/tests/tests/content/src/android/content/cts/ImageCaptureUriExtraToClipDataTest.java
@@ -70,19 +70,19 @@
     public void testUriExtraOutputMigratedToClipData_imageCaptureIntent() {
         startActivityWithAction(MediaStore.ACTION_IMAGE_CAPTURE);
         waitForFileReady();
-        testFileContents();
+        assertFileContents();
     }
 
     public void testUriExtraOutputMigratedToClipData_imageCaptureSecureIntent() {
         startActivityWithAction(MediaStore.ACTION_IMAGE_CAPTURE_SECURE);
         waitForFileReady();
-        testFileContents();
+        assertFileContents();
     }
 
     public void testUriExtraOutputMigratedToClipData_videoCaptureIntent() {
         startActivityWithAction(MediaStore.ACTION_VIDEO_CAPTURE);
         waitForFileReady();
-        testFileContents();
+        assertFileContents();
     }
 
     private void startActivityWithAction(String action) {
@@ -102,7 +102,7 @@
         }
     }
 
-    private void testFileContents() {
+    private void assertFileContents() {
         char[] buffer = new char[TEST_INPUT.length()];
         try {
             FileReader reader = new FileReader(mTestFile);
diff --git a/tests/tests/display/src/android/display/cts/DisplayTest.java b/tests/tests/display/src/android/display/cts/DisplayTest.java
index 1d1db2b..8d8caad 100644
--- a/tests/tests/display/src/android/display/cts/DisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/DisplayTest.java
@@ -32,6 +32,7 @@
 import android.test.InstrumentationTestCase;
 import android.util.DisplayMetrics;
 import android.view.Display;
+import android.view.Display.HdrCapabilities;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
@@ -146,6 +147,21 @@
     }
 
     /**
+     * Verify default display's HDR capability.
+     */
+    public void testDefaultDisplayHdrCapability() {
+        Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
+        HdrCapabilities cap = display.getHdrCapabilities();
+        int[] hdrTypes = cap.getSupportedHdrTypes();
+        for (int type : hdrTypes) {
+            assertTrue(type >= 1 && type <= 3);
+        }
+        assertFalse(cap.getDesiredMaxLuminance() < -1.0f);
+        assertFalse(cap.getDesiredMinLuminance() < -1.0f);
+        assertFalse(cap.getDesiredMaxAverageLuminance() < -1.0f);
+    }
+
+    /**
      * Verify that there is a secondary display.
      */
     public void testSecondaryDisplay() {
diff --git a/tests/tests/libcoreoj/CtsTestPackage.xml b/tests/tests/libcoreoj/CtsTestPackage.xml
index 2578fb9..51fb7fc 100644
--- a/tests/tests/libcoreoj/CtsTestPackage.xml
+++ b/tests/tests/libcoreoj/CtsTestPackage.xml
@@ -433,16 +433,6 @@
               <Test name="testReplaceAll" />
             </TestCase>
           </TestSuite>
-          <TestSuite name="lang">
-            <TestSuite name="invoke">
-              <TestCase name="DeserializeMethodTest">
-                <Test name="testCapturingNonSerLambda" />
-                <Test name="testCapturingNonserIntersectionLambda" />
-                <Test name="testCapturingSerLambda" />
-                <Test name="testEmptyClass" />
-              </TestCase>
-            </TestSuite>
-          </TestSuite>
         </TestSuite>
       </TestSuite>
     </TestSuite>
diff --git a/tools/testng/gen-test-list-xml b/tests/tests/libcoreoj/gen-test-list-xml
similarity index 86%
rename from tools/testng/gen-test-list-xml
rename to tests/tests/libcoreoj/gen-test-list-xml
index e2a5ef8..fc61646 100755
--- a/tools/testng/gen-test-list-xml
+++ b/tests/tests/libcoreoj/gen-test-list-xml
@@ -26,4 +26,4 @@
 test_list_txt=$DIR/test_list.txt
 [[ -f $test_list_txt ]] || echo "Can't find $test_list_txt" >&2
 
-$DIR/gen-test-list-xml.py --app-package-name android.libcore.oj --cts-name CtsLibcoreOj --jar-path CtsLibcoreOj.jar $DIR/test_list.txt
+$DIR/../../../tools/testng/gen-test-list-xml.py --app-package-name android.libcore.oj --cts-name CtsLibcoreOj --jar-path CtsLibcoreOj.jar $DIR/test_list.txt
diff --git a/tools/testng/test_list.txt b/tests/tests/libcoreoj/test_list.txt
similarity index 98%
rename from tools/testng/test_list.txt
rename to tests/tests/libcoreoj/test_list.txt
index 5516c0d..9195c26 100644
--- a/tools/testng/test_list.txt
+++ b/tests/tests/libcoreoj/test_list.txt
@@ -63,10 +63,6 @@
 org.openjdk.tests.java.util.stream.CountTest#testOps
 org.openjdk.tests.java.util.stream.CountTest#testOps
 org.openjdk.tests.java.util.stream.CountTest#testOps
-org.openjdk.tests.java.lang.invoke.DeserializeMethodTest#testCapturingNonSerLambda
-org.openjdk.tests.java.lang.invoke.DeserializeMethodTest#testCapturingNonserIntersectionLambda
-org.openjdk.tests.java.lang.invoke.DeserializeMethodTest#testCapturingSerLambda
-org.openjdk.tests.java.lang.invoke.DeserializeMethodTest#testEmptyClass
 org.openjdk.tests.java.util.stream.DistinctOpTest#testDistinctDistinct
 org.openjdk.tests.java.util.stream.DistinctOpTest#testDistinctSorted
 org.openjdk.tests.java.util.stream.DistinctOpTest#testOp
diff --git a/tests/tests/media/src/android/media/cts/RoutingTest.java b/tests/tests/media/src/android/media/cts/RoutingTest.java
index c0e9a3e..22aaaa3 100644
--- a/tests/tests/media/src/android/media/cts/RoutingTest.java
+++ b/tests/tests/media/src/android/media/cts/RoutingTest.java
@@ -23,6 +23,7 @@
 import android.media.AudioFormat;
 import android.media.AudioManager;
 import android.media.AudioRecord;
+import android.media.AudioRouting;
 import android.media.AudioTrack;
 import android.media.MediaRecorder;
 
@@ -36,7 +37,12 @@
 import java.lang.Runnable;
 
 /**
- * TODO: Insert description here. (generated by pmclean)
+ * AudioTrack / AudioRecord preferred device and routing listener tests.
+ * The routing tests are mostly here to exercise the routing code, as an actual test would require
+ * adding / removing an audio device for the listeners to be called.
+ * The routing listener code is designed to run for two versions of the routing code:
+ *  - the deprecated AudioTrack.OnRoutingChangedListener and AudioRecord.OnRoutingChangedListener
+ *  - the N AudioRouting.OnRoutingChangedListener
  */
 public class RoutingTest extends AndroidTestCase {
     private static final String TAG = "RoutingTest";
@@ -115,29 +121,75 @@
         return myLooper;
     }
 
-    private class AudioTrackRoutingListener implements AudioTrack.OnRoutingChangedListener {
+    private class AudioTrackRoutingListener implements AudioTrack.OnRoutingChangedListener,
+            AudioRouting.OnRoutingChangedListener
+    {
         public void onRoutingChanged(AudioTrack audioTrack) {}
+        public void onRoutingChanged(AudioRouting audioRouting) {}
     }
 
+
     public void test_audioTrack_RoutingListener() {
+        test_audioTrack_RoutingListener(false /*usesAudioRouting*/);
+    }
+
+    public void test_audioTrack_audioRouting_RoutingListener() {
+        test_audioTrack_RoutingListener(true /*usesAudioRouting*/);
+    }
+
+    private void test_audioTrack_RoutingListener(boolean usesAudioRouting) {
         AudioTrack audioTrack = allocAudioTrack();
 
-        audioTrack.addOnRoutingChangedListener(null, null);
+        // null listener
+        if (usesAudioRouting) {
+            audioTrack.addOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) null, null);
+        } else {
+            audioTrack.addOnRoutingChangedListener(
+                    (AudioTrack.OnRoutingChangedListener) null, null);
+        }
 
         AudioTrackRoutingListener listener = new AudioTrackRoutingListener();
         AudioTrackRoutingListener someOtherListener = new AudioTrackRoutingListener();
 
-        audioTrack.addOnRoutingChangedListener(listener, null);
+        // add a listener
+        if (usesAudioRouting) {
+            audioTrack.addOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) listener, null);
+        } else {
+            audioTrack.addOnRoutingChangedListener(listener, null);
+        }
 
-        // remove a listener we didn't add
-        audioTrack.removeOnRoutingChangedListener(someOtherListener);
-
-        audioTrack.removeOnRoutingChangedListener(listener);
+        // remove listeners
+        if (usesAudioRouting) {
+            // remove a listener we didn't add
+            audioTrack.removeOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) someOtherListener);
+            // remove a valid listener
+            audioTrack.removeOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) listener);
+        } else {
+            // remove a listener we didn't add
+            audioTrack.removeOnRoutingChangedListener(
+                    (AudioTrack.OnRoutingChangedListener) someOtherListener);
+            // remove a valid listener
+            audioTrack.removeOnRoutingChangedListener(
+                    (AudioTrack.OnRoutingChangedListener) listener);
+        }
 
         Looper myLooper = prepareIfNeededLooper();
-        audioTrack.addOnRoutingChangedListener(listener, new Handler());
 
-        audioTrack.removeOnRoutingChangedListener(listener);
+        if (usesAudioRouting) {
+            audioTrack.addOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) listener, new Handler());
+            audioTrack.removeOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) listener);
+        } else {
+            audioTrack.addOnRoutingChangedListener(
+                    (AudioTrack.OnRoutingChangedListener) listener, new Handler());
+            audioTrack.removeOnRoutingChangedListener(
+                    (AudioTrack.OnRoutingChangedListener) listener);
+        }
 
         audioTrack.release();
         if (myLooper != null) {
@@ -160,33 +212,78 @@
         return audioRecord;
     }
 
-    private class AudioRecordRoutingListener implements AudioRecord.OnRoutingChangedListener {
+    private class AudioRecordRoutingListener implements AudioRecord.OnRoutingChangedListener,
+            AudioRouting.OnRoutingChangedListener
+    {
         public void onRoutingChanged(AudioRecord audioRecord) {}
+        public void onRoutingChanged(AudioRouting audioRouting) {}
     }
 
     public void test_audioRecord_RoutingListener() {
+        test_audioRecord_RoutingListener(false /*usesAudioRouting*/);
+    }
+
+    public void test_audioRecord_audioRouting_RoutingListener() {
+        test_audioRecord_RoutingListener(true /*usesAudioRouting*/);
+    }
+
+    private void test_audioRecord_RoutingListener(boolean usesAudioRouting) {
         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
             // Can't do it so skip this test
             return;
         }
         AudioRecord audioRecord = allocAudioRecord();
 
-        audioRecord.addOnRoutingChangedListener(null, null);
+        // null listener
+        if (usesAudioRouting) {
+            audioRecord.addOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) null, null);
+        } else {
+            audioRecord.addOnRoutingChangedListener(
+                    (AudioRecord.OnRoutingChangedListener) null, null);
+        }
 
         AudioRecordRoutingListener listener = new AudioRecordRoutingListener();
         AudioRecordRoutingListener someOtherListener = new AudioRecordRoutingListener();
 
-        audioRecord.addOnRoutingChangedListener(listener, null);
+        // add a listener
+        if (usesAudioRouting) {
+            audioRecord.addOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) listener, null);
+        } else {
+            audioRecord.addOnRoutingChangedListener(
+                    (AudioRecord.OnRoutingChangedListener) listener, null);
+        }
 
-        // remove a listener we didn't add
-        audioRecord.removeOnRoutingChangedListener(someOtherListener);
-
-        audioRecord.removeOnRoutingChangedListener(listener);
+        // remove listeners
+        if (usesAudioRouting) {
+            // remove a listener we didn't add
+            audioRecord.removeOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) someOtherListener);
+            // remove a valid listener
+            audioRecord.removeOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) listener);
+        } else {
+            // remove a listener we didn't add
+            audioRecord.removeOnRoutingChangedListener(
+                    (AudioRecord.OnRoutingChangedListener) someOtherListener);
+            // remove a valid listener
+            audioRecord.removeOnRoutingChangedListener(
+                    (AudioRecord.OnRoutingChangedListener) listener);
+        }
 
         Looper myLooper = prepareIfNeededLooper();
-        audioRecord.addOnRoutingChangedListener(listener, new Handler());
-
-        audioRecord.removeOnRoutingChangedListener(listener);
+        if (usesAudioRouting) {
+            audioRecord.addOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) listener, new Handler());
+            audioRecord.removeOnRoutingChangedListener(
+                    (AudioRouting.OnRoutingChangedListener) listener);
+        } else {
+            audioRecord.addOnRoutingChangedListener(
+                    (AudioRecord.OnRoutingChangedListener) listener, new Handler());
+            audioRecord.removeOnRoutingChangedListener(
+                    (AudioRecord.OnRoutingChangedListener) listener);
+        }
 
         audioRecord.release();
         if (myLooper != null) {
diff --git a/tests/tests/os/src/android/os/cts/RequiredComponentsTest.java b/tests/tests/os/src/android/os/cts/RequiredComponentsTest.java
new file mode 100644
index 0000000..378ac09
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/RequiredComponentsTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * 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.os.cts;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.List;
+
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+
+/**
+ * Tests whether all platform components that are implemented
+ * as APKs for various reasons are present.
+ */
+@RunWith(AndroidJUnit4.class)
+public class RequiredComponentsTest {
+    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
+
+    @Test
+    public void testPackageInstallerPresent() throws Exception {
+        Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
+        installerIntent.addCategory(Intent.CATEGORY_DEFAULT);
+        installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
+        List<ResolveInfo> installers = InstrumentationRegistry.getContext()
+                .getPackageManager().queryIntentActivities(installerIntent, MATCH_SYSTEM_ONLY
+                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
+        if (installers.size() == 1) {
+            ResolveInfo resolveInfo = installers.get(0);
+            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
+                fail("The installer must be a privileged app");
+            }
+        } else {
+            fail("There must be exactly one installer; found " + installers);
+        }
+    }
+
+    @Test
+    public void testExtServicesPresent() throws Exception {
+        enforceSharedLibPresentAndProperlyHosted(
+                PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
+                ApplicationInfo.FLAG_SYSTEM,
+                ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
+    }
+
+    @Test
+    public void testSharedServicesPresent() throws Exception {
+        enforceSharedLibPresentAndProperlyHosted(
+                PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
+                ApplicationInfo.FLAG_SYSTEM, 0);
+    }
+
+    private void enforceSharedLibPresentAndProperlyHosted(String libName,
+            int requiredHostAppFlags, int requiredHostAppPrivateFlags) throws Exception {
+        PackageManager packageManager = InstrumentationRegistry.getContext()
+                .getPackageManager();
+
+        // Is the lib present?
+        String[] libs = packageManager.getSystemSharedLibraryNames();
+        boolean libPresent = false;
+        for (String lib : libs) {
+            if (libName.equals(lib)) {
+                libPresent = true;
+                break;
+            }
+        }
+        if (!libPresent) {
+            fail("Missing required shared library:" + libName);
+        }
+
+        // Is it properly hosted?
+        String packageName = packageManager.getServicesSystemSharedLibraryPackageName();
+        PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0);
+
+        assertTrue(libName + " must be hosted by a system app with flags:"
+                + requiredHostAppFlags, (packageInfo.applicationInfo.flags
+                & requiredHostAppFlags) == requiredHostAppFlags);
+
+        assertTrue(libName + " must be hosted by a system app with private flags:"
+                + requiredHostAppPrivateFlags, (packageInfo.applicationInfo.privateFlags
+                & requiredHostAppPrivateFlags) == requiredHostAppPrivateFlags);
+    }
+}
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 9428695..22cf279 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -18,8 +18,8 @@
 */
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android" coreApp="true" android:sharedUserId="android.uid.system"
-          android:sharedUserLabel="@string/android_system_label">
+    package="android" coreApp="true" android:sharedUserId="android.uid.system"
+    android:sharedUserLabel="@string/android_system_label">
 
     <!-- ================================================ -->
     <!-- Special broadcasts that only the system can send -->
@@ -141,43 +141,43 @@
     <protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" />
     <protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" />
     <protected-broadcast
-            android:name="android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED" />
+        android:name="android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED" />
+        android:name="android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT" />
+        android:name="android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT" />
     <protected-broadcast
-            android:name="android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED" />
+        android:name="android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED" />
+        android:name="android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.headsetclient.profile.action.AG_EVENT" />
+        android:name="android.bluetooth.headsetclient.profile.action.AG_EVENT" />
     <protected-broadcast
-            android:name="android.bluetooth.headsetclient.profile.action.AG_CALL_CHANGED" />
+        android:name="android.bluetooth.headsetclient.profile.action.AG_CALL_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.headsetclient.profile.action.RESULT" />
+        android:name="android.bluetooth.headsetclient.profile.action.RESULT" />
     <protected-broadcast
-            android:name="android.bluetooth.headsetclient.profile.action.LAST_VTAG" />
+        android:name="android.bluetooth.headsetclient.profile.action.LAST_VTAG" />
     <protected-broadcast
-            android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED" />
+        android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED" />
+        android:name="android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED" />
+        android:name="android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED" />
+        android:name="android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED" />
+        android:name="android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED" />
+        android:name="android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED" />
+        android:name="android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED" />
+        android:name="android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED" />
     <protected-broadcast
-            android:name="android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS" />
+        android:name="android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS" />
     <protected-broadcast
-            android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
+        android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED" />
     <protected-broadcast android:name="android.btopp.intent.action.INCOMING_FILE_NOTIFICATION" />
     <protected-broadcast android:name="android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT" />
@@ -320,11 +320,11 @@
     <protected-broadcast android:name="android.telecom.action.DEFAULT_DIALER_CHANGED" />
 
     <protected-broadcast
-            android:name="com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION" />
+        android:name="com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION" />
 
     <!-- Defined in RestrictionsManager -->
     <protected-broadcast
-            android:name="android.intent.action.PERMISSION_RESPONSE_RECEIVED" />
+        android:name="android.intent.action.PERMISSION_RESPONSE_RECEIVED" />
     <!-- Defined in RestrictionsManager -->
 
     <protected-broadcast android:name="android.intent.action.REQUEST_PERMISSION" />
@@ -347,9 +347,6 @@
     <protected-broadcast android:name="android.app.action.SYSTEM_UPDATE_POLICY_CHANGED" />
     <protected-broadcast android:name="android.app.action.DEVICE_OWNER_CHANGED" />
 
-    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABLE" />
-    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNAVAILABLE" />
-
     <!-- Added in N -->
     <protected-broadcast android:name="android.intent.action.ANR" />
     <protected-broadcast android:name="android.intent.action.CALL" />
@@ -470,6 +467,9 @@
     <protected-broadcast android:name="com.android.internal.location.ALARM_TIMEOUT" />
     <protected-broadcast android:name="android.intent.action.GLOBAL_BUTTON" />
 
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABLE" />
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNAVAILABLE" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -480,30 +480,31 @@
     <!-- ====================================================================== -->
     <eat-comment />
 
-    <!-- Used for runtime permissions related to user's contacts and profile. -->
+    <!-- Used for runtime permissions related to contacts and profiles on this
+        device. -->
     <permission-group android:name="android.permission-group.CONTACTS"
-                      android:icon="@drawable/perm_group_contacts"
-                      android:label="@string/permgrouplab_contacts"
-                      android:description="@string/permgroupdesc_contacts"
-                      android:priority="100" />
+        android:icon="@drawable/perm_group_contacts"
+        android:label="@string/permgrouplab_contacts"
+        android:description="@string/permgroupdesc_contacts"
+        android:priority="100" />
 
     <!-- Allows an application to read the user's contacts data.
         <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.READ_CONTACTS"
-                android:permissionGroup="android.permission-group.CONTACTS"
-                android:label="@string/permlab_readContacts"
-                android:description="@string/permdesc_readContacts"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.CONTACTS"
+        android:label="@string/permlab_readContacts"
+        android:description="@string/permdesc_readContacts"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write the user's contacts data.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.WRITE_CONTACTS"
-                android:permissionGroup="android.permission-group.CONTACTS"
-                android:label="@string/permlab_writeContacts"
-                android:description="@string/permdesc_writeContacts"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.CONTACTS"
+        android:label="@string/permlab_writeContacts"
+        android:description="@string/permdesc_writeContacts"
+        android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing user's calendar                              -->
@@ -512,28 +513,28 @@
 
     <!-- Used for runtime permissions related to user's calendar. -->
     <permission-group android:name="android.permission-group.CALENDAR"
-                      android:icon="@drawable/perm_group_calendar"
-                      android:label="@string/permgrouplab_calendar"
-                      android:description="@string/permgroupdesc_calendar"
-                      android:priority="200" />
+        android:icon="@drawable/perm_group_calendar"
+        android:label="@string/permgrouplab_calendar"
+        android:description="@string/permgroupdesc_calendar"
+        android:priority="200" />
 
     <!-- Allows an application to read the user's calendar data.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.READ_CALENDAR"
-                android:permissionGroup="android.permission-group.CALENDAR"
-                android:label="@string/permlab_readCalendar"
-                android:description="@string/permdesc_readCalendar"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.CALENDAR"
+        android:label="@string/permlab_readCalendar"
+        android:description="@string/permdesc_readCalendar"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write the user's calendar data.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.WRITE_CALENDAR"
-                android:permissionGroup="android.permission-group.CALENDAR"
-                android:label="@string/permlab_writeCalendar"
-                android:description="@string/permdesc_writeCalendar"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.CALENDAR"
+        android:label="@string/permlab_writeCalendar"
+        android:description="@string/permdesc_writeCalendar"
+        android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing and modifying user's SMS messages            -->
@@ -542,56 +543,56 @@
 
     <!-- Used for runtime permissions related to user's SMS messages. -->
     <permission-group android:name="android.permission-group.SMS"
-                      android:icon="@drawable/perm_group_sms"
-                      android:label="@string/permgrouplab_sms"
-                      android:description="@string/permgroupdesc_sms"
-                      android:priority="300" />
+        android:icon="@drawable/perm_group_sms"
+        android:label="@string/permgrouplab_sms"
+        android:description="@string/permgroupdesc_sms"
+        android:priority="300" />
 
     <!-- Allows an application to send SMS messages.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.SEND_SMS"
-                android:permissionGroup="android.permission-group.SMS"
-                android:label="@string/permlab_sendSms"
-                android:description="@string/permdesc_sendSms"
-                android:permissionFlags="costsMoney"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.SMS"
+        android:label="@string/permlab_sendSms"
+        android:description="@string/permdesc_sendSms"
+        android:permissionFlags="costsMoney"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to receive SMS messages.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.RECEIVE_SMS"
-                android:permissionGroup="android.permission-group.SMS"
-                android:label="@string/permlab_receiveSms"
-                android:description="@string/permdesc_receiveSms"
-                android:protectionLevel="dangerous"/>
+        android:permissionGroup="android.permission-group.SMS"
+        android:label="@string/permlab_receiveSms"
+        android:description="@string/permdesc_receiveSms"
+        android:protectionLevel="dangerous"/>
 
     <!-- Allows an application to read SMS messages.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.READ_SMS"
-                android:permissionGroup="android.permission-group.SMS"
-                android:label="@string/permlab_readSms"
-                android:description="@string/permdesc_readSms"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.SMS"
+        android:label="@string/permlab_readSms"
+        android:description="@string/permdesc_readSms"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to receive WAP push messages.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.RECEIVE_WAP_PUSH"
-                android:permissionGroup="android.permission-group.SMS"
-                android:label="@string/permlab_receiveWapPush"
-                android:description="@string/permdesc_receiveWapPush"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.SMS"
+        android:label="@string/permlab_receiveWapPush"
+        android:description="@string/permdesc_receiveWapPush"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to monitor incoming MMS messages.
         <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.RECEIVE_MMS"
-                android:permissionGroup="android.permission-group.SMS"
-                android:label="@string/permlab_receiveMms"
-                android:description="@string/permdesc_receiveMms"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.SMS"
+        android:label="@string/permlab_receiveMms"
+        android:description="@string/permdesc_receiveMms"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to read previously received cell broadcast
          messages and to register a content observer to get notifications when
@@ -606,10 +607,10 @@
          <p>Protection level: dangerous
          @hide Pending API council approval -->
     <permission android:name="android.permission.READ_CELL_BROADCASTS"
-                android:permissionGroup="android.permission-group.SMS"
-                android:label="@string/permlab_readCellBroadcasts"
-                android:description="@string/permdesc_readCellBroadcasts"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.SMS"
+        android:label="@string/permlab_readCellBroadcasts"
+        android:description="@string/permdesc_readCellBroadcasts"
+        android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing external storage                             -->
@@ -618,10 +619,10 @@
 
     <!-- Used for runtime permissions related to the shared external storage. -->
     <permission-group android:name="android.permission-group.STORAGE"
-                      android:icon="@drawable/perm_group_storage"
-                      android:label="@string/permgrouplab_storage"
-                      android:description="@string/permgroupdesc_storage"
-                      android:priority="900" />
+        android:icon="@drawable/perm_group_storage"
+        android:label="@string/permgrouplab_storage"
+        android:description="@string/permgroupdesc_storage"
+        android:priority="900" />
 
     <!-- Allows an application to read from external storage.
      <p>Any app that declares the {@link #WRITE_EXTERNAL_STORAGE} permission is implicitly
@@ -646,10 +647,10 @@
      <p>Protection level: dangerous
      -->
     <permission android:name="android.permission.READ_EXTERNAL_STORAGE"
-                android:permissionGroup="android.permission-group.STORAGE"
-                android:label="@string/permlab_sdcardRead"
-                android:description="@string/permdesc_sdcardRead"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.STORAGE"
+        android:label="@string/permlab_sdcardRead"
+        android:description="@string/permdesc_sdcardRead"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write to external storage.
          <p class="note"><strong>Note:</strong> If <em>both</em> your <a
@@ -667,10 +668,10 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
-                android:permissionGroup="android.permission-group.STORAGE"
-                android:label="@string/permlab_sdcardWrite"
-                android:description="@string/permdesc_sdcardWrite"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.STORAGE"
+        android:label="@string/permlab_sdcardWrite"
+        android:description="@string/permdesc_sdcardWrite"
+        android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device location                          -->
@@ -679,28 +680,28 @@
 
     <!-- Used for permissions that allow accessing the device location. -->
     <permission-group android:name="android.permission-group.LOCATION"
-                      android:icon="@drawable/perm_group_location"
-                      android:label="@string/permgrouplab_location"
-                      android:description="@string/permgroupdesc_location"
-                      android:priority="400" />
+        android:icon="@drawable/perm_group_location"
+        android:label="@string/permgrouplab_location"
+        android:description="@string/permgroupdesc_location"
+        android:priority="400" />
 
     <!-- Allows an app to access precise location.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_FINE_LOCATION"
-                android:permissionGroup="android.permission-group.LOCATION"
-                android:label="@string/permlab_accessFineLocation"
-                android:description="@string/permdesc_accessFineLocation"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.LOCATION"
+        android:label="@string/permlab_accessFineLocation"
+        android:description="@string/permdesc_accessFineLocation"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an app to access approximate location.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_COARSE_LOCATION"
-                android:permissionGroup="android.permission-group.LOCATION"
-                android:label="@string/permlab_accessCoarseLocation"
-                android:description="@string/permdesc_accessCoarseLocation"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.LOCATION"
+        android:label="@string/permlab_accessCoarseLocation"
+        android:description="@string/permdesc_accessCoarseLocation"
+        android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device telephony                         -->
@@ -709,10 +710,10 @@
 
     <!-- Used for permissions that are associated telephony features. -->
     <permission-group android:name="android.permission-group.PHONE"
-                      android:icon="@drawable/perm_group_phone_calls"
-                      android:label="@string/permgrouplab_phone"
-                      android:description="@string/permgroupdesc_phone"
-                      android:priority="500" />
+        android:icon="@drawable/perm_group_phone_calls"
+        android:label="@string/permgrouplab_phone"
+        android:description="@string/permgroupdesc_phone"
+        android:priority="500" />
 
     <!-- Allows read only access to phone state, including the phone number of the device,
          current cellular network information, the status of any ongoing calls, and a list of any
@@ -728,21 +729,21 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.READ_PHONE_STATE"
-                android:permissionGroup="android.permission-group.PHONE"
-                android:label="@string/permlab_readPhoneState"
-                android:description="@string/permdesc_readPhoneState"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.PHONE"
+        android:label="@string/permlab_readPhoneState"
+        android:description="@string/permdesc_readPhoneState"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to initiate a phone call without going through
         the Dialer user interface for the user to confirm the call.
         <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.CALL_PHONE"
-                android:permissionGroup="android.permission-group.PHONE"
-                android:permissionFlags="costsMoney"
-                android:label="@string/permlab_callPhone"
-                android:description="@string/permdesc_callPhone"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.PHONE"
+        android:permissionFlags="costsMoney"
+        android:label="@string/permlab_callPhone"
+        android:description="@string/permdesc_callPhone"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to access the IMS call service: making and
          modifying a call
@@ -750,10 +751,10 @@
         @hide
     -->
     <permission android:name="android.permission.ACCESS_IMS_CALL_SERVICE"
-                android:permissionGroup="android.permission-group.PHONE"
-                android:label="@string/permlab_accessImsCallService"
-                android:description="@string/permdesc_accessImsCallService"
-                android:protectionLevel="signature|privileged" />
+        android:permissionGroup="android.permission-group.PHONE"
+        android:label="@string/permlab_accessImsCallService"
+        android:description="@string/permdesc_accessImsCallService"
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to read the user's call log.
          <p class="note"><strong>Note:</strong> If your app uses the
@@ -768,10 +769,10 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.READ_CALL_LOG"
-                android:permissionGroup="android.permission-group.PHONE"
-                android:label="@string/permlab_readCallLog"
-                android:description="@string/permdesc_readCallLog"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.PHONE"
+        android:label="@string/permlab_readCallLog"
+        android:description="@string/permdesc_readCallLog"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write (but not read) the user's
          call log data.
@@ -787,28 +788,28 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.WRITE_CALL_LOG"
-                android:permissionGroup="android.permission-group.PHONE"
-                android:label="@string/permlab_writeCallLog"
-                android:description="@string/permdesc_writeCallLog"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.PHONE"
+        android:label="@string/permlab_writeCallLog"
+        android:description="@string/permdesc_writeCallLog"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to add voicemails into the system.
          <p>Protection level: dangerous
     -->
     <permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL"
-                android:permissionGroup="android.permission-group.PHONE"
-                android:label="@string/permlab_addVoicemail"
-                android:description="@string/permdesc_addVoicemail"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.PHONE"
+        android:label="@string/permlab_addVoicemail"
+        android:description="@string/permdesc_addVoicemail"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to use SIP service.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.USE_SIP"
-                android:permissionGroup="android.permission-group.PHONE"
-                android:description="@string/permdesc_use_sip"
-                android:label="@string/permlab_use_sip"
-                android:protectionLevel="dangerous"/>
+        android:permissionGroup="android.permission-group.PHONE"
+        android:description="@string/permdesc_use_sip"
+        android:label="@string/permlab_use_sip"
+        android:protectionLevel="dangerous"/>
 
     <!-- Allows an application to see the number being dialed during an outgoing
          call with the option to redirect the call to a different number or
@@ -816,10 +817,10 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
-                android:permissionGroup="android.permission-group.PHONE"
-                android:label="@string/permlab_processOutgoingCalls"
-                android:description="@string/permdesc_processOutgoingCalls"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.PHONE"
+        android:label="@string/permlab_processOutgoingCalls"
+        android:description="@string/permdesc_processOutgoingCalls"
+        android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device microphone                        -->
@@ -830,19 +831,19 @@
          microphone audio from the device. Note that phone calls also capture audio
          but are in a separate (more visible) permission group. -->
     <permission-group android:name="android.permission-group.MICROPHONE"
-                      android:icon="@drawable/perm_group_microphone"
-                      android:label="@string/permgrouplab_microphone"
-                      android:description="@string/permgroupdesc_microphone"
-                      android:priority="600" />
+        android:icon="@drawable/perm_group_microphone"
+        android:label="@string/permgrouplab_microphone"
+        android:description="@string/permgroupdesc_microphone"
+        android:priority="600" />
 
     <!-- Allows an application to record audio.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.RECORD_AUDIO"
-                android:permissionGroup="android.permission-group.MICROPHONE"
-                android:label="@string/permlab_recordAudio"
-                android:description="@string/permdesc_recordAudio"
-                android:protectionLevel="dangerous"/>
+        android:permissionGroup="android.permission-group.MICROPHONE"
+        android:label="@string/permlab_recordAudio"
+        android:description="@string/permdesc_recordAudio"
+        android:protectionLevel="dangerous"/>
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the UCE Service                              -->
@@ -852,15 +853,15 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_UCE_PRESENCE_SERVICE"
-                android:permissionGroup="android.permission-group.PHONE"
-                android:protectionLevel="signatureOrSystem"/>
+        android:permissionGroup="android.permission-group.PHONE"
+        android:protectionLevel="signatureOrSystem"/>
 
     <!-- @hide Allows an application to Access UCE-OPTIONS.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_UCE_OPTIONS_SERVICE"
-                android:permissionGroup="android.permission-group.PHONE"
-                android:protectionLevel="signatureOrSystem"/>
+        android:permissionGroup="android.permission-group.PHONE"
+        android:protectionLevel="signatureOrSystem"/>
 
 
 
@@ -872,10 +873,10 @@
     <!-- Used for permissions that are associated with accessing
      camera or capturing images/video from the device. -->
     <permission-group android:name="android.permission-group.CAMERA"
-                      android:icon="@drawable/perm_group_camera"
-                      android:label="@string/permgrouplab_camera"
-                      android:description="@string/permgroupdesc_camera"
-                      android:priority="700" />
+        android:icon="@drawable/perm_group_camera"
+        android:label="@string/permgrouplab_camera"
+        android:description="@string/permgroupdesc_camera"
+        android:priority="700" />
 
     <!-- Required to be able to access the camera device.
          <p>This will automatically enforce the <a
@@ -887,10 +888,10 @@
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.CAMERA"
-                android:permissionGroup="android.permission-group.CAMERA"
-                android:label="@string/permlab_camera"
-                android:description="@string/permdesc_camera"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.CAMERA"
+        android:label="@string/permlab_camera"
+        android:description="@string/permdesc_camera"
+        android:protectionLevel="dangerous" />
 
 
     <!-- ====================================================================== -->
@@ -901,28 +902,28 @@
     <!-- Used for permissions that are associated with accessing
          camera or capturing images/video from the device. -->
     <permission-group android:name="android.permission-group.SENSORS"
-                      android:icon="@drawable/perm_group_sensors"
-                      android:label="@string/permgrouplab_sensors"
-                      android:description="@string/permgroupdesc_sensors"
-                      android:priority="800" />
+        android:icon="@drawable/perm_group_sensors"
+        android:label="@string/permgrouplab_sensors"
+        android:description="@string/permgroupdesc_sensors"
+        android:priority="800" />
 
     <!-- Allows an application to access data from sensors that the user uses to
          measure what is happening inside his/her body, such as heart rate.
          <p>Protection level: dangerous -->
     <permission android:name="android.permission.BODY_SENSORS"
-                android:permissionGroup="android.permission-group.SENSORS"
-                android:label="@string/permlab_bodySensors"
-                android:description="@string/permdesc_bodySensors"
-                android:protectionLevel="dangerous" />
+        android:permissionGroup="android.permission-group.SENSORS"
+        android:label="@string/permlab_bodySensors"
+        android:description="@string/permdesc_bodySensors"
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an app to use fingerprint hardware.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.USE_FINGERPRINT"
-                android:permissionGroup="android.permission-group.SENSORS"
-                android:label="@string/permlab_useFingerprint"
-                android:description="@string/permdesc_useFingerprint"
-                android:protectionLevel="normal" />
+        android:permissionGroup="android.permission-group.SENSORS"
+        android:label="@string/permlab_useFingerprint"
+        android:description="@string/permdesc_useFingerprint"
+        android:protectionLevel="normal" />
 
     <!-- ====================================================================== -->
     <!-- REMOVED PERMISSIONS                                                    -->
@@ -930,78 +931,78 @@
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.READ_PROFILE"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.WRITE_PROFILE"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.READ_SOCIAL_STREAM"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.WRITE_SOCIAL_STREAM"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.READ_USER_DICTIONARY"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.WRITE_USER_DICTIONARY"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.WRITE_SMS"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.MANAGE_ACCOUNTS"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.USE_CREDENTIALS"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.SUBSCRIBED_FEEDS_READ"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- @hide We need to keep this around for backwards compatibility -->
     <permission android:name="android.permission.FLASHLIGHT"
-                android:protectionLevel="normal"
-                android:permissionFlags="removed"/>
+        android:protectionLevel="normal"
+        android:permissionFlags="removed"/>
 
     <!-- ====================================================================== -->
     <!-- INSTALL PERMISSIONS                                                    -->
@@ -1016,35 +1017,35 @@
          to handle the respond-via-message action during incoming calls.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to send SMS to premium shortcodes without user permission.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SEND_SMS_NO_CONFIRMATION"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to filter carrier specific sms.
          @hide -->
     <permission android:name="android.permission.CARRIER_FILTER_SMS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to receive emergency cell broadcast messages,
          to record or display them to the user.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.RECEIVE_EMERGENCY_BROADCAST"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to monitor incoming Bluetooth MAP messages, to record
          or perform processing on them. -->
     <!-- @hide -->
     <permission android:name="android.permission.RECEIVE_BLUETOOTH_MAP"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to execute contacts directory search.
          This should only be used by ContactsProvider.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.BIND_DIRECTORY_SEARCH"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to modify cell broadcasts through the content provider.
          <p>Not for use by third-party applications. -->
@@ -1060,56 +1061,56 @@
          <p>Protection level: normal
     -->
     <permission android:name="com.android.alarm.permission.SET_ALARM"
-                android:label="@string/permlab_setAlarm"
-                android:description="@string/permdesc_setAlarm"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_setAlarm"
+        android:description="@string/permdesc_setAlarm"
+        android:protectionLevel="normal" />
 
     <!-- =============================================================== -->
     <!-- Permissions for accessing the user voicemail                    -->
     <!-- =============================================================== -->
     <eat-comment />
 
-    <!-- Allows an application to modify and remove existing voicemails in the system
+    <!-- Allows an application to modify and remove existing voicemails in the system.
         <p>Protection level: signature|privileged
     -->
     <permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to read voicemails in the system.
          <p>Protection level: signature|privileged
     -->
     <permission android:name="com.android.voicemail.permission.READ_VOICEMAIL"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- ======================================= -->
     <!-- Permissions for accessing location info -->
     <!-- ======================================= -->
     <eat-comment />
 
-    <!-- Allows an application to access extra location provider commands
+    <!-- Allows an application to access extra location provider commands.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"
-                android:label="@string/permlab_accessLocationExtraCommands"
-                android:description="@string/permdesc_accessLocationExtraCommands"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_accessLocationExtraCommands"
+        android:description="@string/permdesc_accessLocationExtraCommands"
+        android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows an application to install a location provider into the Location Manager.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.INSTALL_LOCATION_PROVIDER"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows HDMI-CEC service to access device and configuration files.
          This should only be used by HDMI-CEC service.
     -->
     <permission android:name="android.permission.HDMI_CEC"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to use location features in hardware,
          such as the geofencing api.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.LOCATION_HARDWARE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
     <uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
 
     <!-- @SystemApi Allows an application to create mock location providers for testing.
@@ -1117,7 +1118,7 @@
          @hide
     -->
     <permission android:name="android.permission.ACCESS_MOCK_LOCATION"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- ======================================= -->
     <!-- Permissions for accessing networks -->
@@ -1128,73 +1129,73 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.INTERNET"
-                android:description="@string/permdesc_createNetworkSockets"
-                android:label="@string/permlab_createNetworkSockets"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_createNetworkSockets"
+        android:label="@string/permlab_createNetworkSockets"
+        android:protectionLevel="normal" />
 
-    <!-- Allows applications to access information about networks
+    <!-- Allows applications to access information about networks.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.ACCESS_NETWORK_STATE"
-                android:description="@string/permdesc_accessNetworkState"
-                android:label="@string/permlab_accessNetworkState"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_accessNetworkState"
+        android:label="@string/permlab_accessNetworkState"
+        android:protectionLevel="normal" />
 
     <!-- Allows applications to access information about Wi-Fi networks.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.ACCESS_WIFI_STATE"
-                android:description="@string/permdesc_accessWifiState"
-                android:label="@string/permlab_accessWifiState"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_accessWifiState"
+        android:label="@string/permlab_accessWifiState"
+        android:protectionLevel="normal" />
 
     <!-- Allows applications to change Wi-Fi connectivity state.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.CHANGE_WIFI_STATE"
-                android:description="@string/permdesc_changeWifiState"
-                android:label="@string/permlab_changeWifiState"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_changeWifiState"
+        android:label="@string/permlab_changeWifiState"
+        android:protectionLevel="normal" />
 
     <!-- @SystemApi @hide Allows applications to read Wi-Fi credential.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.READ_WIFI_CREDENTIAL"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows applications to change tether state and run
          tether carrier provisioning.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.TETHER_PRIVILEGED"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allow system apps to receive broadcast
          when a wifi network credential is changed.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to modify any wifi configuration, even if created
      by another application. Once reconfigured the original creator cannot make any further
      modifications.
      <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.OVERRIDE_WIFI_CONFIG"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @hide -->
     <permission android:name="android.permission.ACCESS_WIMAX_STATE"
-                android:description="@string/permdesc_accessWimaxState"
-                android:label="@string/permlab_accessWimaxState"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_accessWimaxState"
+        android:label="@string/permlab_accessWimaxState"
+        android:protectionLevel="normal" />
 
     <!-- @hide -->
     <permission android:name="android.permission.CHANGE_WIMAX_STATE"
-                android:description="@string/permdesc_changeWimaxState"
-                android:label="@string/permlab_changeWimaxState"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_changeWimaxState"
+        android:label="@string/permlab_changeWimaxState"
+        android:protectionLevel="normal" />
 
     <!-- Allows applications to act as network scorers. @hide @SystemApi-->
     <permission android:name="android.permission.SCORE_NETWORKS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- ======================================= -->
     <!-- Permissions for short range, peripheral networks -->
@@ -1205,68 +1206,68 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.BLUETOOTH"
-                android:description="@string/permdesc_bluetooth"
-                android:label="@string/permlab_bluetooth"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_bluetooth"
+        android:label="@string/permlab_bluetooth"
+        android:protectionLevel="normal" />
 
     <!-- Allows applications to discover and pair bluetooth devices.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.BLUETOOTH_ADMIN"
-                android:description="@string/permdesc_bluetoothAdmin"
-                android:label="@string/permlab_bluetoothAdmin"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_bluetoothAdmin"
+        android:label="@string/permlab_bluetoothAdmin"
+        android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows applications to pair bluetooth devices without user interaction, and to
          allow or disallow phonebook access or message access.
          This is not available to third party applications. -->
     <permission android:name="android.permission.BLUETOOTH_PRIVILEGED"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Control access to email providers exclusively for Bluetooth
          @hide
     -->
     <permission android:name="android.permission.BLUETOOTH_MAP"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows bluetooth stack to access files
          @hide This should only be used by Bluetooth apk.
     -->
     <permission android:name="android.permission.BLUETOOTH_STACK"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows applications to perform I/O operations over NFC.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.NFC"
-                android:description="@string/permdesc_nfc"
-                android:label="@string/permlab_nfc"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_nfc"
+        android:label="@string/permlab_nfc"
+        android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows an internal user to use privileged ConnectivityManager APIs.
          @hide -->
     <permission android:name="android.permission.CONNECTIVITY_INTERNAL"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows a system application to access hardware packet offload capabilities.
          @hide -->
     <permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi
          @hide -->
     <permission android:name="android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows access to the loop radio (Android@Home mesh network) device.
          @hide -->
     <permission android:name="android.permission.LOOP_RADIO"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows sending and receiving handover transfer status from Wifi and Bluetooth
          @hide -->
     <permission android:name="android.permission.NFC_HANDOVER_STATUS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- ================================== -->
     <!-- Permissions for accessing accounts -->
@@ -1274,18 +1275,26 @@
     <eat-comment />
 
     <!-- Allows access to the list of accounts in the Accounts Service.
-        <p>Protection level: normal
+
+    <p class="note"><strong>Note:</strong> Beginning with Android 6.0 (API level
+    23), if an app shares the signature of the authenticator that manages an
+    account, it does not need <code>"GET_ACCOUNTS"</code> permission to read
+    information about that account. On Android 5.1 and lower, all apps need
+    <code>"GET_ACCOUNTS"</code> permission to read information about any
+    account.</p>
+
+    <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.GET_ACCOUNTS"
-                android:permissionGroup="android.permission-group.CONTACTS"
-                android:protectionLevel="dangerous"
-                android:description="@string/permdesc_getAccounts"
-                android:label="@string/permlab_getAccounts" />
+        android:permissionGroup="android.permission-group.CONTACTS"
+        android:protectionLevel="dangerous"
+        android:description="@string/permdesc_getAccounts"
+        android:label="@string/permlab_getAccounts" />
 
     <!-- @SystemApi Allows applications to call into AccountAuthenticators.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCOUNT_MANAGER"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions for accessing hardware that may effect battery life-->
@@ -1296,34 +1305,34 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"
-                android:description="@string/permdesc_changeWifiMulticastState"
-                android:label="@string/permlab_changeWifiMulticastState"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_changeWifiMulticastState"
+        android:label="@string/permlab_changeWifiMulticastState"
+        android:protectionLevel="normal" />
 
     <!-- Allows access to the vibrator.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.VIBRATE"
-                android:label="@string/permlab_vibrate"
-                android:description="@string/permdesc_vibrate"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_vibrate"
+        android:description="@string/permdesc_vibrate"
+        android:protectionLevel="normal" />
 
     <!-- Allows using PowerManager WakeLocks to keep processor from sleeping or screen
          from dimming.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.WAKE_LOCK"
-                android:label="@string/permlab_wakeLock"
-                android:description="@string/permdesc_wakeLock"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_wakeLock"
+        android:description="@string/permdesc_wakeLock"
+        android:protectionLevel="normal" />
 
     <!-- Allows using the device's IR transmitter, if available.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.TRANSMIT_IR"
-                android:label="@string/permlab_transmitIr"
-                android:description="@string/permdesc_transmitIr"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_transmitIr"
+        android:description="@string/permdesc_transmitIr"
+        android:protectionLevel="normal" />
 
     <!-- ==================================================== -->
     <!-- Permissions related to changing audio settings   -->
@@ -1334,9 +1343,9 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"
-                android:label="@string/permlab_modifyAudioSettings"
-                android:description="@string/permdesc_modifyAudioSettings"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_modifyAudioSettings"
+        android:description="@string/permdesc_modifyAudioSettings"
+        android:protectionLevel="normal" />
 
     <!-- ================================== -->
     <!-- Permissions for accessing hardware -->
@@ -1346,68 +1355,68 @@
     <!-- @SystemApi Allows an application to manage preferences and permissions for USB devices
          @hide -->
     <permission android:name="android.permission.MANAGE_USB"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to access the MTP USB kernel driver.
          For use only by the device side MTP implementation.
          @hide -->
     <permission android:name="android.permission.ACCESS_MTP"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows access to hardware peripherals.  Intended only for hardware testing.
          <p>Not for use by third-party applications.
          @hide
     -->
     <permission android:name="android.permission.HARDWARE_TEST"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows access to FM
          @hide This is not a third-party API (intended for system apps).-->
     <permission android:name="android.permission.ACCESS_FM_RADIO"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows access to configure network interfaces, configure/use IPSec, etc.
          @hide -->
     <permission android:name="android.permission.NET_ADMIN"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows registration for remote audio playback. @hide -->
     <permission android:name="android.permission.REMOTE_AUDIO_PLAYBACK"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows TvInputService to access underlying TV input hardware such as
          built-in tuners and HDMI-in's.
          @hide This should only be used by OEM's TvInputService's.
     -->
     <permission android:name="android.permission.TV_INPUT_HARDWARE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows to capture a frame of TV input hardware such as
          built-in tuners and HDMI-in's.
          @hide <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.CAPTURE_TV_INPUT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @hide Allows TvInputService to access DVB device.
    <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DVB_DEVICE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @hide Allows enabling/disabling OEM unlock
    <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.OEM_UNLOCK_STATE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @hide Allows querying state of PersistentDataBlock
    <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCESS_PDB_STATE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @hide Allows system update service to notify device owner about pending updates.
    <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.NOTIFY_PENDING_SYSTEM_UPDATE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- =========================================== -->
     <!-- Permissions associated with camera and image capture -->
@@ -1418,12 +1427,12 @@
          a camera is in use by an application.
          @hide -->
     <permission android:name="android.permission.CAMERA_DISABLE_TRANSMIT_LED"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows sending the camera service notifications about system-wide events.
         @hide -->
     <permission android:name="android.permission.CAMERA_SEND_SYSTEM_EVENTS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- =========================================== -->
     <!-- Permissions associated with telephony state -->
@@ -1434,50 +1443,50 @@
          Does not include placing calls.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MODIFY_PHONE_STATE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows read only access to precise phone state.
          @hide Pending API council approval -->
     <permission android:name="android.permission.READ_PRECISE_PHONE_STATE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows read access to privileged phone state.
          @hide Used internally. -->
     <permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Protects the ability to register any PhoneAccount with
          PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION. This capability indicates that the PhoneAccount
          corresponds to a device SIM.
          @hide -->
     <permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Protects the ability to register any PhoneAccount with
          PhoneAccount#CAPABILITY_CALL_PROVIDER.
          @hide -->
     <permission android:name="android.permission.REGISTER_CALL_PROVIDER"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Protects the ability to register any PhoneAccount with
          PhoneAccount#CAPABILITY_CONNECTION_MANAGER
          @hide -->
     <permission android:name="android.permission.REGISTER_CONNECTION_MANAGER"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.telecom.InCallService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature|privileged
     -->
     <permission android:name="android.permission.BIND_INCALL_SERVICE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.telecom.CallScreeningService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature|privileged
     -->
     <permission android:name="android.permission.BIND_SCREENING_SERVICE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.telecom.ConnectionService},
          to ensure that only the system can bind to it.
@@ -1486,24 +1495,24 @@
          @SystemApi
          @hide -->
     <permission android:name="android.permission.BIND_CONNECTION_SERVICE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.telecom.ConnectionService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature|privileged
     -->
     <permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to control the in-call experience.
          @hide -->
     <permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to receive STK related commands.
          @hide -->
     <permission android:name="android.permission.RECEIVE_STK_COMMANDS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
@@ -1513,7 +1522,7 @@
     <!-- @SystemApi Allows an application to write to internal media storage
          @hide  -->
     <permission android:name="android.permission.WRITE_MEDIA_STORAGE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to manage access to documents, usually as part
          of a document picker.
@@ -1523,14 +1532,14 @@
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.MANAGE_DOCUMENTS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @hide Allows an application to cache content.
          <p>Not for use by third-party applications.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.CACHE_CONTENT"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions for screenlock         -->
@@ -1541,9 +1550,9 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.DISABLE_KEYGUARD"
-                android:description="@string/permdesc_disableKeyguard"
-                android:label="@string/permlab_disableKeyguard"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_disableKeyguard"
+        android:label="@string/permlab_disableKeyguard"
+        android:protectionLevel="normal" />
 
     <!-- ================================== -->
     <!-- Permissions to access other installed applications  -->
@@ -1552,9 +1561,9 @@
 
     <!-- @deprecated No longer enforced. -->
     <permission android:name="android.permission.GET_TASKS"
-                android:label="@string/permlab_getTasks"
-                android:description="@string/permdesc_getTasks"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_getTasks"
+        android:description="@string/permdesc_getTasks"
+        android:protectionLevel="normal" />
 
     <!-- New version of GET_TASKS that apps can request, since GET_TASKS doesn't really
          give access to task information.  We need this new one because there are
@@ -1567,113 +1576,124 @@
          @hide
          @SystemApi -->
     <permission android:name="android.permission.REAL_GET_TASKS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to start a task from a ActivityManager#RecentTaskInfo.
          @hide -->
     <permission android:name="android.permission.START_TASKS_FROM_RECENTS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to call APIs that allow it to do interactions
          across the users on the device, using singleton services and
          user-targeted broadcasts.  This permission is not available to
          third party applications. -->
     <permission android:name="android.permission.INTERACT_ACROSS_USERS"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
-    <!-- @hide Fuller form of {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
+    <!-- @SystemApi Fuller form of {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
          that removes restrictions on where broadcasts can be sent and allows other
-         types of interactions. -->
+         types of interactions
+         @hide -->
     <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
-                android:protectionLevel="signature|installer" />
+        android:protectionLevel="signature|installer" />
 
     <!-- @SystemApi @hide Allows an application to call APIs that allow it to query and manage
          users on the device. This permission is not available to
          third party applications. -->
     <permission android:name="android.permission.MANAGE_USERS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @hide Allows an application to set the profile owners and the device owner.
          This permission is not available to third party applications.-->
     <permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS"
-                android:protectionLevel="signature"
-                android:label="@string/permlab_manageProfileAndDeviceOwners"
-                android:description="@string/permdesc_manageProfileAndDeviceOwners" />
+        android:protectionLevel="signature"
+        android:label="@string/permlab_manageProfileAndDeviceOwners"
+        android:description="@string/permdesc_manageProfileAndDeviceOwners" />
 
     <!-- Allows an application to get full detailed information about
          recently running tasks, with full fidelity to the real state.
          @hide -->
     <permission android:name="android.permission.GET_DETAILED_TASKS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to change the Z-order of tasks.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.REORDER_TASKS"
-                android:label="@string/permlab_reorderTasks"
-                android:description="@string/permdesc_reorderTasks"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_reorderTasks"
+        android:description="@string/permdesc_reorderTasks"
+        android:protectionLevel="normal" />
 
     <!-- @hide Allows an application to change to remove/kill tasks -->
     <permission android:name="android.permission.REMOVE_TASKS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi @hide Allows an application to create/manage/remove stacks -->
     <permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to start any activity, regardless of permission
          protection or exported state.
          @hide -->
     <permission android:name="android.permission.START_ANY_ACTIVITY"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @deprecated The {@link android.app.ActivityManager#restartPackage}
         API is no longer supported. -->
     <permission android:name="android.permission.RESTART_PACKAGES"
-                android:label="@string/permlab_killBackgroundProcesses"
-                android:description="@string/permdesc_killBackgroundProcesses"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_killBackgroundProcesses"
+        android:description="@string/permdesc_killBackgroundProcesses"
+        android:protectionLevel="normal" />
 
     <!-- Allows an application to call
         {@link android.app.ActivityManager#killBackgroundProcesses}.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"
-                android:label="@string/permlab_killBackgroundProcesses"
-                android:description="@string/permdesc_killBackgroundProcesses"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_killBackgroundProcesses"
+        android:description="@string/permdesc_killBackgroundProcesses"
+        android:protectionLevel="normal" />
 
     <!-- @SystemApi @hide Allows an application to query process states and current
          OOM adjustment scores.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi @hide Allows an application to retrieve a package's importance.
          This permission is not available to third party applications. -->
     <permission android:name="android.permission.GET_PACKAGE_IMPORTANCE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows use of PendingIntent.getIntent().
          @hide -->
     <permission android:name="android.permission.GET_INTENT_SENDER_INTENT"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions affecting the display of other applications  -->
     <!-- ================================== -->
     <eat-comment />
 
-    <!-- Allows an application to open windows using the type
+    <!-- Allows an app to create windows using the type
          {@link android.view.WindowManager.LayoutParams#TYPE_SYSTEM_ALERT},
-         shown on top of all other applications.  Very few applications
+         shown on top of all other apps.  Very few apps
          should use this permission; these windows are intended for
-         system-level interaction with the user. -->
+         system-level interaction with the user.
+
+         <p class="note"><strong>Note:</strong> If the app
+         targets API level 23 or higher, the app user must explicitly grant
+         this permission to the app through a permission management screen. The app requests
+         the user's approval by sending an intent with action
+         {@link android.provider.Settings#ACTION_MANAGE_OVERLAY_PERMISSION}.
+         The app can check whether it has this authorization by calling
+         {@link android.provider.Settings#canDrawOverlays
+         Settings.canDrawOverlays()}.
+         <p>Protection level: signature -->
     <permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
-                android:label="@string/permlab_systemAlertWindow"
-                android:description="@string/permdesc_systemAlertWindow"
-                android:protectionLevel="signature|preinstalled|appop|pre23|development" />
+        android:label="@string/permlab_systemAlertWindow"
+        android:description="@string/permdesc_systemAlertWindow"
+        android:protectionLevel="signature|preinstalled|appop|pre23|development" />
 
     <!-- ================================== -->
     <!-- Permissions affecting the system wallpaper -->
@@ -1684,17 +1704,17 @@
          <p>Protection level: normal
      -->
     <permission android:name="android.permission.SET_WALLPAPER"
-                android:label="@string/permlab_setWallpaper"
-                android:description="@string/permdesc_setWallpaper"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_setWallpaper"
+        android:description="@string/permdesc_setWallpaper"
+        android:protectionLevel="normal" />
 
     <!-- Allows applications to set the wallpaper hints.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.SET_WALLPAPER_HINTS"
-                android:label="@string/permlab_setWallpaperHints"
-                android:description="@string/permdesc_setWallpaperHints"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_setWallpaperHints"
+        android:description="@string/permdesc_setWallpaperHints"
+        android:protectionLevel="normal" />
 
     <!-- ============================================ -->
     <!-- Permissions for changing the system clock -->
@@ -1704,15 +1724,15 @@
     <!-- @SystemApi Allows applications to set the system time.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_TIME"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows applications to set the system time zone.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.SET_TIME_ZONE"
-                android:label="@string/permlab_setTimeZone"
-                android:description="@string/permdesc_setTimeZone"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_setTimeZone"
+        android:description="@string/permdesc_setTimeZone"
+        android:protectionLevel="normal" />
 
     <!-- ==================================================== -->
     <!-- Permissions related to changing status bar   -->
@@ -1723,9 +1743,9 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.EXPAND_STATUS_BAR"
-                android:label="@string/permlab_expandStatusBar"
-                android:description="@string/permdesc_expandStatusBar"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_expandStatusBar"
+        android:description="@string/permdesc_expandStatusBar"
+        android:protectionLevel="normal" />
 
     <!-- ============================================================== -->
     <!-- Permissions related to adding/removing shortcuts from Launcher -->
@@ -1736,17 +1756,17 @@
          <p>Protection level: normal
     -->
     <permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
-                android:label="@string/permlab_install_shortcut"
-                android:description="@string/permdesc_install_shortcut"
-                android:protectionLevel="normal"/>
+        android:label="@string/permlab_install_shortcut"
+        android:description="@string/permdesc_install_shortcut"
+        android:protectionLevel="normal"/>
 
     <!-- Allows an application to uninstall a shortcut in Launcher.
          <p>Protection level: normal
     -->
     <permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
-                android:label="@string/permlab_uninstall_shortcut"
-                android:description="@string/permdesc_uninstall_shortcut"
-                android:protectionLevel="normal"/>
+        android:label="@string/permlab_uninstall_shortcut"
+        android:description="@string/permdesc_uninstall_shortcut"
+        android:protectionLevel="normal"/>
 
     <!-- ==================================================== -->
     <!-- Permissions related to accessing sync settings   -->
@@ -1757,25 +1777,25 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.READ_SYNC_SETTINGS"
-                android:description="@string/permdesc_readSyncSettings"
-                android:label="@string/permlab_readSyncSettings"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_readSyncSettings"
+        android:label="@string/permlab_readSyncSettings"
+        android:protectionLevel="normal" />
 
     <!-- Allows applications to write the sync settings.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.WRITE_SYNC_SETTINGS"
-                android:description="@string/permdesc_writeSyncSettings"
-                android:label="@string/permlab_writeSyncSettings"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_writeSyncSettings"
+        android:label="@string/permlab_writeSyncSettings"
+        android:protectionLevel="normal" />
 
     <!-- Allows applications to read the sync stats.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.READ_SYNC_STATS"
-                android:description="@string/permdesc_readSyncStats"
-                android:label="@string/permlab_readSyncStats"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_readSyncStats"
+        android:label="@string/permlab_readSyncStats"
+        android:protectionLevel="normal" />
 
     <!-- ============================================ -->
     <!-- Permissions for low-level system interaction -->
@@ -1784,62 +1804,71 @@
 
     <!-- @SystemApi @hide Change the screen compatibility mode of applications -->
     <permission android:name="android.permission.SET_SCREEN_COMPATIBILITY"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to modify the current configuration, such
          as locale. -->
     <permission android:name="android.permission.CHANGE_CONFIGURATION"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- Allows an application to read or write the system settings.
-         <p>Protection level: signature
+
+        <p class="note"><strong>Note:</strong> If the app targets API level 23
+        or higher, the app user
+        must explicitly grant this permission to the app through a permission management screen.
+        The app requests the user's approval by sending an intent with action
+        {@link android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}. The app
+        can check whether it has this authorization by calling {@link
+        android.provider.Settings.System#canWrite Settings.System.canWrite()}.
+
+        <p>Protection level: signature
     -->
     <permission android:name="android.permission.WRITE_SETTINGS"
-                android:label="@string/permlab_writeSettings"
-                android:description="@string/permdesc_writeSettings"
-                android:protectionLevel="signature|preinstalled|appop|pre23" />
+        android:label="@string/permlab_writeSettings"
+        android:description="@string/permdesc_writeSettings"
+        android:protectionLevel="signature|preinstalled|appop|pre23" />
 
     <!-- @SystemApi Allows an application to modify the Google service map.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_GSERVICES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to call
         {@link android.app.ActivityManager#forceStopPackage}.
         @hide -->
     <permission android:name="android.permission.FORCE_STOP_PACKAGES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to retrieve the content of the active window
          An active window is the window that has fired an accessibility event. -->
     <permission android:name="android.permission.RETRIEVE_WINDOW_CONTENT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Modify the global animation scaling factor.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_ANIMATION_SCALE"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @deprecated This functionality will be removed in the future; please do
          not use. Allow an application to make its activities persistent. -->
     <permission android:name="android.permission.PERSISTENT_ACTIVITY"
-                android:label="@string/permlab_persistentActivity"
-                android:description="@string/permdesc_persistentActivity"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_persistentActivity"
+        android:description="@string/permdesc_persistentActivity"
+        android:protectionLevel="normal" />
 
     <!-- Allows an application to find out the space used by any package.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.GET_PACKAGE_SIZE"
-                android:label="@string/permlab_getPackageSize"
-                android:description="@string/permdesc_getPackageSize"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_getPackageSize"
+        android:description="@string/permdesc_getPackageSize"
+        android:protectionLevel="normal" />
 
     <!-- @deprecated No longer useful, see
          {@link android.content.pm.PackageManager#addPackageToPreferred}
          for details. -->
     <permission android:name="android.permission.SET_PREFERRED_APPLICATIONS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to receive the
          {@link android.content.Intent#ACTION_BOOT_COMPLETED} that is
@@ -1855,9 +1884,9 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"
-                android:label="@string/permlab_receiveBootCompleted"
-                android:description="@string/permdesc_receiveBootCompleted"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_receiveBootCompleted"
+        android:description="@string/permdesc_receiveBootCompleted"
+        android:protectionLevel="normal" />
 
     <!-- Allows an application to broadcast sticky intents.  These are
          broadcasts whose data is held by the system after being finished,
@@ -1866,90 +1895,90 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.BROADCAST_STICKY"
-                android:label="@string/permlab_broadcastSticky"
-                android:description="@string/permdesc_broadcastSticky"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_broadcastSticky"
+        android:description="@string/permdesc_broadcastSticky"
+        android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows mounting and unmounting file systems for removable storage.
     <p>Not for use by third-party applications.-->
     <permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows formatting file systems for removable storage.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @hide -->
     <permission android:name="android.permission.STORAGE_INTERNAL"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows access to ASEC non-destructive API calls
          @hide  -->
     <permission android:name="android.permission.ASEC_ACCESS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows creation of ASEC volumes
          @hide  -->
     <permission android:name="android.permission.ASEC_CREATE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows destruction of ASEC volumes
          @hide  -->
     <permission android:name="android.permission.ASEC_DESTROY"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows mount / unmount of ASEC volumes
          @hide  -->
     <permission android:name="android.permission.ASEC_MOUNT_UNMOUNT"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows rename of ASEC volumes
          @hide  -->
     <permission android:name="android.permission.ASEC_RENAME"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows applications to write the apn settings.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_APN_SETTINGS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows applications to change network connectivity state.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.CHANGE_NETWORK_STATE"
-                android:description="@string/permdesc_changeNetworkState"
-                android:label="@string/permlab_changeNetworkState"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_changeNetworkState"
+        android:label="@string/permlab_changeNetworkState"
+        android:protectionLevel="normal" />
 
     <!-- Allows an application to clear the caches of all installed
          applications on the device.
          <p>Protection level: system|signature
     -->
     <permission android:name="android.permission.CLEAR_APP_CACHE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to use any media decoder when decoding for playback
          @hide -->
     <permission android:name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to install and/or uninstall CA certificates on
          behalf of the user.
          @hide -->
     <permission android:name="android.permission.MANAGE_CA_CERTIFICATES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to do certain operations needed for
          interacting with the recovery (system update) system.
          @hide -->
     <permission android:name="android.permission.RECOVERY"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows the system to bind to an application's task services
          @hide -->
     <permission android:name="android.permission.BIND_JOB_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
     <uses-permission android:name="android.permission.BIND_JOB_SERVICE"/>
 
     <!-- Allows an application to initiate configuration updates
@@ -1958,7 +1987,7 @@
          it off to the various individual installer components
          @hide -->
     <permission android:name="android.permission.UPDATE_CONFIG"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- ========================================= -->
     <!-- Permissions for special development tools -->
@@ -1968,40 +1997,40 @@
     <!-- @SystemApi Allows an application to read or write the secure system settings.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_SECURE_SETTINGS"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to retrieve state dump information from system services.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DUMP"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to read the low-level system log files.
     <p>Not for use by third-party applications, because
     Log entries can contain the user's private information. -->
     <permission android:name="android.permission.READ_LOGS"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Configure an application for debugging.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_DEBUG_APP"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to set the maximum number of (not needed)
          application processes that can be running.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_PROCESS_LIMIT"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to control whether activities are immediately
          finished when put in the background.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_ALWAYS_FINISH"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allow an application to request that a signal be sent to all persistent processes.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SIGNAL_PERSISTENT_PROCESSES"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- ==================================== -->
     <!-- Private permissions                  -->
@@ -2010,34 +2039,34 @@
 
     <!-- @SystemApi Allows access to the list of accounts in the Accounts Service. -->
     <permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows but does not guarantee access to user passwords at the conclusion of add
-         account -->
-    <permission android:name="android.permission.GET_PASSWORD_PRIVILEGED"
-                android:protectionLevel="signature|privileged" />
+    <!-- Allows but does not guarantee access to user passwords at the conclusion of add account
+    @hide -->
+    <permission android:name="android.permission.GET_PASSWORD"
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows applications to RW to diagnostic resources.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DIAGNOSTIC"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to open, close, or disable the status bar
          and its icons.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.STATUS_BAR"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to be the status bar.  Currently used only by SystemUI.apk
     @hide -->
     <permission android:name="android.permission.STATUS_BAR_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to bind to third party quick settings tiles.
          <p>Should only be requested by the System, should be required by
          TileService declarations.-->
     <permission android:name="android.permission.BIND_QUICK_SETTINGS_TILE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to force a BACK operation on whatever is the
          top activity.
@@ -2045,27 +2074,28 @@
          @hide
     -->
     <permission android:name="android.permission.FORCE_BACK"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to update device statistics.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.UPDATE_DEVICE_STATS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi @hide Allows an application to collect battery statistics -->
     <permission android:name="android.permission.GET_APP_OPS_STATS"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to update application operation statistics. Not for
-         use by third party apps. @hide -->
+         use by third party apps.
+         @hide -->
     <permission android:name="android.permission.UPDATE_APP_OPS_STATS"
-                android:protectionLevel="signature|privileged|installer" />
+        android:protectionLevel="signature|privileged|installer" />
 
-    <!-- Allows an application to update the user app op restrictions.
+    <!-- @SystemApi Allows an application to update the user app op restrictions.
          Not for use by third party apps.
          @hide -->
     <permission android:name="android.permission.MANAGE_APP_OPS_RESTRICTIONS"
-                android:protectionLevel="signature|installer" />
+        android:protectionLevel="signature|installer" />
 
     <!-- @SystemApi Allows an application to open windows that are for use by parts
          of the system user interface.
@@ -2073,7 +2103,7 @@
          @hide
     -->
     <permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to manage (create, destroy,
          Z-order) application tokens in the window manager.
@@ -2081,17 +2111,17 @@
          @hide
     -->
     <permission android:name="android.permission.MANAGE_APP_TOKENS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows System UI to register listeners for events from Window Manager.
          @hide -->
     <permission android:name="android.permission.REGISTER_WINDOW_MANAGER_LISTENERS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @hide Allows the application to temporarily freeze the screen for a
          full-screen transition. -->
     <permission android:name="android.permission.FREEZE_SCREEN"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to inject user events (keys, touch, trackball)
          into the event stream and deliver them to ANY window.  Without this
@@ -2100,24 +2130,24 @@
          @hide
     -->
     <permission android:name="android.permission.INJECT_EVENTS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @hide Allows an application to register an input filter which filters the stream
          of user events (keys, touch, trackball) before they are dispatched to any window. -->
     <permission android:name="android.permission.FILTER_EVENTS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @hide Allows an application to retrieve the window token from the accessibility manager. -->
     <permission android:name="android.permission.RETRIEVE_WINDOW_TOKEN"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @hide Allows an application to collect frame statistics -->
     <permission android:name="android.permission.FRAME_STATS"
-                android:protectionLevel="signature" />
+         android:protectionLevel="signature" />
 
     <!-- @hide Allows an application to temporary enable accessibility on the device. -->
     <permission android:name="android.permission.TEMPORARY_ENABLE_ACCESSIBILITY"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to watch and control how activities are
          started globally in the system.  Only for is in debugging
@@ -2126,13 +2156,13 @@
          @hide
     -->
     <permission android:name="android.permission.SET_ACTIVITY_WATCHER"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to call the activity manager shutdown() API
          to put the higher-level system there into a shutdown state.
          @hide -->
     <permission android:name="android.permission.SHUTDOWN"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to tell the activity manager to temporarily
          stop application switches, putting it into a special mode that
@@ -2140,7 +2170,7 @@
          critical UI such as the home screen.
          @hide -->
     <permission android:name="android.permission.STOP_APP_SWITCHES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to retrieve private information about
          the current top activity, such as any assist context it can provide.
@@ -2148,42 +2178,42 @@
          @hide
     -->
     <permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to retrieve the current state of keys and
          switches.
          <p>Not for use by third-party applications.
          @deprecated The API that used this permission has been removed. -->
     <permission android:name="android.permission.READ_INPUT_STATE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.inputmethodservice.InputMethodService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_INPUT_METHOD"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.media.midi.MidiDeviceService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_MIDI_DEVICE_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.accessibilityservice.AccessibilityService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.printservice.PrintService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_PRINT_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.printservice.recommendation.RecommendationService},
      to ensure that only the system can bind to it.
@@ -2192,7 +2222,7 @@
      <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_PRINT_RECOMMENDATION_SERVICE"
-                android:protectionLevel="signature" />
+            android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.nfc.cardemulation.HostApduService}
          or {@link android.nfc.cardemulation.OffHostApduService} to ensure that only
@@ -2200,84 +2230,107 @@
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_NFC_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by the PrintSpooler to ensure that only the system can bind to it.
          @hide -->
     <permission android:name="android.permission.BIND_PRINT_SPOOLER_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
+
+    <!-- @SystemApi Must be required by the RuntimePermissionPresenterService to ensure
+         that only the system can bind to it.
+         @hide -->
+    <permission android:name="android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE"
+        android:protectionLevel="signature" />
 
     <!-- Must be required by a TextService (e.g. SpellCheckerService)
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_TEXT_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.net.VpnService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_VPN_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.service.wallpaper.WallpaperService},
          to ensure that only the system can bind to it.
          <p>Protection level: system|signature
     -->
     <permission android:name="android.permission.BIND_WALLPAPER"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.service.voice.VoiceInteractionService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_VOICE_INTERACTION"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by hotword enrollment application,
          to ensure that only the system can interact with it.
          @hide <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.MANAGE_VOICE_KEYPHRASES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link com.android.media.remotedisplay.RemoteDisplayProvider},
          to ensure that only the system can bind to it.
          @hide -->
     <permission android:name="android.permission.BIND_REMOTE_DISPLAY"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link android.media.tv.TvInputService}
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_TV_INPUT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
+
+    <!-- @SystemApi
+         Must be required by a {@link com.android.media.tv.remoteprovider.TvRemoteProvider}
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature|privileged
+         <p>Not for use by third-party applications. </p>
+         @hide  -->
+    <permission android:name="android.permission.BIND_TV_REMOTE_SERVICE"
+        android:protectionLevel="signature|privileged" />
+
+    <!-- @SystemApi
+         Must be required for a virtual remote controller for TV.
+         <p>Protection level: signature|privileged
+         <p>Not for use by third-party applications. </p>
+         @hide  -->
+    <permission android:name="android.permission.TV_VIRTUAL_REMOTE_CONTROLLER"
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to modify parental controls
          <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.MODIFY_PARENTAL_CONTROLS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by a {@link android.media.routing.MediaRouteService}
          to ensure that only the system can interact with it.
          @hide -->
     <permission android:name="android.permission.BIND_ROUTE_PROVIDER"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by device administration receiver, to ensure that only the
          system can interact with it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_DEVICE_ADMIN"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Required to add or remove another application as a device admin.
          <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.MANAGE_DEVICE_ADMINS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows low-level access to setting the orientation (actually
          rotation) of the screen.
@@ -2285,33 +2338,33 @@
          @hide
     -->
     <permission android:name="android.permission.SET_ORIENTATION"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows low-level access to setting the pointer speed.
          <p>Not for use by third-party applications.
          @hide
     -->
     <permission android:name="android.permission.SET_POINTER_SPEED"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows low-level access to setting input device calibration.
          <p>Not for use by normal applications.
          @hide -->
     <permission android:name="android.permission.SET_INPUT_CALIBRATION"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows low-level access to setting the keyboard layout.
          <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.SET_KEYBOARD_LAYOUT"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to query tablet mode state and monitor changes
          in it.
          <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.TABLET_MODE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to request installing packages. Apps
          targeting APIs greater than 22 must hold this permission in
@@ -2319,292 +2372,290 @@
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"
-                android:label="@string/permlab_requestInstallPackages"
-                android:description="@string/permdesc_requestInstallPackages"
-                android:protectionLevel="normal" />
+        android:label="@string/permlab_requestInstallPackages"
+        android:description="@string/permdesc_requestInstallPackages"
+        android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows an application to install packages.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.INSTALL_PACKAGES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to clear user data.
          <p>Not for use by third-party applications
          @hide
     -->
     <permission android:name="android.permission.CLEAR_APP_USER_DATA"
-                android:protectionLevel="signature|installer" />
+        android:protectionLevel="signature|installer" />
 
     <!-- @hide Allows an application to get the URI permissions
          granted to another application.
          <p>Not for use by third-party applications
     -->
     <permission android:name="android.permission.GET_APP_GRANTED_URI_PERMISSIONS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @hide Allows an application to clear the URI permissions
          granted to another application.
          <p>Not for use by third-party applications
     -->
     <permission
-            android:name="android.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS"
-            android:protectionLevel="signature" />
+        android:name="android.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS"
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to delete cache files.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DELETE_CACHE_FILES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to delete packages.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DELETE_PACKAGES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to move location of installed package.
          @hide -->
     <permission android:name="android.permission.MOVE_PACKAGE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to change whether an application component (other than its own) is
          enabled or not.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
-    <!-- Allows an application to grant specific permissions.
+    <!-- @SystemApi Allows an application to grant specific permissions.
          @hide -->
     <permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS"
-                android:protectionLevel="signature|installer|verifier" />
+        android:protectionLevel="signature|installer|verifier" />
 
-    <!-- Allows an app that has this permission and the permissions to install packages
+    <!-- @SystemApi Allows an app that has this permission and the permissions to install packages
          to request certain runtime permissions to be granted at installation.
-         @hide
-         @SystemApi -->
+         @hide -->
     <permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS"
-                android:protectionLevel="signature|installer|verifier" />
+        android:protectionLevel="signature|installer|verifier" />
 
-    <!-- Allows an application to revoke specific permissions.
-        @hide
-        @SystemApi -->
+    <!-- @SystemApi Allows an application to revoke specific permissions.
+        @hide -->
     <permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS"
-                android:protectionLevel="signature|installer|verifier" />
+         android:protectionLevel="signature|installer|verifier" />
 
     <!-- @hide Allows an application to observe permission changes. -->
     <permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
          <p>Not for use by third-party applications.
          @hide
     -->
     <permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to take screen shots and more generally
          get access to the frame buffer data.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.READ_FRAME_BUFFER"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to use InputFlinger's low level features.
          @hide -->
     <permission android:name="android.permission.ACCESS_INPUT_FLINGER"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to configure and connect to Wifi displays
          @hide -->
     <permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to control low-level features of Wifi displays
          such as opening an RTSP socket.  This permission should only be used
          by the display manager.
          @hide -->
     <permission android:name="android.permission.CONTROL_WIFI_DISPLAY"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to control the color transforms applied to
          displays system-wide.
          <p>Not for use by third-party applications.</p>
          @hide -->
     <permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to control VPN.
          <p>Not for use by third-party applications.</p>
          @hide -->
     <permission android:name="android.permission.CONTROL_VPN"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
     <uses-permission android:name="android.permission.CONTROL_VPN" />
 
     <!-- @SystemApi Allows an application to capture audio output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to capture audio for hotword detection.
          <p>Not for use by third-party applications.</p>
          @hide -->
     <permission android:name="android.permission.CAPTURE_AUDIO_HOTWORD"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to modify audio routing and override policy decisions.
          <p>Not for use by third-party applications.</p>
          @hide -->
     <permission android:name="android.permission.MODIFY_AUDIO_ROUTING"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to capture video output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to capture secure video output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to know what content is playing and control its playback.
          <p>Not for use by third-party applications due to privacy of media consumption</p>  -->
     <permission android:name="android.permission.MEDIA_CONTENT_CONTROL"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Required to be able to disable the device (very dangerous!).
          <p>Not for use by third-party applications.
          @hide
     -->
     <permission android:name="android.permission.BRICK"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Required to be able to reboot the device.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.REBOOT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows low-level access to power management.
-         <p>Not for use by third-party applications.
-         @hide
-     -->
-    <permission android:name="android.permission.DEVICE_POWER"
-                android:protectionLevel="signature" />
+   <!-- @SystemApi Allows low-level access to power management.
+        <p>Not for use by third-party applications.
+        @hide
+    -->
+   <permission android:name="android.permission.DEVICE_POWER"
+        android:protectionLevel="signature" />
 
-    <!-- Allows access to the PowerManager.userActivity function.
-    <p>Not for use by third-party applications. @hide @SystemApi -->
+   <!-- Allows access to the PowerManager.userActivity function.
+   <p>Not for use by third-party applications. @hide @SystemApi -->
     <permission android:name="android.permission.USER_ACTIVITY"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
-    <!-- @hide Allows low-level access to tun tap driver -->
+   <!-- @hide Allows low-level access to tun tap driver -->
     <permission android:name="android.permission.NET_TUNNELING"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Run as a manufacturer test application, running as the root user.
          Only available when the device is running in manufacturer test mode.
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.FACTORY_TEST"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to broadcast a notification that an application
          package has been removed.
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to broadcast an SMS receipt notification.
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.BROADCAST_SMS"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to broadcast a WAP PUSH receipt notification.
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.BROADCAST_WAP_PUSH"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to broadcast privileged networking requests.
          <p>Not for use by third-party applications. @hide -->
     <permission android:name="android.permission.BROADCAST_NETWORK_PRIVILEGED"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Not for use by third-party applications. -->
     <permission android:name="android.permission.MASTER_CLEAR"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to call any phone number, including emergency
          numbers, without going through the Dialer user interface for the user
          to confirm the call being placed.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CALL_PRIVILEGED"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to perform CDMA OTA provisioning @hide -->
     <permission android:name="android.permission.PERFORM_CDMA_PROVISIONING"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to perform SIM Activation @hide -->
     <permission android:name="android.permission.PERFORM_SIM_ACTIVATION"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows enabling/disabling location update notifications from
          the radio.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CONTROL_LOCATION_UPDATES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows read/write access to the "properties" table in the checkin
          database, to change values that get uploaded.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to collect component usage
          statistics
          <p>Declaring the permission implies intention to use the API and the user of the
          device can grant permission through the Settings application. -->
     <permission android:name="android.permission.PACKAGE_USAGE_STATS"
-                android:protectionLevel="signature|privileged|development|appop" />
+        android:protectionLevel="signature|privileged|development|appop" />
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
 
     <!-- @hide Allows an application to change the app idle state of an app.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CHANGE_APP_IDLE_STATE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @hide @SystemApi Allows an application to temporarily whitelist an inactive app to
          access the network and acquire wakelocks.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Permission an application must hold in order to use
          {@link android.provider.Settings#ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS}.
          This is a normal permission: an app requesting it will always be granted the
          permission, without the user needing to approve or see it. -->
     <permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"
-                android:protectionLevel="normal" />
+        android:protectionLevel="normal" />
 
     <!-- @SystemApi Allows an application to collect battery statistics -->
     <permission android:name="android.permission.BATTERY_STATS"
-                android:protectionLevel="signature|privileged|development" />
+        android:protectionLevel="signature|privileged|development" />
 
     <!-- @SystemApi Allows an application to control the backup and restore process.
     <p>Not for use by third-party applications.
          @hide pending API council -->
     <permission android:name="android.permission.BACKUP"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows a package to launch the secure full-backup confirmation UI.
          ONLY the system process may hold this permission.
          @hide -->
     <permission android:name="android.permission.CONFIRM_FULL_BACKUP"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Must be required by a {@link android.widget.RemoteViewsService},
          to ensure that only the system can bind to it. -->
     <permission android:name="android.permission.BIND_REMOTEVIEWS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to tell the AppWidget service which application
          can access AppWidget's data.  The normal user flow is that a user
@@ -2613,25 +2664,25 @@
          An application that has this permission should honor that contract.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.BIND_APPWIDGET"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Private permission, to restrict who can bring up a dialog to add a new
          keyguard widget
          @hide -->
     <permission android:name="android.permission.BIND_KEYGUARD_APPWIDGET"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Internal permission allowing an application to query/set which
          applications can bind AppWidgets.
          @hide -->
     <permission android:name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows applications to change the background data setting.
     <p>Not for use by third-party applications.
          @hide pending API council -->
     <permission android:name="android.permission.CHANGE_BACKGROUND_DATA_SETTING"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi This permission can be used on content providers to allow the global
          search system to access their data.  Typically it used when the
@@ -2642,7 +2693,7 @@
          it is used by applications to protect themselves from everyone else
          besides global search. -->
     <permission android:name="android.permission.GLOBAL_SEARCH"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Internal permission protecting access to the global search
          system: ensures that only the system can access the provider
@@ -2652,33 +2703,33 @@
          ranking).
          @hide -->
     <permission android:name="android.permission.GLOBAL_SEARCH_CONTROL"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Internal permission to allows an application to read indexable data.
         @hide -->
     <permission android:name="android.permission.READ_SEARCH_INDEXABLES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows applications to set a live wallpaper.
          @hide XXX Change to signature once the picker is moved to its
          own apk as Ghod Intended. -->
     <permission android:name="android.permission.SET_WALLPAPER_COMPONENT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows applications to read dream settings and dream state.
          @hide -->
     <permission android:name="android.permission.READ_DREAM_STATE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows applications to write dream settings, and start or stop dreaming.
          @hide -->
     <permission android:name="android.permission.WRITE_DREAM_STATE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allow an application to read and write the cache partition.
          @hide -->
     <permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by default container service so that only
          the system can bind to it and use it to copy
@@ -2686,67 +2737,67 @@
          accessible to the system.
          @hide -->
     <permission android:name="android.permission.COPY_PROTECTED_DATA"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Internal permission protecting access to the encryption methods
         @hide
     -->
     <permission android:name="android.permission.CRYPT_KEEPER"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to read historical network usage for
          specific networks and applications. @hide -->
     <permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to manage network policies (such as warning and disable
          limits) and to define application-specific rules. @hide -->
     <permission android:name="android.permission.MANAGE_NETWORK_POLICY"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to account its network traffic against other UIDs. Used
          by system services like download manager and media server. Not for use by
          third party apps. @hide -->
     <permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- C2DM permission.
          @hide Used internally.
      -->
     <permission android:name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"
-                android:protectionLevel="signature" />
+          android:protectionLevel="signature" />
     <uses-permission android:name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"/>
 
     <!-- @SystemApi @hide Package verifier needs to have this permission before the PackageManager will
          trust it to verify packages.
     -->
     <permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by package verifier receiver, to ensure that only the
          system can interact with it.
          @hide
     -->
     <permission android:name="android.permission.BIND_PACKAGE_VERIFIER"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi @hide Intent filter verifier needs to have this permission before the
          PackageManager will trust it to verify intent filters.
     -->
     <permission android:name="android.permission.INTENT_FILTER_VERIFICATION_AGENT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Must be required by intent filter verifier receiver, to ensure that only the
          system can interact with it.
          @hide
     -->
     <permission android:name="android.permission.BIND_INTENT_FILTER_VERIFIER"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows applications to access serial ports via the SerialManager.
          @hide -->
     <permission android:name="android.permission.SERIAL_PORT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows the holder to access content providers from outside an ApplicationThread.
          This permission is enforced by the ActivityManagerService on the corresponding APIs,
@@ -2755,27 +2806,27 @@
          @hide
     -->
     <permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to hold an UpdateLock, recommending that a headless
          OTA reboot *not* occur while the lock is held.
          @hide -->
     <permission android:name="android.permission.UPDATE_LOCK"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to read the current set of notifications, including
          any metadata and intents attached.
          @hide -->
     <permission android:name="android.permission.ACCESS_NOTIFICATIONS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Marker permission for applications that wish to access notification policy.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"
-                android:description="@string/permdesc_access_notification_policy"
-                android:label="@string/permlab_access_notification_policy"
-                android:protectionLevel="normal" />
+        android:description="@string/permdesc_access_notification_policy"
+        android:label="@string/permlab_access_notification_policy"
+        android:protectionLevel="normal" />
 
     <!-- Allows modification of do not disturb rules and policies. Only allowed for system
         processes.
@@ -2786,42 +2837,42 @@
     <!-- Allows access to keyguard secure storage.  Only allowed for system processes.
         @hide -->
     <permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows managing (adding, removing) fingerprint templates. Reserved for the system. @hide -->
     <permission android:name="android.permission.MANAGE_FINGERPRINT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an app to reset fingerprint attempt counter. Reserved for the system. @hide -->
     <permission android:name="android.permission.RESET_FINGERPRINT_LOCKOUT"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to control keyguard.  Only allowed for system processes.
         @hide -->
     <permission android:name="android.permission.CONTROL_KEYGUARD"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to listen to trust changes.  Only allowed for system processes.
         @hide -->
     <permission android:name="android.permission.TRUST_LISTENER"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to provide a trust agent.
          @hide For security reasons, this is a platform-only permission. -->
     <permission android:name="android.permission.PROVIDE_TRUST_AGENT"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to launch the trust agent settings activity.
         @hide -->
     <permission android:name="android.permission.LAUNCH_TRUST_AGENT_SETTINGS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Must be required by an {@link
         android.service.trust.TrustAgentService},
         to ensure that only the system can bind to it.
         @hide -->
     <permission android:name="android.permission.BIND_TRUST_AGENT"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link
          android.service.notification.NotificationListenerService},
@@ -2829,7 +2880,7 @@
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link
          android.service.notification.NotificationRankerService         to ensure that only the system can bind to it.
@@ -2837,7 +2888,7 @@
          @hide This is not a third-party API (intended for system apps). -->
     -->
     <permission android:name="android.permission.BIND_NOTIFICATION_RANKER_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link
          android.service.chooser.ChooserTargetService}, to ensure that
@@ -2845,7 +2896,7 @@
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link
          android.service.notification.ConditionProviderService},
@@ -2853,57 +2904,57 @@
          <p>Protection level: signature
          -->
     <permission android:name="android.permission.BIND_CONDITION_PROVIDER_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link android.service.dreams.DreamService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
     <permission android:name="android.permission.BIND_DREAM_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to call into a carrier setup flow. It is up to the
          carrier setup application to enforce that this permission is required
          @hide This is not a third-party API (intended for OEMs and system apps). -->
     <permission android:name="android.permission.INVOKE_CARRIER_SETUP"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to listen for network condition observations.
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.ACCESS_NETWORK_CONDITIONS"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows an application to provision and access DRM certificates
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.ACCESS_DRM_CERTIFICATES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Api Allows an application to manage media projection sessions.
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.MANAGE_MEDIA_PROJECTION"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to read install sessions
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.READ_INSTALL_SESSIONS"
-                android:label="@string/permlab_readInstallSessions"
-                android:description="@string/permdesc_readInstallSessions"
-                android:protectionLevel="normal"/>
+        android:label="@string/permlab_readInstallSessions"
+        android:description="@string/permdesc_readInstallSessions"
+        android:protectionLevel="normal"/>
 
     <!-- @SystemApi Allows an application to remove DRM certificates
          @hide This is not a third-party API (intended for system apps). -->
     <permission android:name="android.permission.REMOVE_DRM_CERTIFICATES"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @deprecated Use {@link android.Manifest.permission#BIND_CARRIER_SERVICES} instead -->
     <permission android:name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to interact with the currently active
          {@link android.service.voice.VoiceInteractionService}.
          @hide -->
     <permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- The system process that is allowed to bind to services in carrier apps will
          have this permission. Carrier apps should use this permission to protect
@@ -2911,9 +2962,9 @@
          <p>Protection level: system|signature
     -->
     <permission android:name="android.permission.BIND_CARRIER_SERVICES"
-                android:label="@string/permlab_bindCarrierServices"
-                android:description="@string/permdesc_bindCarrierServices"
-                android:protectionLevel="signature|privileged" />
+        android:label="@string/permlab_bindCarrierServices"
+        android:description="@string/permdesc_bindCarrierServices"
+        android:protectionLevel="signature|privileged" />
 
     <!-- Allows an application to query whether DO_NOT_ASK_CREDENTIALS_ON_BOOT
          flag is set.
@@ -2921,7 +2972,7 @@
     <permission android:name="android.permission.QUERY_DO_NOT_ASK_CREDENTIALS_ON_BOOT"
                 android:protectionLevel="signature" />
 
-    <!-- Allows applications to kill UIDs.
+    <!-- @SystemApi Allows applications to kill UIDs.
         <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.KILL_UID"
@@ -2959,7 +3010,7 @@
     <!-- Allows the holder to access the ephemeral applications on the device.
     @hide -->
     <permission android:name="android.permission.ACCESS_EPHEMERAL_APPS"
-                android:protectionLevel="signature" />
+            android:protectionLevel="signature" />
 
     <!-- Allows receiving the usage of media resource e.g. video/audio codec and
          graphic memory.
@@ -2971,7 +3022,7 @@
          APIs given by {@link SoundTriggerManager}.
          @hide <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.MANAGE_SOUND_TRIGGER"
-                android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- @SystemApi Allows trusted applications to dispatch managed provisioning message to Managed
          Provisioning app. If requesting app does not have permission, it will be ignored.
@@ -2995,17 +3046,17 @@
          the system can bind to it.
          <p>Protection level: signature -->
     <permission android:name="android.permission.BIND_VR_LISTENER_SERVICE"
-                android:protectionLevel="signature" />
+        android:protectionLevel="signature" />
 
     <!-- Required to make calls to {@link android.service.vr.IVrManager}.
          @hide -->
     <permission android:name="android.permission.ACCESS_VR_MANAGER"
-                android:protectionLevel="signature" />
+            android:protectionLevel="signature" />
 
     <!-- Allows an application to whitelist tasks during lock task mode
          @hide <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.UPDATE_LOCK_TASK_PACKAGES"
-                android:protectionLevel="signature|setup" />
+        android:protectionLevel="signature|setup" />
 
     <!-- @SystemApi Allows an application to replace the app name displayed alongside notifications
          in the N-release and later.
@@ -3026,12 +3077,12 @@
                  android:defaultToDeviceProtectedStorage="true"
                  android:directBootAware="true">
         <activity android:name="com.android.internal.app.ChooserActivity"
-                  android:theme="@style/Theme.DeviceDefault.Resolver"
-                  android:finishOnCloseSystemDialogs="true"
-                  android:excludeFromRecents="true"
-                  android:documentLaunchMode="never"
-                  android:relinquishTaskIdentity="true"
-                  android:process=":ui">
+                android:theme="@style/Theme.DeviceDefault.Resolver"
+                android:finishOnCloseSystemDialogs="true"
+                android:excludeFromRecents="true"
+                android:documentLaunchMode="never"
+                android:relinquishTaskIdentity="true"
+                android:process=":ui">
             <intent-filter>
                 <action android:name="android.intent.action.CHOOSER" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -3039,102 +3090,102 @@
             </intent-filter>
         </activity>
         <activity android:name="com.android.internal.app.IntentForwarderActivity"
-                  android:finishOnCloseSystemDialogs="true"
-                  android:theme="@style/Theme.NoDisplay"
-                  android:excludeFromRecents="true"
-                  android:label="@string/user_owner_label"
-                  android:exported="true"
-        >
+                android:finishOnCloseSystemDialogs="true"
+                android:theme="@style/Theme.NoDisplay"
+                android:excludeFromRecents="true"
+                android:label="@string/user_owner_label"
+                android:exported="true"
+                >
         </activity>
         <activity-alias android:name="com.android.internal.app.ForwardIntentToParent"
-                        android:targetActivity="com.android.internal.app.IntentForwarderActivity"
-                        android:exported="true"
-                        android:label="@string/user_owner_label">
+                android:targetActivity="com.android.internal.app.IntentForwarderActivity"
+                android:exported="true"
+                android:label="@string/user_owner_label">
         </activity-alias>
         <activity-alias android:name="com.android.internal.app.ForwardIntentToManagedProfile"
-                        android:targetActivity="com.android.internal.app.IntentForwarderActivity"
-                        android:icon="@drawable/ic_corp_icon"
-                        android:exported="true"
-                        android:label="@string/managed_profile_label">
+                android:targetActivity="com.android.internal.app.IntentForwarderActivity"
+                android:icon="@drawable/ic_corp_icon"
+                android:exported="true"
+                android:label="@string/managed_profile_label">
         </activity-alias>
         <activity android:name="com.android.internal.app.HeavyWeightSwitcherActivity"
-                  android:theme="@style/Theme.Material.Light.Dialog"
-                  android:label="@string/heavy_weight_switcher_title"
-                  android:finishOnCloseSystemDialogs="true"
-                  android:excludeFromRecents="true"
-                  android:process=":ui">
+                android:theme="@style/Theme.Material.Light.Dialog"
+                android:label="@string/heavy_weight_switcher_title"
+                android:finishOnCloseSystemDialogs="true"
+                android:excludeFromRecents="true"
+                android:process=":ui">
         </activity>
         <activity android:name="com.android.internal.app.PlatLogoActivity"
-                  android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen"
-                  android:configChanges="orientation|keyboardHidden"
-                  android:process=":ui">
+                android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen"
+                android:configChanges="orientation|keyboardHidden"
+                android:process=":ui">
         </activity>
         <activity android:name="com.android.internal.app.DisableCarModeActivity"
-                  android:theme="@style/Theme.NoDisplay"
-                  android:excludeFromRecents="true"
-                  android:process=":ui">
+                android:theme="@style/Theme.NoDisplay"
+                android:excludeFromRecents="true"
+                android:process=":ui">
         </activity>
         <activity android:name="com.android.internal.app.DumpHeapActivity"
-                  android:theme="@style/Theme.Translucent.NoTitleBar"
-                  android:label="@string/dump_heap_title"
-                  android:finishOnCloseSystemDialogs="true"
-                  android:noHistory="true"
-                  android:excludeFromRecents="true"
-                  android:process=":ui">
+                android:theme="@style/Theme.Translucent.NoTitleBar"
+                android:label="@string/dump_heap_title"
+                android:finishOnCloseSystemDialogs="true"
+                android:noHistory="true"
+                android:excludeFromRecents="true"
+                android:process=":ui">
         </activity>
         <provider android:name="com.android.server.am.DumpHeapProvider"
-                  android:authorities="com.android.server.heapdump"
-                  android:grantUriPermissions="true"
-                  android:multiprocess="false"
-                  android:singleUser="true" />
+                android:authorities="com.android.server.heapdump"
+                android:grantUriPermissions="true"
+                android:multiprocess="false"
+                android:singleUser="true" />
 
         <activity android:name="android.accounts.ChooseAccountActivity"
-                  android:excludeFromRecents="true"
-                  android:exported="true"
-                  android:theme="@style/Theme.Material.Light.Dialog"
-                  android:label="@string/choose_account_label"
-                  android:process=":ui">
+                android:excludeFromRecents="true"
+                android:exported="true"
+                android:theme="@style/Theme.Material.Light.Dialog"
+                android:label="@string/choose_account_label"
+                android:process=":ui">
         </activity>
 
         <activity android:name="android.accounts.ChooseTypeAndAccountActivity"
-                  android:excludeFromRecents="true"
-                  android:exported="true"
-                  android:theme="@style/Theme.Material.Light.Dialog"
-                  android:label="@string/choose_account_label"
-                  android:process=":ui">
+                android:excludeFromRecents="true"
+                android:exported="true"
+                android:theme="@style/Theme.Material.Light.Dialog"
+                android:label="@string/choose_account_label"
+                android:process=":ui">
         </activity>
 
         <activity android:name="android.accounts.ChooseAccountTypeActivity"
-                  android:excludeFromRecents="true"
-                  android:theme="@style/Theme.Material.Light.Dialog"
-                  android:label="@string/choose_account_label"
-                  android:process=":ui">
+                android:excludeFromRecents="true"
+                android:theme="@style/Theme.Material.Light.Dialog"
+                android:label="@string/choose_account_label"
+                android:process=":ui">
         </activity>
 
         <activity android:name="android.accounts.CantAddAccountActivity"
-                  android:excludeFromRecents="true"
-                  android:exported="true"
-                  android:theme="@style/Theme.Material.Light.Dialog.NoActionBar"
-                  android:process=":ui">
+                android:excludeFromRecents="true"
+                android:exported="true"
+                android:theme="@style/Theme.Material.Light.Dialog.NoActionBar"
+                android:process=":ui">
         </activity>
 
         <activity android:name="android.accounts.GrantCredentialsPermissionActivity"
-                  android:excludeFromRecents="true"
-                  android:exported="true"
-                  android:theme="@style/Theme.Material.Light.DialogWhenLarge"
-                  android:process=":ui">
+                android:excludeFromRecents="true"
+                android:exported="true"
+                android:theme="@style/Theme.Material.Light.DialogWhenLarge"
+                android:process=":ui">
         </activity>
 
         <activity android:name="android.content.SyncActivityTooManyDeletes"
-                  android:theme="@style/Theme.Material.Light.Dialog"
-                  android:label="@string/sync_too_many_deletes"
-                  android:process=":ui">
+               android:theme="@style/Theme.Material.Light.Dialog"
+               android:label="@string/sync_too_many_deletes"
+               android:process=":ui">
         </activity>
 
         <activity android:name="com.android.internal.app.ShutdownActivity"
-                  android:permission="android.permission.SHUTDOWN"
-                  android:theme="@style/Theme.NoDisplay"
-                  android:excludeFromRecents="true">
+            android:permission="android.permission.SHUTDOWN"
+            android:theme="@style/Theme.NoDisplay"
+            android:excludeFromRecents="true">
             <intent-filter>
                 <action android:name="android.intent.action.ACTION_REQUEST_SHUTDOWN" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -3146,9 +3197,9 @@
         </activity>
 
         <activity android:name="com.android.internal.app.NetInitiatedActivity"
-                  android:theme="@style/Theme.Material.Light.Dialog.Alert"
-                  android:excludeFromRecents="true"
-                  android:process=":ui">
+                android:theme="@style/Theme.Material.Light.Dialog.Alert"
+                android:excludeFromRecents="true"
+                android:process=":ui">
         </activity>
 
         <activity android:name="com.android.internal.app.SystemUserHomeActivity"
@@ -3165,9 +3216,9 @@
         <!-- Activity to prompt user if it's ok to create a new user sandbox for a
              specified account. -->
         <activity android:name="com.android.internal.app.ConfirmUserCreationActivity"
-                  android:excludeFromRecents="true"
-                  android:process=":ui"
-                  android:theme="@style/Theme.Material.Light.Dialog.Alert">
+                android:excludeFromRecents="true"
+                android:process=":ui"
+                android:theme="@style/Theme.Material.Light.Dialog.Alert">
             <intent-filter android:priority="1000">
                 <action android:name="android.os.action.CREATE_USER" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -3175,20 +3226,20 @@
         </activity>
 
         <activity android:name="com.android.internal.app.UnlaunchableAppActivity"
-                  android:theme="@style/Theme.Material.Light.Dialog.Alert"
-                  android:excludeFromRecents="true"
-                  android:process=":ui">
+                android:theme="@style/Theme.Material.Light.Dialog.Alert"
+                android:excludeFromRecents="true"
+                android:process=":ui">
         </activity>
 
         <receiver android:name="com.android.server.BootReceiver"
-                  android:systemUserOnly="true">
+                android:systemUserOnly="true">
             <intent-filter android:priority="1000">
                 <action android:name="android.intent.action.BOOT_COMPLETED" />
             </intent-filter>
         </receiver>
 
         <receiver android:name="com.android.server.updates.CertPinInstallReceiver"
-                  android:permission="android.permission.UPDATE_CONFIG">
+                android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_PINS" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -3196,7 +3247,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.updates.IntentFirewallInstallReceiver"
-                  android:permission="android.permission.UPDATE_CONFIG">
+                android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_INTENT_FIREWALL" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -3204,7 +3255,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.updates.SmsShortCodesInstallReceiver"
-                  android:permission="android.permission.UPDATE_CONFIG">
+                android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_SMS_SHORT_CODES" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -3212,7 +3263,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.updates.ApnDbInstallReceiver"
-                  android:permission="android.permission.UPDATE_CONFIG">
+                android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_APN_DB" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -3220,7 +3271,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.updates.CarrierProvisioningUrlsInstallReceiver"
-                  android:permission="android.permission.UPDATE_CONFIG">
+                android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_CARRIER_PROVISIONING_URLS" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -3228,7 +3279,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.updates.TzDataInstallReceiver"
-                  android:permission="android.permission.UPDATE_CONFIG">
+                android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_TZDATA" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -3236,7 +3287,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.updates.SELinuxPolicyInstallReceiver"
-                  android:permission="android.permission.UPDATE_CONFIG">
+                android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
                 <action android:name="android.intent.action.UPDATE_SEPOLICY" />
                 <data android:scheme="content" android:host="*" android:mimeType="*/*" />
@@ -3244,7 +3295,7 @@
         </receiver>
 
         <receiver android:name="com.android.server.MasterClearReceiver"
-                  android:permission="android.permission.MASTER_CLEAR">
+            android:permission="android.permission.MASTER_CLEAR">
             <intent-filter
                     android:priority="100" >
                 <!-- For Checkin, Settings, etc.: action=MASTER_CLEAR -->
@@ -3257,12 +3308,12 @@
         </receiver>
 
         <service android:name="android.hardware.location.GeofenceHardwareService"
-                 android:permission="android.permission.LOCATION_HARDWARE"
-                 android:exported="false" />
+            android:permission="android.permission.LOCATION_HARDWARE"
+            android:exported="false" />
 
         <service android:name="com.android.internal.backup.LocalTransportService"
-                 android:permission="android.permission.CONFIRM_FULL_BACKUP"
-                 android:exported="false">
+                android:permission="android.permission.CONFIRM_FULL_BACKUP"
+                android:exported="false">
             <intent-filter>
                 <action android:name="android.backup.TRANSPORT_HOST" />
             </intent-filter>
@@ -3287,9 +3338,9 @@
         </service>
 
         <service
-                android:name="com.android.server.pm.BackgroundDexOptService"
-                android:exported="true"
-                android:permission="android.permission.BIND_JOB_SERVICE">
+            android:name="com.android.server.pm.BackgroundDexOptService"
+            android:exported="true"
+            android:permission="android.permission.BIND_JOB_SERVICE">
         </service>
 
     </application>
diff --git a/tests/tests/security/res/raw/bug_17262540.ico b/tests/tests/security/res/raw/bug_17262540.ico
new file mode 100644
index 0000000..49730df
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_17262540.ico
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_17265466.ico b/tests/tests/security/res/raw/bug_17265466.ico
new file mode 100644
index 0000000..527d657
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_17265466.ico
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2015_1531_b_19270126.jpg b/tests/tests/security/res/raw/cve_2015_1531_b_19270126.jpg
new file mode 100644
index 0000000..09f8a7e
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2015_1531_b_19270126.jpg
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java b/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java
new file mode 100644
index 0000000..2afa0a5
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.security.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.test.AndroidTestCase;
+
+import java.io.InputStream;
+
+import com.android.cts.security.R;
+
+public class AllocatePixelRefIntOverflowTest extends AndroidTestCase {
+
+    /**
+     * Verifies that the device is not vulnerable to ANDROID-19270126: Android
+     * BitmapFactory.decodeStream JPG allocPixelRef integer overflow
+     */
+    public void testAllocateJavaPixelRefIntOverflow() {
+        InputStream exploitImage = mContext.getResources().openRawResource(
+                R.raw.cve_2015_1531_b_19270126);
+        /**
+         * The decodeStream method results in SIGSEGV (Segmentation fault) on unpatched devices
+         * while decoding the exploit image which will lead to process crash
+         */
+        BitmapFactory.decodeStream(exploitImage);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java b/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java
new file mode 100644
index 0000000..8fc1a24
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/SkiaICORecursiveDecodingTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.security.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.test.AndroidTestCase;
+
+import java.io.InputStream;
+
+import com.android.cts.security.R;
+
+public class SkiaICORecursiveDecodingTest extends AndroidTestCase {
+
+    public void test_android_bug_17262540() {
+        doSkiaIcoRecursiveDecodingTest(R.raw.bug_17262540);
+    }
+
+    public void test_android_bug_17265466() {
+        doSkiaIcoRecursiveDecodingTest(R.raw.bug_17265466);
+    }
+
+    /**
+     * Verifies that the device prevents recursive decoding of malformed ICO files
+     */
+    public void doSkiaIcoRecursiveDecodingTest(int resId) {
+        InputStream exploitImage = mContext.getResources().openRawResource(resId);
+        /**
+         * The decodeStream method results in SIGSEGV (Segmentation fault) on unpatched devices
+         * while decoding the exploit image which will lead to process crash
+         */
+        Bitmap bitmap = BitmapFactory.decodeStream(exploitImage);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerThrottlingTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerThrottlingTest.java
index d5fda4d..8347bc0 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerThrottlingTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/ShortcutManagerThrottlingTest.java
@@ -18,7 +18,9 @@
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.*;
 
 import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
 
+import java.util.List;
 import java.util.function.BooleanSupplier;
 
 public class ShortcutManagerThrottlingTest extends ShortcutManagerCtsTestsBase {
@@ -131,6 +133,15 @@
         });
     }
 
+    /**
+     * Make sure {@link android.content.pm.ShortcutManager#setDynamicShortcuts(List)} correctly
+     * throttles calls.
+     *
+     * <p>Suppressed for now -- because when an instrumentation test is running, the process
+     * will be in the PROCESS_STATE_FOREGROUND_SERVICE state, so none of calls will be throttled.
+     * Need a different way to verify this.
+     */
+    @Suppress
     @LargeTest
     public void testThrottled_setDynamicShortcuts() {
         runWithCaller(mPackageContext1, () -> {
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index 366e061..ae9dda1 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -98,9 +98,7 @@
         });
         t.start();
         synchronized (mLock) {
-            while (!mOnCellLocationChangedCalled) {
-                mLock.wait();
-            }
+            mLock.wait(TOLERANCE);
         }
         assertTrue(mOnCellLocationChangedCalled);
 
diff --git a/tests/tests/util/src/android/util/cts/LocaleListTest.java b/tests/tests/util/src/android/util/cts/LocaleListTest.java
index e64d955..7693adf 100644
--- a/tests/tests/util/src/android/util/cts/LocaleListTest.java
+++ b/tests/tests/util/src/android/util/cts/LocaleListTest.java
@@ -32,22 +32,6 @@
         assertNull(ll.get(1));
         assertNull(ll.get(10));
 
-        ll = new LocaleList((Locale) null);
-        assertNotNull(ll);
-        assertTrue(ll.isEmpty());
-        assertEquals(0, ll.size());
-        assertNull(ll.get(0));
-        assertNull(ll.get(1));
-        assertNull(ll.get(10));
-
-        ll = new LocaleList((Locale[]) null);
-        assertNotNull(ll);
-        assertTrue(ll.isEmpty());
-        assertEquals(0, ll.size());
-        assertNull(ll.get(0));
-        assertNull(ll.get(1));
-        assertNull(ll.get(10));
-
         ll = new LocaleList(new Locale[0]);
         assertNotNull(ll);
         assertTrue(ll.isEmpty());
@@ -78,6 +62,21 @@
         assertNull(ll.get(10));
     }
 
+    public void testNullArgument() {
+        try {
+            LocaleList ll = new LocaleList((Locale) null);
+            fail("Initializing a LocaleList with a null argument should throw.");
+        } catch (Throwable e) {
+            assertEquals(NullPointerException.class, e.getClass());
+        }
+        try {
+            LocaleList ll = new LocaleList((Locale[]) null);
+            fail("Initializing a LocaleList with a null array should throw.");
+        } catch (Throwable e) {
+            assertEquals(NullPointerException.class, e.getClass());
+        }
+    }
+
     public void testNullArguments() {
         final Locale[] la = {Locale.US, null};
         LocaleList ll = null;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index ff30a2f..2f99b49 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -45,7 +45,7 @@
 
 public class WebViewClientTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
     private static final long TEST_TIMEOUT = 5000;
-    private static final String TEST_URL = "http://foo.com/";
+    private static final String TEST_URL = "http://www.example.com/";
 
     private WebViewOnUiThread mOnUiThread;
     private CtsTestServer mWebServer;
diff --git a/tools/testng/OjTests.xml b/tools/testng/OjTests.xml
deleted file mode 100644
index 2578fb9..0000000
--- a/tools/testng/OjTests.xml
+++ /dev/null
@@ -1,450 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<TestPackage name="CtsLibcoreOj" appPackageName="android.libcore.oj" version="1.0" testType="testNGDeviceTest" jarPath="CtsLibcoreOj.jar">
-  <TestSuite name="org">
-    <TestSuite name="openjdk">
-      <TestSuite name="tests">
-        <TestSuite name="java">
-          <TestSuite name="util">
-            <TestSuite name="stream">
-              <TestCase name="CollectionAndMapModifyStreamTest">
-                <Test name="testCollectionSizeRemove" />
-                <Test name="testMapEntriesSizeRemove" />
-                <Test name="testMapKeysSizeRemove" />
-                <Test name="testMapValuesSizeRemove" />
-              </TestCase>
-              <TestCase name="ConcatOpTest">
-                <Test name="testDoubleSize" />
-                <Test name="testIntSize" />
-                <Test name="testLongSize" />
-                <Test name="testOps" />
-                <Test name="testSize" />
-              </TestCase>
-              <TestCase name="ConcatTest">
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testDoubleConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testIntConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testLongConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-                <Test name="testRefConcat" />
-              </TestCase>
-              <TestCase name="CountLargeTest">
-                <Test name="testDoubleLarge" />
-                <Test name="testIntLarge" />
-                <Test name="testLongLarge" />
-                <Test name="testRefLarge" />
-              </TestCase>
-              <TestCase name="CountTest">
-                <Test name="testOps" />
-                <Test name="testOps" />
-                <Test name="testOps" />
-                <Test name="testOps" />
-              </TestCase>
-              <TestCase name="DistinctOpTest">
-                <Test name="testDistinctDistinct" />
-                <Test name="testDistinctSorted" />
-                <Test name="testOp" />
-                <Test name="testOpWithNull" />
-                <Test name="testOpWithNullSorted" />
-                <Test name="testSortedDistinct" />
-                <Test name="testStable" />
-                <Test name="testUniqOp" />
-                <Test name="testWithUnorderedInfiniteStream" />
-              </TestCase>
-              <TestCase name="DoublePrimitiveOpsTests">
-                <Test name="testLimit" />
-                <Test name="testSort" />
-                <Test name="testSortSort" />
-                <Test name="testToArray" />
-                <Test name="testUnBox" />
-              </TestCase>
-              <TestCase name="ExplodeOpTest">
-                <Test name="testDoubleOps" />
-                <Test name="testFlatMap" />
-                <Test name="testIntOps" />
-                <Test name="testLongOps" />
-                <Test name="testOps" />
-              </TestCase>
-              <TestCase name="FilterOpTest">
-                <Test name="testFilter" />
-                <Test name="testOps" />
-                <Test name="testOps" />
-                <Test name="testOps" />
-                <Test name="testOps" />
-              </TestCase>
-              <TestCase name="FindAnyOpTest">
-                <Test name="testDoubleStream" />
-                <Test name="testFindAny" />
-                <Test name="testFindAnyParallel" />
-                <Test name="testIntStream" />
-                <Test name="testLongStream" />
-                <Test name="testStream" />
-              </TestCase>
-              <TestCase name="FindFirstOpTest">
-                <Test name="testDoubleStream" />
-                <Test name="testFindFirst" />
-                <Test name="testIntStream" />
-                <Test name="testLongStream" />
-                <Test name="testStream" />
-              </TestCase>
-              <TestCase name="ForEachOpTest">
-                <Test name="testDoubleForEachOrdered" />
-                <Test name="testDoubleOps" />
-                <Test name="testForEach" />
-                <Test name="testForEach" />
-                <Test name="testForEachOrdered" />
-                <Test name="testIntForEach" />
-                <Test name="testIntForEachOrdered" />
-                <Test name="testLongForEachOrdered" />
-                <Test name="testLongOps" />
-              </TestCase>
-              <TestCase name="GroupByOpTest">
-                <Test name="testBypassCollect" />
-                <Test name="testGroupBy" />
-                <Test name="testOps" />
-              </TestCase>
-              <TestCase name="InfiniteStreamWithLimitOpTest">
-                <Test name="testDoubleSubsizedWithRange" />
-                <Test name="testDoubleUnorderedFinite" />
-                <Test name="testDoubleUnorderedGenerator" />
-                <Test name="testDoubleUnorderedIteration" />
-                <Test name="testDoubleUnorderedSizedNotSubsizedFinite" />
-                <Test name="testIntSubsizedWithRange" />
-                <Test name="testIntUnorderedFinite" />
-                <Test name="testIntUnorderedGenerator" />
-                <Test name="testIntUnorderedIteration" />
-                <Test name="testIntUnorderedSizedNotSubsizedFinite" />
-                <Test name="testLongSubsizedWithRange" />
-                <Test name="testLongUnorderedFinite" />
-                <Test name="testLongUnorderedGenerator" />
-                <Test name="testLongUnorderedIteration" />
-                <Test name="testLongUnorderedSizedNotSubsizedFinite" />
-                <Test name="testSubsizedWithRange" />
-                <Test name="testUnorderedFinite" />
-                <Test name="testUnorderedGenerator" />
-                <Test name="testUnorderedIteration" />
-                <Test name="testUnorderedSizedNotSubsizedFinite" />
-              </TestCase>
-              <TestCase name="IntPrimitiveOpsTests">
-                <Test name="testBox" />
-                <Test name="testForEach" />
-                <Test name="testLimit" />
-                <Test name="testMap" />
-                <Test name="testParForEach" />
-                <Test name="testParSum" />
-                <Test name="testSequential" />
-                <Test name="testSort" />
-                <Test name="testSortSort" />
-                <Test name="testSum" />
-                <Test name="testTee" />
-                <Test name="testToArray" />
-                <Test name="testUnBox" />
-              </TestCase>
-              <TestCase name="IntReduceTest">
-                <Test name="testOps" />
-                <Test name="testReduce" />
-              </TestCase>
-              <TestCase name="IntSliceOpTest">
-                <Test name="testLimit" />
-                <Test name="testLimitOps" />
-                <Test name="testLimitParallel" />
-                <Test name="testLimitShortCircuit" />
-                <Test name="testLimitSort" />
-                <Test name="testSkip" />
-                <Test name="testSkipLimit" />
-                <Test name="testSkipLimitOps" />
-                <Test name="testSkipOps" />
-                <Test name="testSkipParallel" />
-              </TestCase>
-              <TestCase name="IntUniqOpTest">
-                <Test name="testOp" />
-                <Test name="testOpSorted" />
-                <Test name="testUniqOp" />
-              </TestCase>
-              <TestCase name="LongPrimitiveOpsTests">
-                <Test name="testBox" />
-                <Test name="testForEach" />
-                <Test name="testLimit" />
-                <Test name="testMap" />
-                <Test name="testParForEach" />
-                <Test name="testParSum" />
-                <Test name="testSequential" />
-                <Test name="testSort" />
-                <Test name="testSortSort" />
-                <Test name="testSum" />
-                <Test name="testTee" />
-                <Test name="testToArray" />
-                <Test name="testUnBox" />
-              </TestCase>
-              <TestCase name="MapOpTest">
-                <Test name="testDoubleOps" />
-                <Test name="testEveryMapShape" />
-                <Test name="testIntOps" />
-                <Test name="testLongOps" />
-                <Test name="testMap" />
-                <Test name="testOps" />
-              </TestCase>
-              <TestCase name="MatchOpTest">
-                <Test name="testDoubleInfinite" />
-                <Test name="testDoubleStream" />
-                <Test name="testDoubleStreamMatches" />
-                <Test name="testInfinite" />
-                <Test name="testIntInfinite" />
-                <Test name="testIntStream" />
-                <Test name="testIntStreamMatches" />
-                <Test name="testLongInfinite" />
-                <Test name="testLongStream" />
-                <Test name="testLongStreamMatches" />
-                <Test name="testStream" />
-                <Test name="testStreamMatches" />
-              </TestCase>
-              <TestCase name="MinMaxTest">
-                <Test name="testDoubleMinMax" />
-                <Test name="testDoubleOps" />
-                <Test name="testIntMinMax" />
-                <Test name="testIntOps" />
-                <Test name="testLongMinMax" />
-                <Test name="testLongOps" />
-                <Test name="testMinMax" />
-                <Test name="testOps" />
-              </TestCase>
-              <TestCase name="PrimitiveAverageOpTest">
-                <Test name="testOps" />
-                <Test name="testOps" />
-                <Test name="testOps" />
-              </TestCase>
-              <TestCase name="PrimitiveSumTest">
-                <Test name="testOps" />
-                <Test name="testOps" />
-                <Test name="testOps" />
-              </TestCase>
-              <TestCase name="RangeTest">
-                <Test name="tesIntRangeReduce" />
-                <Test name="testInfiniteRangeFindFirst" />
-                <Test name="testIntInfiniteRangeFindFirst" />
-                <Test name="testIntInfiniteRangeLimit" />
-                <Test name="testIntRange" />
-                <Test name="testLongInfiniteRangeFindFirst" />
-                <Test name="testLongInfiniteRangeLimit" />
-                <Test name="testLongLongRange" />
-                <Test name="testLongLongRangeClosed" />
-                <Test name="testLongRange" />
-                <Test name="testLongRangeReduce" />
-              </TestCase>
-              <TestCase name="ReduceByOpTest">
-                <Test name="testOps" />
-              </TestCase>
-              <TestCase name="ReduceTest">
-                <Test name="testOps" />
-                <Test name="testReduce" />
-              </TestCase>
-              <TestCase name="SequentialOpTest">
-                <Test name="testLazy" />
-                <Test name="testMixedSeqPar" />
-              </TestCase>
-              <TestCase name="SliceOpTest">
-                <Test name="testLimit" />
-                <Test name="testLimitOps" />
-                <Test name="testLimitShortCircuit" />
-                <Test name="testLimitSort" />
-                <Test name="testSkip" />
-                <Test name="testSkipLimit" />
-                <Test name="testSkipLimitOps" />
-                <Test name="testSkipLimitOpsWithNonSplittingSpliterator" />
-                <Test name="testSkipOps" />
-                <Test name="testSlice" />
-              </TestCase>
-              <TestCase name="SortedOpTest">
-                <Test name="testDoubleOps" />
-                <Test name="testDoubleSequentialShortCircuitTerminal" />
-                <Test name="testDoubleSortSort" />
-                <Test name="testDoubleStreamTooLarge" />
-                <Test name="testIntOps" />
-                <Test name="testIntSequentialShortCircuitTerminal" />
-                <Test name="testIntSortSort" />
-                <Test name="testIntStreamTooLarge" />
-                <Test name="testLongOps" />
-                <Test name="testLongSequentialShortCircuitTerminal" />
-                <Test name="testLongSortSort" />
-                <Test name="testLongStreamTooLarge" />
-                <Test name="testOps" />
-                <Test name="testRefStreamTooLarge" />
-                <Test name="testSequentialShortCircuitTerminal" />
-                <Test name="testSortSort" />
-                <Test name="testSorted" />
-              </TestCase>
-              <TestCase name="SpliteratorTest">
-                <Test name="testDoubleSpliterator" />
-                <Test name="testIntSpliterator" />
-                <Test name="testLongSpliterator" />
-                <Test name="testSpliterator" />
-              </TestCase>
-              <TestCase name="StreamBuilderTest">
-                <Test name="testAfterBuilding" />
-                <Test name="testDoubleAfterBuilding" />
-                <Test name="testDoubleSingleton" />
-                <Test name="testDoubleStreamBuilder" />
-                <Test name="testIntAfterBuilding" />
-                <Test name="testIntSingleton" />
-                <Test name="testIntStreamBuilder" />
-                <Test name="testLongAfterBuilding" />
-                <Test name="testLongSingleton" />
-                <Test name="testLongStreamBuilder" />
-                <Test name="testSingleton" />
-                <Test name="testStreamBuilder" />
-              </TestCase>
-              <TestCase name="StreamCloseTest">
-                <Test name="testCascadedExceptions" />
-                <Test name="testEmptyCloseHandler" />
-                <Test name="testOneCloseHandler" />
-                <Test name="testTwoCloseHandlers" />
-              </TestCase>
-              <TestCase name="StreamLinkTest">
-                <Test name="testDoubleManyStreams" />
-                <Test name="testIntManyStreams" />
-                <Test name="testLongManyStreams" />
-                <Test name="testManyStreams" />
-              </TestCase>
-              <TestCase name="StreamParSeqTest">
-                <Test name="testParSeq" />
-              </TestCase>
-              <TestCase name="StreamSpliteratorTest">
-                <Test name="testDoubleParSpliterators" />
-                <Test name="testDoubleSpliterators" />
-                <Test name="testDoubleSplitting" />
-                <Test name="testDoubleStreamSpliterators" />
-                <Test name="testIntParSpliterators" />
-                <Test name="testIntSpliterators" />
-                <Test name="testIntSplitting" />
-                <Test name="testIntStreamSpliterators" />
-                <Test name="testLongParSpliterators" />
-                <Test name="testLongSpliterators" />
-                <Test name="testLongSplitting" />
-                <Test name="testLongStreamSpliterators" />
-                <Test name="testParSpliterators" />
-                <Test name="testSpliterators" />
-                <Test name="testSplitting" />
-                <Test name="testStreamSpliterators" />
-              </TestCase>
-              <TestCase name="SummaryStatisticsTest">
-                <Test name="testDoubleStatistics" />
-                <Test name="testIntStatistics" />
-                <Test name="testLongStatistics" />
-              </TestCase>
-              <TestCase name="TabulatorsTest">
-                <Test name="testComposeFinisher" />
-                <Test name="testGroupedReduce" />
-                <Test name="testJoin" />
-                <Test name="testReduce" />
-                <Test name="testSimpleGroupBy" />
-                <Test name="testSimplePartition" />
-                <Test name="testSimpleToMap" />
-                <Test name="testTwoLevelGroupBy" />
-                <Test name="testTwoLevelPartition" />
-              </TestCase>
-              <TestCase name="TeeOpTest">
-                <Test name="testDoubleOps" />
-                <Test name="testIntOps" />
-                <Test name="testLongOps" />
-                <Test name="testOps" />
-                <Test name="testTee" />
-              </TestCase>
-              <TestCase name="ToArrayOpTest">
-                <Test name="testAsArrayWithType" />
-                <Test name="testDistinctAndSortedPermutations" />
-                <Test name="testDoubleDistinctAndSortedPermutations" />
-                <Test name="testDoubleOps" />
-                <Test name="testDoubleOpsWithFilter" />
-                <Test name="testDoubleOpsWithFlatMap" />
-                <Test name="testDoubleOpsWithMap" />
-                <Test name="testDoubleOpsWithSorted" />
-                <Test name="testDoubleStatefulOpPermutations" />
-                <Test name="testIntDistinctAndSortedPermutations" />
-                <Test name="testIntOps" />
-                <Test name="testIntOpsWithFilter" />
-                <Test name="testIntOpsWithFlatMap" />
-                <Test name="testIntOpsWithMap" />
-                <Test name="testIntOpsWithSorted" />
-                <Test name="testIntStatefulOpPermutations" />
-                <Test name="testLongDistinctAndSortedPermutations" />
-                <Test name="testLongOps" />
-                <Test name="testLongOpsWithFilter" />
-                <Test name="testLongOpsWithFlatMap" />
-                <Test name="testLongOpsWithMap" />
-                <Test name="testLongOpsWithSorted" />
-                <Test name="testLongStatefulOpPermutations" />
-                <Test name="testOps" />
-                <Test name="testOpsWithFilter" />
-                <Test name="testOpsWithFlatMap" />
-                <Test name="testOpsWithMap" />
-                <Test name="testOpsWithSorted" />
-                <Test name="testStatefulOpPermutations" />
-                <Test name="testToArray" />
-              </TestCase>
-            </TestSuite>
-            <TestCase name="FillableStringTest">
-              <Test name="testStringBuffer" />
-              <Test name="testStringBuilder" />
-              <Test name="testStringJoiner" />
-            </TestCase>
-            <TestCase name="MapTest">
-              <Test name="testForEach" />
-              <Test name="testReplaceAll" />
-            </TestCase>
-          </TestSuite>
-          <TestSuite name="lang">
-            <TestSuite name="invoke">
-              <TestCase name="DeserializeMethodTest">
-                <Test name="testCapturingNonSerLambda" />
-                <Test name="testCapturingNonserIntersectionLambda" />
-                <Test name="testCapturingSerLambda" />
-                <Test name="testEmptyClass" />
-              </TestCase>
-            </TestSuite>
-          </TestSuite>
-        </TestSuite>
-      </TestSuite>
-    </TestSuite>
-  </TestSuite>
-</TestPackage>