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>