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 android.content.BroadcastReceiver;
     20 import android.content.ClipData;
     21 import android.content.ComponentName;
     22 import android.content.ContentResolver;
     23 import android.content.ContentValues;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.UriPermission;
     27 import android.database.Cursor;
     28 import android.net.Uri;
     29 import android.os.SystemClock;
     30 import android.test.AndroidTestCase;
     31 import android.util.Log;
     32 
     33 import com.android.cts.permissiondeclareapp.GrantUriPermission;
     34 
     35 import java.io.IOException;
     36 import java.util.List;
     37 
     38 /**
     39  * Tests that signature-enforced permissions cannot be accessed by apps signed
     40  * with different certs than app that declares the permission.
     41  *
     42  * Accesses app cts/tests/appsecurity-tests/test-apps/PermissionDeclareApp/...
     43  */
     44 public class AccessPermissionWithDiffSigTest extends AndroidTestCase {
     45     private static final ComponentName GRANT_URI_PERM_COMP
     46             = new ComponentName("com.android.cts.permissiondeclareapp",
     47                     "com.android.cts.permissiondeclareapp.GrantUriPermission");
     48     private static final Uri PERM_URI = Uri.parse("content://ctspermissionwithsignature");
     49     private static final Uri PERM_URI_GRANTING = Uri.parse("content://ctspermissionwithsignaturegranting");
     50     private static final Uri PERM_URI_PATH = Uri.parse("content://ctspermissionwithsignaturepath");
     51     private static final Uri PERM_URI_PATH_RESTRICTING = Uri.parse(
     52             "content://ctspermissionwithsignaturepathrestricting");
     53     private static final Uri PRIV_URI = Uri.parse("content://ctsprivateprovider");
     54     private static final Uri PRIV_URI_GRANTING = Uri.parse("content://ctsprivateprovidergranting");
     55     private static final String EXPECTED_MIME_TYPE = "got/theMIME";
     56 
     57     private static final Uri AMBIGUOUS_URI_COMPAT = Uri.parse("content://ctsambiguousprovidercompat");
     58     private static final String EXPECTED_MIME_TYPE_AMBIGUOUS = "got/theUnspecifiedMIME";
     59     private static final Uri AMBIGUOUS_URI = Uri.parse("content://ctsambiguousprovider");
     60 
     61     @Override
     62     protected void tearDown() throws Exception {
     63         super.tearDown();
     64 
     65         // Always dispose, usually to clean up from failed tests
     66         ReceiveUriActivity.finishCurInstanceSync();
     67     }
     68 
     69     private void assertReadingContentUriNotAllowed(Uri uri, String msg) {
     70         try {
     71             getContext().getContentResolver().query(uri, null, null, null, null);
     72             fail("expected SecurityException reading " + uri + ": " + msg);
     73         } catch (SecurityException expected) {
     74             assertNotNull("security exception's error message.", expected.getMessage());
     75         }
     76     }
     77 
     78     private void assertReadingContentUriAllowed(Uri uri) {
     79         try {
     80             getContext().getContentResolver().query(uri, null, null, null, null);
     81         } catch (SecurityException e) {
     82             fail("unexpected SecurityException reading " + uri + ": " + e.getMessage());
     83         }
     84     }
     85 
     86     private void assertReadingClipNotAllowed(ClipData clip, String msg) {
     87         for (int i=0; i<clip.getItemCount(); i++) {
     88             ClipData.Item item = clip.getItemAt(i);
     89             Uri uri = item.getUri();
     90             if (uri != null) {
     91                 assertReadingContentUriNotAllowed(uri, msg);
     92             } else {
     93                 Intent intent = item.getIntent();
     94                 uri = intent.getData();
     95                 if (uri != null) {
     96                     assertReadingContentUriNotAllowed(uri, msg);
     97                 }
     98                 ClipData intentClip = intent.getClipData();
     99                 if (intentClip != null) {
    100                     assertReadingClipNotAllowed(intentClip, msg);
    101                 }
    102             }
    103         }
    104     }
    105 
    106     private void assertOpenFileDescriptorModeNotAllowed(Uri uri, String msg, String mode) {
    107         try {
    108             getContext().getContentResolver().openFileDescriptor(uri, mode).close();
    109             fail("expected SecurityException writing " + uri + ": " + msg);
    110         } catch (IOException e) {
    111             throw new IllegalStateException(e);
    112         } catch (SecurityException expected) {
    113             assertNotNull("security exception's error message.", expected.getMessage());
    114         }
    115     }
    116 
    117     private void assertWritingContentUriNotAllowed(Uri uri, String msg) {
    118         final ContentResolver resolver = getContext().getContentResolver();
    119         try {
    120             resolver.insert(uri, new ContentValues());
    121             fail("expected SecurityException inserting " + uri + ": " + msg);
    122         } catch (SecurityException expected) {
    123             assertNotNull("security exception's error message.", expected.getMessage());
    124         }
    125 
    126         try {
    127             resolver.update(uri, new ContentValues(), null, null);
    128             fail("expected SecurityException updating " + uri + ": " + msg);
    129         } catch (SecurityException expected) {
    130             assertNotNull("security exception's error message.", expected.getMessage());
    131         }
    132 
    133         try {
    134             resolver.delete(uri, null, null);
    135             fail("expected SecurityException deleting " + uri + ": " + msg);
    136         } catch (SecurityException expected) {
    137             assertNotNull("security exception's error message.", expected.getMessage());
    138         }
    139 
    140         try {
    141             getContext().getContentResolver().openOutputStream(uri).close();
    142             fail("expected SecurityException writing " + uri + ": " + msg);
    143         } catch (IOException e) {
    144             throw new IllegalStateException(e);
    145         } catch (SecurityException expected) {
    146             assertNotNull("security exception's error message.", expected.getMessage());
    147         }
    148 
    149         assertOpenFileDescriptorModeNotAllowed(uri, msg, "w");
    150         assertOpenFileDescriptorModeNotAllowed(uri, msg, "wt");
    151         assertOpenFileDescriptorModeNotAllowed(uri, msg, "wa");
    152         assertOpenFileDescriptorModeNotAllowed(uri, msg, "rw");
    153         assertOpenFileDescriptorModeNotAllowed(uri, msg, "rwt");
    154     }
    155 
    156     private void assertWritingContentUriAllowed(Uri uri) {
    157         final ContentResolver resolver = getContext().getContentResolver();
    158         try {
    159             resolver.insert(uri, new ContentValues());
    160             resolver.update(uri, new ContentValues(), null, null);
    161             resolver.delete(uri, null, null);
    162 
    163             resolver.openOutputStream(uri).close();
    164             resolver.openFileDescriptor(uri, "w").close();
    165             resolver.openFileDescriptor(uri, "wt").close();
    166             resolver.openFileDescriptor(uri, "wa").close();
    167             resolver.openFileDescriptor(uri, "rw").close();
    168             resolver.openFileDescriptor(uri, "rwt").close();
    169         } catch (IOException e) {
    170             fail("unexpected IOException writing " + uri + ": " + e.getMessage());
    171         } catch (SecurityException e) {
    172             fail("unexpected SecurityException writing " + uri + ": " + e.getMessage());
    173         }
    174     }
    175 
    176     private void assertWritingClipNotAllowed(ClipData clip, String msg) {
    177         for (int i=0; i<clip.getItemCount(); i++) {
    178             ClipData.Item item = clip.getItemAt(i);
    179             Uri uri = item.getUri();
    180             if (uri != null) {
    181                 assertWritingContentUriNotAllowed(uri, msg);
    182             } else {
    183                 Intent intent = item.getIntent();
    184                 uri = intent.getData();
    185                 if (uri != null) {
    186                     assertWritingContentUriNotAllowed(uri, msg);
    187                 }
    188                 ClipData intentClip = intent.getClipData();
    189                 if (intentClip != null) {
    190                     assertWritingClipNotAllowed(intentClip, msg);
    191                 }
    192             }
    193         }
    194     }
    195 
    196     /**
    197      * Test that the ctspermissionwithsignature content provider cannot be read,
    198      * since this app lacks the required certs
    199      */
    200     public void testReadProviderWithDiff() {
    201         assertReadingContentUriRequiresPermission(PERM_URI,
    202                 "com.android.cts.permissionWithSignature");
    203     }
    204 
    205     /**
    206      * Test that the ctspermissionwithsignature content provider cannot be written,
    207      * since this app lacks the required certs
    208      */
    209     public void testWriteProviderWithDiff() {
    210         assertWritingContentUriRequiresPermission(PERM_URI,
    211                 "com.android.cts.permissionWithSignature");
    212     }
    213 
    214     /**
    215      * Test that the ctsprivateprovider content provider cannot be read,
    216      * since it is not exported from its app.
    217      */
    218     public void testReadProviderWhenPrivate() {
    219         assertReadingContentUriNotAllowed(PRIV_URI, "shouldn't read private provider");
    220     }
    221 
    222     /**
    223      * Test that the ctsambiguousprovider content provider cannot be read,
    224      * since it doesn't have an "exported=" line.
    225      */
    226     public void testReadProviderWhenAmbiguous() {
    227         assertReadingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't read ambiguous provider");
    228     }
    229 
    230     /**
    231      * Old App Compatibility Test
    232      *
    233      * Test that the ctsambiguousprovidercompat content provider can be read for older
    234      * API versions, because it didn't specify either exported=true or exported=false.
    235      */
    236     public void testReadProviderWhenAmbiguousCompat() {
    237         assertReadingContentUriAllowed(AMBIGUOUS_URI_COMPAT);
    238     }
    239 
    240     /**
    241      * Old App Compatibility Test
    242      *
    243      * Test that the ctsambiguousprovidercompat content provider can be written for older
    244      * API versions, because it didn't specify either exported=true or exported=false.
    245      */
    246     public void testWriteProviderWhenAmbiguousCompat() {
    247         assertWritingContentUriAllowed(AMBIGUOUS_URI_COMPAT);
    248     }
    249 
    250     /**
    251      * Test that the ctsprivateprovider content provider cannot be written,
    252      * since it is not exported from its app.
    253      */
    254     public void testWriteProviderWhenPrivate() {
    255         assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write private provider");
    256     }
    257 
    258     /**
    259      * Test that the ctsambiguousprovider content provider cannot be written,
    260      * since it doesn't have an exported= line.
    261      */
    262     public void testWriteProviderWhenAmbiguous() {
    263         assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write ambiguous provider");
    264     }
    265 
    266     private static ClipData makeSingleClipData(Uri uri) {
    267         return new ClipData("foo", new String[] { "foo/bar" },
    268                 new ClipData.Item(uri));
    269     }
    270 
    271     private static ClipData makeMultiClipData(Uri uri) {
    272         Uri grantClip1Uri = Uri.withAppendedPath(uri, "clip1");
    273         Uri grantClip2Uri = Uri.withAppendedPath(uri, "clip2");
    274         Uri grantClip3Uri = Uri.withAppendedPath(uri, "clip3");
    275         Uri grantClip4Uri = Uri.withAppendedPath(uri, "clip4");
    276         Uri grantClip5Uri = Uri.withAppendedPath(uri, "clip5");
    277         ClipData clip = new ClipData("foo", new String[] { "foo/bar" },
    278                 new ClipData.Item(grantClip1Uri));
    279         clip.addItem(new ClipData.Item(grantClip2Uri));
    280         // Intents in the ClipData should allow their data: and clip URIs
    281         // to be granted, but only respect the grant flags of the top-level
    282         // Intent.
    283         clip.addItem(new ClipData.Item(new Intent(Intent.ACTION_VIEW, grantClip3Uri)));
    284         Intent intent = new Intent(Intent.ACTION_VIEW, grantClip4Uri);
    285         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
    286                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    287         clip.addItem(new ClipData.Item(intent));
    288         intent = new Intent(Intent.ACTION_VIEW);
    289         intent.setClipData(new ClipData("foo", new String[] { "foo/bar" },
    290                 new ClipData.Item(grantClip5Uri)));
    291         clip.addItem(new ClipData.Item(intent));
    292         return clip;
    293     }
    294 
    295     private static Intent makeClipIntent(ClipData clip, int flags) {
    296         Intent intent = new Intent();
    297         intent.setClipData(clip);
    298         intent.addFlags(flags);
    299         return intent;
    300     }
    301 
    302     private static Intent makeClipIntent(Uri uri, int flags) {
    303         return makeClipIntent(makeMultiClipData(uri), flags);
    304     }
    305 
    306     private void doTryGrantUriActivityPermissionToSelf(Uri uri, int mode) {
    307         Uri grantDataUri = Uri.withAppendedPath(uri, "data");
    308         Intent grantIntent = new Intent();
    309         grantIntent.setData(grantDataUri);
    310         grantIntent.addFlags(mode | Intent.FLAG_ACTIVITY_NEW_TASK);
    311         grantIntent.setClass(getContext(), ReceiveUriActivity.class);
    312         try {
    313             ReceiveUriActivity.clearStarted();
    314             getContext().startActivity(grantIntent);
    315             ReceiveUriActivity.waitForStart();
    316             fail("expected SecurityException granting " + grantDataUri + " to activity");
    317         } catch (SecurityException e) {
    318             // This is what we want.
    319         }
    320 
    321         grantIntent = makeClipIntent(uri, mode | Intent.FLAG_ACTIVITY_NEW_TASK);
    322         grantIntent.setClass(getContext(), ReceiveUriActivity.class);
    323         try {
    324             ReceiveUriActivity.clearStarted();
    325             getContext().startActivity(grantIntent);
    326             ReceiveUriActivity.waitForStart();
    327             fail("expected SecurityException granting " + grantIntent.getClipData() + " to activity");
    328         } catch (SecurityException e) {
    329             // This is what we want.
    330         }
    331     }
    332 
    333     /**
    334      * Test that we can't grant a permission to ourself.
    335      */
    336     public void testGrantReadUriActivityPermissionToSelf() {
    337         doTryGrantUriActivityPermissionToSelf(
    338                 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
    339                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    340     }
    341 
    342     /**
    343      * Test that we can't grant a permission to ourself.
    344      */
    345     public void testGrantWriteUriActivityPermissionToSelf() {
    346         doTryGrantUriActivityPermissionToSelf(
    347                 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
    348                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    349     }
    350 
    351     /**
    352      * Test that we can't grant a permission to ourself.
    353      */
    354     public void testGrantReadUriActivityPrivateToSelf() {
    355         doTryGrantUriActivityPermissionToSelf(
    356                 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
    357                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    358     }
    359 
    360     /**
    361      * Test that we can't grant a permission to ourself.
    362      */
    363     public void testGrantWriteUriActivityPrivateToSelf() {
    364         doTryGrantUriActivityPermissionToSelf(
    365                 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
    366                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    367     }
    368 
    369     private void doTryGrantUriServicePermissionToSelf(Uri uri, int mode) {
    370         Uri grantDataUri = Uri.withAppendedPath(uri, "data");
    371         Intent grantIntent = new Intent();
    372         grantIntent.setData(grantDataUri);
    373         grantIntent.addFlags(mode);
    374         grantIntent.setClass(getContext(), ReceiveUriService.class);
    375         try {
    376             getContext().startService(grantIntent);
    377             fail("expected SecurityException granting " + grantDataUri + " to service");
    378         } catch (SecurityException e) {
    379             // This is what we want.
    380         }
    381 
    382         grantIntent = makeClipIntent(uri, mode);
    383         grantIntent.setClass(getContext(), ReceiveUriService.class);
    384         try {
    385             getContext().startService(grantIntent);
    386             fail("expected SecurityException granting " + grantIntent.getClipData() + " to service");
    387         } catch (SecurityException e) {
    388             // This is what we want.
    389         }
    390     }
    391 
    392     /**
    393      * Test that we can't grant a permission to ourself.
    394      */
    395     public void testGrantReadUriServicePermissionToSelf() {
    396         doTryGrantUriServicePermissionToSelf(
    397                 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
    398                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    399     }
    400 
    401     /**
    402      * Test that we can't grant a permission to ourself.
    403      */
    404     public void testGrantWriteUriServicePermissionToSelf() {
    405         doTryGrantUriServicePermissionToSelf(
    406                 Uri.withAppendedPath(PERM_URI_GRANTING, "foo"),
    407                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    408     }
    409 
    410     /**
    411      * Test that we can't grant a permission to ourself.
    412      */
    413     public void testGrantReadUriServicePrivateToSelf() {
    414         doTryGrantUriServicePermissionToSelf(
    415                 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
    416                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    417     }
    418 
    419     /**
    420      * Test that we can't grant a permission to ourself.
    421      */
    422     public void testGrantWriteUriServicePrivateToSelf() {
    423         doTryGrantUriServicePermissionToSelf(
    424                 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"),
    425                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    426     }
    427 
    428     private static class GrantResultReceiver extends BroadcastReceiver {
    429         boolean mHaveResult = false;
    430         boolean mGoodResult = false;
    431         boolean mSucceeded = false;
    432 
    433         @Override
    434         public void onReceive(Context context, Intent intent) {
    435             synchronized (this) {
    436                 mHaveResult = true;
    437                 switch (getResultCode()) {
    438                     case GrantUriPermission.FAILURE:
    439                         mGoodResult = true;
    440                         mSucceeded = false;
    441                         break;
    442                     case GrantUriPermission.SUCCESS:
    443                         mGoodResult = true;
    444                         mSucceeded = true;
    445                         break;
    446                     default:
    447                         mGoodResult = false;
    448                         break;
    449                 }
    450                 notifyAll();
    451             }
    452         }
    453 
    454         void assertSuccess(String failureMessage) {
    455             synchronized (this) {
    456                 final long startTime = SystemClock.uptimeMillis();
    457                 while (!mHaveResult) {
    458                     try {
    459                         wait(5000);
    460                     } catch (InterruptedException e) {
    461                     }
    462                     if (SystemClock.uptimeMillis() >= (startTime+5000)) {
    463                         throw new RuntimeException("Timeout");
    464                     }
    465                 }
    466                 if (!mGoodResult) {
    467                     fail("Broadcast receiver did not return good result");
    468                 }
    469                 if (!mSucceeded) {
    470                     fail(failureMessage);
    471                 }
    472             }
    473         }
    474 
    475         void assertFailure(String failureMessage) {
    476             synchronized (this) {
    477                 final long startTime = SystemClock.uptimeMillis();
    478                 while (!mHaveResult) {
    479                     try {
    480                         wait(5000);
    481                     } catch (InterruptedException e) {
    482                     }
    483                     if (SystemClock.uptimeMillis() >= (startTime+5000)) {
    484                         throw new RuntimeException("Timeout");
    485                     }
    486                 }
    487                 if (!mGoodResult) {
    488                     fail("Broadcast receiver did not return good result");
    489                 }
    490                 if (mSucceeded) {
    491                     fail(failureMessage);
    492                 }
    493             }
    494         }
    495     }
    496 
    497     private void grantUriPermissionFail(Uri uri, int mode, boolean service) {
    498         Uri grantDataUri = Uri.withAppendedPath(uri, "data");
    499         Intent grantIntent = new Intent();
    500         grantIntent.setData(grantDataUri);
    501         grantIntent.addFlags(mode);
    502         grantIntent.setClass(getContext(),
    503                 service ? ReceiveUriService.class : ReceiveUriActivity.class);
    504         Intent intent = new Intent();
    505         intent.setComponent(GRANT_URI_PERM_COMP);
    506         intent.setAction(service ? GrantUriPermission.ACTION_START_SERVICE
    507                 : GrantUriPermission.ACTION_START_ACTIVITY);
    508         intent.putExtra(GrantUriPermission.EXTRA_INTENT, grantIntent);
    509         GrantResultReceiver receiver = new GrantResultReceiver();
    510         getContext().sendOrderedBroadcast(intent, null, receiver, null, 0, null, null);
    511         receiver.assertFailure("Able to grant URI permission to " + grantDataUri + " when should not");
    512 
    513         grantIntent = makeClipIntent(uri, mode);
    514         grantIntent.setClass(getContext(),
    515                 service ? ReceiveUriService.class : ReceiveUriActivity.class);
    516         intent = new Intent();
    517         intent.setComponent(GRANT_URI_PERM_COMP);
    518         intent.setAction(service ? GrantUriPermission.ACTION_START_SERVICE
    519                 : GrantUriPermission.ACTION_START_ACTIVITY);
    520         intent.putExtra(GrantUriPermission.EXTRA_INTENT, grantIntent);
    521         receiver = new GrantResultReceiver();
    522         getContext().sendOrderedBroadcast(intent, null, receiver, null, 0, null, null);
    523         receiver.assertFailure("Able to grant URI permission to " + grantIntent.getClipData()
    524                 + " when should not");
    525     }
    526 
    527     private void doTestGrantUriPermissionFail(Uri uri) {
    528         grantUriPermissionFail(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, false);
    529         grantUriPermissionFail(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
    530         grantUriPermissionFail(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    531         grantUriPermissionFail(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
    532     }
    533 
    534     /**
    535      * Test that the ctspermissionwithsignature content provider can not grant
    536      * URI permissions to others.
    537      */
    538     public void testGrantPermissionNonGrantingFail() {
    539         doTestGrantUriPermissionFail(PERM_URI);
    540     }
    541 
    542     /**
    543      * Test that the ctspermissionwithsignaturegranting content provider can not grant
    544      * URI permissions to paths outside of the grant tree
    545      */
    546     public void testGrantPermissionOutsideGrantingFail() {
    547         doTestGrantUriPermissionFail(PERM_URI_GRANTING);
    548         doTestGrantUriPermissionFail(Uri.withAppendedPath(PERM_URI_GRANTING, "invalid"));
    549     }
    550 
    551     /**
    552      * Test that the ctsprivateprovider content provider can not grant
    553      * URI permissions to others.
    554      */
    555     public void testGrantPrivateNonGrantingFail() {
    556         doTestGrantUriPermissionFail(PRIV_URI);
    557     }
    558 
    559     /**
    560      * Test that the ctsambiguousprovider content provider can not grant
    561      * URI permissions to others.
    562      */
    563     public void testGrantAmbiguousNonGrantingFail() {
    564         doTestGrantUriPermissionFail(AMBIGUOUS_URI);
    565     }
    566 
    567     /**
    568      * Test that the ctsprivateprovidergranting content provider can not grant
    569      * URI permissions to paths outside of the grant tree
    570      */
    571     public void testGrantPrivateOutsideGrantingFail() {
    572         doTestGrantUriPermissionFail(PRIV_URI_GRANTING);
    573         doTestGrantUriPermissionFail(Uri.withAppendedPath(PRIV_URI_GRANTING, "invalid"));
    574     }
    575 
    576     private void grantClipUriPermission(ClipData clip, int mode, boolean service) {
    577         Intent grantIntent = new Intent();
    578         if (clip.getItemCount() == 1) {
    579             grantIntent.setData(clip.getItemAt(0).getUri());
    580         } else {
    581             grantIntent.setClipData(clip);
    582             // Make this Intent unique from the one that started it.
    583             for (int i=0; i<clip.getItemCount(); i++) {
    584                 Uri uri = clip.getItemAt(i).getUri();
    585                 if (uri != null) {
    586                     grantIntent.addCategory(uri.toString());
    587                 }
    588             }
    589         }
    590         grantIntent.addFlags(mode);
    591         grantIntent.setClass(getContext(),
    592                 service ? ReceiveUriService.class : ReceiveUriActivity.class);
    593         Intent intent = new Intent();
    594         intent.setComponent(GRANT_URI_PERM_COMP);
    595         intent.setAction(service ? GrantUriPermission.ACTION_START_SERVICE
    596                 : GrantUriPermission.ACTION_START_ACTIVITY);
    597         intent.putExtra(GrantUriPermission.EXTRA_INTENT, grantIntent);
    598         getContext().sendBroadcast(intent);
    599     }
    600 
    601     private void assertReadingClipAllowed(ClipData clip) {
    602         for (int i=0; i<clip.getItemCount(); i++) {
    603             ClipData.Item item = clip.getItemAt(i);
    604             Uri uri = item.getUri();
    605             if (uri != null) {
    606                 Cursor c = getContext().getContentResolver().query(uri,
    607                         null, null, null, null);
    608                 if (c != null) {
    609                     c.close();
    610                 }
    611             } else {
    612                 Intent intent = item.getIntent();
    613                 uri = intent.getData();
    614                 if (uri != null) {
    615                     Cursor c = getContext().getContentResolver().query(uri,
    616                             null, null, null, null);
    617                     if (c != null) {
    618                         c.close();
    619                     }
    620                 }
    621                 ClipData intentClip = intent.getClipData();
    622                 if (intentClip != null) {
    623                     assertReadingClipAllowed(intentClip);
    624                 }
    625             }
    626         }
    627     }
    628 
    629     private void doTestGrantActivityUriReadPermission(Uri uri, boolean useClip) {
    630         final Uri subUri = Uri.withAppendedPath(uri, "foo");
    631         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
    632         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
    633         final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
    634 
    635         final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri);
    636         final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri);
    637 
    638         // Precondition: no current access.
    639         assertReadingClipNotAllowed(subClip, "shouldn't read when starting test");
    640         assertReadingClipNotAllowed(sub2Clip, "shouldn't read when starting test");
    641 
    642         // --------------------------------
    643 
    644         ReceiveUriActivity.clearStarted();
    645         grantClipUriPermission(subClip, Intent.FLAG_GRANT_READ_URI_PERMISSION, false);
    646         ReceiveUriActivity.waitForStart();
    647 
    648         // See if we now have access to the provider.
    649         assertReadingClipAllowed(subClip);
    650 
    651         // But not writing.
    652         assertWritingClipNotAllowed(subClip, "shouldn't write from granted read");
    653 
    654         // And not to the base path.
    655         assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
    656 
    657         // And not to a sub path.
    658         assertReadingContentUriNotAllowed(subSubUri, "shouldn't read non-granted sub URI");
    659 
    660         // --------------------------------
    661 
    662         ReceiveUriActivity.clearNewIntent();
    663         grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_READ_URI_PERMISSION, false);
    664         ReceiveUriActivity.waitForNewIntent();
    665 
    666         if (false) {
    667             synchronized (this) {
    668                 Log.i("**", "******************************* WAITING!!!");
    669                 try {
    670                     wait(10000);
    671                 } catch (InterruptedException e) {
    672                 }
    673             }
    674         }
    675 
    676         // See if we now have access to the provider.
    677         assertReadingClipAllowed(sub2Clip);
    678 
    679         // And still have access to the original URI.
    680         assertReadingClipAllowed(subClip);
    681 
    682         // But not writing.
    683         assertWritingClipNotAllowed(sub2Clip, "shouldn't write from granted read");
    684 
    685         // And not to the base path.
    686         assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
    687 
    688         // And not to a sub path.
    689         assertReadingContentUriNotAllowed(sub2SubUri, "shouldn't read non-granted sub URI");
    690 
    691         // And make sure we can't generate a permission to a running activity.
    692         doTryGrantUriActivityPermissionToSelf(
    693                 Uri.withAppendedPath(uri, "hah"),
    694                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    695         doTryGrantUriActivityPermissionToSelf(
    696                 Uri.withAppendedPath(uri, "hah"),
    697                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    698 
    699         // --------------------------------
    700 
    701         // Dispose of activity.
    702         ReceiveUriActivity.finishCurInstanceSync();
    703 
    704         synchronized (this) {
    705             Log.i("**", "******************************* WAITING!!!");
    706             try {
    707                 wait(100);
    708             } catch (InterruptedException e) {
    709             }
    710         }
    711 
    712         // Ensure reading no longer allowed.
    713         assertReadingClipNotAllowed(subClip, "shouldn't read after losing granted URI");
    714         assertReadingClipNotAllowed(sub2Clip, "shouldn't read after losing granted URI");
    715     }
    716 
    717     private void assertWritingClipAllowed(ClipData clip) {
    718         for (int i=0; i<clip.getItemCount(); i++) {
    719             ClipData.Item item = clip.getItemAt(i);
    720             Uri uri = item.getUri();
    721             if (uri != null) {
    722                 getContext().getContentResolver().insert(uri, new ContentValues());
    723             } else {
    724                 Intent intent = item.getIntent();
    725                 uri = intent.getData();
    726                 if (uri != null) {
    727                     getContext().getContentResolver().insert(uri, new ContentValues());
    728                 }
    729                 ClipData intentClip = intent.getClipData();
    730                 if (intentClip != null) {
    731                     assertWritingClipAllowed(intentClip);
    732                 }
    733             }
    734         }
    735     }
    736 
    737     private void doTestGrantActivityUriWritePermission(Uri uri, boolean useClip) {
    738         final Uri subUri = Uri.withAppendedPath(uri, "foo");
    739         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
    740         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
    741         final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
    742 
    743         final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri);
    744         final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri);
    745 
    746         // Precondition: no current access.
    747         assertWritingClipNotAllowed(subClip, "shouldn't write when starting test");
    748         assertWritingClipNotAllowed(sub2Clip, "shouldn't write when starting test");
    749 
    750         // --------------------------------
    751 
    752         ReceiveUriActivity.clearStarted();
    753         grantClipUriPermission(subClip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
    754         ReceiveUriActivity.waitForStart();
    755 
    756         // See if we now have access to the provider.
    757         assertWritingClipAllowed(subClip);
    758 
    759         // But not reading.
    760         assertReadingClipNotAllowed(subClip, "shouldn't read from granted write");
    761 
    762         // And not to the base path.
    763         assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
    764 
    765         // And not a sub-path.
    766         assertWritingContentUriNotAllowed(subSubUri, "shouldn't write non-granted sub URI");
    767 
    768         // --------------------------------
    769 
    770         ReceiveUriActivity.clearNewIntent();
    771         grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
    772         ReceiveUriActivity.waitForNewIntent();
    773 
    774         if (false) {
    775             synchronized (this) {
    776                 Log.i("**", "******************************* WAITING!!!");
    777                 try {
    778                     wait(10000);
    779                 } catch (InterruptedException e) {
    780                 }
    781             }
    782         }
    783 
    784         // See if we now have access to the provider.
    785         assertWritingClipAllowed(sub2Clip);
    786 
    787         // And still have access to the original URI.
    788         assertWritingClipAllowed(subClip);
    789 
    790         // But not reading.
    791         assertReadingClipNotAllowed(sub2Clip, "shouldn't read from granted write");
    792 
    793         // And not to the base path.
    794         assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
    795 
    796         // And not a sub-path.
    797         assertWritingContentUriNotAllowed(sub2SubUri, "shouldn't write non-granted sub URI");
    798 
    799         // And make sure we can't generate a permission to a running activity.
    800         doTryGrantUriActivityPermissionToSelf(
    801                 Uri.withAppendedPath(uri, "hah"),
    802                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    803         doTryGrantUriActivityPermissionToSelf(
    804                 Uri.withAppendedPath(uri, "hah"),
    805                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    806 
    807         // --------------------------------
    808 
    809         // Dispose of activity.
    810         ReceiveUriActivity.finishCurInstanceSync();
    811 
    812         synchronized (this) {
    813             Log.i("**", "******************************* WAITING!!!");
    814             try {
    815                 wait(100);
    816             } catch (InterruptedException e) {
    817             }
    818         }
    819 
    820         // Ensure writing no longer allowed.
    821         assertWritingClipNotAllowed(subClip, "shouldn't write after losing granted URI");
    822         assertWritingClipNotAllowed(sub2Clip, "shouldn't write after losing granted URI");
    823     }
    824 
    825     /**
    826      * Test that the ctspermissionwithsignaturegranting content provider can grant a read
    827      * permission.
    828      */
    829     public void testGrantReadPermissionFromStartActivity() {
    830         doTestGrantActivityUriReadPermission(PERM_URI_GRANTING, false);
    831         doTestGrantActivityUriReadPermission(PERM_URI_GRANTING, true);
    832     }
    833 
    834     /**
    835      * Test that the ctspermissionwithsignaturegranting content provider can grant a write
    836      * permission.
    837      */
    838     public void testGrantWritePermissionFromStartActivity() {
    839         doTestGrantActivityUriWritePermission(PERM_URI_GRANTING, true);
    840         doTestGrantActivityUriWritePermission(PERM_URI_GRANTING, false);
    841     }
    842 
    843     /**
    844      * Test that the ctsprivateprovidergranting content provider can grant a read
    845      * permission.
    846      */
    847     public void testGrantReadPrivateFromStartActivity() {
    848         doTestGrantActivityUriReadPermission(PRIV_URI_GRANTING, false);
    849         doTestGrantActivityUriReadPermission(PRIV_URI_GRANTING, true);
    850     }
    851 
    852     /**
    853      * Test that the ctsprivateprovidergranting content provider can grant a write
    854      * permission.
    855      */
    856     public void testGrantWritePrivateFromStartActivity() {
    857         doTestGrantActivityUriWritePermission(PRIV_URI_GRANTING, true);
    858         doTestGrantActivityUriWritePermission(PRIV_URI_GRANTING, false);
    859     }
    860 
    861     private void doTestGrantServiceUriReadPermission(Uri uri, boolean useClip) {
    862         final Uri subUri = Uri.withAppendedPath(uri, "foo");
    863         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
    864         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
    865         final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
    866 
    867         ReceiveUriService.stop(getContext());
    868 
    869         final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri);
    870         final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri);
    871 
    872         // Precondition: no current access.
    873         assertReadingClipNotAllowed(subClip, "shouldn't read when starting test");
    874         assertReadingClipNotAllowed(sub2Clip, "shouldn't read when starting test");
    875 
    876         // --------------------------------
    877 
    878         ReceiveUriService.clearStarted();
    879         grantClipUriPermission(subClip, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    880         ReceiveUriService.waitForStart();
    881 
    882         int firstStartId = ReceiveUriService.getCurStartId();
    883 
    884         // See if we now have access to the provider.
    885         assertReadingClipAllowed(subClip);
    886 
    887         // But not writing.
    888         assertWritingClipNotAllowed(subClip, "shouldn't write from granted read");
    889 
    890         // And not to the base path.
    891         assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
    892 
    893         // And not to a sub path.
    894         assertReadingContentUriNotAllowed(subSubUri, "shouldn't read non-granted sub URI");
    895 
    896         // --------------------------------
    897 
    898         // Send another Intent to it.
    899         ReceiveUriService.clearStarted();
    900         grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
    901         ReceiveUriService.waitForStart();
    902 
    903         if (false) {
    904             synchronized (this) {
    905                 Log.i("**", "******************************* WAITING!!!");
    906                 try {
    907                     wait(10000);
    908                 } catch (InterruptedException e) {
    909                 }
    910             }
    911         }
    912 
    913         // See if we now have access to the provider.
    914         assertReadingClipAllowed(sub2Clip);
    915 
    916         // And still to the previous URI.
    917         assertReadingClipAllowed(subClip);
    918 
    919         // But not writing.
    920         assertWritingClipNotAllowed(sub2Clip, "shouldn't write from granted read");
    921 
    922         // And not to the base path.
    923         assertReadingContentUriNotAllowed(uri, "shouldn't read non-granted base URI");
    924 
    925         // And not to a sub path.
    926         assertReadingContentUriNotAllowed(sub2SubUri, "shouldn't read non-granted sub URI");
    927 
    928         // --------------------------------
    929 
    930         // Stop the first command.
    931         ReceiveUriService.stopCurWithId(firstStartId);
    932 
    933         // Ensure reading no longer allowed.
    934         assertReadingClipNotAllowed(subClip, "shouldn't read after losing granted URI");
    935 
    936         // And make sure we can't generate a permission to a running service.
    937         doTryGrantUriActivityPermissionToSelf(subUri,
    938                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
    939         doTryGrantUriActivityPermissionToSelf(subUri,
    940                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    941 
    942         // --------------------------------
    943 
    944         // Dispose of service.
    945         ReceiveUriService.stopSync(getContext());
    946 
    947         // Ensure reading no longer allowed.
    948         assertReadingClipNotAllowed(subClip, "shouldn't read after losing granted URI");
    949         assertReadingClipNotAllowed(sub2Clip, "shouldn't read after losing granted URI");
    950     }
    951 
    952     private void doTestGrantServiceUriWritePermission(Uri uri, boolean useClip) {
    953         final Uri subUri = Uri.withAppendedPath(uri, "foo");
    954         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
    955         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
    956         final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
    957 
    958         ReceiveUriService.stop(getContext());
    959 
    960         final ClipData subClip = useClip ? makeMultiClipData(subUri) : makeSingleClipData(subUri);
    961         final ClipData sub2Clip = useClip ? makeMultiClipData(sub2Uri) : makeSingleClipData(sub2Uri);
    962 
    963         // Precondition: no current access.
    964         assertReadingClipNotAllowed(subClip, "shouldn't read when starting test");
    965         assertReadingClipNotAllowed(sub2Clip, "shouldn't read when starting test");
    966 
    967         // --------------------------------
    968 
    969         ReceiveUriService.clearStarted();
    970         grantClipUriPermission(subClip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
    971         ReceiveUriService.waitForStart();
    972 
    973         int firstStartId = ReceiveUriService.getCurStartId();
    974 
    975         // See if we now have access to the provider.
    976         assertWritingClipAllowed(subClip);
    977 
    978         // But not reading.
    979         assertReadingClipNotAllowed(subClip, "shouldn't read from granted write");
    980 
    981         // And not to the base path.
    982         assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
    983 
    984         // And not a sub-path.
    985         assertWritingContentUriNotAllowed(subSubUri, "shouldn't write non-granted sub URI");
    986 
    987         // --------------------------------
    988 
    989         // Send another Intent to it.
    990         ReceiveUriService.clearStarted();
    991         grantClipUriPermission(sub2Clip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true);
    992         ReceiveUriService.waitForStart();
    993 
    994         // See if we now have access to the provider.
    995         assertWritingClipAllowed(sub2Clip);
    996 
    997         // And still to the previous URI.
    998         assertWritingClipAllowed(subClip);
    999 
   1000         // But not reading.
   1001         assertReadingClipNotAllowed(sub2Clip, "shouldn't read from granted write");
   1002 
   1003         // And not to the base path.
   1004         assertWritingContentUriNotAllowed(uri, "shouldn't write non-granted base URI");
   1005 
   1006         // And not a sub-path.
   1007         assertWritingContentUriNotAllowed(sub2SubUri, "shouldn't write non-granted sub URI");
   1008 
   1009         if (false) {
   1010             synchronized (this) {
   1011                 Log.i("**", "******************************* WAITING!!!");
   1012                 try {
   1013                     wait(10000);
   1014                 } catch (InterruptedException e) {
   1015                 }
   1016             }
   1017         }
   1018 
   1019         // --------------------------------
   1020 
   1021         // Stop the first command.
   1022         ReceiveUriService.stopCurWithId(firstStartId);
   1023 
   1024         // Ensure writing no longer allowed.
   1025         assertWritingClipNotAllowed(subClip, "shouldn't write after losing granted URI");
   1026 
   1027         // And make sure we can't generate a permission to a running service.
   1028         doTryGrantUriActivityPermissionToSelf(subUri,
   1029                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1030         doTryGrantUriActivityPermissionToSelf(subUri,
   1031                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1032 
   1033         // --------------------------------
   1034 
   1035         // Dispose of service.
   1036         ReceiveUriService.stopSync(getContext());
   1037 
   1038         // Ensure writing no longer allowed.
   1039         assertWritingClipNotAllowed(subClip, "shouldn't write after losing granted URI");
   1040         assertWritingClipNotAllowed(sub2Clip, "shouldn't write after losing granted URI");
   1041     }
   1042 
   1043     public void testGrantReadPermissionFromStartService() {
   1044         doTestGrantServiceUriReadPermission(PERM_URI_GRANTING, false);
   1045         doTestGrantServiceUriReadPermission(PERM_URI_GRANTING, true);
   1046     }
   1047 
   1048     public void testGrantWritePermissionFromStartService() {
   1049         doTestGrantServiceUriWritePermission(PERM_URI_GRANTING, false);
   1050         doTestGrantServiceUriWritePermission(PERM_URI_GRANTING, true);
   1051     }
   1052 
   1053     public void testGrantReadPrivateFromStartService() {
   1054         doTestGrantServiceUriReadPermission(PRIV_URI_GRANTING, false);
   1055         doTestGrantServiceUriReadPermission(PRIV_URI_GRANTING, true);
   1056     }
   1057 
   1058     public void testGrantWritePrivateFromStartService() {
   1059         doTestGrantServiceUriWritePermission(PRIV_URI_GRANTING, false);
   1060         doTestGrantServiceUriWritePermission(PRIV_URI_GRANTING, true);
   1061     }
   1062 
   1063     /**
   1064      * Test that ctspermissionwithsignaturepath can't grant read permissions
   1065      * on paths it doesn't have permission to.
   1066      */
   1067     public void testGrantReadUriActivityPathPermissionToSelf() {
   1068         doTryGrantUriActivityPermissionToSelf(PERM_URI_PATH,
   1069                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1070     }
   1071 
   1072     /**
   1073      * Test that ctspermissionwithsignaturepath can't grant write permissions
   1074      * on paths it doesn't have permission to.
   1075      */
   1076     public void testGrantWriteUriActivityPathPermissionToSelf() {
   1077         doTryGrantUriActivityPermissionToSelf(PERM_URI_PATH,
   1078                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1079     }
   1080 
   1081     /**
   1082      * Test that ctspermissionwithsignaturepath can't grant read permissions
   1083      * on paths it doesn't have permission to.
   1084      */
   1085     public void testGrantReadUriActivitySubPathPermissionToSelf() {
   1086         doTryGrantUriActivityPermissionToSelf(
   1087                 Uri.withAppendedPath(PERM_URI_PATH, "foo"),
   1088                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1089     }
   1090 
   1091     /**
   1092      * Test that ctspermissionwithsignaturepath can't grant write permissions
   1093      * on paths it doesn't have permission to.
   1094      */
   1095     public void testGrantWriteUriActivitySubPathPermissionToSelf() {
   1096         doTryGrantUriActivityPermissionToSelf(
   1097                 Uri.withAppendedPath(PERM_URI_PATH, "foo"),
   1098                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1099     }
   1100 
   1101     /**
   1102      * Test that the ctspermissionwithsignaturepath content provider can grant a read
   1103      * permission.
   1104      */
   1105     public void testGrantReadPathPermissionFromStartActivity() {
   1106         doTestGrantActivityUriReadPermission(PERM_URI_PATH, false);
   1107         doTestGrantActivityUriReadPermission(PERM_URI_PATH, true);
   1108     }
   1109 
   1110     /**
   1111      * Test that the ctspermissionwithsignaturepath content provider can grant a write
   1112      * permission.
   1113      */
   1114     public void testGrantWritePathPermissionFromStartActivity() {
   1115         doTestGrantActivityUriWritePermission(PERM_URI_PATH, false);
   1116         doTestGrantActivityUriWritePermission(PERM_URI_PATH, true);
   1117     }
   1118 
   1119     /**
   1120      * Test that the ctspermissionwithsignaturepath content provider can grant a read
   1121      * permission.
   1122      */
   1123     public void testGrantReadPathPermissionFromStartService() {
   1124         doTestGrantServiceUriReadPermission(PERM_URI_PATH, false);
   1125         doTestGrantServiceUriReadPermission(PERM_URI_PATH, true);
   1126     }
   1127 
   1128     /**
   1129      * Test that the ctspermissionwithsignaturepath content provider can grant a write
   1130      * permission.
   1131      */
   1132     public void testGrantWritePathPermissionFromStartService() {
   1133         doTestGrantServiceUriWritePermission(PERM_URI_PATH, false);
   1134         doTestGrantServiceUriWritePermission(PERM_URI_PATH, true);
   1135     }
   1136 
   1137     /**
   1138      * Verify that we can access paths outside the {@code path-permission}
   1139      * protections, which should only rely on {@code provider} permissions.
   1140      */
   1141     public void testRestrictingProviderNoMatchingPath() {
   1142         assertReadingContentUriAllowed(PERM_URI_PATH_RESTRICTING);
   1143         assertWritingContentUriAllowed(PERM_URI_PATH_RESTRICTING);
   1144 
   1145         // allowed by no top-level permission
   1146         final Uri test = PERM_URI_PATH_RESTRICTING.buildUpon().appendPath("fo").build();
   1147         assertReadingContentUriAllowed(test);
   1148         assertWritingContentUriAllowed(test);
   1149     }
   1150 
   1151     /**
   1152      * Verify that paths under {@code path-permission} restriction aren't
   1153      * allowed, even though the {@code provider} requires no permissions.
   1154      */
   1155     public void testRestrictingProviderMatchingPathDenied() {
   1156         // rejected by "foo" prefix
   1157         final Uri test1 = PERM_URI_PATH_RESTRICTING.buildUpon().appendPath("foo").build();
   1158         assertReadingContentUriNotAllowed(test1, null);
   1159         assertWritingContentUriNotAllowed(test1, null);
   1160 
   1161         // rejected by "foo" prefix
   1162         final Uri test2 = PERM_URI_PATH_RESTRICTING.buildUpon()
   1163                 .appendPath("foo").appendPath("ba").build();
   1164         assertReadingContentUriNotAllowed(test2, null);
   1165         assertWritingContentUriNotAllowed(test2, null);
   1166     }
   1167 
   1168     /**
   1169      * Verify that at least one {@code path-permission} rule will grant access,
   1170      * even if the caller doesn't hold another matching {@code path-permission}.
   1171      */
   1172     public void testRestrictingProviderMultipleMatchingPath() {
   1173         // allowed by narrow "foo/bar" prefix
   1174         final Uri test1 = PERM_URI_PATH_RESTRICTING.buildUpon()
   1175                 .appendPath("foo").appendPath("bar").build();
   1176         assertReadingContentUriAllowed(test1);
   1177         assertWritingContentUriAllowed(test1);
   1178 
   1179         // allowed by narrow "foo/bar" prefix
   1180         final Uri test2 = PERM_URI_PATH_RESTRICTING.buildUpon()
   1181                 .appendPath("foo").appendPath("bar2").build();
   1182         assertReadingContentUriAllowed(test2);
   1183         assertWritingContentUriAllowed(test2);
   1184     }
   1185 
   1186     public void testGetMimeTypePermission() {
   1187         // Precondition: no current access.
   1188         assertReadingContentUriNotAllowed(PERM_URI, "shouldn't read when starting test");
   1189         assertWritingContentUriNotAllowed(PERM_URI, "shouldn't write when starting test");
   1190 
   1191         // All apps should be able to get MIME type regardless of permission.
   1192         assertEquals(getContext().getContentResolver().getType(PERM_URI), EXPECTED_MIME_TYPE);
   1193     }
   1194 
   1195     public void testGetMimeTypePrivate() {
   1196         // Precondition: no current access.
   1197         assertReadingContentUriNotAllowed(PRIV_URI, "shouldn't read when starting test");
   1198         assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write when starting test");
   1199 
   1200         // All apps should be able to get MIME type even if provider is private.
   1201         assertEquals(getContext().getContentResolver().getType(PRIV_URI), EXPECTED_MIME_TYPE);
   1202     }
   1203 
   1204     public void testGetMimeTypeAmbiguous() {
   1205         // Precondition: no current access.
   1206         assertReadingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't read when starting test");
   1207         assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write when starting test");
   1208 
   1209         // All apps should be able to get MIME type even if provider is private.
   1210         assertEquals(getContext().getContentResolver().getType(AMBIGUOUS_URI), EXPECTED_MIME_TYPE);
   1211     }
   1212 
   1213     /**
   1214      * Old App Compatibility Test
   1215      *
   1216      * We should be able to access the mime type of a content provider of an older
   1217      * application, even if that application didn't explicitly declare either
   1218      * exported=true or exported=false
   1219      */
   1220     public void testGetMimeTypeAmbiguousCompat() {
   1221         // All apps should be able to get MIME type even if provider is private.
   1222         assertEquals(EXPECTED_MIME_TYPE_AMBIGUOUS,
   1223                 getContext().getContentResolver().getType(AMBIGUOUS_URI_COMPAT));
   1224     }
   1225 
   1226     /**
   1227      * Validate behavior of persistable permission grants.
   1228      */
   1229     public void testGrantPersistableUriPermission() {
   1230         final ContentResolver resolver = getContext().getContentResolver();
   1231 
   1232         final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo");
   1233         final ClipData clip = makeSingleClipData(target);
   1234 
   1235         // Make sure we can't see the target
   1236         assertReadingClipNotAllowed(clip, "reading should have failed");
   1237         assertWritingClipNotAllowed(clip, "writing should have failed");
   1238 
   1239         // Make sure we can't take a grant we don't have
   1240         try {
   1241             resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1242             fail("taking read should have failed");
   1243         } catch (SecurityException expected) {
   1244         }
   1245 
   1246         // And since we were just installed, no persisted grants yet
   1247         assertNoPersistedUriPermission();
   1248 
   1249         // Now, let's grant ourselves some access
   1250         ReceiveUriActivity.clearStarted();
   1251         grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
   1252                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   1253         ReceiveUriActivity.waitForStart();
   1254 
   1255         // We should now have reading access, even before taking the persistable
   1256         // grant. Persisted grants should still be empty.
   1257         assertReadingClipAllowed(clip);
   1258         assertWritingClipNotAllowed(clip, "writing should have failed");
   1259         assertNoPersistedUriPermission();
   1260 
   1261         // Take the read grant and verify we have it!
   1262         long before = System.currentTimeMillis();
   1263         resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1264         long after = System.currentTimeMillis();
   1265         assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after);
   1266 
   1267         // Make sure we can't take a grant we don't have
   1268         try {
   1269             resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1270             fail("taking write should have failed");
   1271         } catch (SecurityException expected) {
   1272         }
   1273 
   1274         // Launch again giving ourselves persistable read and write access
   1275         ReceiveUriActivity.clearNewIntent();
   1276         grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
   1277                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   1278                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   1279         ReceiveUriActivity.waitForNewIntent();
   1280 
   1281         // Previous persisted grant should be unchanged
   1282         assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after);
   1283 
   1284         // We should have both read and write; read is persisted, and write
   1285         // isn't persisted yet.
   1286         assertReadingClipAllowed(clip);
   1287         assertWritingClipAllowed(clip);
   1288 
   1289         // Take again, but still only read; should just update timestamp
   1290         before = System.currentTimeMillis();
   1291         resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1292         after = System.currentTimeMillis();
   1293         assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after);
   1294 
   1295         // And take yet again, both read and write
   1296         before = System.currentTimeMillis();
   1297         resolver.takePersistableUriPermission(target,
   1298                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1299         after = System.currentTimeMillis();
   1300         assertPersistedUriPermission(target,
   1301                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   1302                 before, after);
   1303 
   1304         // Now drop the persisted grant; write first, then read
   1305         resolver.releasePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   1306         assertPersistedUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, before, after);
   1307         resolver.releasePersistableUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   1308         assertNoPersistedUriPermission();
   1309 
   1310         // And even though we dropped the persistable grants, our activity is
   1311         // still running with the global grants (until reboot).
   1312         assertReadingClipAllowed(clip);
   1313         assertWritingClipAllowed(clip);
   1314 
   1315         ReceiveUriActivity.finishCurInstanceSync();
   1316     }
   1317 
   1318     private void assertNoPersistedUriPermission() {
   1319         assertPersistedUriPermission(null, 0, -1, -1);
   1320     }
   1321 
   1322     private void assertPersistedUriPermission(Uri uri, int flags, long before, long after) {
   1323         // Assert local
   1324         final List<UriPermission> perms = getContext()
   1325                 .getContentResolver().getPersistedUriPermissions();
   1326         if (uri != null) {
   1327             assertEquals("expected exactly one permission", 1, perms.size());
   1328 
   1329             final UriPermission perm = perms.get(0);
   1330             assertEquals("unexpected uri", uri, perm.getUri());
   1331 
   1332             final long actual = perm.getPersistedTime();
   1333             if (before != -1) {
   1334                 assertTrue("found " + actual + " before " + before, actual >= before);
   1335             }
   1336             if (after != -1) {
   1337                 assertTrue("found " + actual + " after " + after, actual <= after);
   1338             }
   1339 
   1340             final boolean expectedRead = (flags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0;
   1341             final boolean expectedWrite = (flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0;
   1342             assertEquals("unexpected read status", expectedRead, perm.isReadPermission());
   1343             assertEquals("unexpected write status", expectedWrite, perm.isWritePermission());
   1344 
   1345         } else {
   1346             assertEquals("expected zero permissions", 0, perms.size());
   1347         }
   1348 
   1349         // And assert remote
   1350         Intent intent = new Intent();
   1351         intent.setComponent(GRANT_URI_PERM_COMP);
   1352         intent.setAction(GrantUriPermission.ACTION_VERIFY_OUTGOING_PERSISTED);
   1353         intent.putExtra(GrantUriPermission.EXTRA_URI, uri);
   1354         GrantResultReceiver receiver = new GrantResultReceiver();
   1355         getContext().sendOrderedBroadcast(intent, null, receiver, null, 0, null, null);
   1356         receiver.assertSuccess("unexpected outgoing persisted Uri status");
   1357     }
   1358 }
   1359