Home | History | Annotate | Download | only in usespermissiondiffcertapp
      1 /*
      2  * Copyright (C) 2009 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.usespermissiondiffcertapp;
     18 
     19 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_CLEAR_PRIMARY_CLIP;
     20 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_GRANT_URI;
     21 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_REVOKE_URI;
     22 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_SET_PRIMARY_CLIP;
     23 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_START_ACTIVITY;
     24 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_START_SERVICE;
     25 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_VERIFY_OUTGOING_PERSISTED;
     26 import static com.android.cts.permissiondeclareapp.UtilsProvider.EXTRA_INTENT;
     27 import static com.android.cts.permissiondeclareapp.UtilsProvider.EXTRA_MODE;
     28 import static com.android.cts.permissiondeclareapp.UtilsProvider.EXTRA_PACKAGE_NAME;
     29 import static com.android.cts.permissiondeclareapp.UtilsProvider.EXTRA_URI;
     30 
     31 import android.content.ClipData;
     32 import android.content.ClipboardManager;
     33 import android.content.ContentResolver;
     34 import android.content.ContentValues;
     35 import android.content.Intent;
     36 import android.content.UriPermission;
     37 import android.database.Cursor;
     38 import android.net.Uri;
     39 import android.os.Bundle;
     40 import android.provider.CalendarContract;
     41 import android.provider.ContactsContract;
     42 import android.test.AndroidTestCase;
     43 import android.util.Log;
     44 
     45 import androidx.test.InstrumentationRegistry;
     46 
     47 import com.android.cts.permissiondeclareapp.UtilsProvider;
     48 
     49 import java.io.IOException;
     50 import java.util.List;
     51 
     52 /**
     53  * Tests that signature-enforced permissions cannot be accessed by apps signed
     54  * with different certs than app that declares the permission.
     55  *
     56  * Accesses app cts/tests/appsecurity-tests/test-apps/PermissionDeclareApp/...
     57  */
     58 public class AccessPermissionWithDiffSigTest extends AndroidTestCase {
     59     private static final Uri PERM_URI = Uri.parse("content://ctspermissionwithsignature");
     60     private static final Uri PERM_URI_GRANTING = Uri.parse("content://ctspermissionwithsignaturegranting");
     61     private static final Uri PERM_URI_PATH = Uri.parse("content://ctspermissionwithsignaturepath");
     62     private static final Uri PERM_URI_PATH_RESTRICTING = Uri.parse(
     63             "content://ctspermissionwithsignaturepathrestricting");
     64     private static final Uri PRIV_URI = Uri.parse("content://ctsprivateprovider");
     65     private static final Uri PRIV_URI_GRANTING = Uri.parse("content://ctsprivateprovidergranting");
     66     private static final String EXPECTED_MIME_TYPE = "got/theMIME";
     67 
     68     private static final Uri AMBIGUOUS_URI_COMPAT = Uri.parse("content://ctsambiguousprovidercompat");
     69     private static final String EXPECTED_MIME_TYPE_AMBIGUOUS = "got/theUnspecifiedMIME";
     70     private static final Uri AMBIGUOUS_URI = Uri.parse("content://ctsambiguousprovider");
     71 
     72     private static final Uri[] GRANTABLE = new Uri[] {
     73             Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
     74             Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
     75             Uri.withAppendedPath(PERM_URI_PATH, "foo"),
     76     };
     77 
     78     private static final Uri[] NOT_GRANTABLE = new Uri[] {
     79             Uri.withAppendedPath(PERM_URI, "foo"),
     80             Uri.withAppendedPath(PRIV_URI, "foo"),
     81             Uri.withAppendedPath(PERM_URI_PATH_RESTRICTING, "foo"),
     82             CalendarContract.CONTENT_URI,
     83             ContactsContract.AUTHORITY_URI,
     84     };
     85 
     86     @Override
     87     protected void tearDown() throws Exception {
     88         super.tearDown();
     89 
     90         // Always dispose, usually to clean up from failed tests
     91         ReceiveUriActivity.finishCurInstanceSync();
     92     }
     93 
     94     private void assertReadingContentUriNotAllowed(Uri uri, String msg) {
     95         try {
     96             getContext().getContentResolver().query(uri, null, null, null, null);
     97             fail("expected SecurityException reading " + uri + ": " + msg);
     98         } catch (SecurityException expected) {
     99             assertNotNull("security exception's error message.", expected.getMessage());
    100         }
    101     }
    102 
    103     private void assertReadingContentUriAllowed(Uri uri) {
    104         try {
    105             getContext().getContentResolver().query(uri, null, null, null, null);
    106         } catch (SecurityException e) {
    107             fail("unexpected SecurityException reading " + uri + ": " + e.getMessage());
    108         }
    109     }
    110 
    111     private void assertReadingClipNotAllowed(ClipData clip) {
    112         assertReadingClipNotAllowed(clip, null);
    113     }
    114 
    115     private void assertReadingClipNotAllowed(ClipData clip, String msg) {
    116         for (int i=0; i<clip.getItemCount(); i++) {
    117             ClipData.Item item = clip.getItemAt(i);
    118             Uri uri = item.getUri();
    119             if (uri != null) {
    120                 assertReadingContentUriNotAllowed(uri, msg);
    121             } else {
    122                 Intent intent = item.getIntent();
    123                 uri = intent.getData();
    124                 if (uri != null) {
    125                     assertReadingContentUriNotAllowed(uri, msg);
    126                 }
    127                 ClipData intentClip = intent.getClipData();
    128                 if (intentClip != null) {
    129                     assertReadingClipNotAllowed(intentClip, msg);
    130                 }
    131             }
    132         }
    133     }
    134 
    135     private void assertOpenFileDescriptorModeNotAllowed(Uri uri, String msg, String mode) {
    136         try {
    137             getContext().getContentResolver().openFileDescriptor(uri, mode).close();
    138             fail("expected SecurityException writing " + uri + ": " + msg);
    139         } catch (IOException e) {
    140             throw new IllegalStateException(e);
    141         } catch (SecurityException expected) {
    142             assertNotNull("security exception's error message.", expected.getMessage());
    143         }
    144     }
    145 
    146     private void assertContentUriAllowed(Uri uri) {
    147         assertReadingContentUriAllowed(uri);
    148         assertWritingContentUriAllowed(uri);
    149     }
    150 
    151     private void assertContentUriNotAllowed(Uri uri, String msg) {
    152         assertReadingContentUriNotAllowed(uri, msg);
    153         assertWritingContentUriNotAllowed(uri, msg);
    154     }
    155 
    156     private void assertWritingContentUriNotAllowed(Uri uri, String msg) {
    157         final ContentResolver resolver = getContext().getContentResolver();
    158         try {
    159             resolver.insert(uri, new ContentValues());
    160             fail("expected SecurityException inserting " + uri + ": " + msg);
    161         } catch (SecurityException expected) {
    162             assertNotNull("security exception's error message.", expected.getMessage());
    163         }
    164 
    165         try {
    166             resolver.update(uri, new ContentValues(), null, null);
    167             fail("expected SecurityException updating " + uri + ": " + msg);
    168         } catch (SecurityException expected) {
    169             assertNotNull("security exception's error message.", expected.getMessage());
    170         }
    171 
    172         try {
    173             resolver.delete(uri, null, null);
    174             fail("expected SecurityException deleting " + uri + ": " + msg);
    175         } catch (SecurityException expected) {
    176             assertNotNull("security exception's error message.", expected.getMessage());
    177         }
    178 
    179         try {
    180             getContext().getContentResolver().openOutputStream(uri).close();
    181             fail("expected SecurityException writing " + uri + ": " + msg);
    182         } catch (IOException e) {
    183             throw new IllegalStateException(e);
    184         } catch (SecurityException expected) {
    185             assertNotNull("security exception's error message.", expected.getMessage());
    186         }
    187 
    188         assertOpenFileDescriptorModeNotAllowed(uri, msg, "w");
    189         assertOpenFileDescriptorModeNotAllowed(uri, msg, "wt");
    190         assertOpenFileDescriptorModeNotAllowed(uri, msg, "wa");
    191         assertOpenFileDescriptorModeNotAllowed(uri, msg, "rw");
    192         assertOpenFileDescriptorModeNotAllowed(uri, msg, "rwt");
    193     }
    194 
    195     private void assertWritingContentUriAllowed(Uri uri) {
    196         final ContentResolver resolver = getContext().getContentResolver();
    197         try {
    198             resolver.insert(uri, new ContentValues());
    199             resolver.update(uri, new ContentValues(), null, null);
    200             resolver.delete(uri, null, null);
    201 
    202             resolver.openOutputStream(uri).close();
    203             resolver.openFileDescriptor(uri, "w").close();
    204             resolver.openFileDescriptor(uri, "wt").close();
    205             resolver.openFileDescriptor(uri, "wa").close();
    206             resolver.openFileDescriptor(uri, "rw").close();
    207             resolver.openFileDescriptor(uri, "rwt").close();
    208         } catch (IOException e) {
    209             fail("unexpected IOException writing " + uri + ": " + e.getMessage());
    210         } catch (SecurityException e) {
    211             fail("unexpected SecurityException writing " + uri + ": " + e.getMessage());
    212         }
    213     }
    214 
    215     private void assertWritingClipNotAllowed(ClipData clip) {
    216         assertWritingClipNotAllowed(clip, null);
    217     }
    218 
    219     private void assertWritingClipNotAllowed(ClipData clip, String msg) {
    220         for (int i=0; i<clip.getItemCount(); i++) {
    221             ClipData.Item item = clip.getItemAt(i);
    222             Uri uri = item.getUri();
    223             if (uri != null) {
    224                 assertWritingContentUriNotAllowed(uri, msg);
    225             } else {
    226                 Intent intent = item.getIntent();
    227                 uri = intent.getData();
    228                 if (uri != null) {
    229                     assertWritingContentUriNotAllowed(uri, msg);
    230                 }
    231                 ClipData intentClip = intent.getClipData();
    232                 if (intentClip != null) {
    233                     assertWritingClipNotAllowed(intentClip, msg);
    234                 }
    235             }
    236         }
    237     }
    238 
    239     /**
    240      * Test that the ctspermissionwithsignature content provider cannot be read,
    241      * since this app lacks the required certs
    242      */
    243     public void testReadProviderWithDiff() {
    244         assertReadingContentUriRequiresPermission(PERM_URI,
    245                 "com.android.cts.permissionWithSignature");
    246     }
    247 
    248     /**
    249      * Test that the ctspermissionwithsignature content provider cannot be written,
    250      * since this app lacks the required certs
    251      */
    252     public void testWriteProviderWithDiff() {
    253         assertWritingContentUriRequiresPermission(PERM_URI,
    254                 "com.android.cts.permissionWithSignature");
    255     }
    256 
    257     /**
    258      * Test that the ctsprivateprovider content provider cannot be read,
    259      * since it is not exported from its app.
    260      */
    261     public void testReadProviderWhenPrivate() {
    262         assertReadingContentUriNotAllowed(PRIV_URI, "shouldn't read private provider");
    263     }
    264 
    265     /**
    266      * Test that the ctsambiguousprovider content provider cannot be read,
    267      * since it doesn't have an "exported=" line.
    268      */
    269     public void testReadProviderWhenAmbiguous() {
    270         assertReadingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't read ambiguous provider");
    271     }
    272 
    273     /**
    274      * Old App Compatibility Test
    275      *
    276      * Test that the ctsambiguousprovidercompat content provider can be read for older
    277      * API versions, because it didn't specify either exported=true or exported=false.
    278      */
    279     public void testReadProviderWhenAmbiguousCompat() {
    280         assertReadingContentUriAllowed(AMBIGUOUS_URI_COMPAT);
    281     }
    282 
    283     /**
    284      * Old App Compatibility Test
    285      *
    286      * Test that the ctsambiguousprovidercompat content provider can be written for older
    287      * API versions, because it didn't specify either exported=true or exported=false.
    288      */
    289     public void testWriteProviderWhenAmbiguousCompat() {
    290         assertWritingContentUriAllowed(AMBIGUOUS_URI_COMPAT);
    291     }
    292 
    293     /**
    294      * Test that the ctsprivateprovider content provider cannot be written,
    295      * since it is not exported from its app.
    296      */
    297     public void testWriteProviderWhenPrivate() {
    298         assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write private provider");
    299     }
    300 
    301     /**
    302      * Test that the ctsambiguousprovider content provider cannot be written,
    303      * since it doesn't have an exported= line.
    304      */
    305     public void testWriteProviderWhenAmbiguous() {
    306         assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write ambiguous provider");
    307     }
    308 
    309     private static ClipData makeSingleClipData(Uri uri) {
    310         return new ClipData("foo", new String[] { "foo/bar" },
    311                 new ClipData.Item(uri));
    312     }
    313 
    314     private static ClipData makeMultiClipData(Uri uri) {
    315         Uri grantClip1Uri = Uri.withAppendedPath(uri, "clip1");
    316         Uri grantClip2Uri = Uri.withAppendedPath(uri, "clip2");
    317         Uri grantClip3Uri = Uri.withAppendedPath(uri, "clip3");
    318         Uri grantClip4Uri = Uri.withAppendedPath(uri, "clip4");
    319         Uri grantClip5Uri = Uri.withAppendedPath(uri, "clip5");
    320         ClipData clip = new ClipData("foo", new String[] { "foo/bar" },
    321                 new ClipData.Item(grantClip1Uri));
    322         clip.addItem(new ClipData.Item(grantClip2Uri));
    323         // Intents in the ClipData should allow their data: and clip URIs
    324         // to be granted, but only respect the grant flags of the top-level
    325         // Intent.
    326         clip.addItem(new ClipData.Item(new Intent(Intent.ACTION_VIEW, grantClip3Uri)));
    327         Intent intent = new Intent(Intent.ACTION_VIEW, grantClip4Uri);
    328         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
    329                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    330         clip.addItem(new ClipData.Item(intent));
    331         intent = new Intent(Intent.ACTION_VIEW);
    332         intent.setClipData(new ClipData("foo", new String[] { "foo/bar" },
    333                 new ClipData.Item(grantClip5Uri)));
    334         clip.addItem(new ClipData.Item(intent));
    335         return clip;
    336     }
    337 
    338     private static Intent makeClipIntent(ClipData clip, int flags) {
    339         Intent intent = new Intent();
    340         intent.setClipData(clip);
    341         intent.addFlags(flags);
    342         return intent;
    343     }
    344 
    345     private static Intent makeClipIntent(Uri uri, int flags) {
    346         return makeClipIntent(makeMultiClipData(uri), flags);
    347     }
    348 
    349     private void doTryGrantUriActivityPermissionToSelf(Uri uri, int mode) {
    350         Uri grantDataUri = Uri.withAppendedPath(uri, "data");
    351         Intent grantIntent = new Intent();
    352         grantIntent.setData(grantDataUri);
    353         grantIntent.addFlags(mode | Intent.FLAG_ACTIVITY_NEW_TASK);
    354         grantIntent.setClass(getContext(), ReceiveUriActivity.class);
    355         try {
    356             ReceiveUriActivity.clearStarted();
    357             getContext().startActivity(grantIntent);
    358             ReceiveUriActivity.waitForStart();
    359             fail("expected SecurityException granting " + grantDataUri + " to activity");
    360         } catch (SecurityException e) {
    361             // This is what we want.
    362         }
    363 
    364         grantIntent = makeClipIntent(uri, mode | Intent.FLAG_ACTIVITY_NEW_TASK);
    365         grantIntent.setClass(getContext(), ReceiveUriActivity.class);
    366         try {
    367             ReceiveUriActivity.clearStarted();
    368             getContext().startActivity(grantIntent);
    369             ReceiveUriActivity.waitForStart();
    370             fail("expected SecurityException granting " + grantIntent.getClipData() + " to activity");
    371         } catch (SecurityException e) {
    372             // This is what we want.
    373         }
    374     }
    375 
    376     /**
    377      * Test that we can't grant a permission to ourself.
    378      */
    379     public void testGrantReadUriActivityPermissionToSelf() {
    380         doTryGrantUriActivityPermissionToSelf(
    381                 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
    382                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    383     }
    384 
    385     /**
    386      * Test that we can't grant a permission to ourself.
    387      */
    388     public void testGrantWriteUriActivityPermissionToSelf() {
    389         doTryGrantUriActivityPermissionToSelf(
    390                 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
    391                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    392     }
    393 
    394     /**
    395      * Test that we can't grant a permission to ourself.
    396      */
    397     public void testGrantReadUriActivityPrivateToSelf() {
    398         doTryGrantUriActivityPermissionToSelf(
    399                 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
    400                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    401     }
    402 
    403     /**
    404      * Test that we can't grant a permission to ourself.
    405      */
    406     public void testGrantWriteUriActivityPrivateToSelf() {
    407         doTryGrantUriActivityPermissionToSelf(
    408                 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
    409                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    410     }
    411 
    412     private void doTryGrantUriServicePermissionToSelf(Uri uri, int mode) {
    413         Uri grantDataUri = Uri.withAppendedPath(uri, "data");
    414         Intent grantIntent = new Intent();
    415         grantIntent.setData(grantDataUri);
    416         grantIntent.addFlags(mode);
    417         grantIntent.setClass(getContext(), ReceiveUriService.class);
    418         try {
    419             getContext().startService(grantIntent);
    420             fail("expected SecurityException granting " + grantDataUri + " to service");
    421         } catch (SecurityException e) {
    422             // This is what we want.
    423         }
    424 
    425         grantIntent = makeClipIntent(uri, mode);
    426         grantIntent.setClass(getContext(), ReceiveUriService.class);
    427         try {
    428             getContext().startService(grantIntent);
    429             fail("expected SecurityException granting " + grantIntent.getClipData() + " to service");
    430         } catch (SecurityException e) {
    431             // This is what we want.
    432         }
    433     }
    434 
    435     /**
    436      * Test that we can't grant a permission to ourself.
    437      */
    438     public void testGrantReadUriServicePermissionToSelf() {
    439         doTryGrantUriServicePermissionToSelf(
    440                 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
    441                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    442     }
    443 
    444     /**
    445      * Test that we can't grant a permission to ourself.
    446      */
    447     public void testGrantWriteUriServicePermissionToSelf() {
    448         doTryGrantUriServicePermissionToSelf(
    449                 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
    450                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    451     }
    452 
    453     /**
    454      * Test that we can't grant a permission to ourself.
    455      */
    456     public void testGrantReadUriServicePrivateToSelf() {
    457         doTryGrantUriServicePermissionToSelf(
    458                 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
    459                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    460     }
    461 
    462     /**
    463      * Test that we can't grant a permission to ourself.
    464      */
    465     public void testGrantWriteUriServicePrivateToSelf() {
    466         doTryGrantUriServicePermissionToSelf(
    467                 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
    468                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    469     }
    470 
    471     private void grantUriPermissionFail(Uri uri, int mode, boolean service) {
    472         Uri grantDataUri = Uri.withAppendedPath(uri, "data");
    473         Intent grantIntent = new Intent();
    474         grantIntent.setData(grantDataUri);
    475         grantIntent.addFlags(mode);
    476         grantIntent.setClass(getContext(),
    477                 service ? ReceiveUriService.class : ReceiveUriActivity.class);
    478         Intent intent = new Intent();
    479         intent.setAction(service ? ACTION_START_SERVICE : ACTION_START_ACTIVITY);
    480         intent.putExtra(EXTRA_INTENT, grantIntent);
    481         try {
    482             call(intent);
    483             fail("Able to grant URI permission to " + grantDataUri + " when should not");
    484         } catch (Exception expected) {
    485         }
    486 
    487         grantIntent = makeClipIntent(uri, mode);
    488         grantIntent.setClass(getContext(),
    489                 service ? ReceiveUriService.class : ReceiveUriActivity.class);
    490         intent = new Intent();
    491         intent.setAction(service ? ACTION_START_SERVICE : ACTION_START_ACTIVITY);
    492         intent.putExtra(EXTRA_INTENT, grantIntent);
    493         try {
    494             call(intent);
    495             fail("Able to grant URI permission to " + grantIntent.getClipData()
    496                     + " when should not");
    497         } catch (Exception expected) {
    498         }
    499     }
    500 
    501     private void doTestGrantUriPermissionFail(Uri uri) {
    502         for (boolean service : new boolean[] { false, true }) {
    503             for (int flags : new int[] {
    504                     Intent.FLAG_GRANT_READ_URI_PERMISSION, Intent.FLAG_GRANT_WRITE_URI_PERMISSION
    505             }) {
    506                 grantUriPermissionFail(uri,
    507                         flags, service);
    508                 grantUriPermissionFail(uri,
    509                         flags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, service);
    510                 grantUriPermissionFail(uri,
    511                         flags | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, service);
    512             }
    513         }
    514     }
    515 
    516     /**
    517      * Test that the ctspermissionwithsignature content provider can not grant
    518      * URI permissions to others.
    519      */
    520     public void testGrantPermissionNonGrantingFail() {
    521         doTestGrantUriPermissionFail(PERM_URI);
    522     }
    523 
    524     /**
    525      * Test that the ctspermissionwithsignaturegranting content provider can not grant
    526      * URI permissions to paths outside of the grant tree
    527      */
    528     public void testGrantPermissionOutsideGrantingFail() {
    529         doTestGrantUriPermissionFail(PERM_URI_GRANTING);
    530         doTestGrantUriPermissionFail(Uri.withAppendedPath(PERM_URI_GRANTING, "invalid"));
    531     }
    532 
    533     /**
    534      * Test that the ctsprivateprovider content provider can not grant
    535      * URI permissions to others.
    536      */
    537     public void testGrantPrivateNonGrantingFail() {
    538         doTestGrantUriPermissionFail(PRIV_URI);
    539     }
    540 
    541     /**
    542      * Test that the ctsambiguousprovider content provider can not grant
    543      * URI permissions to others.
    544      */
    545     public void testGrantAmbiguousNonGrantingFail() {
    546         doTestGrantUriPermissionFail(AMBIGUOUS_URI);
    547     }
    548 
    549     /**
    550      * Test that the ctsprivateprovidergranting content provider can not grant
    551      * URI permissions to paths outside of the grant tree
    552      */
    553     public void testGrantPrivateOutsideGrantingFail() {
    554         doTestGrantUriPermissionFail(PRIV_URI_GRANTING);
    555         doTestGrantUriPermissionFail(Uri.withAppendedPath(PRIV_URI_GRANTING, "invalid"));
    556     }
    557 
    558     private void call(Intent intent) {
    559         final Bundle extras = new Bundle();
    560         extras.putParcelable(Intent.EXTRA_INTENT, intent);
    561         getContext().getContentResolver().call(UtilsProvider.URI, "", "", extras);
    562     }
    563 
    564     private void grantClipUriPermission(ClipData clip, int mode, boolean service) {
    565         Intent grantIntent = new Intent();
    566         if (clip.getItemCount() == 1) {
    567             grantIntent.setData(clip.getItemAt(0).getUri());
    568         } else {
    569             grantIntent.setClipData(clip);
    570             // Make this Intent unique from the one that started it.
    571             for (int i=0; i<clip.getItemCount(); i++) {
    572                 Uri uri = clip.getItemAt(i).getUri();
    573                 if (uri != null) {
    574                     grantIntent.addCategory(uri.toString());
    575                 }
    576             }
    577         }
    578         grantIntent.addFlags(mode);
    579         grantIntent.setClass(getContext(),
    580                 service ? ReceiveUriService.class : ReceiveUriActivity.class);
    581         Intent intent = new Intent();
    582         intent.setAction(service ? ACTION_START_SERVICE : ACTION_START_ACTIVITY);
    583         intent.putExtra(EXTRA_INTENT, grantIntent);
    584         call(intent);
    585     }
    586 
    587     private void grantClipUriPermissionViaContext(Uri uri, int mode) {
    588         Intent intent = new Intent();
    589         intent.setAction(ACTION_GRANT_URI);
    590         intent.putExtra(EXTRA_PACKAGE_NAME, getContext().getPackageName());
    591         intent.putExtra(EXTRA_URI, uri);
    592         intent.putExtra(EXTRA_MODE, mode);
    593         call(intent);
    594     }
    595 
    596     private void revokeClipUriPermissionViaContext(Uri uri, int mode) {
    597         Intent intent = new Intent();
    598         intent.setAction(ACTION_REVOKE_URI);
    599         intent.putExtra(EXTRA_URI, uri);
    600         intent.putExtra(EXTRA_MODE, mode);
    601         call(intent);
    602     }
    603 
    604     private void setPrimaryClip(ClipData clip) {
    605         Intent intent = new Intent();
    606         intent.setAction(ACTION_SET_PRIMARY_CLIP);
    607         intent.setClipData(clip);
    608         call(intent);
    609     }
    610 
    611     private void clearPrimaryClip() {
    612         Intent intent = new Intent();
    613         intent.setAction(ACTION_CLEAR_PRIMARY_CLIP);
    614         call(intent);
    615     }
    616 
    617     private void assertReadingClipAllowed(ClipData clip) {
    618         for (int i=0; i<clip.getItemCount(); i++) {
    619             ClipData.Item item = clip.getItemAt(i);
    620             Uri uri = item.getUri();
    621             if (uri != null) {
    622                 Cursor c = getContext().getContentResolver().query(uri,
    623                         null, null, null, null);
    624                 if (c != null) {
    625                     c.close();
    626                 }
    627             } else {
    628                 Intent intent = item.getIntent();
    629                 uri = intent.getData();
    630                 if (uri != null) {
    631                     Cursor c = getContext().getContentResolver().query(uri,
    632                             null, null, null, null);
    633                     if (c != null) {
    634                         c.close();
    635                     }
    636                 }
    637                 ClipData intentClip = intent.getClipData();
    638                 if (intentClip != null) {
    639                     assertReadingClipAllowed(intentClip);
    640                 }
    641             }
    642         }
    643     }
    644 
    645     private void doTestGrantActivityUriReadPermission(Uri uri, boolean useClip) {
    646         final Uri subUri = Uri.withAppendedPath(uri, "foo");
    647         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
    648         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
    649         final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
    650 
    651         final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri);
    652         final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri);
    653 
    654         // Precondition: no current access.
    655         assertReadingClipNotAllowed(subClip, "shouldn't read when starting test");
    656         assertReadingClipNotAllowed(sub2Clip, "shouldn't read when starting test");
    657 
    658         // --------------------------------
    659 
    660         ReceiveUriActivity.clearStarted();
    661         grantClipUriPermission(subClip, Intent.FLAG_GRANT_READ_URI_PERMISSION, false);
    662         ReceiveUriActivity.waitForStart();
    663 
    664         // See if we now have access to the provider.
    665         assertReadingClipAllowed(subClip);
    666 
    667         // But not writing.
    668         assertWritingClipNotAllowed(subClip, "shouldn't write from granted read");
    669 
    670         // And not to the base path.
    671         assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
    672 
    673         // And not to a sub path.
    674         assertReadingContentUriNotAllowed(subSubUri, "shouldn't read non-granted sub URI");
    675 
    676         // --------------------------------
    677 
    678         ReceiveUriActivity.clearNewIntent();
    679         grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_READ_URI_PERMISSION, false);
    680         ReceiveUriActivity.waitForNewIntent();
    681 
    682         if (false) {
    683             synchronized (this) {
    684                 Log.i("**", "******************************* WAITING!!!");
    685                 try {
    686                     wait(10000);
    687                 } catch (InterruptedException e) {
    688                 }
    689             }
    690         }
    691 
    692         // See if we now have access to the provider.
    693         assertReadingClipAllowed(sub2Clip);
    694 
    695         // And still have access to the original URI.
    696         assertReadingClipAllowed(subClip);
    697 
    698         // But not writing.
    699         assertWritingClipNotAllowed(sub2Clip, "shouldn't write from granted read");
    700 
    701         // And not to the base path.
    702         assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
    703 
    704         // And not to a sub path.
    705         assertReadingContentUriNotAllowed(sub2SubUri, "shouldn't read non-granted sub URI");
    706 
    707         // And make sure we can't generate a permission to a running activity.
    708         doTryGrantUriActivityPermissionToSelf(
    709                 Uri.withAppendedPath(uri, "hah"),
    710                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    711         doTryGrantUriActivityPermissionToSelf(
    712                 Uri.withAppendedPath(uri, "hah"),
    713                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    714 
    715         // --------------------------------
    716 
    717         // Dispose of activity.
    718         ReceiveUriActivity.finishCurInstanceSync();
    719 
    720         synchronized (this) {
    721             Log.i("**", "******************************* WAITING!!!");
    722             try {
    723                 wait(100);
    724             } catch (InterruptedException e) {
    725             }
    726         }
    727 
    728         // Ensure reading no longer allowed.
    729         assertReadingClipNotAllowed(subClip, "shouldn't read after losing granted URI");
    730         assertReadingClipNotAllowed(sub2Clip, "shouldn't read after losing granted URI");
    731     }
    732 
    733     private void assertWritingClipAllowed(ClipData clip) {
    734         for (int i=0; i<clip.getItemCount(); i++) {
    735             ClipData.Item item = clip.getItemAt(i);
    736             Uri uri = item.getUri();
    737             if (uri != null) {
    738                 getContext().getContentResolver().insert(uri, new ContentValues());
    739             } else {
    740                 Intent intent = item.getIntent();
    741                 uri = intent.getData();
    742                 if (uri != null) {
    743                     getContext().getContentResolver().insert(uri, new ContentValues());
    744                 }
    745                 ClipData intentClip = intent.getClipData();
    746                 if (intentClip != null) {
    747                     assertWritingClipAllowed(intentClip);
    748                 }
    749             }
    750         }
    751     }
    752 
    753     private void doTestGrantActivityUriWritePermission(Uri uri, boolean useClip) {
    754         final Uri subUri = Uri.withAppendedPath(uri, "foo");
    755         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
    756         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
    757         final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
    758 
    759         final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri);
    760         final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri);
    761 
    762         // Precondition: no current access.
    763         assertWritingClipNotAllowed(subClip, "shouldn't write when starting test");
    764         assertWritingClipNotAllowed(sub2Clip, "shouldn't write when starting test");
    765 
    766         // --------------------------------
    767 
    768         ReceiveUriActivity.clearStarted();
    769         grantClipUriPermission(subClip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
    770         ReceiveUriActivity.waitForStart();
    771 
    772         // See if we now have access to the provider.
    773         assertWritingClipAllowed(subClip);
    774 
    775         // But not reading.
    776         assertReadingClipNotAllowed(subClip, "shouldn't read from granted write");
    777 
    778         // And not to the base path.
    779         assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
    780 
    781         // And not a sub-path.
    782         assertWritingContentUriNotAllowed(subSubUri, "shouldn't write non-granted sub URI");
    783 
    784         // --------------------------------
    785 
    786         ReceiveUriActivity.clearNewIntent();
    787         grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
    788         ReceiveUriActivity.waitForNewIntent();
    789 
    790         if (false) {
    791             synchronized (this) {
    792                 Log.i("**", "******************************* WAITING!!!");
    793                 try {
    794                     wait(10000);
    795                 } catch (InterruptedException e) {
    796                 }
    797             }
    798         }
    799 
    800         // See if we now have access to the provider.
    801         assertWritingClipAllowed(sub2Clip);
    802 
    803         // And still have access to the original URI.
    804         assertWritingClipAllowed(subClip);
    805 
    806         // But not reading.
    807         assertReadingClipNotAllowed(sub2Clip, "shouldn't read from granted write");
    808 
    809         // And not to the base path.
    810         assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
    811 
    812         // And not a sub-path.
    813         assertWritingContentUriNotAllowed(sub2SubUri, "shouldn't write non-granted sub URI");
    814 
    815         // And make sure we can't generate a permission to a running activity.
    816         doTryGrantUriActivityPermissionToSelf(
    817                 Uri.withAppendedPath(uri, "hah"),
    818                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    819         doTryGrantUriActivityPermissionToSelf(
    820                 Uri.withAppendedPath(uri, "hah"),
    821                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    822 
    823         // --------------------------------
    824 
    825         // Dispose of activity.
    826         ReceiveUriActivity.finishCurInstanceSync();
    827 
    828         synchronized (this) {
    829             Log.i("**", "******************************* WAITING!!!");
    830             try {
    831                 wait(100);
    832             } catch (InterruptedException e) {
    833             }
    834         }
    835 
    836         // Ensure writing no longer allowed.
    837         assertWritingClipNotAllowed(subClip, "shouldn't write after losing granted URI");
    838         assertWritingClipNotAllowed(sub2Clip, "shouldn't write after losing granted URI");
    839     }
    840 
    841     /**
    842      * Test that the ctspermissionwithsignaturegranting content provider can grant a read
    843      * permission.
    844      */
    845     public void testGrantReadPermissionFromStartActivity() {
    846         doTestGrantActivityUriReadPermission(PERM_URI_GRANTING, false);
    847         doTestGrantActivityUriReadPermission(PERM_URI_GRANTING, true);
    848     }
    849 
    850     /**
    851      * Test that the ctspermissionwithsignaturegranting content provider can grant a write
    852      * permission.
    853      */
    854     public void testGrantWritePermissionFromStartActivity() {
    855         doTestGrantActivityUriWritePermission(PERM_URI_GRANTING, true);
    856         doTestGrantActivityUriWritePermission(PERM_URI_GRANTING, false);
    857     }
    858 
    859     /**
    860      * Test that the ctsprivateprovidergranting content provider can grant a read
    861      * permission.
    862      */
    863     public void testGrantReadPrivateFromStartActivity() {
    864         doTestGrantActivityUriReadPermission(PRIV_URI_GRANTING, false);
    865         doTestGrantActivityUriReadPermission(PRIV_URI_GRANTING, true);
    866     }
    867 
    868     /**
    869      * Test that the ctsprivateprovidergranting content provider can grant a write
    870      * permission.
    871      */
    872     public void testGrantWritePrivateFromStartActivity() {
    873         doTestGrantActivityUriWritePermission(PRIV_URI_GRANTING, true);
    874         doTestGrantActivityUriWritePermission(PRIV_URI_GRANTING, false);
    875     }
    876 
    877     private void doTestGrantServiceUriReadPermission(Uri uri, boolean useClip) {
    878         final Uri subUri = Uri.withAppendedPath(uri, "foo");
    879         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
    880         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
    881         final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
    882 
    883         ReceiveUriService.stop(getContext());
    884 
    885         final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri);
    886         final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri);
    887 
    888         // Precondition: no current access.
    889         assertReadingClipNotAllowed(subClip, "shouldn't read when starting test");
    890         assertReadingClipNotAllowed(sub2Clip, "shouldn't read when starting test");
    891 
    892         // --------------------------------
    893 
    894         ReceiveUriService.clearStarted();
    895         grantClipUriPermission(subClip, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    896         ReceiveUriService.waitForStart();
    897 
    898         int firstStartId = ReceiveUriService.getCurStartId();
    899 
    900         // See if we now have access to the provider.
    901         assertReadingClipAllowed(subClip);
    902 
    903         // But not writing.
    904         assertWritingClipNotAllowed(subClip, "shouldn't write from granted read");
    905 
    906         // And not to the base path.
    907         assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
    908 
    909         // And not to a sub path.
    910         assertReadingContentUriNotAllowed(subSubUri, "shouldn't read non-granted sub URI");
    911 
    912         // --------------------------------
    913 
    914         // Send another Intent to it.
    915         ReceiveUriService.clearStarted();
    916         grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    917         ReceiveUriService.waitForStart();
    918 
    919         if (false) {
    920             synchronized (this) {
    921                 Log.i("**", "******************************* WAITING!!!");
    922                 try {
    923                     wait(10000);
    924                 } catch (InterruptedException e) {
    925                 }
    926             }
    927         }
    928 
    929         // See if we now have access to the provider.
    930         assertReadingClipAllowed(sub2Clip);
    931 
    932         // And still to the previous URI.
    933         assertReadingClipAllowed(subClip);
    934 
    935         // But not writing.
    936         assertWritingClipNotAllowed(sub2Clip, "shouldn't write from granted read");
    937 
    938         // And not to the base path.
    939         assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
    940 
    941         // And not to a sub path.
    942         assertReadingContentUriNotAllowed(sub2SubUri, "shouldn't read non-granted sub URI");
    943 
    944         // --------------------------------
    945 
    946         // Stop the first command.
    947         ReceiveUriService.stopCurWithId(firstStartId);
    948 
    949         // Ensure reading no longer allowed.
    950         assertReadingClipNotAllowed(subClip, "shouldn't read after losing granted URI");
    951 
    952         // And make sure we can't generate a permission to a running service.
    953         doTryGrantUriActivityPermissionToSelf(subUri,
    954                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    955         doTryGrantUriActivityPermissionToSelf(subUri,
    956                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    957 
    958         // --------------------------------
    959 
    960         // Dispose of service.
    961         ReceiveUriService.stopSync(getContext());
    962 
    963         // Ensure reading no longer allowed.
    964         assertReadingClipNotAllowed(subClip, "shouldn't read after losing granted URI");
    965         assertReadingClipNotAllowed(sub2Clip, "shouldn't read after losing granted URI");
    966     }
    967 
    968     private void doTestGrantServiceUriWritePermission(Uri uri, boolean useClip) {
    969         final Uri subUri = Uri.withAppendedPath(uri, "foo");
    970         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
    971         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
    972         final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
    973 
    974         ReceiveUriService.stop(getContext());
    975 
    976         final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri);
    977         final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri);
    978 
    979         // Precondition: no current access.
    980         assertReadingClipNotAllowed(subClip, "shouldn't read when starting test");
    981         assertReadingClipNotAllowed(sub2Clip, "shouldn't read when starting test");
    982 
    983         // --------------------------------
    984 
    985         ReceiveUriService.clearStarted();
    986         grantClipUriPermission(subClip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
    987         ReceiveUriService.waitForStart();
    988 
    989         int firstStartId = ReceiveUriService.getCurStartId();
    990 
    991         // See if we now have access to the provider.
    992         assertWritingClipAllowed(subClip);
    993 
    994         // But not reading.
    995         assertReadingClipNotAllowed(subClip, "shouldn't read from granted write");
    996 
    997         // And not to the base path.
    998         assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
    999 
   1000         // And not a sub-path.
   1001         assertWritingContentUriNotAllowed(subSubUri, "shouldn't write non-granted sub URI");
   1002 
   1003         // --------------------------------
   1004 
   1005         // Send another Intent to it.
   1006         ReceiveUriService.clearStarted();
   1007         grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
   1008         ReceiveUriService.waitForStart();
   1009 
   1010         // See if we now have access to the provider.
   1011         assertWritingClipAllowed(sub2Clip);
   1012 
   1013         // And still to the previous URI.
   1014         assertWritingClipAllowed(subClip);
   1015 
   1016         // But not reading.
   1017         assertReadingClipNotAllowed(sub2Clip, "shouldn't read from granted write");
   1018 
   1019         // And not to the base path.
   1020         assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
   1021 
   1022         // And not a sub-path.
   1023         assertWritingContentUriNotAllowed(sub2SubUri, "shouldn't write non-granted sub URI");
   1024 
   1025         if (false) {
   1026             synchronized (this) {
   1027                 Log.i("**", "******************************* WAITING!!!");
   1028                 try {
   1029                     wait(10000);
   1030                 } catch (InterruptedException e) {
   1031                 }
   1032             }
   1033         }
   1034 
   1035         // --------------------------------
   1036 
   1037         // Stop the first command.
   1038         ReceiveUriService.stopCurWithId(firstStartId);
   1039 
   1040         // Ensure writing no longer allowed.
   1041         assertWritingClipNotAllowed(subClip, "shouldn't write after losing granted URI");
   1042 
   1043         // And make sure we can't generate a permission to a running service.
   1044         doTryGrantUriActivityPermissionToSelf(subUri,
   1045                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1046         doTryGrantUriActivityPermissionToSelf(subUri,
   1047                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1048 
   1049         // --------------------------------
   1050 
   1051         // Dispose of service.
   1052         ReceiveUriService.stopSync(getContext());
   1053 
   1054         // Ensure writing no longer allowed.
   1055         assertWritingClipNotAllowed(subClip, "shouldn't write after losing granted URI");
   1056         assertWritingClipNotAllowed(sub2Clip, "shouldn't write after losing granted URI");
   1057     }
   1058 
   1059     public void testGrantReadPermissionFromStartService() {
   1060         doTestGrantServiceUriReadPermission(PERM_URI_GRANTING, false);
   1061         doTestGrantServiceUriReadPermission(PERM_URI_GRANTING, true);
   1062     }
   1063 
   1064     public void testGrantWritePermissionFromStartService() {
   1065         doTestGrantServiceUriWritePermission(PERM_URI_GRANTING, false);
   1066         doTestGrantServiceUriWritePermission(PERM_URI_GRANTING, true);
   1067     }
   1068 
   1069     public void testGrantReadPrivateFromStartService() {
   1070         doTestGrantServiceUriReadPermission(PRIV_URI_GRANTING, false);
   1071         doTestGrantServiceUriReadPermission(PRIV_URI_GRANTING, true);
   1072     }
   1073 
   1074     public void testGrantWritePrivateFromStartService() {
   1075         doTestGrantServiceUriWritePermission(PRIV_URI_GRANTING, false);
   1076         doTestGrantServiceUriWritePermission(PRIV_URI_GRANTING, true);
   1077     }
   1078 
   1079     /**
   1080      * Test that ctspermissionwithsignaturepath can't grant read permissions
   1081      * on paths it doesn't have permission to.
   1082      */
   1083     public void testGrantReadUriActivityPathPermissionToSelf() {
   1084         doTryGrantUriActivityPermissionToSelf(PERM_URI_PATH,
   1085                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1086     }
   1087 
   1088     /**
   1089      * Test that ctspermissionwithsignaturepath can't grant write permissions
   1090      * on paths it doesn't have permission to.
   1091      */
   1092     public void testGrantWriteUriActivityPathPermissionToSelf() {
   1093         doTryGrantUriActivityPermissionToSelf(PERM_URI_PATH,
   1094                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1095     }
   1096 
   1097     /**
   1098      * Test that ctspermissionwithsignaturepath can't grant read permissions
   1099      * on paths it doesn't have permission to.
   1100      */
   1101     public void testGrantReadUriActivitySubPathPermissionToSelf() {
   1102         doTryGrantUriActivityPermissionToSelf(
   1103                 Uri.withAppendedPath(PERM_URI_PATH, "foo"),
   1104                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1105     }
   1106 
   1107     /**
   1108      * Test that ctspermissionwithsignaturepath can't grant write permissions
   1109      * on paths it doesn't have permission to.
   1110      */
   1111     public void testGrantWriteUriActivitySubPathPermissionToSelf() {
   1112         doTryGrantUriActivityPermissionToSelf(
   1113                 Uri.withAppendedPath(PERM_URI_PATH, "foo"),
   1114                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1115     }
   1116 
   1117     /**
   1118      * Test that the ctspermissionwithsignaturepath content provider can grant a read
   1119      * permission.
   1120      */
   1121     public void testGrantReadPathPermissionFromStartActivity() {
   1122         doTestGrantActivityUriReadPermission(PERM_URI_PATH, false);
   1123         doTestGrantActivityUriReadPermission(PERM_URI_PATH, true);
   1124     }
   1125 
   1126     /**
   1127      * Test that the ctspermissionwithsignaturepath content provider can grant a write
   1128      * permission.
   1129      */
   1130     public void testGrantWritePathPermissionFromStartActivity() {
   1131         doTestGrantActivityUriWritePermission(PERM_URI_PATH, false);
   1132         doTestGrantActivityUriWritePermission(PERM_URI_PATH, true);
   1133     }
   1134 
   1135     /**
   1136      * Test that the ctspermissionwithsignaturepath content provider can grant a read
   1137      * permission.
   1138      */
   1139     public void testGrantReadPathPermissionFromStartService() {
   1140         doTestGrantServiceUriReadPermission(PERM_URI_PATH, false);
   1141         doTestGrantServiceUriReadPermission(PERM_URI_PATH, true);
   1142     }
   1143 
   1144     /**
   1145      * Test that the ctspermissionwithsignaturepath content provider can grant a write
   1146      * permission.
   1147      */
   1148     public void testGrantWritePathPermissionFromStartService() {
   1149         doTestGrantServiceUriWritePermission(PERM_URI_PATH, false);
   1150         doTestGrantServiceUriWritePermission(PERM_URI_PATH, true);
   1151     }
   1152 
   1153     /**
   1154      * Verify that we can access paths outside the {@code path-permission}
   1155      * protections, which should only rely on {@code provider} permissions.
   1156      */
   1157     public void testRestrictingProviderNoMatchingPath() {
   1158         assertReadingContentUriAllowed(PERM_URI_PATH_RESTRICTING);
   1159         assertWritingContentUriAllowed(PERM_URI_PATH_RESTRICTING);
   1160 
   1161         // allowed by no top-level permission
   1162         final Uri test = PERM_URI_PATH_RESTRICTING.buildUpon().appendPath("fo").build();
   1163         assertReadingContentUriAllowed(test);
   1164         assertWritingContentUriAllowed(test);
   1165     }
   1166 
   1167     /**
   1168      * Verify that paths under {@code path-permission} restriction aren't
   1169      * allowed, even though the {@code provider} requires no permissions.
   1170      */
   1171     public void testRestrictingProviderMatchingPathDenied() {
   1172         // rejected by "foo" prefix
   1173         final Uri test1 = PERM_URI_PATH_RESTRICTING.buildUpon().appendPath("foo").build();
   1174         assertReadingContentUriNotAllowed(test1, null);
   1175         assertWritingContentUriNotAllowed(test1, null);
   1176 
   1177         // rejected by "foo" prefix
   1178         final Uri test2 = PERM_URI_PATH_RESTRICTING.buildUpon()
   1179                 .appendPath("foo").appendPath("ba").build();
   1180         assertReadingContentUriNotAllowed(test2, null);
   1181         assertWritingContentUriNotAllowed(test2, null);
   1182     }
   1183 
   1184     /**
   1185      * Test that shady {@link Uri} are blocked by {@code path-permission}.
   1186      */
   1187     public void testRestrictingProviderMatchingShadyPaths() {
   1188         assertContentUriAllowed(
   1189                 Uri.parse("content://ctspermissionwithsignaturepathrestricting/"));
   1190         assertContentUriAllowed(
   1191                 Uri.parse("content://ctspermissionwithsignaturepathrestricting//"));
   1192         assertContentUriAllowed(
   1193                 Uri.parse("content://ctspermissionwithsignaturepathrestricting///"));
   1194         assertContentUriNotAllowed(
   1195                 Uri.parse("content://ctspermissionwithsignaturepathrestricting/foo"), null);
   1196         assertContentUriNotAllowed(
   1197                 Uri.parse("content://ctspermissionwithsignaturepathrestricting//foo"), null);
   1198         assertContentUriNotAllowed(
   1199                 Uri.parse("content://ctspermissionwithsignaturepathrestricting///foo"), null);
   1200         assertContentUriNotAllowed(
   1201                 Uri.parse("content://ctspermissionwithsignaturepathrestricting/foo//baz"), null);
   1202     }
   1203 
   1204     /**
   1205      * Verify that at least one {@code path-permission} rule will grant access,
   1206      * even if the caller doesn't hold another matching {@code path-permission}.
   1207      */
   1208     public void testRestrictingProviderMultipleMatchingPath() {
   1209         // allowed by narrow "foo/bar" prefix
   1210         final Uri test1 = PERM_URI_PATH_RESTRICTING.buildUpon()
   1211                 .appendPath("foo").appendPath("bar").build();
   1212         assertReadingContentUriAllowed(test1);
   1213         assertWritingContentUriAllowed(test1);
   1214 
   1215         // allowed by narrow "foo/bar" prefix
   1216         final Uri test2 = PERM_URI_PATH_RESTRICTING.buildUpon()
   1217                 .appendPath("foo").appendPath("bar2").build();
   1218         assertReadingContentUriAllowed(test2);
   1219         assertWritingContentUriAllowed(test2);
   1220     }
   1221 
   1222     public void testGetMimeTypePermission() {
   1223         // Precondition: no current access.
   1224         assertReadingContentUriNotAllowed(PERM_URI, "shouldn't read when starting test");
   1225         assertWritingContentUriNotAllowed(PERM_URI, "shouldn't write when starting test");
   1226 
   1227         // All apps should be able to get MIME type regardless of permission.
   1228         assertEquals(getContext().getContentResolver().getType(PERM_URI), EXPECTED_MIME_TYPE);
   1229     }
   1230 
   1231     public void testGetMimeTypePrivate() {
   1232         // Precondition: no current access.
   1233         assertReadingContentUriNotAllowed(PRIV_URI, "shouldn't read when starting test");
   1234         assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write when starting test");
   1235 
   1236         // All apps should be able to get MIME type even if provider is private.
   1237         assertEquals(getContext().getContentResolver().getType(PRIV_URI), EXPECTED_MIME_TYPE);
   1238     }
   1239 
   1240     public void testGetMimeTypeAmbiguous() {
   1241         // Precondition: no current access.
   1242         assertReadingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't read when starting test");
   1243         assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write when starting test");
   1244 
   1245         // All apps should be able to get MIME type even if provider is private.
   1246         assertEquals(getContext().getContentResolver().getType(AMBIGUOUS_URI), EXPECTED_MIME_TYPE);
   1247     }
   1248 
   1249     /**
   1250      * Old App Compatibility Test
   1251      *
   1252      * We should be able to access the mime type of a content provider of an older
   1253      * application, even if that application didn't explicitly declare either
   1254      * exported=true or exported=false
   1255      */
   1256     public void testGetMimeTypeAmbiguousCompat() {
   1257         // All apps should be able to get MIME type even if provider is private.
   1258         assertEquals(EXPECTED_MIME_TYPE_AMBIGUOUS,
   1259                 getContext().getContentResolver().getType(AMBIGUOUS_URI_COMPAT));
   1260     }
   1261 
   1262     /**
   1263      * Validate behavior of persistable permission grants.
   1264      */
   1265     public void testGrantPersistableUriPermission() {
   1266         final ContentResolver resolver = getContext().getContentResolver();
   1267 
   1268         final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo");
   1269         final ClipData clip = makeSingleClipData(target);
   1270 
   1271         // Make sure we can't see the target
   1272         assertReadingClipNotAllowed(clip, "reading should have failed");
   1273         assertWritingClipNotAllowed(clip, "writing should have failed");
   1274 
   1275         // Make sure we can't take a grant we don't have
   1276         try {
   1277             resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1278             fail("taking read should have failed");
   1279         } catch (SecurityException expected) {
   1280         }
   1281 
   1282         // And since we were just installed, no persisted grants yet
   1283         assertNoPersistedUriPermission();
   1284 
   1285         // Now, let's grant ourselves some access
   1286         ReceiveUriActivity.clearStarted();
   1287         grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
   1288                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   1289         ReceiveUriActivity.waitForStart();
   1290 
   1291         // We should now have reading access, even before taking the persistable
   1292         // grant. Persisted grants should still be empty.
   1293         assertReadingClipAllowed(clip);
   1294         assertWritingClipNotAllowed(clip, "writing should have failed");
   1295         assertNoPersistedUriPermission();
   1296 
   1297         // Take the read grant and verify we have it!
   1298         long before = System.currentTimeMillis();
   1299         resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1300         long after = System.currentTimeMillis();
   1301         assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after);
   1302 
   1303         // Make sure we can't take a grant we don't have
   1304         try {
   1305             resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1306             fail("taking write should have failed");
   1307         } catch (SecurityException expected) {
   1308         }
   1309 
   1310         // Launch again giving ourselves persistable read and write access
   1311         ReceiveUriActivity.clearNewIntent();
   1312         grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
   1313                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   1314                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   1315         ReceiveUriActivity.waitForNewIntent();
   1316 
   1317         // Previous persisted grant should be unchanged
   1318         assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after);
   1319 
   1320         // We should have both read and write; read is persisted, and write
   1321         // isn't persisted yet.
   1322         assertReadingClipAllowed(clip);
   1323         assertWritingClipAllowed(clip);
   1324 
   1325         // Take again, but still only read; should just update timestamp
   1326         before = System.currentTimeMillis();
   1327         resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1328         after = System.currentTimeMillis();
   1329         assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after);
   1330 
   1331         // And take yet again, both read and write
   1332         before = System.currentTimeMillis();
   1333         resolver.takePersistableUriPermission(target,
   1334                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1335         after = System.currentTimeMillis();
   1336         assertPersistedUriPermission(target,
   1337                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   1338                 before, after);
   1339 
   1340         // Now drop the persisted grant; write first, then read
   1341         resolver.releasePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1342         assertPersistedUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, before, after);
   1343         resolver.releasePersistableUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1344         assertNoPersistedUriPermission();
   1345 
   1346         // And even though we dropped the persistable grants, our activity is
   1347         // still running with the global grants (until reboot).
   1348         assertReadingClipAllowed(clip);
   1349         assertWritingClipAllowed(clip);
   1350 
   1351         ReceiveUriActivity.finishCurInstanceSync();
   1352     }
   1353 
   1354     private void assertNoPersistedUriPermission() {
   1355         assertPersistedUriPermission(null, 0, -1, -1);
   1356     }
   1357 
   1358     private void assertPersistedUriPermission(Uri uri, int flags, long before, long after) {
   1359         // Assert local
   1360         final List<UriPermission> perms = getContext()
   1361                 .getContentResolver().getPersistedUriPermissions();
   1362         if (uri != null) {
   1363             assertEquals("expected exactly one permission", 1, perms.size());
   1364 
   1365             final UriPermission perm = perms.get(0);
   1366             assertEquals("unexpected uri", uri, perm.getUri());
   1367 
   1368             final long actual = perm.getPersistedTime();
   1369             if (before != -1) {
   1370                 assertTrue("found " + actual + " before " + before, actual >= before);
   1371             }
   1372             if (after != -1) {
   1373                 assertTrue("found " + actual + " after " + after, actual <= after);
   1374             }
   1375 
   1376             final boolean expectedRead = (flags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0;
   1377             final boolean expectedWrite = (flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0;
   1378             assertEquals("unexpected read status", expectedRead, perm.isReadPermission());
   1379             assertEquals("unexpected write status", expectedWrite, perm.isWritePermission());
   1380 
   1381         } else {
   1382             assertEquals("expected zero permissions", 0, perms.size());
   1383         }
   1384 
   1385         // And assert remote
   1386         Intent intent = new Intent();
   1387         intent.setAction(ACTION_VERIFY_OUTGOING_PERSISTED);
   1388         intent.putExtra(EXTRA_URI, uri);
   1389         call(intent);
   1390     }
   1391 
   1392     /**
   1393      * Validate behavior of prefix permission grants.
   1394      */
   1395     public void testGrantPrefixUriPermission() throws Exception {
   1396         final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo1");
   1397         final Uri targetMeow = Uri.withAppendedPath(target, "meow");
   1398         final Uri targetMeowCat = Uri.withAppendedPath(targetMeow, "cat");
   1399 
   1400         final ClipData clip = makeSingleClipData(target);
   1401         final ClipData clipMeow = makeSingleClipData(targetMeow);
   1402         final ClipData clipMeowCat = makeSingleClipData(targetMeowCat);
   1403 
   1404         // Make sure we can't see the target
   1405         assertReadingClipNotAllowed(clip, "reading should have failed");
   1406         assertWritingClipNotAllowed(clip, "writing should have failed");
   1407 
   1408         // Give ourselves prefix read access
   1409         ReceiveUriActivity.clearStarted();
   1410         grantClipUriPermission(clipMeow, Intent.FLAG_GRANT_READ_URI_PERMISSION
   1411                 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
   1412         ReceiveUriActivity.waitForStart();
   1413 
   1414         // Verify prefix read access
   1415         assertReadingClipNotAllowed(clip, "reading should have failed");
   1416         assertReadingClipAllowed(clipMeow);
   1417         assertReadingClipAllowed(clipMeowCat);
   1418         assertWritingClipNotAllowed(clip, "writing should have failed");
   1419         assertWritingClipNotAllowed(clipMeow, "writing should have failed");
   1420         assertWritingClipNotAllowed(clipMeowCat, "writing should have failed");
   1421 
   1422         // Now give ourselves exact write access
   1423         ReceiveUriActivity.clearNewIntent();
   1424         grantClipUriPermission(clip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
   1425         ReceiveUriActivity.waitForNewIntent();
   1426 
   1427         // Verify we have exact write access, but not prefix write
   1428         assertReadingClipNotAllowed(clip, "reading should have failed");
   1429         assertReadingClipAllowed(clipMeow);
   1430         assertReadingClipAllowed(clipMeowCat);
   1431         assertWritingClipAllowed(clip);
   1432         assertWritingClipNotAllowed(clipMeow, "writing should have failed");
   1433         assertWritingClipNotAllowed(clipMeowCat, "writing should have failed");
   1434 
   1435         ReceiveUriActivity.finishCurInstanceSync();
   1436     }
   1437 
   1438     public void testGrantPersistablePrefixUriPermission() {
   1439         final ContentResolver resolver = getContext().getContentResolver();
   1440 
   1441         final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo2");
   1442         final Uri targetMeow = Uri.withAppendedPath(target, "meow");
   1443 
   1444         final ClipData clip = makeSingleClipData(target);
   1445         final ClipData clipMeow = makeSingleClipData(targetMeow);
   1446 
   1447         // Make sure we can't see the target
   1448         assertReadingClipNotAllowed(clip, "reading should have failed");
   1449 
   1450         // Give ourselves prefix read access
   1451         ReceiveUriActivity.clearStarted();
   1452         grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
   1453                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
   1454                 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
   1455         ReceiveUriActivity.waitForStart();
   1456 
   1457         // Verify prefix read access
   1458         assertReadingClipAllowed(clip);
   1459         assertReadingClipAllowed(clipMeow);
   1460 
   1461         // Verify we can persist direct grant
   1462         long before = System.currentTimeMillis();
   1463         resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1464         long after = System.currentTimeMillis();
   1465         assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after);
   1466 
   1467         // But we can't take anywhere under the prefix
   1468         try {
   1469             resolver.takePersistableUriPermission(targetMeow,
   1470                     Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1471             fail("taking under prefix should have failed");
   1472         } catch (SecurityException expected) {
   1473         }
   1474 
   1475         // Should still have access regardless of taking
   1476         assertReadingClipAllowed(clip);
   1477         assertReadingClipAllowed(clipMeow);
   1478 
   1479         // And clean up our grants
   1480         resolver.releasePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1481         assertNoPersistedUriPermission();
   1482 
   1483         ReceiveUriActivity.finishCurInstanceSync();
   1484     }
   1485 
   1486     /**
   1487      * Validate behavior of directly granting/revoking permission grants.
   1488      */
   1489     public void testDirectGrantRevokeUriPermission() throws Exception {
   1490         final ContentResolver resolver = getContext().getContentResolver();
   1491 
   1492         final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo3");
   1493         final Uri targetMeow = Uri.withAppendedPath(target, "meow");
   1494         final Uri targetMeowCat = Uri.withAppendedPath(targetMeow, "cat");
   1495 
   1496         final ClipData clip = makeSingleClipData(target);
   1497         final ClipData clipMeow = makeSingleClipData(targetMeow);
   1498         final ClipData clipMeowCat = makeSingleClipData(targetMeowCat);
   1499 
   1500         // Make sure we can't see the target
   1501         assertReadingClipNotAllowed(clipMeow, "reading should have failed");
   1502         assertWritingClipNotAllowed(clipMeow, "writing should have failed");
   1503 
   1504         // Give ourselves some grants:
   1505         // /meow/cat  WRITE|PERSISTABLE
   1506         // /meow      READ|PREFIX
   1507         // /meow      WRITE
   1508         grantClipUriPermissionViaContext(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   1509                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
   1510         grantClipUriPermissionViaContext(targetMeow, Intent.FLAG_GRANT_READ_URI_PERMISSION
   1511                 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
   1512         grantClipUriPermissionViaContext(targetMeow, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1513 
   1514         long before = System.currentTimeMillis();
   1515         resolver.takePersistableUriPermission(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1516         long after = System.currentTimeMillis();
   1517         assertPersistedUriPermission(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, before, after);
   1518 
   1519         // Verify they look good
   1520         assertReadingClipNotAllowed(clip, "reading should have failed");
   1521         assertReadingClipAllowed(clipMeow);
   1522         assertReadingClipAllowed(clipMeowCat);
   1523         assertWritingClipNotAllowed(clip, "writing should have failed");
   1524         assertWritingClipAllowed(clipMeow);
   1525         assertWritingClipAllowed(clipMeowCat);
   1526 
   1527         // Revoke anyone with write under meow
   1528         revokeClipUriPermissionViaContext(targetMeow, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1529 
   1530         // This should have nuked persisted permission at lower level, but it
   1531         // shoulnd't have touched our prefix read.
   1532         assertReadingClipNotAllowed(clip, "reading should have failed");
   1533         assertReadingClipAllowed(clipMeow);
   1534         assertReadingClipAllowed(clipMeowCat);
   1535         assertWritingClipNotAllowed(clip, "writing should have failed");
   1536         assertWritingClipNotAllowed(clipMeow, "writing should have failed");
   1537         assertWritingClipNotAllowed(clipMeowCat, "writing should have failed");
   1538         assertNoPersistedUriPermission();
   1539 
   1540         // Revoking read at top of tree should nuke everything else
   1541         revokeClipUriPermissionViaContext(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1542         assertReadingClipNotAllowed(clip, "reading should have failed");
   1543         assertReadingClipNotAllowed(clipMeow, "reading should have failed");
   1544         assertReadingClipNotAllowed(clipMeowCat, "reading should have failed");
   1545         assertWritingClipNotAllowed(clip, "writing should have failed");
   1546         assertWritingClipNotAllowed(clipMeow, "writing should have failed");
   1547         assertWritingClipNotAllowed(clipMeowCat, "writing should have failed");
   1548         assertNoPersistedUriPermission();
   1549     }
   1550 
   1551     /**
   1552      * Validate behavior of a direct permission grant, where the receiver of
   1553      * that permission revokes it.
   1554      */
   1555     public void testDirectGrantReceiverRevokeUriPermission() throws Exception {
   1556         final ContentResolver resolver = getContext().getContentResolver();
   1557 
   1558         final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo3");
   1559         final Uri targetMeow = Uri.withAppendedPath(target, "meow");
   1560         final Uri targetMeowCat = Uri.withAppendedPath(targetMeow, "cat");
   1561 
   1562         final ClipData clip = makeSingleClipData(target);
   1563         final ClipData clipMeow = makeSingleClipData(targetMeow);
   1564         final ClipData clipMeowCat = makeSingleClipData(targetMeowCat);
   1565 
   1566         // Make sure we can't see the target
   1567         assertReadingClipNotAllowed(clipMeow, "reading should have failed");
   1568         assertWritingClipNotAllowed(clipMeow, "writing should have failed");
   1569 
   1570         // Give ourselves some grants:
   1571         // /meow/cat  WRITE|PERSISTABLE
   1572         // /meow      READ|PREFIX
   1573         // /meow      WRITE
   1574         grantClipUriPermissionViaContext(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   1575                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
   1576         grantClipUriPermissionViaContext(targetMeow, Intent.FLAG_GRANT_READ_URI_PERMISSION
   1577                 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
   1578         grantClipUriPermissionViaContext(targetMeow, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1579 
   1580         long before = System.currentTimeMillis();
   1581         resolver.takePersistableUriPermission(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1582         long after = System.currentTimeMillis();
   1583         assertPersistedUriPermission(targetMeowCat, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, before, after);
   1584 
   1585         // Verify they look good
   1586         assertReadingClipNotAllowed(clip, "reading should have failed");
   1587         assertReadingClipAllowed(clipMeow);
   1588         assertReadingClipAllowed(clipMeowCat);
   1589         assertWritingClipNotAllowed(clip, "writing should have failed");
   1590         assertWritingClipAllowed(clipMeow);
   1591         assertWritingClipAllowed(clipMeowCat);
   1592 
   1593         // Revoke anyone with write under meow
   1594         getContext().revokeUriPermission(targetMeow, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1595 
   1596         // This should have nuked persisted permission at lower level, but it
   1597         // shoulnd't have touched our prefix read.
   1598         assertReadingClipNotAllowed(clip, "reading should have failed");
   1599         assertReadingClipAllowed(clipMeow);
   1600         assertReadingClipAllowed(clipMeowCat);
   1601         assertWritingClipNotAllowed(clip, "writing should have failed");
   1602         assertWritingClipNotAllowed(clipMeow, "writing should have failed");
   1603         assertWritingClipNotAllowed(clipMeowCat, "writing should have failed");
   1604         assertNoPersistedUriPermission();
   1605 
   1606         // Revoking read at top of tree should nuke everything else
   1607         getContext().revokeUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1608         assertReadingClipNotAllowed(clip, "reading should have failed");
   1609         assertReadingClipNotAllowed(clipMeow, "reading should have failed");
   1610         assertReadingClipNotAllowed(clipMeowCat, "reading should have failed");
   1611         assertWritingClipNotAllowed(clip, "writing should have failed");
   1612         assertWritingClipNotAllowed(clipMeow, "writing should have failed");
   1613         assertWritingClipNotAllowed(clipMeowCat, "writing should have failed");
   1614         assertNoPersistedUriPermission();
   1615     }
   1616 
   1617     public void testClipboardWithPermission() throws Exception {
   1618         for (Uri target : GRANTABLE) {
   1619             final ClipData clip = makeSingleClipData(target);
   1620 
   1621             // Normally we can't see the underlying clip data
   1622             assertReadingClipNotAllowed(clip);
   1623             assertWritingClipNotAllowed(clip);
   1624 
   1625             // Use shell's permissions to ensure we can access the clipboard
   1626             InstrumentationRegistry.getInstrumentation().getUiAutomation()
   1627                     .adoptShellPermissionIdentity();
   1628             ClipData clipFromClipboard;
   1629             try {
   1630                 // But if someone puts it on the clipboard, we can read it
   1631                 setPrimaryClip(clip);
   1632                 clipFromClipboard = getContext()
   1633                         .getSystemService(ClipboardManager.class).getPrimaryClip();
   1634             } finally {
   1635                 InstrumentationRegistry.getInstrumentation().getUiAutomation()
   1636                         .dropShellPermissionIdentity();
   1637             }
   1638             assertClipDataEquals(clip, clipFromClipboard);
   1639             assertReadingClipAllowed(clipFromClipboard);
   1640             assertWritingClipNotAllowed(clipFromClipboard);
   1641 
   1642             // And if clipboard is cleared, we lose access
   1643             clearPrimaryClip();
   1644             assertReadingClipNotAllowed(clipFromClipboard);
   1645             assertWritingClipNotAllowed(clipFromClipboard);
   1646         }
   1647     }
   1648 
   1649     public void testClipboardWithoutPermission() throws Exception {
   1650         for (Uri target : NOT_GRANTABLE) {
   1651             final ClipData clip = makeSingleClipData(target);
   1652 
   1653             // Can't see it directly
   1654             assertReadingClipNotAllowed(clip);
   1655             assertWritingClipNotAllowed(clip);
   1656 
   1657             // Can't put on clipboard if we don't own it
   1658             try {
   1659                 setPrimaryClip(clip);
   1660                 fail("Unexpected ability to put protected data " + clip + " on clipboard!");
   1661             } catch (Exception expected) {
   1662             }
   1663         }
   1664     }
   1665 
   1666     private static void assertClipDataEquals(ClipData expected, ClipData actual) {
   1667         assertEquals(expected.getItemCount(), actual.getItemCount());
   1668         for (int i = 0; i < expected.getItemCount(); i++) {
   1669             final ClipData.Item expectedItem = expected.getItemAt(i);
   1670             final ClipData.Item actualItem = actual.getItemAt(i);
   1671             assertEquals(expectedItem.getText(), actualItem.getText());
   1672             assertEquals(expectedItem.getHtmlText(), actualItem.getHtmlText());
   1673             assertEquals(expectedItem.getIntent(), actualItem.getIntent());
   1674             assertEquals(expectedItem.getUri(), actualItem.getUri());
   1675         }
   1676     }
   1677 }
   1678