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 17package com.android.cts.usepermission; 18 19import static junit.framework.Assert.assertEquals; 20import static org.junit.Assert.fail; 21 22import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess; 23import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess; 24import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess; 25import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess; 26import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand; 27 28import android.Manifest; 29import android.content.pm.PackageManager; 30import android.os.Environment; 31import org.junit.Test; 32 33/** 34 * Runtime permission behavior tests for apps targeting API 23 35 */ 36public class UsePermissionTest23 extends BasePermissionsTest { 37 private static final int REQUEST_CODE_PERMISSIONS = 42; 38 39 public void testFail() throws Exception { 40 fail("Expected"); 41 } 42 43 @Test 44 public void testKill() throws Exception { 45 android.os.Process.killProcess(android.os.Process.myPid()); 46 } 47 48 @Test 49 public void testDefault() throws Exception { 50 logCommand("/system/bin/cat", "/proc/self/mountinfo"); 51 52 // New permission model is denied by default 53 assertAllPermissionsRevoked(); 54 55 assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState()); 56 assertDirNoAccess(Environment.getExternalStorageDirectory()); 57 assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir()); 58 assertMediaNoAccess(getInstrumentation().getContext().getContentResolver(), false); 59 } 60 61 @Test 62 public void testGranted() throws Exception { 63 logCommand("/system/bin/cat", "/proc/self/mountinfo"); 64 grantPermission(Manifest.permission.READ_EXTERNAL_STORAGE); 65 assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext() 66 .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)); 67 assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext() 68 .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)); 69 assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState()); 70 assertDirReadWriteAccess(Environment.getExternalStorageDirectory()); 71 assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir()); 72 assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver()); 73 } 74 75 @Test 76 public void testInteractiveGrant() throws Exception { 77 logCommand("/system/bin/cat", "/proc/self/mountinfo"); 78 79 // Start out without permission 80 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 81 .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)); 82 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 83 .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)); 84 assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState()); 85 assertDirNoAccess(Environment.getExternalStorageDirectory()); 86 assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir()); 87 assertMediaNoAccess(getInstrumentation().getContext().getContentResolver(), false); 88 89 // Go through normal grant flow 90 BasePermissionActivity.Result result = requestPermissions(new String[] { 91 Manifest.permission.READ_EXTERNAL_STORAGE, 92 Manifest.permission.WRITE_EXTERNAL_STORAGE}, 93 REQUEST_CODE_PERMISSIONS, 94 BasePermissionActivity.class, 95 () -> { 96 try { 97 clickAllowButton(); 98 getUiDevice().waitForIdle(); 99 } catch (Exception e) { 100 throw new RuntimeException(e); 101 } 102 }); 103 104 assertEquals(REQUEST_CODE_PERMISSIONS, result.requestCode); 105 assertEquals(Manifest.permission.READ_EXTERNAL_STORAGE, result.permissions[0]); 106 assertEquals(Manifest.permission.WRITE_EXTERNAL_STORAGE, result.permissions[1]); 107 assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]); 108 assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[1]); 109 110 logCommand("/system/bin/cat", "/proc/self/mountinfo"); 111 112 // We should have permission now! 113 assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext() 114 .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)); 115 assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext() 116 .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)); 117 assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState()); 118 assertDirReadWriteAccess(Environment.getExternalStorageDirectory()); 119 assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir()); 120 assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver()); 121 } 122 123 @Test 124 public void testRuntimeGroupGrantSpecificity() throws Exception { 125 // Start out without permission 126 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 127 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS)); 128 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 129 .checkSelfPermission(Manifest.permission.READ_CONTACTS)); 130 131 String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS}; 132 133 // request only one permission from the 'contacts' permission group 134 BasePermissionActivity.Result result = requestPermissions(permissions, 135 REQUEST_CODE_PERMISSIONS, 136 BasePermissionActivity.class, 137 () -> { 138 try { 139 clickAllowButton(); 140 getUiDevice().waitForIdle(); 141 } catch (Exception e) { 142 throw new RuntimeException(e); 143 } 144 }); 145 146 // Expect the permission is granted 147 assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS, 148 permissions, new boolean[] {true}); 149 150 // Make sure no undeclared as used permissions are granted 151 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 152 .checkSelfPermission(Manifest.permission.READ_CONTACTS)); 153 } 154 155 @Test 156 public void testRuntimeGroupGrantExpansion() throws Exception { 157 // Start out without permission 158 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 159 .checkSelfPermission(Manifest.permission.RECEIVE_SMS)); 160 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 161 .checkSelfPermission(Manifest.permission.SEND_SMS)); 162 163 String[] permissions = new String[] {Manifest.permission.RECEIVE_SMS}; 164 165 // request only one permission from the 'SMS' permission group at runtime, 166 // but two from this group are <uses-permission> in the manifest 167 // request only one permission from the 'contacts' permission group 168 BasePermissionActivity.Result result = requestPermissions(permissions, 169 REQUEST_CODE_PERMISSIONS, 170 BasePermissionActivity.class, 171 () -> { 172 try { 173 clickAllowButton(); 174 getUiDevice().waitForIdle(); 175 } catch (Exception e) { 176 throw new RuntimeException(e); 177 } 178 }); 179 180 // Expect the permission is granted 181 assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS, 182 permissions, new boolean[] {true}); 183 184 // We should now have been granted both of the permissions from this group. 185 // NOTE: This is undesired behavior which will be fixed for target API 24. 186 assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext() 187 .checkSelfPermission(Manifest.permission.SEND_SMS)); 188 } 189 190 @Test 191 public void testCancelledPermissionRequest() throws Exception { 192 // Make sure we don't have the permission 193 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 194 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS)); 195 196 String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS}; 197 198 // Request the permission and cancel the request 199 BasePermissionActivity.Result result = requestPermissions(permissions, 200 REQUEST_CODE_PERMISSIONS, 201 BasePermissionActivity.class, 202 () -> { 203 try { 204 clickDenyButton(); 205 getUiDevice().waitForIdle(); 206 } catch (Exception e) { 207 throw new RuntimeException(e); 208 } 209 }); 210 211 // Expect the permission is not granted 212 assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS, 213 permissions, new boolean[] {false}); 214 } 215 216 @Test 217 public void testRequestGrantedPermission() throws Exception { 218 // Make sure we don't have the permission 219 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 220 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS)); 221 222 String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS}; 223 224 // Request the permission and allow it 225 BasePermissionActivity.Result firstResult = requestPermissions(permissions, 226 REQUEST_CODE_PERMISSIONS, 227 BasePermissionActivity.class, () -> { 228 try { 229 clickAllowButton(); 230 getUiDevice().waitForIdle(); 231 } catch (Exception e) { 232 throw new RuntimeException(e); 233 } 234 }); 235 236 // Expect the permission is granted 237 assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS, 238 permissions, new boolean[] {true}); 239 240 // Request the permission and do nothing 241 BasePermissionActivity.Result secondResult = requestPermissions(new String[] { 242 Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 1, 243 BasePermissionActivity.class, null); 244 245 // Expect the permission is granted 246 assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1, 247 permissions, new boolean[] {true}); 248 } 249 250 @Test 251 public void testDenialWithPrejudice() throws Exception { 252 // Make sure we don't have the permission 253 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 254 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS)); 255 256 String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS}; 257 258 // Request the permission and deny it 259 BasePermissionActivity.Result firstResult = requestPermissions( 260 permissions, REQUEST_CODE_PERMISSIONS, 261 BasePermissionActivity.class, () -> { 262 try { 263 clickDenyButton(); 264 getUiDevice().waitForIdle(); 265 } catch (Exception e) { 266 throw new RuntimeException(e); 267 } 268 }); 269 270 // Expect the permission is not granted 271 assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS, 272 permissions, new boolean[] {false}); 273 274 // Request the permission and choose don't ask again 275 BasePermissionActivity.Result secondResult = requestPermissions(new String[] { 276 Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 1, 277 BasePermissionActivity.class, () -> { 278 try { 279 denyWithPrejudice(); 280 getUiDevice().waitForIdle(); 281 } catch (Exception e) { 282 throw new RuntimeException(e); 283 } 284 }); 285 286 // Expect the permission is not granted 287 assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1, 288 permissions, new boolean[] {false}); 289 290 // Request the permission and do nothing 291 BasePermissionActivity.Result thirdResult = requestPermissions(new String[] { 292 Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 2, 293 BasePermissionActivity.class, null); 294 295 // Expect the permission is not granted 296 assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS + 2, 297 permissions, new boolean[] {false}); 298 } 299 300 @Test 301 public void testRevokeAffectsWholeGroup_part1() throws Exception { 302 // Grant the group 303 grantPermission(Manifest.permission.READ_CALENDAR); 304 305 // Make sure we have the permissions 306 assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext() 307 .checkSelfPermission(Manifest.permission.READ_CALENDAR)); 308 assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext() 309 .checkSelfPermission(Manifest.permission.WRITE_CALENDAR)); 310 311 // Revoke the group 312 revokePermission(Manifest.permission.READ_CALENDAR); 313 314 // We just committed a suicide by revoking the permission. See part2 below... 315 } 316 317 @Test 318 public void testRevokeAffectsWholeGroup_part2() throws Exception { 319 // Make sure we don't have the permissions 320 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 321 .checkSelfPermission(Manifest.permission.READ_CALENDAR)); 322 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 323 .checkSelfPermission(Manifest.permission.WRITE_CALENDAR)); 324 } 325 326 @Test 327 public void testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part1() throws Exception { 328 // Make sure we don't have the permission 329 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 330 .checkSelfPermission(Manifest.permission.READ_CALENDAR)); 331 332 String[] permissions = new String[] {Manifest.permission.READ_CALENDAR}; 333 334 // Request the permission and deny it 335 BasePermissionActivity.Result firstResult = requestPermissions( 336 permissions, REQUEST_CODE_PERMISSIONS, 337 BasePermissionActivity.class, () -> { 338 try { 339 clickDenyButton(); 340 getUiDevice().waitForIdle(); 341 } catch (Exception e) { 342 throw new RuntimeException(e); 343 } 344 }); 345 346 // Expect the permission is not granted 347 assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS, 348 permissions, new boolean[] {false}); 349 350 // Request the permission and choose don't ask again 351 BasePermissionActivity.Result secondResult = requestPermissions(new String[] { 352 Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS + 1, 353 BasePermissionActivity.class, () -> { 354 try { 355 denyWithPrejudice(); 356 getUiDevice().waitForIdle(); 357 } catch (Exception e) { 358 throw new RuntimeException(e); 359 } 360 }); 361 362 // Expect the permission is not granted 363 assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1, 364 permissions, new boolean[] {false}); 365 366 // Clear the denial with prejudice 367 grantPermission(Manifest.permission.READ_CALENDAR); 368 revokePermission(Manifest.permission.READ_CALENDAR); 369 370 // We just committed a suicide by revoking the permission. See part2 below... 371 } 372 373 @Test 374 public void testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part2() throws Exception { 375 // Make sure we don't have the permission 376 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 377 .checkSelfPermission(Manifest.permission.READ_CALENDAR)); 378 379 // Request the permission and allow it 380 BasePermissionActivity.Result thirdResult = requestPermissions(new String[] { 381 Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS + 2, 382 BasePermissionActivity.class, () -> { 383 try { 384 clickAllowButton(); 385 getUiDevice().waitForIdle(); 386 } catch (Exception e) { 387 throw new RuntimeException(e); 388 } 389 }); 390 391 // Make sure the permission is granted 392 assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS + 2, 393 new String[] {Manifest.permission.READ_CALENDAR}, new boolean[] {true}); 394 } 395 396 @Test 397 public void testRequestNonRuntimePermission() throws Exception { 398 // Make sure we don't have the permission 399 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 400 .checkSelfPermission(Manifest.permission.BIND_PRINT_SERVICE)); 401 402 String[] permissions = new String[] {Manifest.permission.BIND_PRINT_SERVICE}; 403 404 // Request the permission and do nothing 405 BasePermissionActivity.Result result = requestPermissions(permissions, 406 REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, null); 407 408 // Expect the permission is not granted 409 assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS, 410 permissions, new boolean[] {false}); 411 } 412 413 @Test 414 public void testRequestNonExistentPermission() throws Exception { 415 // Make sure we don't have the permission 416 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 417 .checkSelfPermission("permission.does.not.exist")); 418 419 String[] permissions = new String[] {"permission.does.not.exist"}; 420 421 // Request the permission and do nothing 422 BasePermissionActivity.Result result = requestPermissions(permissions, 423 REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, null); 424 425 // Expect the permission is not granted 426 assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS, 427 permissions, new boolean[] {false}); 428 } 429 430 @Test 431 public void testRequestPermissionFromTwoGroups() throws Exception { 432 // Make sure we don't have the permissions 433 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 434 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS)); 435 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 436 .checkSelfPermission(Manifest.permission.WRITE_CALENDAR)); 437 438 String[] permissions = new String[] { 439 Manifest.permission.WRITE_CONTACTS, 440 Manifest.permission.WRITE_CALENDAR 441 }; 442 443 // Request the permission and do nothing 444 BasePermissionActivity.Result result = requestPermissions(permissions, 445 REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, () -> { 446 try { 447 clickAllowButton(); 448 getUiDevice().waitForIdle(); 449 clickAllowButton(); 450 getUiDevice().waitForIdle(); 451 } catch (Exception e) { 452 throw new RuntimeException(e); 453 } 454 }); 455 456 // Expect the permission is not granted 457 assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS, 458 permissions, new boolean[] {true, true}); 459 } 460 461 @Test 462 public void testNoResidualPermissionsOnUninstall_part1() throws Exception { 463 // Grant all permissions 464 grantPermissions(new String[] { 465 Manifest.permission.WRITE_CALENDAR, 466 Manifest.permission.WRITE_CONTACTS, 467 Manifest.permission.WRITE_EXTERNAL_STORAGE, 468 Manifest.permission.READ_SMS, 469 Manifest.permission.CALL_PHONE, 470 Manifest.permission.RECORD_AUDIO, 471 Manifest.permission.BODY_SENSORS, 472 Manifest.permission.ACCESS_COARSE_LOCATION, 473 Manifest.permission.CAMERA 474 }); 475 } 476 477 @Test 478 public void testNoResidualPermissionsOnUninstall_part2() throws Exception { 479 // Make no permissions are granted after uninstalling and installing the app 480 assertAllPermissionsRevoked(); 481 } 482 483 @Test 484 public void testRevokePropagatedOnUpgradeOldToNewModel_part2() throws Exception { 485 assertPermissionsGrantState(new String[] {Manifest.permission.WRITE_CALENDAR}, 486 PackageManager.PERMISSION_DENIED); 487 } 488 489 @Test 490 public void testRevokePropagatedOnUpgradeNewToNewModel_part1() throws Exception { 491 // Make sure we don't have the permission 492 assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext() 493 .checkSelfPermission(Manifest.permission.READ_CALENDAR)); 494 495 // Request the permission and allow it 496 BasePermissionActivity.Result thirdResult = requestPermissions(new String[] { 497 Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS, 498 BasePermissionActivity.class, () -> { 499 try { 500 clickAllowButton(); 501 getUiDevice().waitForIdle(); 502 } catch (Exception e) { 503 throw new RuntimeException(e); 504 } 505 }); 506 507 // Make sure the permission is granted 508 assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS, 509 new String[] {Manifest.permission.READ_CALENDAR}, new boolean[] {true}); 510 } 511 512 @Test 513 public void testRevokePropagatedOnUpgradeNewToNewModel_part2() throws Exception { 514 // Make sure the permission is still granted after the upgrade 515 assertPermissionsGrantState(new String[] {Manifest.permission.READ_CALENDAR}, 516 PackageManager.PERMISSION_GRANTED); 517 // Also make sure one of the not granted permissions is still not granted 518 assertPermissionsGrantState(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, 519 PackageManager.PERMISSION_DENIED); 520 } 521 522 @Test 523 public void testAllPermissionsGrantedOnUpgrade() throws Exception { 524 assertAllPermissionsGrantState(PackageManager.PERMISSION_GRANTED); 525 } 526 527 private void assertAllPermissionsRevoked() { 528 assertAllPermissionsGrantState(PackageManager.PERMISSION_DENIED); 529 } 530 531 private void assertAllPermissionsGrantState(int grantState) { 532 assertPermissionsGrantState(new String[] { 533 Manifest.permission.SEND_SMS, 534 Manifest.permission.RECEIVE_SMS, 535 Manifest.permission.RECEIVE_WAP_PUSH, 536 Manifest.permission.RECEIVE_MMS, 537 Manifest.permission.READ_CALENDAR, 538 Manifest.permission.WRITE_CALENDAR, 539 Manifest.permission.WRITE_CONTACTS, 540 Manifest.permission.READ_EXTERNAL_STORAGE, 541 Manifest.permission.WRITE_EXTERNAL_STORAGE, 542 Manifest.permission.READ_SMS, 543 Manifest.permission.READ_PHONE_STATE, 544 Manifest.permission.READ_CALL_LOG, 545 Manifest.permission.WRITE_CALL_LOG, 546 Manifest.permission.ADD_VOICEMAIL, 547 Manifest.permission.CALL_PHONE, 548 Manifest.permission.USE_SIP, 549 Manifest.permission.PROCESS_OUTGOING_CALLS, 550 Manifest.permission.RECORD_AUDIO, 551 Manifest.permission.ACCESS_FINE_LOCATION, 552 Manifest.permission.ACCESS_COARSE_LOCATION, 553 Manifest.permission.CAMERA, 554 Manifest.permission.BODY_SENSORS, 555 "android.permission.READ_CELL_BROADCASTS" 556 }, grantState); 557 } 558 559 private void assertPermissionsGrantState(String[] permissions, int grantState) { 560 for (String permission : permissions) { 561 assertEquals(grantState, getInstrumentation().getContext() 562 .checkSelfPermission(permission)); 563 } 564 } 565 566 private void denyWithPrejudice() throws Exception { 567 if (!getInstrumentation().getContext().getPackageManager() 568 .hasSystemFeature(PackageManager.FEATURE_LEANBACK)) { 569 clickDontAskAgainCheckbox(); 570 clickDenyButton(); 571 } else { 572 clickDontAskAgainButton(); 573 } 574 } 575} 576