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