| /* |
| * 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.appsecurity.cts; |
| |
| import android.platform.test.annotations.AppModeFull; |
| import android.platform.test.annotations.Presubmit; |
| |
| import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; |
| import com.android.tradefed.build.IBuildInfo; |
| import com.android.tradefed.device.DeviceNotAvailableException; |
| import com.android.tradefed.testtype.DeviceTestCase; |
| import com.android.tradefed.testtype.IAbi; |
| import com.android.tradefed.testtype.IAbiReceiver; |
| import com.android.tradefed.testtype.IBuildReceiver; |
| |
| /** |
| * Set of tests that verify behavior of runtime permissions, including both |
| * dynamic granting and behavior of legacy apps. |
| */ |
| @AppModeFull // TODO: Needs porting to instant |
| public class PermissionsHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver { |
| private static final String USES_PERMISSION_PKG = "com.android.cts.usepermission"; |
| private static final String ESCALATE_PERMISSION_PKG = "com.android.cts.escalate.permission"; |
| |
| private static final String APK_22 = "CtsUsePermissionApp22.apk"; |
| private static final String APK_23 = "CtsUsePermissionApp23.apk"; |
| private static final String APK_25 = "CtsUsePermissionApp25.apk"; |
| private static final String APK_26 = "CtsUsePermissionApp26.apk"; |
| private static final String APK_Latest = "CtsUsePermissionAppLatest.apk"; |
| |
| private static final String APK_PERMISSION_POLICY_25 = "CtsPermissionPolicyTest25.apk"; |
| private static final String PERMISSION_POLICY_25_PKG = "com.android.cts.permission.policy"; |
| |
| private static final String APK_DECLARE_NON_RUNTIME_PERMISSIONS = |
| "CtsDeclareNonRuntimePermissions.apk"; |
| private static final String APK_ESCLATE_TO_RUNTIME_PERMISSIONS = |
| "CtsEscalateToRuntimePermissions.apk"; |
| |
| private static final String APK_ACCESS_SERIAL_LEGACY = "CtsAccessSerialLegacy.apk"; |
| private static final String APK_ACCESS_SERIAL_MODERN = "CtsAccessSerialModern.apk"; |
| private static final String ACCESS_SERIAL_PKG = "android.os.cts"; |
| |
| private static final String SCREEN_OFF_TIMEOUT_NS = "system"; |
| private static final String SCREEN_OFF_TIMEOUT_KEY = "screen_off_timeout"; |
| private String mScreenTimeoutBeforeTest; |
| |
| private IAbi mAbi; |
| private CompatibilityBuildHelper mBuildHelper; |
| |
| @Override |
| public void setAbi(IAbi abi) { |
| mAbi = abi; |
| } |
| |
| @Override |
| public void setBuild(IBuildInfo buildInfo) { |
| mBuildHelper = new CompatibilityBuildHelper(buildInfo); |
| } |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| |
| Utils.prepareSingleUser(getDevice()); |
| assertNotNull(mAbi); |
| assertNotNull(mBuildHelper); |
| |
| getDevice().uninstallPackage(USES_PERMISSION_PKG); |
| getDevice().uninstallPackage(ESCALATE_PERMISSION_PKG); |
| getDevice().uninstallPackage(PERMISSION_POLICY_25_PKG); |
| getDevice().uninstallPackage(ACCESS_SERIAL_PKG); |
| |
| // Set screen timeout to 30 min to not timeout while waiting for UI to change |
| mScreenTimeoutBeforeTest = getDevice().getSetting(SCREEN_OFF_TIMEOUT_NS, |
| SCREEN_OFF_TIMEOUT_KEY); |
| getDevice().setSetting(SCREEN_OFF_TIMEOUT_NS, SCREEN_OFF_TIMEOUT_KEY, "1800000"); |
| |
| // Wake up device |
| getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP"); |
| getDevice().disableKeyguard(); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| super.tearDown(); |
| |
| getDevice().setSetting(SCREEN_OFF_TIMEOUT_NS, SCREEN_OFF_TIMEOUT_KEY, |
| mScreenTimeoutBeforeTest); |
| |
| getDevice().uninstallPackage(USES_PERMISSION_PKG); |
| getDevice().uninstallPackage(ESCALATE_PERMISSION_PKG); |
| getDevice().uninstallPackage(PERMISSION_POLICY_25_PKG); |
| getDevice().uninstallPackage(ACCESS_SERIAL_PKG); |
| } |
| |
| public void testFail() throws Exception { |
| // Sanity check that remote failure is host failure |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| boolean didThrow = false; |
| try { |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testFail"); |
| } catch (AssertionError expected) { |
| didThrow = true; |
| } |
| if (!didThrow) { |
| fail("Expected remote failure"); |
| } |
| } |
| |
| public void testKill() throws Exception { |
| // Sanity check that remote kill is host failure |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| boolean didThrow = false; |
| try { |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testKill"); |
| } catch (AssertionError expected) { |
| didThrow = true; |
| } |
| if (!didThrow) { |
| fail("Expected remote failure"); |
| } |
| } |
| |
| public void testCompatDefault22() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22", |
| "testCompatDefault"); |
| } |
| |
| public void testCompatRevoked22() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), false, false)); |
| boolean didThrow = false; |
| try { |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22", |
| "testCompatRevoked_part1"); |
| } catch (AssertionError expected) { |
| didThrow = true; |
| } |
| if (!didThrow) { |
| fail("App must be killed on a permission revoke"); |
| } |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22", |
| "testCompatRevoked_part2"); |
| } |
| |
| public void testNoRuntimePrompt22() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22", |
| "testNoRuntimePrompt"); |
| } |
| |
| public void testDefault23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testDefault"); |
| } |
| |
| public void testGranted23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testGranted"); |
| } |
| |
| public void testInteractiveGrant23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testInteractiveGrant"); |
| } |
| |
| public void testRuntimeGroupGrantSpecificity23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRuntimeGroupGrantSpecificity"); |
| } |
| |
| public void testRuntimeGroupGrantExpansion23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRuntimeGroupGrantExpansion"); |
| } |
| |
| public void testRuntimeGroupGrantExpansion25() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_25), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRuntimeGroupGrantExpansion"); |
| } |
| |
| public void testRuntimeGroupGrantExpansion26() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_26), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest26", |
| "testRuntimeGroupGrantNoExpansion"); |
| } |
| |
| public void testRuntimeGroupGrantExpansionLatest() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_Latest), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest26", |
| "testRuntimeGroupGrantNoExpansion"); |
| } |
| |
| public void testCancelledPermissionRequest23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testCancelledPermissionRequest"); |
| } |
| |
| public void testRequestGrantedPermission23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRequestGrantedPermission"); |
| } |
| |
| public void testDenialWithPrejudice23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testDenialWithPrejudice"); |
| } |
| |
| public void testRevokeAffectsWholeGroup23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| boolean didThrow = false; |
| try { |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRevokeAffectsWholeGroup_part1"); |
| } catch (AssertionError expected) { |
| didThrow = true; |
| } |
| if (!didThrow) { |
| fail("Should have thrown an exception."); |
| } |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRevokeAffectsWholeGroup_part2"); |
| } |
| |
| public void testGrantPreviouslyRevokedWithPrejudiceShowsPrompt23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| boolean didThrow = false; |
| try { |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part1"); |
| } catch (Throwable expected) { |
| didThrow = true; |
| } |
| if (!didThrow) { |
| fail("App must be killed on a permission revoke"); |
| } |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part2"); |
| } |
| |
| public void testRequestNonRuntimePermission23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRequestNonRuntimePermission"); |
| } |
| |
| public void testRequestNonExistentPermission23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRequestNonExistentPermission"); |
| } |
| |
| @Presubmit |
| public void testRequestPermissionFromTwoGroups23() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRequestPermissionFromTwoGroups"); |
| } |
| |
| public void testUpgradeKeepsPermissions() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22", |
| "testAllPermissionsGrantedByDefault"); |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), true, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testAllPermissionsGrantedOnUpgrade"); |
| } |
| |
| public void testNoDowngradePermissionModel() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| boolean didThrow = false; |
| try { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), true, false)); |
| } catch (AssertionError expected) { |
| didThrow = true; |
| } |
| if (!didThrow) { |
| fail("Permission mode downgrade not allowed"); |
| } |
| } |
| |
| public void testNoResidualPermissionsOnUninstall() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testNoResidualPermissionsOnUninstall_part1"); |
| assertNull(getDevice().uninstallPackage(USES_PERMISSION_PKG)); |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testNoResidualPermissionsOnUninstall_part2"); |
| } |
| |
| public void testRevokePropagatedOnUpgradeOldToNewModel() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_22), false, false)); |
| boolean didThrow = false; |
| try { |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest22", |
| "testRevokePropagatedOnUpgradeOldToNewModel_part1"); |
| } catch (AssertionError expected) { |
| didThrow = true; |
| } |
| if (!didThrow) { |
| fail("App must be killed on a permission revoke"); |
| } |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), true, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRevokePropagatedOnUpgradeOldToNewModel_part2"); |
| } |
| |
| public void testRevokePropagatedOnUpgradeNewToNewModel() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRevokePropagatedOnUpgradeNewToNewModel_part1"); |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), true, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testRevokePropagatedOnUpgradeNewToNewModel_part2"); |
| } |
| |
| public void testNoPermissionEscalation() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile( |
| APK_DECLARE_NON_RUNTIME_PERMISSIONS), false, false)); |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile( |
| APK_ESCLATE_TO_RUNTIME_PERMISSIONS), true, false)); |
| runDeviceTests(ESCALATE_PERMISSION_PKG, |
| "com.android.cts.escalatepermission.PermissionEscalationTest", |
| "testCannotEscalateNonRuntimePermissionsToRuntime"); |
| } |
| |
| public void testNoProtectionFlagsAddedToNonSignatureProtectionPermissions25() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile( |
| APK_PERMISSION_POLICY_25), false, false)); |
| runDeviceTests(PERMISSION_POLICY_25_PKG, |
| "com.android.cts.permission.policy.PermissionPolicyTest25", |
| "testNoProtectionFlagsAddedToNonSignatureProtectionPermissions"); |
| } |
| |
| public void testLegacyAppAccessSerial() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile( |
| APK_PERMISSION_POLICY_25), false, false)); |
| runDeviceTests(PERMISSION_POLICY_25_PKG, |
| "com.android.cts.permission.policy.PermissionPolicyTest25", |
| "testNoProtectionFlagsAddedToNonSignatureProtectionPermissions"); |
| } |
| |
| public void testNullPermissionRequest() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testNullPermissionRequest"); |
| } |
| |
| public void testNullAndRealPermission() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testNullAndRealPermission"); |
| } |
| |
| public void testInvalidPermission() throws Exception { |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_23), false, false)); |
| runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.UsePermissionTest23", |
| "testInvalidPermission"); |
| } |
| |
| |
| public void testSerialAccessPolicy() throws Exception { |
| // Verify legacy app behavior |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile( |
| APK_ACCESS_SERIAL_LEGACY), false, false)); |
| runDeviceTests(ACCESS_SERIAL_PKG, |
| "android.os.cts.AccessSerialLegacyTest", |
| "testAccessSerialNoPermissionNeeded"); |
| |
| // Verify modern app behavior |
| assertNull(getDevice().installPackage(mBuildHelper.getTestFile( |
| APK_ACCESS_SERIAL_MODERN), true, false)); |
| runDeviceTests(ACCESS_SERIAL_PKG, |
| "android.os.cts.AccessSerialModernTest", |
| "testAccessSerialPermissionNeeded"); |
| } |
| |
| private void runDeviceTests(String packageName, String testClassName, String testMethodName) |
| throws DeviceNotAvailableException { |
| Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName); |
| } |
| } |