Home | History | Annotate | Download | only in usepermission
      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 
     17 package com.android.cts.usepermission;
     18 
     19 import static junit.framework.Assert.assertEquals;
     20 
     21 import static org.junit.Assert.fail;
     22 
     23 import android.Manifest;
     24 import android.content.ContentValues;
     25 import android.content.Context;
     26 import android.content.pm.PackageManager;
     27 import android.database.Cursor;
     28 import android.net.Uri;
     29 import android.os.Build;
     30 import android.provider.CalendarContract;
     31 
     32 import androidx.test.InstrumentationRegistry;
     33 
     34 import org.junit.Before;
     35 import org.junit.Test;
     36 
     37 import java.util.ArrayList;
     38 import java.util.Arrays;
     39 
     40 /**
     41  * Runtime permission behavior tests for apps targeting API 23
     42  */
     43 public class UsePermissionTest23 extends BasePermissionsTest {
     44     private static final int REQUEST_CODE_PERMISSIONS = 42;
     45 
     46     private final Context mContext = getInstrumentation().getContext();
     47 
     48     private boolean mLeanback;
     49     private boolean mWatch;
     50 
     51     @Before
     52     public void initialize() {
     53         PackageManager pm = getInstrumentation().getContext().getPackageManager();
     54         mLeanback = pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
     55         mWatch = pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
     56     }
     57 
     58     @Test
     59     public void testFail() throws Exception {
     60         fail("Expected");
     61     }
     62 
     63     @Test
     64     public void testKill() throws Exception {
     65         android.os.Process.killProcess(android.os.Process.myPid());
     66     }
     67 
     68     @Test
     69     public void testDefault() throws Exception {
     70         // New permission model is denied by default
     71         assertAllPermissionsRevoked();
     72     }
     73 
     74     @Test
     75     public void testGranted() throws Exception {
     76         grantPermission(Manifest.permission.READ_CALENDAR);
     77 
     78         // Read/write access should be allowed
     79         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
     80                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
     81         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
     82                 .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
     83         final Uri uri = insertCalendarItem();
     84         try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
     85             assertEquals(1, c.getCount());
     86         }
     87     }
     88 
     89     @Test
     90     public void testInteractiveGrant() throws Exception {
     91         // Start out without permission
     92         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
     93                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
     94         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
     95                 .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
     96         try {
     97             insertCalendarItem();
     98             fail();
     99         } catch (SecurityException expected) {
    100         }
    101         try (Cursor c = mContext.getContentResolver().query(
    102                 CalendarContract.Calendars.CONTENT_URI, null, null, null)) {
    103             fail();
    104         } catch (SecurityException expected) {
    105         }
    106 
    107         // Go through normal grant flow
    108         BasePermissionActivity.Result result = requestPermissions(new String[] {
    109                 Manifest.permission.READ_CALENDAR,
    110                 Manifest.permission.WRITE_CALENDAR},
    111                 REQUEST_CODE_PERMISSIONS,
    112                 BasePermissionActivity.class,
    113                 () -> {
    114                     try {
    115                         clickAllowButton();
    116                         getUiDevice().waitForIdle();
    117                     } catch (Exception e) {
    118                         throw new RuntimeException(e);
    119                     }
    120                 });
    121 
    122         assertEquals(REQUEST_CODE_PERMISSIONS, result.requestCode);
    123         assertEquals(Manifest.permission.READ_CALENDAR, result.permissions[0]);
    124         assertEquals(Manifest.permission.WRITE_CALENDAR, result.permissions[1]);
    125         assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
    126         assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[1]);
    127 
    128         // We should have permission now!
    129         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
    130                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
    131         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
    132                 .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
    133         final Uri uri = insertCalendarItem();
    134         try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
    135             assertEquals(1, c.getCount());
    136         }
    137     }
    138 
    139     @Test
    140     public void testRuntimeGroupGrantSpecificity() throws Exception {
    141         // Start out without permission
    142         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    143                 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
    144         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    145                 .checkSelfPermission(Manifest.permission.READ_CONTACTS));
    146 
    147         String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
    148 
    149         // request only one permission from the 'contacts' permission group
    150         BasePermissionActivity.Result result = requestPermissions(permissions,
    151                 REQUEST_CODE_PERMISSIONS,
    152                 BasePermissionActivity.class,
    153                 () -> {
    154                     try {
    155                         clickAllowButton();
    156                         getUiDevice().waitForIdle();
    157                     } catch (Exception e) {
    158                         throw new RuntimeException(e);
    159                     }
    160                 });
    161 
    162         // Expect the permission is granted
    163         assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
    164                 permissions, new boolean[] {true});
    165 
    166         // Make sure no undeclared as used permissions are granted
    167         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    168                 .checkSelfPermission(Manifest.permission.READ_CONTACTS));
    169     }
    170 
    171     @Test
    172     public void testRuntimeGroupGrantExpansion() throws Exception {
    173         // Start out without permission
    174         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    175                 .checkSelfPermission(Manifest.permission.RECEIVE_SMS));
    176         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    177                 .checkSelfPermission(Manifest.permission.SEND_SMS));
    178 
    179         String[] permissions = new String[] {Manifest.permission.RECEIVE_SMS};
    180 
    181         // request only one permission from the 'SMS' permission group at runtime,
    182         // but two from this group are <uses-permission> in the manifest
    183         // request only one permission from the 'contacts' permission group
    184         BasePermissionActivity.Result result = requestPermissions(permissions,
    185                 REQUEST_CODE_PERMISSIONS,
    186                 BasePermissionActivity.class,
    187                 () -> {
    188                     try {
    189                         clickAllowButton();
    190                         getUiDevice().waitForIdle();
    191                     } catch (Exception e) {
    192                         throw new RuntimeException(e);
    193                     }
    194                 });
    195 
    196         // Expect the permission is granted
    197         assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
    198                 permissions, new boolean[] {true});
    199 
    200         // We should now have been granted both of the permissions from this group.
    201         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
    202                 .checkSelfPermission(Manifest.permission.SEND_SMS));
    203     }
    204 
    205     @Test
    206     public void testCancelledPermissionRequest() throws Exception {
    207         // Make sure we don't have the permission
    208         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    209                 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
    210 
    211         String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
    212 
    213         // Request the permission and cancel the request
    214         BasePermissionActivity.Result result = requestPermissions(permissions,
    215                 REQUEST_CODE_PERMISSIONS,
    216                 BasePermissionActivity.class,
    217                 () -> {
    218                     try {
    219                         clickDenyButton();
    220                         getUiDevice().waitForIdle();
    221                     } catch (Exception e) {
    222                         throw new RuntimeException(e);
    223                     }
    224                 });
    225 
    226         // Expect the permission is not granted
    227         assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
    228                 permissions, new boolean[] {false});
    229     }
    230 
    231     @Test
    232     public void testRequestGrantedPermission() throws Exception {
    233         // Make sure we don't have the permission
    234         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    235                 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
    236 
    237         String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
    238 
    239         // Request the permission and allow it
    240         BasePermissionActivity.Result firstResult = requestPermissions(permissions,
    241                 REQUEST_CODE_PERMISSIONS,
    242                 BasePermissionActivity.class, () -> {
    243                     try {
    244                         clickAllowButton();
    245                         getUiDevice().waitForIdle();
    246                     } catch (Exception e) {
    247                         throw new RuntimeException(e);
    248                     }
    249                 });
    250 
    251         // Expect the permission is granted
    252         assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS,
    253                 permissions, new boolean[] {true});
    254 
    255         // Request the permission and do nothing
    256         BasePermissionActivity.Result secondResult = requestPermissions(new String[] {
    257                 Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 1,
    258                 BasePermissionActivity.class, null);
    259 
    260         // Expect the permission is granted
    261         assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1,
    262                 permissions, new boolean[] {true});
    263     }
    264 
    265     @Test
    266     public void testDenialWithPrejudice() throws Exception {
    267         // Make sure we don't have the permission
    268         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    269                 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
    270 
    271         String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
    272 
    273         // Request the permission and deny it
    274         BasePermissionActivity.Result firstResult = requestPermissions(
    275                 permissions, REQUEST_CODE_PERMISSIONS,
    276                 BasePermissionActivity.class, () -> {
    277                     try {
    278                         clickDenyButton();
    279                         getUiDevice().waitForIdle();
    280                     } catch (Exception e) {
    281                         throw new RuntimeException(e);
    282                     }
    283                 });
    284 
    285         // Expect the permission is not granted
    286         assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS,
    287                 permissions, new boolean[] {false});
    288 
    289         // Request the permission and choose don't ask again
    290         BasePermissionActivity.Result secondResult = requestPermissions(new String[] {
    291                         Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 1,
    292                 BasePermissionActivity.class, () -> {
    293                     try {
    294                         denyWithPrejudice();
    295                         getUiDevice().waitForIdle();
    296                     } catch (Exception e) {
    297                         throw new RuntimeException(e);
    298                     }
    299                 });
    300 
    301         // Expect the permission is not granted
    302         assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1,
    303                 permissions, new boolean[] {false});
    304 
    305         // Request the permission and do nothing
    306         BasePermissionActivity.Result thirdResult = requestPermissions(new String[] {
    307                         Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 2,
    308                 BasePermissionActivity.class, null);
    309 
    310         // Expect the permission is not granted
    311         assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS + 2,
    312                 permissions, new boolean[] {false});
    313     }
    314 
    315     @Test
    316     public void testRevokeAffectsWholeGroup_part1() throws Exception {
    317         // Grant the group
    318         grantPermission(Manifest.permission.READ_CALENDAR);
    319 
    320         // Make sure we have the permissions
    321         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
    322                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
    323         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
    324                 .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
    325 
    326         // Revoke the group
    327         revokePermission(Manifest.permission.READ_CALENDAR);
    328 
    329         // We just committed a suicide by revoking the permission. See part2 below...
    330     }
    331 
    332     @Test
    333     public void testRevokeAffectsWholeGroup_part2() throws Exception {
    334         // Make sure we don't have the permissions
    335         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    336                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
    337         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    338                 .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
    339     }
    340 
    341     @Test
    342     public void testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part1() throws Exception {
    343         // Make sure we don't have the permission
    344         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    345                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
    346 
    347         String[] permissions = new String[] {Manifest.permission.READ_CALENDAR};
    348 
    349         // Request the permission and deny it
    350         BasePermissionActivity.Result firstResult = requestPermissions(
    351                 permissions, REQUEST_CODE_PERMISSIONS,
    352                 BasePermissionActivity.class, () -> {
    353                     try {
    354                         clickDenyButton();
    355                         getUiDevice().waitForIdle();
    356                     } catch (Exception e) {
    357                         throw new RuntimeException(e);
    358                     }
    359                 });
    360 
    361         // Expect the permission is not granted
    362         assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS,
    363                 permissions, new boolean[] {false});
    364 
    365         // Request the permission and choose don't ask again
    366         BasePermissionActivity.Result secondResult = requestPermissions(new String[] {
    367                         Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS + 1,
    368                 BasePermissionActivity.class, () -> {
    369                     try {
    370                         denyWithPrejudice();
    371                         getUiDevice().waitForIdle();
    372                     } catch (Exception e) {
    373                         throw new RuntimeException(e);
    374                     }
    375                 });
    376 
    377         // Expect the permission is not granted
    378         assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1,
    379                 permissions, new boolean[] {false});
    380 
    381         // Clear the denial with prejudice
    382         grantPermission(Manifest.permission.READ_CALENDAR);
    383         revokePermission(Manifest.permission.READ_CALENDAR);
    384 
    385         // We just committed a suicide by revoking the permission. See part2 below...
    386     }
    387 
    388     @Test
    389     public void testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part2() throws Exception {
    390         // Make sure we don't have the permission
    391         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    392                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
    393 
    394         // Request the permission and allow it
    395         BasePermissionActivity.Result thirdResult = requestPermissions(new String[] {
    396                         Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS + 2,
    397                 BasePermissionActivity.class, () -> {
    398                     try {
    399                         clickAllowButton();
    400                         getUiDevice().waitForIdle();
    401                     } catch (Exception e) {
    402                         throw new RuntimeException(e);
    403                     }
    404                 });
    405 
    406         // Make sure the permission is granted
    407         assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS + 2,
    408                 new String[] {Manifest.permission.READ_CALENDAR}, new boolean[] {true});
    409     }
    410 
    411     @Test
    412     public void testRequestNonRuntimePermission() throws Exception {
    413         // Make sure we don't have the permission
    414         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    415                 .checkSelfPermission(Manifest.permission.BIND_PRINT_SERVICE));
    416 
    417         String[] permissions = new String[] {Manifest.permission.BIND_PRINT_SERVICE};
    418 
    419         // Request the permission and do nothing
    420         BasePermissionActivity.Result result = requestPermissions(permissions,
    421                 REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, null);
    422 
    423         // Expect the permission is not granted
    424         assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
    425                 permissions, new boolean[] {false});
    426     }
    427 
    428     @Test
    429     public void testRequestNonExistentPermission() throws Exception {
    430         // Make sure we don't have the permission
    431         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    432                 .checkSelfPermission("permission.does.not.exist"));
    433 
    434         String[] permissions = new String[] {"permission.does.not.exist"};
    435 
    436         // Request the permission and do nothing
    437         BasePermissionActivity.Result result = requestPermissions(permissions,
    438                 REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, null);
    439 
    440         // Expect the permission is not granted
    441         assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
    442                 permissions, new boolean[] {false});
    443     }
    444 
    445     @Test
    446     public void testRequestPermissionFromTwoGroups() throws Exception {
    447         // Make sure we don't have the permissions
    448         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    449                 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
    450         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    451                 .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
    452 
    453         String[] permissions = new String[] {
    454                 Manifest.permission.WRITE_CONTACTS,
    455                 Manifest.permission.WRITE_CALENDAR
    456         };
    457 
    458         // Request the permission and allow it
    459         BasePermissionActivity.Result result = requestPermissions(permissions,
    460                 REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, () -> {
    461             try {
    462                 clickAllowButton();
    463                 getUiDevice().waitForIdle();
    464                 clickAllowButton();
    465                 getUiDevice().waitForIdle();
    466             } catch (Exception e) {
    467                 throw new RuntimeException(e);
    468             }
    469         });
    470 
    471         // Expect the permission are reported as granted
    472         assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
    473                 permissions, new boolean[] {true, true});
    474 
    475         // The permissions are granted
    476         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
    477                 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
    478         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
    479                 .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
    480 
    481         // In API < N_MR1 all permissions of a group are granted. I.e. the grant was "expanded"
    482         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
    483                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
    484 
    485         // Even the contacts group was expanded, the read-calendar permission is not in the
    486         // manifest, hence not granted.
    487         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    488                 .checkSelfPermission(Manifest.permission.READ_CONTACTS));
    489     }
    490 
    491     @Test
    492     public void testNoResidualPermissionsOnUninstall_part1() throws Exception {
    493         ArrayList<String> perms = new ArrayList<>(Arrays.asList(
    494                 Manifest.permission.WRITE_CALENDAR,
    495                 Manifest.permission.WRITE_CONTACTS,
    496                 Manifest.permission.READ_SMS,
    497                 Manifest.permission.CALL_PHONE,
    498                 Manifest.permission.RECORD_AUDIO,
    499                 Manifest.permission.BODY_SENSORS,
    500                 Manifest.permission.CAMERA
    501         ));
    502 
    503         perms.add(Manifest.permission.READ_EXTERNAL_STORAGE);
    504 
    505         // Grant all permissions
    506         grantPermissions(perms.toArray(new String[perms.size()]));
    507 
    508         // Don't use UI for granting location permission as this shows another dialog
    509         String packageName = InstrumentationRegistry.getTargetContext().getPackageName();
    510         getInstrumentation().getUiAutomation().grantRuntimePermission(packageName,
    511                 Manifest.permission.ACCESS_FINE_LOCATION);
    512         getInstrumentation().getUiAutomation().grantRuntimePermission(packageName,
    513                 Manifest.permission.ACCESS_COARSE_LOCATION);
    514         getInstrumentation().getUiAutomation().grantRuntimePermission(packageName,
    515                 Manifest.permission.ACCESS_BACKGROUND_LOCATION);
    516     }
    517 
    518     @Test
    519     public void testNoResidualPermissionsOnUninstall_part2() throws Exception {
    520         // Make no permissions are granted after uninstalling and installing the app
    521         assertAllPermissionsRevoked();
    522     }
    523 
    524     @Test
    525     public void testRevokePropagatedOnUpgradeOldToNewModel_part2() throws Exception {
    526         assertPermissionsGrantState(new String[] {Manifest.permission.WRITE_CALENDAR},
    527                 PackageManager.PERMISSION_DENIED);
    528     }
    529 
    530     @Test
    531     public void testRevokePropagatedOnUpgradeNewToNewModel_part1() throws Exception {
    532         // Make sure we don't have the permission
    533         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    534                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
    535 
    536         // Request the permission and allow it
    537         BasePermissionActivity.Result thirdResult = requestPermissions(new String[] {
    538                         Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS,
    539                 BasePermissionActivity.class, () -> {
    540                     try {
    541                         clickAllowButton();
    542                         getUiDevice().waitForIdle();
    543                     } catch (Exception e) {
    544                         throw new RuntimeException(e);
    545                     }
    546                 });
    547 
    548         // Make sure the permission is granted
    549         assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS,
    550                 new String[] {Manifest.permission.READ_CALENDAR}, new boolean[] {true});
    551     }
    552 
    553     @Test
    554     public void testRevokePropagatedOnUpgradeNewToNewModel_part2() throws Exception {
    555         // Make sure the permission is still granted after the upgrade
    556         assertPermissionsGrantState(new String[] {Manifest.permission.READ_CALENDAR},
    557                 PackageManager.PERMISSION_GRANTED);
    558         // Also make sure one of the not granted permissions is still not granted
    559         assertPermissionsGrantState(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},
    560                 PackageManager.PERMISSION_DENIED);
    561     }
    562 
    563     @Test
    564     public void testAllPermissionsGrantedOnUpgrade() throws Exception {
    565         assertAllPermissionsGrantState(PackageManager.PERMISSION_GRANTED);
    566     }
    567 
    568     @Test
    569     public void testNullPermissionRequest() throws Exception {
    570         String[] permissions = new String[] {null};
    571 
    572         // Go through normal grant flow
    573         BasePermissionActivity.Result result = requestPermissions(permissions,
    574                 REQUEST_CODE_PERMISSIONS,
    575                 BasePermissionActivity.class,
    576                 () -> { /* empty */ });
    577 
    578         assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
    579                 permissions, new boolean[] {false});
    580     }
    581 
    582     @Test
    583     public void testNullAndRealPermission() throws Exception {
    584         // Make sure we don't have the permissions
    585         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    586                 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
    587         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
    588                 .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
    589 
    590         String[] permissions = new String[] {
    591                 null,
    592                 Manifest.permission.WRITE_CONTACTS,
    593                 null,
    594                 Manifest.permission.RECORD_AUDIO
    595         };
    596 
    597         // Request the permission and allow it
    598         BasePermissionActivity.Result result = requestPermissions(permissions,
    599                 REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, () -> {
    600                     try {
    601                         clickAllowButton();
    602                         getUiDevice().waitForIdle();
    603                         clickAllowButton();
    604                         getUiDevice().waitForIdle();
    605                     } catch (Exception e) {
    606                         throw new RuntimeException(e);
    607                     }
    608                 });
    609 
    610         // Expect the permission are reported as granted
    611         assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
    612                 permissions, new boolean[] {false, true, false, true});
    613 
    614         // The permissions are granted
    615         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
    616                 .checkSelfPermission(Manifest.permission.WRITE_CONTACTS));
    617         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
    618                 .checkSelfPermission(Manifest.permission.RECORD_AUDIO));
    619     }
    620 
    621     @Test
    622     public void testInvalidPermission() throws Exception {
    623         String[] permissions = new String[] {
    624                 getInstrumentation().getContext().getPackageName() + ".abadname"
    625         };
    626 
    627         // Request the permission and allow it
    628         BasePermissionActivity.Result result = requestPermissions(permissions,
    629                 REQUEST_CODE_PERMISSIONS,
    630                 BasePermissionActivity.class,
    631                 () -> { /* empty */ });
    632 
    633         // Expect the permissions is not granted
    634         assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
    635                 permissions, new boolean[] {false});
    636     }
    637 
    638     private void assertAllPermissionsRevoked() {
    639         assertAllPermissionsGrantState(PackageManager.PERMISSION_DENIED);
    640     }
    641 
    642     private void assertAllPermissionsGrantState(int grantState) {
    643         ArrayList<String> perms = new ArrayList<>(Arrays.asList(
    644                 Manifest.permission.SEND_SMS,
    645                 Manifest.permission.RECEIVE_SMS,
    646                 Manifest.permission.RECEIVE_WAP_PUSH,
    647                 Manifest.permission.RECEIVE_MMS,
    648                 Manifest.permission.READ_CALENDAR,
    649                 Manifest.permission.WRITE_CALENDAR,
    650                 Manifest.permission.WRITE_CONTACTS,
    651                 Manifest.permission.READ_SMS,
    652                 Manifest.permission.READ_PHONE_STATE,
    653                 Manifest.permission.READ_CALL_LOG,
    654                 Manifest.permission.WRITE_CALL_LOG,
    655                 Manifest.permission.ADD_VOICEMAIL,
    656                 Manifest.permission.CALL_PHONE,
    657                 Manifest.permission.USE_SIP,
    658                 Manifest.permission.PROCESS_OUTGOING_CALLS,
    659                 Manifest.permission.RECORD_AUDIO,
    660                 Manifest.permission.ACCESS_FINE_LOCATION,
    661                 Manifest.permission.ACCESS_COARSE_LOCATION,
    662                 Manifest.permission.CAMERA,
    663                 Manifest.permission.BODY_SENSORS,
    664                 Manifest.permission.READ_CELL_BROADCASTS,
    665 
    666                 // Split permissions
    667                 Manifest.permission.ACCESS_BACKGROUND_LOCATION
    668         ));
    669 
    670         perms.add(Manifest.permission.READ_EXTERNAL_STORAGE);
    671         perms.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    672         assertPermissionsGrantState(perms.toArray(new String[perms.size()]), grantState);
    673     }
    674 
    675     private void assertPermissionsGrantState(String[] permissions, int grantState) {
    676         for (String permission : permissions) {
    677             assertEquals(grantState, getInstrumentation().getContext()
    678                     .checkSelfPermission(permission));
    679         }
    680     }
    681 
    682     private void denyWithPrejudice() throws Exception {
    683         if (mLeanback || mWatch) {
    684             clickDontAskAgainButton();
    685         } else {
    686             clickDenyAndDontAskAgainButton();
    687         }
    688     }
    689 
    690     /**
    691      * Attempt to insert a new unique calendar item; this might be ignored if
    692      * this legacy app has its permission revoked.
    693      */
    694     private Uri insertCalendarItem() {
    695         final ContentValues values = new ContentValues();
    696         values.put(CalendarContract.Calendars.NAME, "cts" + System.nanoTime());
    697         values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "cts");
    698         values.put(CalendarContract.Calendars.CALENDAR_COLOR, 0xffff0000);
    699         return mContext.getContentResolver().insert(CalendarContract.Calendars.CONTENT_URI, values);
    700     }
    701 }
    702