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