1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.cts.deviceandprofileowner; 17 18 import static android.Manifest.permission.READ_CONTACTS; 19 import static android.Manifest.permission.WRITE_CONTACTS; 20 import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT; 21 import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED; 22 import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED; 23 import static android.app.admin.DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY; 24 import static android.app.admin.DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT; 25 import static android.app.admin.DevicePolicyManager.PERMISSION_POLICY_PROMPT; 26 import static android.content.pm.PackageManager.PERMISSION_DENIED; 27 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 28 29 import static com.android.cts.devicepolicy.PermissionUtils.permissionGrantStateToString; 30 import static com.android.cts.devicepolicy.PermissionUtils.permissionPolicyToString; 31 32 import static com.google.common.truth.Truth.assertWithMessage; 33 34 import android.Manifest.permission; 35 import android.app.UiAutomation; 36 import android.app.admin.DevicePolicyManager; 37 import android.content.Context; 38 import android.content.IntentFilter; 39 import android.os.Process; 40 import android.os.UserHandle; 41 import android.os.UserManager; 42 import android.util.Log; 43 44 import androidx.test.uiautomator.By; 45 import androidx.test.uiautomator.BySelector; 46 import androidx.test.uiautomator.UiDevice; 47 import androidx.test.uiautomator.UiObject2; 48 49 import com.android.compatibility.common.util.CddTest; 50 import com.android.compatibility.common.util.PollingCheck; 51 import com.android.cts.devicepolicy.PermissionBroadcastReceiver; 52 import com.android.cts.devicepolicy.PermissionUtils; 53 54 import com.google.android.collect.Sets; 55 56 import java.util.Set; 57 58 /** 59 * Test Runtime Permissions APIs in DevicePolicyManager. 60 */ 61 public class PermissionsTest extends BaseDeviceAdminTest { 62 63 private static final String TAG = "PermissionsTest"; 64 65 private static final String PERMISSION_APP_PACKAGE_NAME = "com.android.cts.permissionapp"; 66 private static final String PRE_M_APP_PACKAGE_NAME 67 = "com.android.cts.launcherapps.simplepremapp"; 68 private static final String PERMISSIONS_ACTIVITY_NAME 69 = PERMISSION_APP_PACKAGE_NAME + ".PermissionActivity"; 70 private static final String CUSTOM_PERM_A_NAME = "com.android.cts.permissionapp.permA"; 71 private static final String CUSTOM_PERM_B_NAME = "com.android.cts.permissionapp.permB"; 72 73 private static final String ACTION_PERMISSION_RESULT 74 = "com.android.cts.permission.action.PERMISSION_RESULT"; 75 76 private static final BySelector CRASH_POPUP_BUTTON_SELECTOR = By 77 .clazz(android.widget.Button.class.getName()) 78 .text("OK") 79 .pkg("android"); 80 private static final BySelector CRASH_POPUP_TEXT_SELECTOR = By 81 .clazz(android.widget.TextView.class.getName()) 82 .pkg("android"); 83 private static final String CRASH_WATCHER_ID = "CRASH"; 84 85 private static final Set<String> LOCATION_PERMISSIONS = Sets.newHashSet( 86 permission.ACCESS_FINE_LOCATION, 87 permission.ACCESS_BACKGROUND_LOCATION, 88 permission.ACCESS_COARSE_LOCATION); 89 90 private static final Set<String> SENSORS_PERMISSIONS = Sets.newHashSet( 91 permission.ACCESS_FINE_LOCATION, 92 permission.ACCESS_COARSE_LOCATION, 93 permission.CAMERA, 94 permission.ACTIVITY_RECOGNITION, 95 permission.BODY_SENSORS); 96 97 98 private PermissionBroadcastReceiver mReceiver; 99 private UiDevice mDevice; 100 private UiAutomation mUiAutomation; 101 102 @Override setUp()103 protected void setUp() throws Exception { 104 super.setUp(); 105 mReceiver = new PermissionBroadcastReceiver(); 106 mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PERMISSION_RESULT), 107 Context.RECEIVER_EXPORTED); 108 mDevice = UiDevice.getInstance(getInstrumentation()); 109 mUiAutomation = getInstrumentation().getUiAutomation(); 110 } 111 112 @Override tearDown()113 protected void tearDown() throws Exception { 114 mContext.unregisterReceiver(mReceiver); 115 mDevice.removeWatcher(CRASH_WATCHER_ID); 116 super.tearDown(); 117 } 118 testPermissionGrantStateDenied()119 public void testPermissionGrantStateDenied() throws Exception { 120 setPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_DENIED); 121 122 assertPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_DENIED); 123 assertCannotRequestPermissionFromActivity(READ_CONTACTS); 124 } 125 testPermissionGrantStateDenied_otherPermissionIsGranted()126 public void testPermissionGrantStateDenied_otherPermissionIsGranted() throws Exception { 127 int grantStateA = mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 128 PERMISSION_APP_PACKAGE_NAME, CUSTOM_PERM_A_NAME); 129 int grantStateB = mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 130 PERMISSION_APP_PACKAGE_NAME, CUSTOM_PERM_B_NAME); 131 try { 132 setPermissionGrantState(CUSTOM_PERM_A_NAME, PERMISSION_GRANT_STATE_GRANTED); 133 setPermissionGrantState(CUSTOM_PERM_B_NAME, PERMISSION_GRANT_STATE_DENIED); 134 135 assertPermissionGrantState(CUSTOM_PERM_A_NAME, PERMISSION_GRANT_STATE_GRANTED); 136 assertPermissionGrantState(CUSTOM_PERM_B_NAME, PERMISSION_GRANT_STATE_DENIED); 137 138 /* 139 * CUSTOM_PERM_A_NAME and CUSTOM_PERM_B_NAME are in the same permission group and one is 140 * granted the other one is not. 141 * 142 * It should not be possible to get the permission that was denied via policy granted by 143 * requesting it. 144 */ 145 assertCannotRequestPermissionFromActivity(CUSTOM_PERM_B_NAME); 146 } finally { 147 // Restore original state 148 setPermissionGrantState(CUSTOM_PERM_A_NAME, grantStateA); 149 setPermissionGrantState(CUSTOM_PERM_B_NAME, grantStateB); 150 } 151 } 152 testPermissionGrantStateGranted()153 public void testPermissionGrantStateGranted() throws Exception { 154 setPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_GRANTED); 155 156 assertPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_GRANTED); 157 assertCanRequestPermissionFromActivity(READ_CONTACTS); 158 } 159 testPermissionGrantState_preMApp_preQDeviceAdmin()160 public void testPermissionGrantState_preMApp_preQDeviceAdmin() throws Exception { 161 // These tests are to make sure that pre-M apps are not granted/denied runtime permissions 162 // by a profile owner that targets pre-Q 163 assertCannotSetPermissionGrantStatePreMApp(READ_CONTACTS, PERMISSION_GRANT_STATE_DENIED); 164 assertCannotSetPermissionGrantStatePreMApp(READ_CONTACTS, PERMISSION_GRANT_STATE_GRANTED); 165 } 166 assertCannotSetPermissionGrantStatePreMApp(String permission, int value)167 private void assertCannotSetPermissionGrantStatePreMApp(String permission, int value) 168 throws Exception { 169 assertFalse(mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 170 PRE_M_APP_PACKAGE_NAME, permission, value)); 171 assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 172 PRE_M_APP_PACKAGE_NAME, permission), PERMISSION_GRANT_STATE_DEFAULT); 173 174 // Install runtime permissions should always be granted 175 PermissionUtils.checkPermission(permission, PERMISSION_GRANTED, PRE_M_APP_PACKAGE_NAME); 176 PermissionUtils.checkPermissionAndAppOps(permission, PERMISSION_GRANTED, 177 PRE_M_APP_PACKAGE_NAME); 178 } 179 testPermissionGrantState_preMApp()180 public void testPermissionGrantState_preMApp() throws Exception { 181 // These tests are to make sure that pre-M apps can be granted/denied runtime permissions 182 // by a profile owner targets Q or later 183 assertCanSetPermissionGrantStatePreMApp(READ_CONTACTS, PERMISSION_GRANT_STATE_DENIED); 184 assertCanSetPermissionGrantStatePreMApp(READ_CONTACTS, PERMISSION_GRANT_STATE_GRANTED); 185 } 186 assertCanSetPermissionGrantStatePreMApp(String permission, int value)187 private void assertCanSetPermissionGrantStatePreMApp(String permission, int value) 188 throws Exception { 189 Log.d(TAG, "Calling " + mDevicePolicyManager + ".setPermissionGrantState(" 190 + PRE_M_APP_PACKAGE_NAME + ", " + permission + ", " 191 + permissionGrantStateToString(value) + ")"); 192 boolean result = mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 193 PRE_M_APP_PACKAGE_NAME, permission, value); 194 Log.d(TAG, "Result: " + result); 195 196 assertWithMessage("%s.setPermissionGrantState(%s, %s, %s)", mDevicePolicyManager, 197 ADMIN_RECEIVER_COMPONENT, PRE_M_APP_PACKAGE_NAME, 198 permissionGrantStateToString(value)).that(result).isTrue(); 199 200 assertPermissionGrantState(mDevicePolicyManager, PRE_M_APP_PACKAGE_NAME, permission, value); 201 202 Context context = mContext; 203 204 // Install time permissions should always be granted 205 PermissionUtils.checkPermission(context, permission, PERMISSION_GRANTED, 206 PRE_M_APP_PACKAGE_NAME); 207 208 // For pre-M apps the access to the data might be prevented via app-ops. Hence check that 209 // they are correctly set 210 switch (value) { 211 case PERMISSION_GRANT_STATE_GRANTED: 212 PermissionUtils.checkPermissionAndAppOps(context, permission, PERMISSION_GRANTED, 213 PRE_M_APP_PACKAGE_NAME); 214 break; 215 case PERMISSION_GRANT_STATE_DENIED: 216 PermissionUtils.checkPermissionAndAppOps(context, permission, PERMISSION_DENIED, 217 PRE_M_APP_PACKAGE_NAME); 218 break; 219 default: 220 fail("unsupported policy value (" + value + ")"); 221 } 222 } 223 testPermissionPolicyAutoDeny()224 public void testPermissionPolicyAutoDeny() throws Exception { 225 setPermissionPolicy(PERMISSION_POLICY_AUTO_DENY); 226 227 assertPermissionPolicy(PERMISSION_POLICY_AUTO_DENY); 228 assertCannotRequestPermissionFromActivity(READ_CONTACTS); 229 } 230 testPermissionPolicyAutoDeny_permissionLocked()231 public void testPermissionPolicyAutoDeny_permissionLocked() throws Exception { 232 int grantState = mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 233 PERMISSION_APP_PACKAGE_NAME, READ_CONTACTS); 234 int permissionPolicy = mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT); 235 try { 236 setPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_DENIED); 237 setPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_DEFAULT); 238 239 // Wait for permission grant state to propagate. 240 PollingCheck.waitFor(() -> mDevicePolicyManager.getPermissionGrantState( 241 ADMIN_RECEIVER_COMPONENT, PERMISSION_APP_PACKAGE_NAME, READ_CONTACTS) 242 == PERMISSION_GRANT_STATE_DEFAULT); 243 244 testPermissionPolicyAutoDeny(); 245 246 // Permission should be locked, so changing the policy should not change the grant state 247 setPermissionPolicy(PERMISSION_POLICY_PROMPT); 248 249 assertPermissionPolicy(PERMISSION_POLICY_PROMPT); 250 assertCannotRequestPermissionFromActivity(READ_CONTACTS); 251 252 setPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT); 253 254 assertPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT); 255 assertCannotRequestPermissionFromActivity(READ_CONTACTS); 256 } finally { 257 // Restore original state 258 setPermissionGrantState(READ_CONTACTS, grantState); 259 setPermissionPolicy(permissionPolicy); 260 } 261 } 262 testPermissionPolicyAutoGrant()263 public void testPermissionPolicyAutoGrant() throws Exception { 264 int permissionPolicy = mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT); 265 try { 266 setPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT); 267 268 assertPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT); 269 assertCanRequestPermissionFromActivity(READ_CONTACTS); 270 } finally { 271 // Restore original state 272 setPermissionPolicy(permissionPolicy); 273 } 274 } 275 testPermissionPolicyAutoGrant_permissionLocked()276 public void testPermissionPolicyAutoGrant_permissionLocked() throws Exception { 277 int grantState = mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 278 PERMISSION_APP_PACKAGE_NAME, READ_CONTACTS); 279 int permissionPolicy = mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT); 280 try { 281 setPermissionGrantState(READ_CONTACTS, PERMISSION_GRANT_STATE_DEFAULT); 282 setPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT); 283 284 assertPermissionPolicy(PERMISSION_POLICY_AUTO_GRANT); 285 assertCanRequestPermissionFromActivity(READ_CONTACTS); 286 287 // permission should be locked, so changing the policy should not change the grant state 288 setPermissionPolicy(PERMISSION_POLICY_PROMPT); 289 290 assertPermissionPolicy(PERMISSION_POLICY_PROMPT); 291 assertCanRequestPermissionFromActivity(READ_CONTACTS); 292 293 setPermissionPolicy(PERMISSION_POLICY_AUTO_DENY); 294 295 assertPermissionPolicy(PERMISSION_POLICY_AUTO_DENY); 296 assertCanRequestPermissionFromActivity(READ_CONTACTS); 297 } finally { 298 // Restore original state 299 setPermissionGrantState(READ_CONTACTS, grantState); 300 setPermissionPolicy(permissionPolicy); 301 } 302 } 303 testCannotRequestPermission()304 public void testCannotRequestPermission() throws Exception { 305 assertCannotRequestPermissionFromActivity(READ_CONTACTS); 306 } 307 testCanRequestPermission()308 public void testCanRequestPermission() throws Exception { 309 assertCanRequestPermissionFromActivity(READ_CONTACTS); 310 } 311 testPermissionPrompts()312 public void testPermissionPrompts() throws Exception { 313 // register a crash watcher 314 mDevice.registerWatcher(CRASH_WATCHER_ID, () -> { 315 UiObject2 button = mDevice.findObject(CRASH_POPUP_BUTTON_SELECTOR); 316 if (button != null) { 317 UiObject2 text = mDevice.findObject(CRASH_POPUP_TEXT_SELECTOR); 318 Log.d(TAG, "Removing an error dialog: " + text != null ? text.getText() : null); 319 button.click(); 320 return true; 321 } 322 return false; 323 }); 324 mDevice.runWatchers(); 325 setPermissionPolicy(PERMISSION_POLICY_PROMPT); 326 327 assertPermissionPolicy(PERMISSION_POLICY_PROMPT); 328 PermissionUtils.launchActivityAndRequestPermission(mReceiver, mDevice, READ_CONTACTS, 329 PERMISSION_DENIED, PERMISSION_APP_PACKAGE_NAME, PERMISSIONS_ACTIVITY_NAME); 330 PermissionUtils.checkPermission(READ_CONTACTS, PERMISSION_DENIED, 331 PERMISSION_APP_PACKAGE_NAME); 332 PermissionUtils.launchActivityAndRequestPermission(mReceiver, mDevice, READ_CONTACTS, 333 PERMISSION_GRANTED, PERMISSION_APP_PACKAGE_NAME, PERMISSIONS_ACTIVITY_NAME); 334 PermissionUtils.checkPermission(READ_CONTACTS, PERMISSION_GRANTED, 335 PERMISSION_APP_PACKAGE_NAME); 336 } 337 revokePermission(String sensorPermission)338 private void revokePermission(String sensorPermission) { 339 if (LOCATION_PERMISSIONS.contains(sensorPermission)) { 340 mUiAutomation.revokeRuntimePermission(PERMISSION_APP_PACKAGE_NAME, 341 permission.ACCESS_FINE_LOCATION); 342 mUiAutomation.revokeRuntimePermission(PERMISSION_APP_PACKAGE_NAME, 343 permission.ACCESS_COARSE_LOCATION); 344 } else { 345 mUiAutomation.revokeRuntimePermission(PERMISSION_APP_PACKAGE_NAME, sensorPermission); 346 } 347 } 348 setPermissionPolicy(int permissionPolicy)349 private void setPermissionPolicy(int permissionPolicy) { 350 Log.d(TAG, "Calling setPermissionPolicy(" + permissionPolicyToString(permissionPolicy) 351 + ") using DPM " + mDevicePolicyManager + " on uid " + Process.myUid()); 352 mDevicePolicyManager.setPermissionPolicy(ADMIN_RECEIVER_COMPONENT, permissionPolicy); 353 } 354 setPermissionGrantState(String permission, int grantState)355 private boolean setPermissionGrantState(String permission, int grantState) { 356 return setPermissionGrantState(mDevicePolicyManager, permission, grantState); 357 } 358 setPermissionGrantState(DevicePolicyManager dpm, String permission, int grantState)359 private boolean setPermissionGrantState(DevicePolicyManager dpm, String permission, 360 int grantState) { 361 boolean result = dpm.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 362 PERMISSION_APP_PACKAGE_NAME, permission, grantState); 363 Log.d(TAG, "setPermissionGrantState(" + PERMISSION_APP_PACKAGE_NAME + ", " + permission 364 + "): requested " + grantState + " (" + permissionGrantStateToString(grantState) 365 + ") using DPM " + mDevicePolicyManager + " on uid " + Process.myUid() 366 + ", got " + result); 367 return result; 368 } 369 assertPermissionGrantState(String permission, int expectedState)370 private void assertPermissionGrantState(String permission, int expectedState) { 371 assertPermissionGrantState(mDevicePolicyManager, permission, expectedState); 372 } 373 assertPermissionGrantState(DevicePolicyManager dpm, String permission, int expectedState)374 private void assertPermissionGrantState(DevicePolicyManager dpm, String permission, 375 int expectedState) { 376 assertPermissionGrantState(dpm, PERMISSION_APP_PACKAGE_NAME, permission, expectedState); 377 } 378 assertPermissionGrantState(DevicePolicyManager dpm, String packageName, String permission, int expectedState)379 private void assertPermissionGrantState(DevicePolicyManager dpm, String packageName, 380 String permission, int expectedState) { 381 int actualState = dpm.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT, 382 packageName, permission); 383 384 assertWithMessage("%s.getPermissionGrantState(%s, %s, %s) (where %s=%s and %s=%s)", 385 mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT, packageName, permission, 386 expectedState, permissionGrantStateToString(expectedState), 387 actualState, permissionGrantStateToString(actualState)) 388 .that(actualState) 389 .isEqualTo(expectedState); 390 } 391 assertPermissionPolicy(int expectedPolicy)392 private void assertPermissionPolicy(int expectedPolicy) { 393 int actualPolicy = mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT); 394 assertWithMessage("%s.getPermissionPolicy(%s) (where %s=%s and %s=%s)", 395 mDevicePolicyManager, ADMIN_RECEIVER_COMPONENT, 396 expectedPolicy, permissionPolicyToString(expectedPolicy), 397 actualPolicy, permissionPolicyToString(actualPolicy)) 398 .that(actualPolicy) 399 .isEqualTo(expectedPolicy); 400 } 401 assertCanRequestPermissionFromActivity(String permission)402 private void assertCanRequestPermissionFromActivity(String permission) throws Exception { 403 PermissionUtils.launchActivityAndRequestPermission( 404 mReceiver, permission, PERMISSION_GRANTED, 405 PERMISSION_APP_PACKAGE_NAME, PERMISSIONS_ACTIVITY_NAME); 406 } 407 assertCannotRequestPermissionFromActivity(String permission)408 private void assertCannotRequestPermissionFromActivity(String permission) throws Exception { 409 PermissionUtils.launchActivityAndRequestPermission( 410 mReceiver, permission, PERMISSION_DENIED, 411 PERMISSION_APP_PACKAGE_NAME, PERMISSIONS_ACTIVITY_NAME); 412 } 413 } 414