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 tearDown()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 assertReadingContentUriNotAllowed(Uri uri, String msg)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 assertReadingContentUriAllowed(Uri uri)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 assertReadingClipNotAllowed(ClipData clip)109 private void assertReadingClipNotAllowed(ClipData clip) { 110 assertReadingClipNotAllowed(clip, null); 111 } 112 assertReadingClipNotAllowed(ClipData clip, String msg)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 assertOpenFileDescriptorModeNotAllowed(Uri uri, String msg, String mode)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 assertWritingContentUriNotAllowed(Uri uri, String msg)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 assertWritingContentUriAllowed(Uri uri)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 assertWritingClipNotAllowed(ClipData clip)203 private void assertWritingClipNotAllowed(ClipData clip) { 204 assertWritingClipNotAllowed(clip, null); 205 } 206 assertWritingClipNotAllowed(ClipData clip, String msg)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 */ testReadProviderWithDiff()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 */ testWriteProviderWithDiff()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 */ testReadProviderWhenPrivate()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 */ testReadProviderWhenAmbiguous()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 */ testReadProviderWhenAmbiguousCompat()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 */ testWriteProviderWhenAmbiguousCompat()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 */ testWriteProviderWhenPrivate()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 */ testWriteProviderWhenAmbiguous()293 public void testWriteProviderWhenAmbiguous() { 294 assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write ambiguous provider"); 295 } 296 makeSingleClipData(Uri uri)297 private static ClipData makeSingleClipData(Uri uri) { 298 return new ClipData("foo", new String[] { "foo/bar" }, 299 new ClipData.Item(uri)); 300 } 301 makeMultiClipData(Uri uri)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 makeClipIntent(ClipData clip, int flags)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 makeClipIntent(Uri uri, int flags)333 private static Intent makeClipIntent(Uri uri, int flags) { 334 return makeClipIntent(makeMultiClipData(uri), flags); 335 } 336 doTryGrantUriActivityPermissionToSelf(Uri uri, int mode)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 */ testGrantReadUriActivityPermissionToSelf()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 */ testGrantWriteUriActivityPermissionToSelf()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 */ testGrantReadUriActivityPrivateToSelf()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 */ testGrantWriteUriActivityPrivateToSelf()394 public void testGrantWriteUriActivityPrivateToSelf() { 395 doTryGrantUriActivityPermissionToSelf( 396 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"), 397 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 398 } 399 doTryGrantUriServicePermissionToSelf(Uri uri, int mode)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 */ testGrantReadUriServicePermissionToSelf()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 */ testGrantWriteUriServicePermissionToSelf()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 */ testGrantReadUriServicePrivateToSelf()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 */ testGrantWriteUriServicePrivateToSelf()453 public void testGrantWriteUriServicePrivateToSelf() { 454 doTryGrantUriServicePermissionToSelf( 455 Uri.withAppendedPath(PRIV_URI_GRANTING, "foo"), 456 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 457 } 458 grantUriPermissionFail(Uri uri, int mode, boolean service)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 doTestGrantUriPermissionFail(Uri uri)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 */ testGrantPermissionNonGrantingFail()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 */ testGrantPermissionOutsideGrantingFail()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 */ testGrantPrivateNonGrantingFail()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 */ testGrantAmbiguousNonGrantingFail()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 */ testGrantPrivateOutsideGrantingFail()533 public void testGrantPrivateOutsideGrantingFail() { 534 doTestGrantUriPermissionFail(PRIV_URI_GRANTING); 535 doTestGrantUriPermissionFail(Uri.withAppendedPath(PRIV_URI_GRANTING, "invalid")); 536 } 537 call(Intent intent)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 grantClipUriPermission(ClipData clip, int mode, boolean service)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 grantClipUriPermissionViaContext(Uri uri, int mode)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 revokeClipUriPermissionViaContext(Uri uri, int mode)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 setPrimaryClip(ClipData clip)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 clearPrimaryClip()591 private void clearPrimaryClip() { 592 Intent intent = new Intent(); 593 intent.setAction(ACTION_CLEAR_PRIMARY_CLIP); 594 call(intent); 595 } 596 assertReadingClipAllowed(ClipData clip)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 doTestGrantActivityUriReadPermission(Uri uri, boolean useClip)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 assertWritingClipAllowed(ClipData clip)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 doTestGrantActivityUriWritePermission(Uri uri, boolean useClip)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 */ testGrantReadPermissionFromStartActivity()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 */ testGrantWritePermissionFromStartActivity()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 */ testGrantReadPrivateFromStartActivity()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 */ testGrantWritePrivateFromStartActivity()852 public void testGrantWritePrivateFromStartActivity() { 853 doTestGrantActivityUriWritePermission(PRIV_URI_GRANTING, true); 854 doTestGrantActivityUriWritePermission(PRIV_URI_GRANTING, false); 855 } 856 doTestGrantServiceUriReadPermission(Uri uri, boolean useClip)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 doTestGrantServiceUriWritePermission(Uri uri, boolean useClip)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 testGrantReadPermissionFromStartService()1039 public void testGrantReadPermissionFromStartService() { 1040 doTestGrantServiceUriReadPermission(PERM_URI_GRANTING, false); 1041 doTestGrantServiceUriReadPermission(PERM_URI_GRANTING, true); 1042 } 1043 testGrantWritePermissionFromStartService()1044 public void testGrantWritePermissionFromStartService() { 1045 doTestGrantServiceUriWritePermission(PERM_URI_GRANTING, false); 1046 doTestGrantServiceUriWritePermission(PERM_URI_GRANTING, true); 1047 } 1048 testGrantReadPrivateFromStartService()1049 public void testGrantReadPrivateFromStartService() { 1050 doTestGrantServiceUriReadPermission(PRIV_URI_GRANTING, false); 1051 doTestGrantServiceUriReadPermission(PRIV_URI_GRANTING, true); 1052 } 1053 testGrantWritePrivateFromStartService()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 */ testGrantReadUriActivityPathPermissionToSelf()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 */ testGrantWriteUriActivityPathPermissionToSelf()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 */ testGrantReadUriActivitySubPathPermissionToSelf()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 */ testGrantWriteUriActivitySubPathPermissionToSelf()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 */ testGrantReadPathPermissionFromStartActivity()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 */ testGrantWritePathPermissionFromStartActivity()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 */ testGrantReadPathPermissionFromStartService()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 */ testGrantWritePathPermissionFromStartService()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 */ testRestrictingProviderNoMatchingPath()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 */ testRestrictingProviderMatchingPathDenied()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 */ testRestrictingProviderMultipleMatchingPath()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 testGetMimeTypePermission()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 testGetMimeTypePrivate()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 testGetMimeTypeAmbiguous()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 */ testGetMimeTypeAmbiguousCompat()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 */ testGrantPersistableUriPermission()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 assertNoPersistedUriPermission()1314 private void assertNoPersistedUriPermission() { 1315 assertPersistedUriPermission(null, 0, -1, -1); 1316 } 1317 assertPersistedUriPermission(Uri uri, int flags, long before, long after)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 */ testGrantPrefixUriPermission()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 testGrantPersistablePrefixUriPermission()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 */ testDirectGrantRevokeUriPermission()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 */ testDirectGrantReceiverRevokeUriPermission()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 testClipboardWithPermission()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 testClipboardWithoutPermission()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 assertClipDataEquals(ClipData expected, ClipData actual)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