1 /* 2 * Copyright (C) 2008 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 android.content.cts; 18 19 import static android.Manifest.permission.READ_WALLPAPER_INTERNAL; 20 import static android.content.cts.contenturitestapp.IContentUriTestService.PKG_ACCESS_TYPE_GENERAL; 21 import static android.content.cts.contenturitestapp.IContentUriTestService.PKG_ACCESS_TYPE_GRANT; 22 import static android.content.cts.contenturitestapp.IContentUriTestService.PKG_ACCESS_TYPE_NONE; 23 import static android.content.pm.PackageManager.PERMISSION_DENIED; 24 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 25 26 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 27 28 import static com.android.server.am.Flags.FLAG_USE_PERMISSION_MANAGER_FOR_BROADCAST_DELIVERY_CHECK; 29 30 import static org.junit.Assert.assertEquals; 31 import static org.junit.Assert.assertFalse; 32 import static org.junit.Assert.assertNotNull; 33 import static org.junit.Assert.assertNotSame; 34 import static org.junit.Assert.assertNull; 35 import static org.junit.Assert.assertSame; 36 import static org.junit.Assert.assertTrue; 37 import static org.junit.Assert.fail; 38 39 import android.app.Activity; 40 import android.app.AppOpsManager; 41 import android.app.BroadcastOptions; 42 import android.app.Instrumentation; 43 import android.app.Service; 44 import android.app.WallpaperManager; 45 import android.content.ActivityNotFoundException; 46 import android.content.AttributionSource; 47 import android.content.BroadcastReceiver; 48 import android.content.ComponentName; 49 import android.content.Context; 50 import android.content.ContextParams; 51 import android.content.Intent; 52 import android.content.IntentFilter; 53 import android.content.ServiceConnection; 54 import android.content.SharedPreferences; 55 import android.content.cts.contenturitestapp.IContentUriTestService; 56 import android.content.pm.PackageManager; 57 import android.content.res.ColorStateList; 58 import android.content.res.Resources.NotFoundException; 59 import android.content.res.Resources.Theme; 60 import android.content.res.TypedArray; 61 import android.content.res.XmlResourceParser; 62 import android.database.Cursor; 63 import android.database.sqlite.SQLiteCursorDriver; 64 import android.database.sqlite.SQLiteDatabase; 65 import android.database.sqlite.SQLiteQuery; 66 import android.graphics.Bitmap; 67 import android.graphics.drawable.BitmapDrawable; 68 import android.graphics.drawable.Drawable; 69 import android.net.Uri; 70 import android.net.wifi.WifiManager; 71 import android.os.Binder; 72 import android.os.Build; 73 import android.os.Bundle; 74 import android.os.Handler; 75 import android.os.IBinder; 76 import android.os.Looper; 77 import android.os.Process; 78 import android.os.UserHandle; 79 import android.platform.test.annotations.AppModeFull; 80 import android.platform.test.annotations.RequiresFlagsEnabled; 81 import android.platform.test.flag.junit.CheckFlagsRule; 82 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 83 import android.preference.PreferenceManager; 84 import android.util.AttributeSet; 85 import android.util.Log; 86 import android.util.Xml; 87 import android.view.WindowManager; 88 89 import androidx.test.filters.SdkSuppress; 90 import androidx.test.platform.app.InstrumentationRegistry; 91 92 import com.android.compatibility.common.util.ApiTest; 93 import com.android.compatibility.common.util.PollingCheck; 94 import com.android.compatibility.common.util.ShellIdentityUtils; 95 import com.android.compatibility.common.util.SystemUtil; 96 import com.android.cts.IBinderPermissionTestService; 97 98 import org.junit.After; 99 import org.junit.Before; 100 import org.junit.Rule; 101 import org.junit.Test; 102 import org.junit.runner.RunWith; 103 import org.junit.runners.JUnit4; 104 import org.xmlpull.v1.XmlPullParser; 105 import org.xmlpull.v1.XmlPullParserException; 106 107 import java.io.File; 108 import java.io.FileOutputStream; 109 import java.io.IOException; 110 import java.io.InputStream; 111 import java.util.ArrayList; 112 import java.util.Arrays; 113 import java.util.List; 114 115 @AppModeFull // TODO(Instant) Figure out which APIs should work. 116 @RunWith(JUnit4.class) 117 public class ContextTest { 118 private static final String TAG = "ContextTest"; 119 private static final String ACTUAL_RESULT = "ResultSetByReceiver"; 120 121 private static final String INTIAL_RESULT = "IntialResult"; 122 123 private static final String VALUE_ADDED = "ValueAdded"; 124 private static final String KEY_ADDED = "AddedByReceiver"; 125 126 private static final String VALUE_REMOVED = "ValueWillBeRemove"; 127 private static final String KEY_REMOVED = "ToBeRemoved"; 128 129 private static final String VALUE_KEPT = "ValueKept"; 130 private static final String KEY_KEPT = "ToBeKept"; 131 132 private static final String MOCK_STICKY_ACTION = "android.content.cts.ContextTest." 133 + "STICKY_BROADCAST_RESULT"; 134 135 private static final String ACTION_BROADCAST_TESTORDER = 136 "android.content.cts.ContextTest.BROADCAST_TESTORDER"; 137 private final static String MOCK_ACTION1 = ACTION_BROADCAST_TESTORDER + "1"; 138 private final static String MOCK_ACTION2 = ACTION_BROADCAST_TESTORDER + "2"; 139 140 // Note: keep these constants in sync with the permissions used by BinderPermissionTestService. 141 // 142 // A permission that's granted to this test package. 143 public static final String GRANTED_PERMISSION = "android.permission.USE_CREDENTIALS"; 144 // A permission that's not granted to this test package. 145 public static final String NOT_GRANTED_PERMISSION = "android.permission.HARDWARE_TEST"; 146 147 private static final int BROADCAST_TIMEOUT = 10000; 148 private static final int SERVICE_TIMEOUT = 15000; 149 private static final int ROOT_UID = 0; 150 151 /** 152 * Shell command to broadcast {@link ResultReceiver#MOCK_ACTION} as an external app. 153 */ 154 private static final String EXTERNAL_APP_BROADCAST_COMMAND = 155 "am broadcast -a " + ResultReceiver.MOCK_ACTION + " -f " 156 + Intent.FLAG_RECEIVER_FOREGROUND; 157 158 /* TestService for testCheckContentUriPermissionFull tests. */ 159 private static final String PKG_TEST_SERVICE = "android.content.cts.contenturitestapp"; 160 private static final String CLS_TEST_SERVICE = PKG_TEST_SERVICE + ".TestService"; 161 private static final ComponentName COMPONENT_CONTENT_URI_TEST_SERVICE = 162 new ComponentName(PKG_TEST_SERVICE, CLS_TEST_SERVICE); 163 164 private IContentUriTestService mContentUriTestService; 165 private ServiceConnection mContentUriServiceConnection; 166 167 private Object mLockObj; 168 169 private ArrayList<BroadcastReceiver> mRegisteredReceiverList; 170 171 private boolean mWallpaperChanged; 172 private BitmapDrawable mOriginalWallpaper = null; 173 private volatile IBinderPermissionTestService mBinderPermissionTestService; 174 private ServiceConnection mBinderPermissionTestConnection; 175 176 protected Context mContext; 177 178 @Rule 179 public final CheckFlagsRule mCheckFlagsRule = 180 DeviceFlagsValueProvider.createCheckFlagsRule(); 181 182 /** 183 * Returns the Context object that's being tested. 184 */ getContextUnderTest()185 protected Context getContextUnderTest() { 186 return InstrumentationRegistry.getInstrumentation().getTargetContext(); 187 } 188 getContext()189 public Context getContext() { 190 return mContext; 191 } 192 193 @Before setUp()194 public final void setUp() throws Exception { 195 mContext = getContextUnderTest(); 196 mContext.setTheme(R.style.Test_Theme); 197 198 mLockObj = new Object(); 199 200 mRegisteredReceiverList = new ArrayList<BroadcastReceiver>(); 201 } 202 203 @After tearDown()204 public final void tearDown() throws Exception { 205 if (mOriginalWallpaper != null && mWallpaperChanged) { 206 mContext.setWallpaper(mOriginalWallpaper.getBitmap()); 207 } 208 209 for (BroadcastReceiver receiver : mRegisteredReceiverList) { 210 mContext.unregisterReceiver(receiver); 211 } 212 } 213 214 @Test testGetString()215 public void testGetString() { 216 String testString = mContext.getString(R.string.context_test_string1); 217 assertEquals("This is %s string.", testString); 218 219 testString = mContext.getString(R.string.context_test_string1, "expected"); 220 assertEquals("This is expected string.", testString); 221 222 testString = mContext.getString(R.string.context_test_string2); 223 assertEquals("This is test string.", testString); 224 225 // Test wrong resource id 226 try { 227 testString = mContext.getString(0, "expected"); 228 fail("Wrong resource id should not be accepted."); 229 } catch (NotFoundException e) { 230 } 231 232 // Test wrong resource id 233 try { 234 testString = mContext.getString(0); 235 fail("Wrong resource id should not be accepted."); 236 } catch (NotFoundException e) { 237 } 238 } 239 240 @Test testGetText()241 public void testGetText() { 242 CharSequence testCharSequence = mContext.getText(R.string.context_test_string2); 243 assertEquals("This is test string.", testCharSequence.toString()); 244 245 // Test wrong resource id 246 try { 247 testCharSequence = mContext.getText(0); 248 fail("Wrong resource id should not be accepted."); 249 } catch (NotFoundException e) { 250 } 251 } 252 253 @Test 254 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) testCreateAttributionContext()255 public void testCreateAttributionContext() throws Exception { 256 final String tag = "testCreateAttributionContext"; 257 final Context attrib = mContext.createAttributionContext(tag); 258 assertEquals(tag, attrib.getAttributionTag()); 259 assertEquals(null, mContext.getAttributionTag()); 260 } 261 262 @Test 263 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) testCreateAttributionContextFromParams()264 public void testCreateAttributionContextFromParams() throws Exception { 265 final ContextParams params = new ContextParams.Builder() 266 .setAttributionTag("foo") 267 .setNextAttributionSource(new AttributionSource.Builder(1) 268 .setPackageName("bar") 269 .setAttributionTag("baz") 270 .build()) 271 .build(); 272 final Context attributionContext = getContext().createContext(params); 273 274 assertEquals(params, attributionContext.getParams()); 275 assertEquals(params.getNextAttributionSource(), 276 attributionContext.getAttributionSource().getNext()); 277 assertEquals(params.getAttributionTag(), 278 attributionContext.getAttributionSource().getAttributionTag()); 279 } 280 281 @Test 282 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) testContextParams()283 public void testContextParams() throws Exception { 284 final ContextParams params = new ContextParams.Builder() 285 .setAttributionTag("foo") 286 .setNextAttributionSource(new AttributionSource.Builder(1) 287 .setPackageName("bar") 288 .setAttributionTag("baz") 289 .build()) 290 .build(); 291 292 assertEquals("foo", params.getAttributionTag()); 293 assertEquals(1, params.getNextAttributionSource().getUid()); 294 assertEquals("bar", params.getNextAttributionSource().getPackageName()); 295 assertEquals("baz", params.getNextAttributionSource().getAttributionTag()); 296 } 297 298 // TODO: Add `buildFakeAttributionSource()` and `validateContextParams()` methods back, later 299 // when Android R (sdk version 30) is no longer supported 300 301 @Test 302 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) 303 @ApiTest(apis = {"android.content.AttributionSource.Builder#setNext"}) testAttributionSourceSetNext()304 public void testAttributionSourceSetNext() throws Exception { 305 final AttributionSource next = new AttributionSource.Builder(2) 306 .setPackageName("nextBar") 307 .setAttributionTag("nextBaz") 308 .build(); 309 final ContextParams params = new ContextParams.Builder() 310 .setAttributionTag("foo") 311 .setNextAttributionSource(new AttributionSource.Builder(1) 312 .setPackageName("bar") 313 .setAttributionTag("baz") 314 .setNext(next) 315 .build()) 316 .build(); 317 // Setting a 'next' should not affect prev. 318 assertEquals("foo", params.getAttributionTag()); 319 assertEquals(1, params.getNextAttributionSource().getUid()); 320 assertEquals("bar", params.getNextAttributionSource().getPackageName()); 321 assertEquals("baz", params.getNextAttributionSource().getAttributionTag()); 322 323 final AttributionSource check = 324 params.getNextAttributionSource().getNext(); 325 assertEquals(2, check.getUid()); 326 assertEquals("nextBar", check.getPackageName()); 327 assertEquals("nextBaz", check.getAttributionTag()); 328 } 329 330 @Test 331 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) 332 @ApiTest(apis = {"android.content.AttributionSource.Builder#setNextAttributionSource"}) testAttributionSourceSetNextAttributionSource()333 public void testAttributionSourceSetNextAttributionSource() throws Exception { 334 final AttributionSource next = new AttributionSource.Builder(2) 335 .setPackageName("nextBar") 336 .setAttributionTag("nextBaz") 337 .build(); 338 final ContextParams params = new ContextParams.Builder() 339 .setAttributionTag("foo") 340 .setNextAttributionSource(new AttributionSource.Builder(1) 341 .setPackageName("bar") 342 .setAttributionTag("baz") 343 .setNextAttributionSource(next) 344 .build()) 345 .build(); 346 // Setting a 'next' should not affect prev. 347 assertEquals("foo", params.getAttributionTag()); 348 assertEquals(1, params.getNextAttributionSource().getUid()); 349 assertEquals("bar", params.getNextAttributionSource().getPackageName()); 350 assertEquals("baz", params.getNextAttributionSource().getAttributionTag()); 351 352 final AttributionSource check = 353 params.getNextAttributionSource().getNext(); 354 assertEquals(2, check.getUid()); 355 assertEquals("nextBar", check.getPackageName()); 356 assertEquals("nextBaz", check.getAttributionTag()); 357 } 358 359 @Test testContextParams_Inherit()360 public void testContextParams_Inherit() throws Exception { 361 final ContextParams orig = new ContextParams.Builder() 362 .setAttributionTag("foo").build(); 363 { 364 final ContextParams params = new ContextParams.Builder(orig).build(); 365 assertEquals("foo", params.getAttributionTag()); 366 } 367 { 368 final ContextParams params = new ContextParams.Builder(orig) 369 .setAttributionTag("bar").build(); 370 assertEquals("bar", params.getAttributionTag()); 371 } 372 { 373 final ContextParams params = new ContextParams.Builder(orig) 374 .setAttributionTag(null).build(); 375 assertEquals(null, params.getAttributionTag()); 376 } 377 } 378 379 /** 380 * Ensure that default and device encrypted storage areas are stored 381 * separately on disk. All devices must support these storage areas, even if 382 * they don't have file-based encryption, so that apps can go through a 383 * backup/restore cycle between FBE and non-FBE devices. 384 */ 385 @Test testCreateDeviceProtectedStorageContext()386 public void testCreateDeviceProtectedStorageContext() throws Exception { 387 final Context deviceContext = mContext.createDeviceProtectedStorageContext(); 388 389 assertFalse(mContext.isDeviceProtectedStorage()); 390 assertTrue(deviceContext.isDeviceProtectedStorage()); 391 392 final File defaultFile = new File(mContext.getFilesDir(), "test"); 393 final File deviceFile = new File(deviceContext.getFilesDir(), "test"); 394 395 assertFalse(deviceFile.equals(defaultFile)); 396 397 deviceFile.createNewFile(); 398 399 // Make sure storage areas are mutually exclusive 400 assertFalse(defaultFile.exists()); 401 assertTrue(deviceFile.exists()); 402 } 403 404 @Test testMoveSharedPreferencesFrom()405 public void testMoveSharedPreferencesFrom() throws Exception { 406 final Context deviceContext = mContext.createDeviceProtectedStorageContext(); 407 408 mContext.getSharedPreferences("test", Context.MODE_PRIVATE).edit().putInt("answer", 42) 409 .commit(); 410 411 // Verify that we can migrate 412 assertTrue(deviceContext.moveSharedPreferencesFrom(mContext, "test")); 413 assertEquals(0, mContext.getSharedPreferences("test", Context.MODE_PRIVATE) 414 .getInt("answer", 0)); 415 assertEquals(42, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE) 416 .getInt("answer", 0)); 417 418 // Trying to migrate again when already done is a no-op 419 assertTrue(deviceContext.moveSharedPreferencesFrom(mContext, "test")); 420 assertEquals(0, mContext.getSharedPreferences("test", Context.MODE_PRIVATE) 421 .getInt("answer", 0)); 422 assertEquals(42, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE) 423 .getInt("answer", 0)); 424 425 // Add a new value and verify that we can migrate back 426 deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE).edit() 427 .putInt("question", 24).commit(); 428 429 assertTrue(mContext.moveSharedPreferencesFrom(deviceContext, "test")); 430 assertEquals(42, mContext.getSharedPreferences("test", Context.MODE_PRIVATE) 431 .getInt("answer", 0)); 432 assertEquals(24, mContext.getSharedPreferences("test", Context.MODE_PRIVATE) 433 .getInt("question", 0)); 434 assertEquals(0, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE) 435 .getInt("answer", 0)); 436 assertEquals(0, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE) 437 .getInt("question", 0)); 438 } 439 440 @Test testMoveDatabaseFrom()441 public void testMoveDatabaseFrom() throws Exception { 442 final Context deviceContext = mContext.createDeviceProtectedStorageContext(); 443 444 SQLiteDatabase db = mContext.openOrCreateDatabase("test.db", 445 Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null); 446 db.execSQL("CREATE TABLE list(item TEXT);"); 447 db.execSQL("INSERT INTO list VALUES ('cat')"); 448 db.execSQL("INSERT INTO list VALUES ('dog')"); 449 db.close(); 450 451 // Verify that we can migrate 452 assertTrue(deviceContext.moveDatabaseFrom(mContext, "test.db")); 453 db = deviceContext.openOrCreateDatabase("test.db", 454 Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null); 455 Cursor c = db.query("list", null, null, null, null, null, null); 456 assertEquals(2, c.getCount()); 457 assertTrue(c.moveToFirst()); 458 assertEquals("cat", c.getString(0)); 459 assertTrue(c.moveToNext()); 460 assertEquals("dog", c.getString(0)); 461 c.close(); 462 db.execSQL("INSERT INTO list VALUES ('mouse')"); 463 db.close(); 464 465 // Trying to migrate again when already done is a no-op 466 assertTrue(deviceContext.moveDatabaseFrom(mContext, "test.db")); 467 468 // Verify that we can migrate back 469 assertTrue(mContext.moveDatabaseFrom(deviceContext, "test.db")); 470 db = mContext.openOrCreateDatabase("test.db", 471 Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null); 472 c = db.query("list", null, null, null, null, null, null); 473 assertEquals(3, c.getCount()); 474 assertTrue(c.moveToFirst()); 475 assertEquals("cat", c.getString(0)); 476 assertTrue(c.moveToNext()); 477 assertEquals("dog", c.getString(0)); 478 assertTrue(c.moveToNext()); 479 assertEquals("mouse", c.getString(0)); 480 c.close(); 481 db.close(); 482 } 483 484 @Test testAccessTheme()485 public void testAccessTheme() { 486 mContext.setTheme(R.style.Test_Theme); 487 final Theme testTheme = mContext.getTheme(); 488 assertNotNull(testTheme); 489 490 int[] attrs = { 491 android.R.attr.windowNoTitle, 492 android.R.attr.panelColorForeground, 493 android.R.attr.panelColorBackground 494 }; 495 TypedArray attrArray = null; 496 try { 497 attrArray = testTheme.obtainStyledAttributes(attrs); 498 assertTrue(attrArray.getBoolean(0, false)); 499 assertEquals(0xff000000, attrArray.getColor(1, 0)); 500 assertEquals(0xffffffff, attrArray.getColor(2, 0)); 501 } finally { 502 if (attrArray != null) { 503 attrArray.recycle(); 504 attrArray = null; 505 } 506 } 507 508 // setTheme only works for the first time 509 mContext.setTheme(android.R.style.Theme_Black); 510 assertSame(testTheme, mContext.getTheme()); 511 } 512 513 @Test testObtainStyledAttributes()514 public void testObtainStyledAttributes() { 515 // Test obtainStyledAttributes(int[]) 516 TypedArray testTypedArray = mContext 517 .obtainStyledAttributes(android.R.styleable.View); 518 assertNotNull(testTypedArray); 519 assertTrue(testTypedArray.length() > 2); 520 assertTrue(testTypedArray.length() > 0); 521 testTypedArray.recycle(); 522 523 // Test obtainStyledAttributes(int, int[]) 524 testTypedArray = mContext.obtainStyledAttributes(android.R.style.TextAppearance_Small, 525 android.R.styleable.TextAppearance); 526 assertNotNull(testTypedArray); 527 assertTrue(testTypedArray.length() > 2); 528 testTypedArray.recycle(); 529 530 // Test wrong null array pointer 531 try { 532 testTypedArray = mContext.obtainStyledAttributes(-1, null); 533 fail("obtainStyledAttributes will throw a NullPointerException here."); 534 } catch (NullPointerException e) { 535 } 536 537 // Test obtainStyledAttributes(AttributeSet, int[]) with unavailable resource id. 538 int[] testInt = {0, 0}; 539 testTypedArray = mContext.obtainStyledAttributes(-1, testInt); 540 // fail("Wrong resource id should not be accepted."); 541 assertNotNull(testTypedArray); 542 assertEquals(2, testTypedArray.length()); 543 testTypedArray.recycle(); 544 545 // Test obtainStyledAttributes(AttributeSet, int[]) 546 int[] attrs = android.R.styleable.DatePicker; 547 testTypedArray = mContext.obtainStyledAttributes(getAttributeSet(R.layout.context_layout), 548 attrs); 549 assertNotNull(testTypedArray); 550 assertEquals(attrs.length, testTypedArray.length()); 551 testTypedArray.recycle(); 552 553 // Test obtainStyledAttributes(AttributeSet, int[], int, int) 554 testTypedArray = mContext.obtainStyledAttributes(getAttributeSet(R.layout.context_layout), 555 attrs, 0, 0); 556 assertNotNull(testTypedArray); 557 assertEquals(attrs.length, testTypedArray.length()); 558 testTypedArray.recycle(); 559 } 560 561 @Test testGetSystemService()562 public void testGetSystemService() { 563 // Test invalid service name 564 assertNull(mContext.getSystemService("invalid")); 565 566 // Test valid service name 567 assertNotNull(mContext.getSystemService(Context.WINDOW_SERVICE)); 568 } 569 570 @Test testGetSystemServiceByClass()571 public void testGetSystemServiceByClass() { 572 // Test invalid service class 573 assertNull(mContext.getSystemService(Object.class)); 574 575 // Test valid service name 576 assertNotNull(mContext.getSystemService(WindowManager.class)); 577 assertEquals(mContext.getSystemService(Context.WINDOW_SERVICE), 578 mContext.getSystemService(WindowManager.class)); 579 } 580 581 @Test testGetColorStateList()582 public void testGetColorStateList() { 583 try { 584 mContext.getColorStateList(0); 585 fail("Failed at testGetColorStateList"); 586 } catch (NotFoundException e) { 587 //expected 588 } 589 590 final ColorStateList colorStateList = mContext.getColorStateList(R.color.color2); 591 final int[] focusedState = {android.R.attr.state_focused}; 592 final int focusColor = colorStateList.getColorForState(focusedState, R.color.failColor); 593 assertEquals(0xffff0000, focusColor); 594 } 595 596 @Test testGetColor()597 public void testGetColor() { 598 try { 599 mContext.getColor(0); 600 fail("Failed at testGetColor"); 601 } catch (NotFoundException e) { 602 //expected 603 } 604 605 final int color = mContext.getColor(R.color.color2); 606 assertEquals(0xffffff00, color); 607 } 608 609 /** 610 * Developers have come to expect at least ext4-style filename behavior, so 611 * verify that the underlying filesystem supports them. 612 */ 613 @Test testFilenames()614 public void testFilenames() throws Exception { 615 final File base = mContext.getFilesDir(); 616 assertValidFile(new File(base, "foo")); 617 assertValidFile(new File(base, ".bar")); 618 assertValidFile(new File(base, "foo.bar")); 619 assertValidFile(new File(base, "\u2603")); 620 assertValidFile(new File(base, "\uD83D\uDCA9")); 621 622 final int pid = android.os.Process.myPid(); 623 final StringBuilder sb = new StringBuilder(255); 624 while (sb.length() <= 255) { 625 sb.append(pid); 626 sb.append(mContext.getPackageName()); 627 } 628 sb.setLength(255); 629 630 final String longName = sb.toString(); 631 final File longDir = new File(base, longName); 632 assertValidFile(longDir); 633 longDir.mkdir(); 634 final File longFile = new File(longDir, longName); 635 assertValidFile(longFile); 636 } 637 638 @Test testMainLooper()639 public void testMainLooper() throws Exception { 640 final Thread mainThread = Looper.getMainLooper().getThread(); 641 final Handler handler = new Handler(mContext.getMainLooper()); 642 handler.post(() -> { 643 assertEquals(mainThread, Thread.currentThread()); 644 }); 645 } 646 647 @Test testMainExecutor()648 public void testMainExecutor() throws Exception { 649 final Thread mainThread = Looper.getMainLooper().getThread(); 650 mContext.getMainExecutor().execute(() -> { 651 assertEquals(mainThread, Thread.currentThread()); 652 }); 653 } 654 assertValidFile(File file)655 private void assertValidFile(File file) throws Exception { 656 Log.d(TAG, "Checking " + file); 657 if (file.exists()) { 658 assertTrue("File already exists and couldn't be deleted before test: " + file, 659 file.delete()); 660 } 661 assertTrue("Failed to create " + file, file.createNewFile()); 662 assertTrue("Doesn't exist after create " + file, file.exists()); 663 assertTrue("Failed to delete after create " + file, file.delete()); 664 new FileOutputStream(file).close(); 665 assertTrue("Doesn't exist after stream " + file, file.exists()); 666 assertTrue("Failed to delete after stream " + file, file.delete()); 667 } 668 beginDocument(XmlPullParser parser, String firstElementName)669 static void beginDocument(XmlPullParser parser, String firstElementName) 670 throws XmlPullParserException, IOException { 671 int type; 672 while ((type = parser.next()) != parser.START_TAG 673 && type != parser.END_DOCUMENT) { 674 ; 675 } 676 677 if (type != parser.START_TAG) { 678 throw new XmlPullParserException("No start tag found"); 679 } 680 681 if (!parser.getName().equals(firstElementName)) { 682 throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() + 683 ", expected " + firstElementName); 684 } 685 } 686 getAttributeSet(int resourceId)687 private AttributeSet getAttributeSet(int resourceId) { 688 final XmlResourceParser parser = mContext.getResources().getXml( 689 resourceId); 690 691 try { 692 beginDocument(parser, "RelativeLayout"); 693 } catch (XmlPullParserException e) { 694 e.printStackTrace(); 695 } catch (IOException e) { 696 e.printStackTrace(); 697 } 698 699 final AttributeSet attr = Xml.asAttributeSet(parser); 700 assertNotNull(attr); 701 return attr; 702 } 703 registerBroadcastReceiver(BroadcastReceiver receiver, IntentFilter filter)704 private void registerBroadcastReceiver(BroadcastReceiver receiver, IntentFilter filter) { 705 registerBroadcastReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED); 706 } 707 registerBroadcastReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags)708 private void registerBroadcastReceiver(BroadcastReceiver receiver, IntentFilter filter, 709 int flags) { 710 mContext.registerReceiver(receiver, filter, flags); 711 712 mRegisteredReceiverList.add(receiver); 713 } 714 715 @Test testSendOrderedBroadcast1()716 public void testSendOrderedBroadcast1() throws InterruptedException { 717 final HighPriorityBroadcastReceiver highPriorityReceiver = 718 new HighPriorityBroadcastReceiver(); 719 final LowPriorityBroadcastReceiver lowPriorityReceiver = 720 new LowPriorityBroadcastReceiver(); 721 722 final IntentFilter filterHighPriority = new IntentFilter(ResultReceiver.MOCK_ACTION); 723 filterHighPriority.setPriority(1); 724 final IntentFilter filterLowPriority = new IntentFilter(ResultReceiver.MOCK_ACTION); 725 registerBroadcastReceiver(highPriorityReceiver, filterHighPriority); 726 registerBroadcastReceiver(lowPriorityReceiver, filterLowPriority); 727 728 final Intent broadcastIntent = new Intent(ResultReceiver.MOCK_ACTION) 729 .setPackage(mContext.getPackageName()); 730 broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 731 mContext.sendOrderedBroadcast(broadcastIntent, null); 732 new PollingCheck(BROADCAST_TIMEOUT) { 733 @Override 734 protected boolean check() { 735 return highPriorityReceiver.hasReceivedBroadCast() 736 && !lowPriorityReceiver.hasReceivedBroadCast(); 737 } 738 }.run(); 739 740 synchronized (highPriorityReceiver) { 741 highPriorityReceiver.notify(); 742 } 743 744 new PollingCheck(BROADCAST_TIMEOUT) { 745 @Override 746 protected boolean check() { 747 return highPriorityReceiver.hasReceivedBroadCast() 748 && lowPriorityReceiver.hasReceivedBroadCast(); 749 } 750 }.run(); 751 } 752 753 @Test testSendOrderedBroadcast2()754 public void testSendOrderedBroadcast2() throws InterruptedException { 755 final TestBroadcastReceiver broadcastReceiver = new TestBroadcastReceiver(); 756 broadcastReceiver.mIsOrderedBroadcasts = true; 757 758 Bundle bundle = new Bundle(); 759 bundle.putString(KEY_KEPT, VALUE_KEPT); 760 bundle.putString(KEY_REMOVED, VALUE_REMOVED); 761 Intent intent = new Intent(ResultReceiver.MOCK_ACTION) 762 .setPackage(mContext.getPackageName()); 763 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 764 mContext.sendOrderedBroadcast(intent, null, broadcastReceiver, null, 1, 765 INTIAL_RESULT, bundle); 766 767 synchronized (mLockObj) { 768 try { 769 mLockObj.wait(BROADCAST_TIMEOUT); 770 } catch (InterruptedException e) { 771 fail("unexpected InterruptedException."); 772 } 773 } 774 775 assertTrue("Receiver didn't make any response.", broadcastReceiver.hadReceivedBroadCast()); 776 assertEquals("Incorrect code: " + broadcastReceiver.getResultCode(), 3, 777 broadcastReceiver.getResultCode()); 778 assertEquals(ACTUAL_RESULT, broadcastReceiver.getResultData()); 779 Bundle resultExtras = broadcastReceiver.getResultExtras(false); 780 assertEquals(VALUE_ADDED, resultExtras.getString(KEY_ADDED)); 781 assertEquals(VALUE_KEPT, resultExtras.getString(KEY_KEPT)); 782 assertNull(resultExtras.getString(KEY_REMOVED)); 783 } 784 785 @Test testSendOrderedBroadcastWithAppOp()786 public void testSendOrderedBroadcastWithAppOp() { 787 // we use a HighPriorityBroadcastReceiver because the final receiver should get the 788 // broadcast only at the end. 789 final ResultReceiver receiver = new HighPriorityBroadcastReceiver(); 790 final ResultReceiver finalReceiver = new ResultReceiver(); 791 792 setAppOpMode(AppOpsManager.OPSTR_READ_CELL_BROADCASTS, AppOpsManager.MODE_ALLOWED); 793 794 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 795 796 mContext.sendOrderedBroadcast( 797 new Intent(ResultReceiver.MOCK_ACTION).setPackage(mContext.getPackageName()), 798 null, // permission 799 AppOpsManager.OPSTR_READ_CELL_BROADCASTS, 800 finalReceiver, 801 null, // scheduler 802 0, // initial code 803 null, //initial data 804 null); // initial extras 805 806 new PollingCheck(BROADCAST_TIMEOUT) { 807 @Override 808 protected boolean check() { 809 return receiver.hasReceivedBroadCast() 810 && !finalReceiver.hasReceivedBroadCast(); 811 } 812 }.run(); 813 814 synchronized (receiver) { 815 receiver.notify(); 816 } 817 818 new PollingCheck(BROADCAST_TIMEOUT) { 819 @Override 820 protected boolean check() { 821 // ensure that first receiver has received broadcast before final receiver 822 return receiver.hasReceivedBroadCast() 823 && finalReceiver.hasReceivedBroadCast(); 824 } 825 }.run(); 826 } 827 828 @Test testSendOrderedBroadcastWithAppOp_NotGranted()829 public void testSendOrderedBroadcastWithAppOp_NotGranted() { 830 final ResultReceiver receiver = new ResultReceiver(); 831 setAppOpMode(AppOpsManager.OPSTR_READ_CELL_BROADCASTS, AppOpsManager.MODE_ERRORED); 832 833 834 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 835 836 mContext.sendOrderedBroadcast( 837 new Intent(ResultReceiver.MOCK_ACTION).setPackage(mContext.getPackageName()), 838 null, // permission 839 AppOpsManager.OPSTR_READ_CELL_BROADCASTS, 840 null, // final receiver 841 null, // scheduler 842 0, // initial code 843 null, //initial data 844 null); // initial extras 845 846 boolean broadcastNeverSent = false; 847 try { 848 new PollingCheck(BROADCAST_TIMEOUT) { 849 @Override 850 protected boolean check() { 851 return receiver.hasReceivedBroadCast(); 852 } 853 854 public void runWithInterruption() throws InterruptedException { 855 if (check()) { 856 return; 857 } 858 859 long timeout = BROADCAST_TIMEOUT; 860 while (timeout > 0) { 861 try { 862 Thread.sleep(50 /* time slice */); 863 } catch (InterruptedException e) { 864 fail("unexpected InterruptedException"); 865 } 866 867 if (check()) { 868 return; 869 } 870 871 timeout -= 50; // time slice 872 } 873 throw new InterruptedException(); 874 } 875 }.runWithInterruption(); 876 } catch (InterruptedException e) { 877 broadcastNeverSent = true; 878 } 879 880 assertTrue(broadcastNeverSent); 881 } 882 883 @Test testRegisterReceiver1()884 public void testRegisterReceiver1() throws InterruptedException { 885 final FilteredReceiver broadcastReceiver = new FilteredReceiver(); 886 final IntentFilter filter = new IntentFilter(MOCK_ACTION1); 887 888 // Test registerReceiver 889 mContext.registerReceiver(broadcastReceiver, filter, Context.RECEIVER_EXPORTED_UNAUDITED); 890 891 // Test unwanted intent(action = MOCK_ACTION2) 892 broadcastReceiver.reset(); 893 waitForFilteredIntent(mContext, MOCK_ACTION2); 894 assertFalse(broadcastReceiver.hadReceivedBroadCast1()); 895 assertFalse(broadcastReceiver.hadReceivedBroadCast2()); 896 897 // Send wanted intent(action = MOCK_ACTION1) 898 broadcastReceiver.reset(); 899 waitForFilteredIntent(mContext, MOCK_ACTION1); 900 assertTrue(broadcastReceiver.hadReceivedBroadCast1()); 901 assertFalse(broadcastReceiver.hadReceivedBroadCast2()); 902 903 mContext.unregisterReceiver(broadcastReceiver); 904 905 // Test unregisterReceiver 906 FilteredReceiver broadcastReceiver2 = new FilteredReceiver(); 907 mContext.registerReceiver(broadcastReceiver2, filter, Context.RECEIVER_EXPORTED_UNAUDITED); 908 mContext.unregisterReceiver(broadcastReceiver2); 909 910 // Test unwanted intent(action = MOCK_ACTION2) 911 broadcastReceiver2.reset(); 912 waitForFilteredIntent(mContext, MOCK_ACTION2); 913 assertFalse(broadcastReceiver2.hadReceivedBroadCast1()); 914 assertFalse(broadcastReceiver2.hadReceivedBroadCast2()); 915 916 // Send wanted intent(action = MOCK_ACTION1), but the receiver is unregistered. 917 broadcastReceiver2.reset(); 918 waitForFilteredIntent(mContext, MOCK_ACTION1); 919 assertFalse(broadcastReceiver2.hadReceivedBroadCast1()); 920 assertFalse(broadcastReceiver2.hadReceivedBroadCast2()); 921 } 922 923 @Test testRegisterReceiver2()924 public void testRegisterReceiver2() throws InterruptedException { 925 FilteredReceiver broadcastReceiver = new FilteredReceiver(); 926 IntentFilter filter = new IntentFilter(); 927 filter.addAction(MOCK_ACTION1); 928 929 // Test registerReceiver 930 mContext.registerReceiver(broadcastReceiver, filter, null, null, 931 Context.RECEIVER_EXPORTED_UNAUDITED); 932 933 // Test unwanted intent(action = MOCK_ACTION2) 934 broadcastReceiver.reset(); 935 waitForFilteredIntent(mContext, MOCK_ACTION2); 936 assertFalse(broadcastReceiver.hadReceivedBroadCast1()); 937 assertFalse(broadcastReceiver.hadReceivedBroadCast2()); 938 939 // Send wanted intent(action = MOCK_ACTION1) 940 broadcastReceiver.reset(); 941 waitForFilteredIntent(mContext, MOCK_ACTION1); 942 assertTrue(broadcastReceiver.hadReceivedBroadCast1()); 943 assertFalse(broadcastReceiver.hadReceivedBroadCast2()); 944 945 mContext.unregisterReceiver(broadcastReceiver); 946 } 947 948 @Test testRegisterReceiverForAllUsers()949 public void testRegisterReceiverForAllUsers() throws InterruptedException { 950 FilteredReceiver broadcastReceiver = new FilteredReceiver(); 951 IntentFilter filter = new IntentFilter(); 952 filter.addAction(MOCK_ACTION1); 953 954 // Test registerReceiverForAllUsers without permission: verify SecurityException. 955 try { 956 mContext.registerReceiverForAllUsers(broadcastReceiver, filter, null, null, 957 Context.RECEIVER_EXPORTED_UNAUDITED); 958 fail("testRegisterReceiverForAllUsers: " 959 + "SecurityException expected on registerReceiverForAllUsers"); 960 } catch (SecurityException se) { 961 // expected 962 } 963 964 // Test registerReceiverForAllUsers with permission. 965 try { 966 ShellIdentityUtils.invokeMethodWithShellPermissions( 967 mContext, 968 (ctx) -> ctx.registerReceiverForAllUsers(broadcastReceiver, filter, null, null, 969 Context.RECEIVER_EXPORTED_UNAUDITED) 970 ); 971 } catch (SecurityException se) { 972 fail("testRegisterReceiverForAllUsers: SecurityException not expected"); 973 } 974 975 // Test unwanted intent(action = MOCK_ACTION2) 976 broadcastReceiver.reset(); 977 waitForFilteredIntent(mContext, MOCK_ACTION2); 978 assertFalse(broadcastReceiver.hadReceivedBroadCast1()); 979 assertFalse(broadcastReceiver.hadReceivedBroadCast2()); 980 981 // Send wanted intent(action = MOCK_ACTION1) 982 broadcastReceiver.reset(); 983 waitForFilteredIntent(mContext, MOCK_ACTION1); 984 assertTrue(broadcastReceiver.hadReceivedBroadCast1()); 985 assertEquals(broadcastReceiver.getSendingUser(), Process.myUserHandle()); 986 assertFalse(broadcastReceiver.hadReceivedBroadCast2()); 987 988 mContext.unregisterReceiver(broadcastReceiver); 989 } 990 991 @Test testAccessWallpaper()992 public void testAccessWallpaper() throws IOException, InterruptedException { 993 if (!isWallpaperSupported()) return; 994 995 SystemUtil.runWithShellPermissionIdentity( 996 () -> mOriginalWallpaper = (BitmapDrawable) mContext.getWallpaper(), 997 READ_WALLPAPER_INTERNAL); 998 999 // set Wallpaper by context#setWallpaper(Bitmap) 1000 Bitmap bitmap = Bitmap.createBitmap(20, 30, Bitmap.Config.RGB_565); 1001 1002 // grant permission READ_WALLPAPER_INTERNAL for the whole test 1003 SystemUtil.runWithShellPermissionIdentity(() -> { 1004 // Test getWallpaper 1005 Drawable testDrawable = mContext.getWallpaper(); 1006 // Test peekWallpaper 1007 Drawable testDrawable2 = mContext.peekWallpaper(); 1008 1009 mContext.setWallpaper(bitmap); 1010 mWallpaperChanged = true; 1011 synchronized (this) { 1012 wait(500); 1013 } 1014 1015 assertNotSame(testDrawable, mContext.peekWallpaper()); 1016 assertNotNull(mContext.getWallpaper()); 1017 assertNotSame(testDrawable2, mContext.peekWallpaper()); 1018 assertNotNull(mContext.peekWallpaper()); 1019 1020 // set Wallpaper by context#setWallpaper(InputStream) 1021 mContext.clearWallpaper(); 1022 1023 testDrawable = mContext.getWallpaper(); 1024 InputStream stream = mContext.getResources().openRawResource(R.drawable.scenery); 1025 1026 mContext.setWallpaper(stream); 1027 synchronized (this) { 1028 wait(1000); 1029 } 1030 1031 assertNotSame(testDrawable, mContext.peekWallpaper()); 1032 }, READ_WALLPAPER_INTERNAL); 1033 } 1034 1035 @Test testAccessDatabase()1036 public void testAccessDatabase() { 1037 String DATABASE_NAME = "databasetest"; 1038 String DATABASE_NAME1 = DATABASE_NAME + "1"; 1039 String DATABASE_NAME2 = DATABASE_NAME + "2"; 1040 SQLiteDatabase mDatabase; 1041 File mDatabaseFile; 1042 1043 SQLiteDatabase.CursorFactory factory = new SQLiteDatabase.CursorFactory() { 1044 public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery, 1045 String editTable, SQLiteQuery query) { 1046 return new android.database.sqlite.SQLiteCursor(db, masterQuery, editTable, query) { 1047 @Override 1048 public boolean requery() { 1049 setSelectionArguments(new String[]{"2"}); 1050 return super.requery(); 1051 } 1052 }; 1053 } 1054 }; 1055 1056 // FIXME: Move cleanup into tearDown() 1057 for (String db : mContext.databaseList()) { 1058 File f = mContext.getDatabasePath(db); 1059 if (f.exists()) { 1060 mContext.deleteDatabase(db); 1061 } 1062 } 1063 1064 // Test openOrCreateDatabase with null and actual factory 1065 mDatabase = mContext.openOrCreateDatabase(DATABASE_NAME1, 1066 Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, factory); 1067 assertNotNull(mDatabase); 1068 mDatabase.close(); 1069 mDatabase = mContext.openOrCreateDatabase(DATABASE_NAME2, 1070 Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, factory); 1071 assertNotNull(mDatabase); 1072 mDatabase.close(); 1073 1074 // Test getDatabasePath 1075 File actualDBPath = mContext.getDatabasePath(DATABASE_NAME1); 1076 1077 // Test databaseList() 1078 List<String> list = Arrays.asList(mContext.databaseList()); 1079 assertTrue("1) database list: " + list, list.contains(DATABASE_NAME1)); 1080 assertTrue("2) database list: " + list, list.contains(DATABASE_NAME2)); 1081 1082 // Test deleteDatabase() 1083 for (int i = 1; i < 3; i++) { 1084 mDatabaseFile = mContext.getDatabasePath(DATABASE_NAME + i); 1085 assertTrue(mDatabaseFile.exists()); 1086 mContext.deleteDatabase(DATABASE_NAME + i); 1087 mDatabaseFile = new File(actualDBPath, DATABASE_NAME + i); 1088 assertFalse(mDatabaseFile.exists()); 1089 } 1090 } 1091 1092 @Test testEnforceUriPermission1()1093 public void testEnforceUriPermission1() { 1094 try { 1095 Uri uri = Uri.parse("content://ctstest"); 1096 mContext.enforceUriPermission(uri, Binder.getCallingPid(), 1097 Binder.getCallingUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 1098 "enforceUriPermission is not working without possessing an IPC."); 1099 fail("enforceUriPermission is not working without possessing an IPC."); 1100 } catch (SecurityException e) { 1101 // If the function is OK, it should throw a SecurityException here because currently no 1102 // IPC is handled by this process. 1103 } 1104 } 1105 1106 @Test testEnforceUriPermission2()1107 public void testEnforceUriPermission2() { 1108 Uri uri = Uri.parse("content://ctstest"); 1109 try { 1110 mContext.enforceUriPermission(uri, NOT_GRANTED_PERMISSION, 1111 NOT_GRANTED_PERMISSION, Binder.getCallingPid(), Binder.getCallingUid(), 1112 Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 1113 "enforceUriPermission is not working without possessing an IPC."); 1114 fail("enforceUriPermission is not working without possessing an IPC."); 1115 } catch (SecurityException e) { 1116 // If the function is ok, it should throw a SecurityException here because currently no 1117 // IPC is handled by this process. 1118 } 1119 } 1120 1121 @Test testGetPackageResourcePath()1122 public void testGetPackageResourcePath() { 1123 assertNotNull(mContext.getPackageResourcePath()); 1124 } 1125 1126 @Test testStartActivityWithActivityNotFound()1127 public void testStartActivityWithActivityNotFound() { 1128 Intent intent = new Intent(mContext, ContextCtsActivity.class); 1129 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1130 try { 1131 mContext.startActivity(intent); 1132 fail("Test startActivity should throw a ActivityNotFoundException here."); 1133 } catch (ActivityNotFoundException e) { 1134 // Because ContextWrapper is a wrapper class, so no need to test 1135 // the details of the function's performance. Getting a result 1136 // from the wrapped class is enough for testing. 1137 } 1138 } 1139 1140 @Test testStartActivities()1141 public void testStartActivities() throws Exception { 1142 final Intent[] intents = { 1143 new Intent().setComponent(new ComponentName(mContext, 1144 AvailableIntentsActivity.class)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 1145 new Intent().setComponent(new ComponentName(mContext, 1146 ImageCaptureActivity.class)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 1147 }; 1148 1149 final Instrumentation.ActivityMonitor firstMonitor = getInstrumentation() 1150 .addMonitor(AvailableIntentsActivity.class.getName(), null /* result */, 1151 false /* block */); 1152 final Instrumentation.ActivityMonitor secondMonitor = getInstrumentation() 1153 .addMonitor(ImageCaptureActivity.class.getName(), null /* result */, 1154 false /* block */); 1155 1156 mContext.startActivities(intents); 1157 1158 Activity firstActivity = getInstrumentation().waitForMonitorWithTimeout(firstMonitor, 5000); 1159 assertNotNull(firstActivity); 1160 1161 Activity secondActivity = getInstrumentation().waitForMonitorWithTimeout(secondMonitor, 1162 5000); 1163 assertNotNull(secondActivity); 1164 } 1165 1166 @Test testStartActivityAsUser()1167 public void testStartActivityAsUser() { 1168 try (ActivitySession activitySession = new ActivitySession()) { 1169 Intent intent = new Intent(mContext, AvailableIntentsActivity.class); 1170 1171 activitySession.assertActivityLaunched(intent.getComponent().getClassName(), 1172 () -> SystemUtil.runWithShellPermissionIdentity(() -> 1173 mContext.startActivityAsUser(intent, UserHandle.CURRENT))); 1174 } 1175 } 1176 1177 @Test testStartActivity()1178 public void testStartActivity() { 1179 try (ActivitySession activitySession = new ActivitySession()) { 1180 Intent intent = new Intent(mContext, AvailableIntentsActivity.class); 1181 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1182 1183 activitySession.assertActivityLaunched(intent.getComponent().getClassName(), 1184 () -> mContext.startActivity(intent)); 1185 } 1186 } 1187 1188 /** 1189 * Helper class to launch / close test activity. 1190 */ 1191 private class ActivitySession implements AutoCloseable { 1192 private Activity mTestActivity; 1193 private static final int ACTIVITY_LAUNCH_TIMEOUT = 5000; 1194 assertActivityLaunched(String activityClassName, Runnable activityStarter)1195 void assertActivityLaunched(String activityClassName, Runnable activityStarter) { 1196 final Instrumentation.ActivityMonitor monitor = getInstrumentation() 1197 .addMonitor(activityClassName, null /* result */, 1198 false /* block */); 1199 activityStarter.run(); 1200 // Wait for activity launch with timeout. 1201 mTestActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 1202 ACTIVITY_LAUNCH_TIMEOUT); 1203 assertNotNull(mTestActivity); 1204 } 1205 1206 @Override close()1207 public void close() { 1208 if (mTestActivity != null) { 1209 mTestActivity.finishAndRemoveTask(); 1210 } 1211 } 1212 } 1213 1214 @Test testCreatePackageContext()1215 public void testCreatePackageContext() throws PackageManager.NameNotFoundException { 1216 Context actualContext = mContext.createPackageContext("com.android.shell", 1217 Context.CONTEXT_IGNORE_SECURITY); 1218 1219 assertNotNull(actualContext); 1220 } 1221 1222 @Test testCreatePackageContextAsUser()1223 public void testCreatePackageContextAsUser() throws Exception { 1224 for (UserHandle user : new UserHandle[]{ 1225 android.os.Process.myUserHandle(), 1226 UserHandle.ALL, UserHandle.CURRENT, UserHandle.SYSTEM 1227 }) { 1228 assertEquals(user, mContext 1229 .createPackageContextAsUser("com.android.shell", 0, user).getUser()); 1230 } 1231 } 1232 1233 @Test testCreateContextAsUser()1234 public void testCreateContextAsUser() throws Exception { 1235 for (UserHandle user : new UserHandle[]{ 1236 android.os.Process.myUserHandle(), 1237 UserHandle.ALL, UserHandle.CURRENT, UserHandle.SYSTEM 1238 }) { 1239 assertEquals(user, mContext.createContextAsUser(user, 0).getUser()); 1240 } 1241 } 1242 1243 @Test testGetMainLooper()1244 public void testGetMainLooper() { 1245 assertNotNull(mContext.getMainLooper()); 1246 } 1247 1248 @Test testGetApplicationContext()1249 public void testGetApplicationContext() { 1250 assertSame(mContext.getApplicationContext(), mContext.getApplicationContext()); 1251 } 1252 1253 @Test testGetSharedPreferences()1254 public void testGetSharedPreferences() { 1255 SharedPreferences sp; 1256 SharedPreferences localSP; 1257 1258 sp = PreferenceManager.getDefaultSharedPreferences(mContext); 1259 String packageName = mContext.getPackageName(); 1260 localSP = mContext.getSharedPreferences(packageName + "_preferences", 1261 Context.MODE_PRIVATE); 1262 assertSame(sp, localSP); 1263 } 1264 1265 @Test testRevokeUriPermission()1266 public void testRevokeUriPermission() { 1267 Uri uri = Uri.parse("contents://ctstest"); 1268 mContext.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1269 } 1270 1271 @Test testAccessService()1272 public void testAccessService() throws InterruptedException { 1273 MockContextService.reset(); 1274 bindExpectResult(mContext, new Intent(mContext, MockContextService.class)); 1275 1276 // Check startService 1277 assertTrue(MockContextService.hadCalledOnStart()); 1278 // Check bindService 1279 assertTrue(MockContextService.hadCalledOnBind()); 1280 1281 assertTrue(MockContextService.hadCalledOnDestory()); 1282 // Check unbinService 1283 assertTrue(MockContextService.hadCalledOnUnbind()); 1284 } 1285 1286 @Test testGetPackageCodePath()1287 public void testGetPackageCodePath() { 1288 assertNotNull(mContext.getPackageCodePath()); 1289 } 1290 1291 @Test testGetPackageName()1292 public void testGetPackageName() { 1293 assertEquals("android.content.cts", mContext.getPackageName()); 1294 } 1295 1296 @Test testGetCacheDir()1297 public void testGetCacheDir() { 1298 assertNotNull(mContext.getCacheDir()); 1299 } 1300 1301 @Test testGetContentResolver()1302 public void testGetContentResolver() { 1303 assertSame(mContext.getContentResolver(), mContext.getContentResolver()); 1304 } 1305 1306 @Test testGetFileStreamPath()1307 public void testGetFileStreamPath() { 1308 String TEST_FILENAME = "TestGetFileStreamPath"; 1309 1310 // Test the path including the input filename 1311 String fileStreamPath = mContext.getFileStreamPath(TEST_FILENAME).toString(); 1312 assertTrue(fileStreamPath.indexOf(TEST_FILENAME) >= 0); 1313 } 1314 1315 @Test testGetClassLoader()1316 public void testGetClassLoader() { 1317 assertSame(mContext.getClassLoader(), mContext.getClassLoader()); 1318 } 1319 1320 @Test testGetWallpaperDesiredMinimumHeightAndWidth()1321 public void testGetWallpaperDesiredMinimumHeightAndWidth() { 1322 if (!isWallpaperSupported()) return; 1323 1324 int height = mContext.getWallpaperDesiredMinimumHeight(); 1325 int width = mContext.getWallpaperDesiredMinimumWidth(); 1326 1327 // returned value is <= 0, the caller should use the height of the 1328 // default display instead. 1329 // That is to say, the return values of desired minimumHeight and 1330 // minimunWidth are at the same side of 0-dividing line. 1331 assertTrue((height > 0 && width > 0) || (height <= 0 && width <= 0)); 1332 } 1333 1334 @Test testAccessStickyBroadcast()1335 public void testAccessStickyBroadcast() throws InterruptedException { 1336 ResultReceiver resultReceiver = new ResultReceiver(); 1337 1338 Intent intent = new Intent(MOCK_STICKY_ACTION); 1339 TestBroadcastReceiver stickyReceiver = new TestBroadcastReceiver(); 1340 1341 mContext.sendStickyBroadcast(intent); 1342 1343 waitForReceiveBroadCast(resultReceiver); 1344 1345 assertEquals(intent.getAction(), 1346 mContext.registerReceiver(stickyReceiver, new IntentFilter(MOCK_STICKY_ACTION), 1347 Context.RECEIVER_NOT_EXPORTED).getAction()); 1348 1349 synchronized (mLockObj) { 1350 mLockObj.wait(BROADCAST_TIMEOUT); 1351 } 1352 1353 assertTrue("Receiver didn't make any response.", stickyReceiver.hadReceivedBroadCast()); 1354 1355 mContext.unregisterReceiver(stickyReceiver); 1356 mContext.removeStickyBroadcast(intent); 1357 1358 assertNull(mContext.registerReceiver(stickyReceiver, 1359 new IntentFilter(MOCK_STICKY_ACTION), Context.RECEIVER_EXPORTED_UNAUDITED)); 1360 mContext.unregisterReceiver(stickyReceiver); 1361 } 1362 1363 @Test testCheckCallingOrSelfUriPermissions()1364 public void testCheckCallingOrSelfUriPermissions() { 1365 List<Uri> uris = new ArrayList<>(); 1366 Uri uri1 = Uri.parse("content://ctstest1"); 1367 uris.add(uri1); 1368 Uri uri2 = Uri.parse("content://ctstest2"); 1369 uris.add(uri2); 1370 1371 int[] retValue = mContext.checkCallingOrSelfUriPermissions(uris, 1372 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1373 assertEquals(retValue.length, 2); 1374 // This package does not have access to the given URIs 1375 assertEquals(PERMISSION_DENIED, retValue[0]); 1376 assertEquals(PERMISSION_DENIED, retValue[1]); 1377 } 1378 1379 @Test testCheckCallingOrSelfUriPermission()1380 public void testCheckCallingOrSelfUriPermission() { 1381 Uri uri = Uri.parse("content://ctstest"); 1382 1383 int retValue = mContext.checkCallingOrSelfUriPermission(uri, 1384 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1385 assertEquals(PERMISSION_DENIED, retValue); 1386 } 1387 1388 @Test testGrantUriPermission()1389 public void testGrantUriPermission() { 1390 mContext.grantUriPermission("com.android.mms", Uri.parse("contents://ctstest"), 1391 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1392 } 1393 1394 @Test testCheckPermissionGranted()1395 public void testCheckPermissionGranted() { 1396 int returnValue = mContext.checkPermission( 1397 GRANTED_PERMISSION, Process.myPid(), Process.myUid()); 1398 assertEquals(PERMISSION_GRANTED, returnValue); 1399 } 1400 1401 @Test testCheckPermissionNotGranted()1402 public void testCheckPermissionNotGranted() { 1403 int returnValue = mContext.checkPermission( 1404 NOT_GRANTED_PERMISSION, Process.myPid(), Process.myUid()); 1405 assertEquals(PERMISSION_DENIED, returnValue); 1406 } 1407 1408 @Test testCheckPermissionRootUser()1409 public void testCheckPermissionRootUser() { 1410 // Test with root user, everything will be granted. 1411 int returnValue = mContext.checkPermission(NOT_GRANTED_PERMISSION, 1, ROOT_UID); 1412 assertEquals(PERMISSION_GRANTED, returnValue); 1413 } 1414 1415 @Test testCheckPermissionInvalidRequest()1416 public void testCheckPermissionInvalidRequest() { 1417 // Test with null permission. 1418 try { 1419 int returnValue = mContext.checkPermission(null, 0, ROOT_UID); 1420 fail("checkPermission should not accept null permission"); 1421 } catch (IllegalArgumentException e) { 1422 } 1423 1424 // Test with invalid uid and included granted permission. 1425 int returnValue = mContext.checkPermission(GRANTED_PERMISSION, 1, -11); 1426 assertEquals(PERMISSION_DENIED, returnValue); 1427 } 1428 1429 @Test testCheckSelfPermissionGranted()1430 public void testCheckSelfPermissionGranted() { 1431 int returnValue = mContext.checkSelfPermission(GRANTED_PERMISSION); 1432 assertEquals(PERMISSION_GRANTED, returnValue); 1433 } 1434 1435 @Test testCheckSelfPermissionNotGranted()1436 public void testCheckSelfPermissionNotGranted() { 1437 int returnValue = mContext.checkSelfPermission(NOT_GRANTED_PERMISSION); 1438 assertEquals(PERMISSION_DENIED, returnValue); 1439 } 1440 1441 @Test testEnforcePermissionGranted()1442 public void testEnforcePermissionGranted() { 1443 mContext.enforcePermission( 1444 GRANTED_PERMISSION, Process.myPid(), Process.myUid(), 1445 "permission isn't granted"); 1446 } 1447 1448 @Test testEnforcePermissionNotGranted()1449 public void testEnforcePermissionNotGranted() { 1450 try { 1451 mContext.enforcePermission( 1452 NOT_GRANTED_PERMISSION, Process.myPid(), Process.myUid(), 1453 "permission isn't granted"); 1454 fail("Permission shouldn't be granted."); 1455 } catch (SecurityException expected) { 1456 } 1457 } 1458 1459 @Test testCheckCallingOrSelfPermission_noIpc()1460 public void testCheckCallingOrSelfPermission_noIpc() { 1461 // There's no ongoing Binder call, so this package's permissions are checked. 1462 int retValue = mContext.checkCallingOrSelfPermission(GRANTED_PERMISSION); 1463 assertEquals(PERMISSION_GRANTED, retValue); 1464 1465 retValue = mContext.checkCallingOrSelfPermission(NOT_GRANTED_PERMISSION); 1466 assertEquals(PERMISSION_DENIED, retValue); 1467 } 1468 1469 @Test testCheckCallingOrSelfPermission_ipc()1470 public void testCheckCallingOrSelfPermission_ipc() throws Exception { 1471 bindBinderPermissionTestService(); 1472 try { 1473 int retValue = mBinderPermissionTestService.doCheckCallingOrSelfPermission( 1474 GRANTED_PERMISSION); 1475 assertEquals(PERMISSION_GRANTED, retValue); 1476 1477 retValue = mBinderPermissionTestService.doCheckCallingOrSelfPermission( 1478 NOT_GRANTED_PERMISSION); 1479 assertEquals(PERMISSION_DENIED, retValue); 1480 } finally { 1481 mContext.unbindService(mBinderPermissionTestConnection); 1482 } 1483 } 1484 1485 @Test testEnforceCallingOrSelfPermission_noIpc()1486 public void testEnforceCallingOrSelfPermission_noIpc() { 1487 // There's no ongoing Binder call, so this package's permissions are checked. 1488 mContext.enforceCallingOrSelfPermission( 1489 GRANTED_PERMISSION, "permission isn't granted"); 1490 1491 try { 1492 mContext.enforceCallingOrSelfPermission( 1493 NOT_GRANTED_PERMISSION, "permission isn't granted"); 1494 fail("Permission shouldn't be granted."); 1495 } catch (SecurityException expected) { 1496 } 1497 } 1498 1499 @Test testEnforceCallingOrSelfPermission_ipc()1500 public void testEnforceCallingOrSelfPermission_ipc() throws Exception { 1501 bindBinderPermissionTestService(); 1502 try { 1503 mBinderPermissionTestService.doEnforceCallingOrSelfPermission(GRANTED_PERMISSION); 1504 1505 try { 1506 mBinderPermissionTestService.doEnforceCallingOrSelfPermission( 1507 NOT_GRANTED_PERMISSION); 1508 fail("Permission shouldn't be granted."); 1509 } catch (SecurityException expected) { 1510 } 1511 } finally { 1512 mContext.unbindService(mBinderPermissionTestConnection); 1513 } 1514 } 1515 1516 @Test testCheckCallingPermission_noIpc()1517 public void testCheckCallingPermission_noIpc() { 1518 // Denied because no IPC is active. 1519 int retValue = mContext.checkCallingPermission(GRANTED_PERMISSION); 1520 assertEquals(PERMISSION_DENIED, retValue); 1521 } 1522 1523 @Test testEnforceCallingPermission_noIpc()1524 public void testEnforceCallingPermission_noIpc() { 1525 try { 1526 mContext.enforceCallingPermission( 1527 GRANTED_PERMISSION, 1528 "enforceCallingPermission is not working without possessing an IPC."); 1529 fail("enforceCallingPermission is not working without possessing an IPC."); 1530 } catch (SecurityException e) { 1531 // Currently no IPC is handled by this process, this exception is expected 1532 } 1533 } 1534 1535 @Test testEnforceCallingPermission_ipc()1536 public void testEnforceCallingPermission_ipc() throws Exception { 1537 bindBinderPermissionTestService(); 1538 try { 1539 mBinderPermissionTestService.doEnforceCallingPermission(GRANTED_PERMISSION); 1540 1541 try { 1542 mBinderPermissionTestService.doEnforceCallingPermission(NOT_GRANTED_PERMISSION); 1543 fail("Permission shouldn't be granted."); 1544 } catch (SecurityException expected) { 1545 } 1546 } finally { 1547 mContext.unbindService(mBinderPermissionTestConnection); 1548 } 1549 } 1550 1551 @Test testCheckCallingPermission_ipc()1552 public void testCheckCallingPermission_ipc() throws Exception { 1553 bindBinderPermissionTestService(); 1554 try { 1555 int returnValue = mBinderPermissionTestService.doCheckCallingPermission( 1556 GRANTED_PERMISSION); 1557 assertEquals(PERMISSION_GRANTED, returnValue); 1558 1559 returnValue = mBinderPermissionTestService.doCheckCallingPermission( 1560 NOT_GRANTED_PERMISSION); 1561 assertEquals(PERMISSION_DENIED, returnValue); 1562 } finally { 1563 mContext.unbindService(mBinderPermissionTestConnection); 1564 } 1565 } 1566 bindBinderPermissionTestService()1567 private void bindBinderPermissionTestService() { 1568 Intent intent = new Intent(mContext, IBinderPermissionTestService.class); 1569 intent.setComponent(new ComponentName( 1570 "com.android.cts", "com.android.cts.BinderPermissionTestService")); 1571 1572 mBinderPermissionTestConnection = new ServiceConnection() { 1573 @Override 1574 public void onServiceConnected(ComponentName componentName, IBinder iBinder) { 1575 mBinderPermissionTestService = 1576 IBinderPermissionTestService.Stub.asInterface(iBinder); 1577 } 1578 1579 @Override 1580 public void onServiceDisconnected(ComponentName componentName) { 1581 } 1582 }; 1583 1584 assertTrue("Service not bound", mContext.bindService( 1585 intent, mBinderPermissionTestConnection, Context.BIND_AUTO_CREATE)); 1586 1587 new PollingCheck(SERVICE_TIMEOUT) { 1588 protected boolean check() { 1589 return mBinderPermissionTestService != null; // Service was bound. 1590 } 1591 }.run(); 1592 } 1593 1594 @Test testCheckUriPermissions()1595 public void testCheckUriPermissions() { 1596 List<Uri> uris = new ArrayList<>(); 1597 Uri uri1 = Uri.parse("content://ctstest1"); 1598 uris.add(uri1); 1599 Uri uri2 = Uri.parse("content://ctstest2"); 1600 uris.add(uri2); 1601 1602 // Root has access to all URIs 1603 int[] retValue = mContext.checkUriPermissions(uris, Binder.getCallingPid(), 0, 1604 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1605 assertEquals(retValue.length, 2); 1606 assertEquals(PERMISSION_GRANTED, retValue[0]); 1607 assertEquals(PERMISSION_GRANTED, retValue[1]); 1608 1609 retValue = mContext.checkUriPermissions(uris, Binder.getCallingPid(), 1610 Binder.getCallingUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1611 assertEquals(retValue.length, 2); 1612 // This package does not have access to the given URIs 1613 assertEquals(PERMISSION_DENIED, retValue[0]); 1614 assertEquals(PERMISSION_DENIED, retValue[1]); 1615 } 1616 1617 @Test testCheckUriPermission1()1618 public void testCheckUriPermission1() { 1619 Uri uri = Uri.parse("content://ctstest"); 1620 1621 int retValue = mContext.checkUriPermission(uri, Binder.getCallingPid(), 0, 1622 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1623 assertEquals(PERMISSION_GRANTED, retValue); 1624 1625 retValue = mContext.checkUriPermission(uri, Binder.getCallingPid(), 1626 Binder.getCallingUid(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1627 assertEquals(PERMISSION_DENIED, retValue); 1628 } 1629 1630 @Test testCheckUriPermission2()1631 public void testCheckUriPermission2() { 1632 Uri uri = Uri.parse("content://ctstest"); 1633 1634 int retValue = mContext.checkUriPermission(uri, NOT_GRANTED_PERMISSION, 1635 NOT_GRANTED_PERMISSION, Binder.getCallingPid(), 0, 1636 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1637 assertEquals(PERMISSION_GRANTED, retValue); 1638 1639 retValue = mContext.checkUriPermission(uri, NOT_GRANTED_PERMISSION, 1640 NOT_GRANTED_PERMISSION, Binder.getCallingPid(), Binder.getCallingUid(), 1641 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1642 assertEquals(PERMISSION_DENIED, retValue); 1643 } 1644 1645 @RequiresFlagsEnabled(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) 1646 @Test testCheckContentUriPermissionFull_exceptionsAndNonExistentProviders()1647 public void testCheckContentUriPermissionFull_exceptionsAndNonExistentProviders() { 1648 final int myPid = Process.myPid(); 1649 final int myUid = Process.myUid(); 1650 final Uri nonExistentContentUri = Uri.parse("content://provider.does.not.exist"); 1651 final Uri fileUri = Uri.parse("file://some.file"); 1652 try { 1653 mContext.checkContentUriPermissionFull(nonExistentContentUri, myPid, myUid, 1654 /* modeFlags */ 0); 1655 fail("Shouldn't accept non-access mode flags"); 1656 } catch (IllegalArgumentException expected) { 1657 } 1658 1659 try { 1660 mContext.checkContentUriPermissionFull(nonExistentContentUri, myPid, myUid, 1661 Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 1662 fail("Shouldn't accept non-access mode flags"); 1663 } catch (IllegalArgumentException expected) { 1664 } 1665 1666 try { 1667 mContext.checkContentUriPermissionFull(fileUri, myPid, myUid, 1668 Intent.FLAG_GRANT_READ_URI_PERMISSION); 1669 fail("Shouldn't accept non-content URIs"); 1670 } catch (IllegalArgumentException expected) { 1671 } 1672 1673 int res = mContext.checkContentUriPermissionFull(fileUri, myPid, Process.INVALID_UID, 1674 Intent.FLAG_GRANT_READ_URI_PERMISSION); 1675 String msg = "Should return PERMISSION_DENIED for an invalid UID"; 1676 assertEquals(msg, PERMISSION_DENIED, res); 1677 1678 // Non-existent content URI 1679 res = mContext.checkContentUriPermissionFull(nonExistentContentUri, myPid, 1680 myUid, Intent.FLAG_GRANT_READ_URI_PERMISSION); 1681 msg = "Should return PERMISSION_DENIED for a non-existent content URI"; 1682 assertEquals(msg, PERMISSION_DENIED, res); 1683 } 1684 1685 /** 1686 * This test does the following: 1687 * 1. Binds to TestService in {@link android.content.cts.contenturitestapp}. 1688 * 2. Sends a message to TestService requesting a content URI that this package has (or doesn't 1689 * have) access to via grants or general permissions. 1690 * 3. Checks the result from checkContentUriPermissionFull(). 1691 */ 1692 @RequiresFlagsEnabled(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS) 1693 @Test testCheckContentUriPermissionFull_withGrantsAndGeneralAccess()1694 public void testCheckContentUriPermissionFull_withGrantsAndGeneralAccess() { 1695 try { 1696 setUpContentUriTestServiceConnection(); 1697 1698 internalTestCheckContentUriPermissionFull(PKG_ACCESS_TYPE_NONE, 1699 /* modeFlagsTestHasAccessTo */ 0); 1700 1701 int[] packageAccessTypeValues = new int[]{ 1702 PKG_ACCESS_TYPE_GRANT, 1703 PKG_ACCESS_TYPE_GENERAL 1704 }; 1705 int[] modeFlagsTestHasAccessToValues = new int[]{ 1706 Intent.FLAG_GRANT_READ_URI_PERMISSION, 1707 Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 1708 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 1709 }; 1710 1711 for (int packageAccessType : packageAccessTypeValues) { 1712 for (int modeFlagsTestHasAccessTo : modeFlagsTestHasAccessToValues) { 1713 internalTestCheckContentUriPermissionFull(packageAccessType, 1714 modeFlagsTestHasAccessTo); 1715 } 1716 } 1717 } catch (Exception e) { 1718 fail(e.getMessage()); 1719 } finally { 1720 mContext.unbindService(mContentUriServiceConnection); 1721 } 1722 } 1723 setUpContentUriTestServiceConnection()1724 private void setUpContentUriTestServiceConnection() { 1725 mContentUriServiceConnection = new ServiceConnection() { 1726 @Override 1727 public void onServiceConnected(ComponentName name, IBinder service) { 1728 mContentUriTestService = IContentUriTestService.Stub.asInterface(service); 1729 } 1730 1731 @Override 1732 public void onServiceDisconnected(ComponentName name) { 1733 mContentUriTestService = null; 1734 } 1735 }; 1736 1737 Intent intent = new Intent(); 1738 intent.setComponent(COMPONENT_CONTENT_URI_TEST_SERVICE); 1739 assertTrue(mContext.bindService(intent, mContentUriServiceConnection, 1740 Service.BIND_AUTO_CREATE)); 1741 1742 new PollingCheck(SERVICE_TIMEOUT) { 1743 protected boolean check() { 1744 return mContentUriTestService != null; 1745 } 1746 }.run(); 1747 } 1748 internalTestCheckContentUriPermissionFull(int packageAccessType, int modeFlagsTestHasAccessTo)1749 private void internalTestCheckContentUriPermissionFull(int packageAccessType, 1750 int modeFlagsTestHasAccessTo) throws Exception { 1751 Uri contentUri = mContentUriTestService.getContentUriForContext(packageAccessType, 1752 modeFlagsTestHasAccessTo); 1753 String argsInfo = "packageAccessType: " + packageAccessType + ", modeFlags: " 1754 + modeFlagsTestHasAccessTo; 1755 assertNotNull("Can't retrieve content URI for args (" + argsInfo + ")", contentUri); 1756 1757 boolean hasRead = (modeFlagsTestHasAccessTo & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0; 1758 boolean hasWrite = (modeFlagsTestHasAccessTo & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0; 1759 final int myPid = Process.myPid(); 1760 final int myUid = Process.myUid(); 1761 1762 // Checks for read permission 1763 String msg = getInternalContentUriErrorMessage(hasRead, "read", packageAccessType, 1764 contentUri); 1765 int expected = hasRead ? PERMISSION_GRANTED : PERMISSION_DENIED; 1766 int actual = mContext.checkContentUriPermissionFull(contentUri, myPid, myUid, 1767 Intent.FLAG_GRANT_READ_URI_PERMISSION); 1768 assertEquals(msg, expected, actual); 1769 1770 // Checks for write permission 1771 msg = getInternalContentUriErrorMessage(hasWrite, "write", packageAccessType, contentUri); 1772 expected = hasWrite ? PERMISSION_GRANTED : PERMISSION_DENIED; 1773 actual = mContext.checkContentUriPermissionFull(contentUri, myPid, myUid, 1774 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1775 assertEquals(msg, expected, actual); 1776 1777 // Checks for read and write permissions 1778 msg = getInternalContentUriErrorMessage(hasRead && hasWrite, "read and write", 1779 packageAccessType, contentUri); 1780 expected = (hasRead && hasWrite) ? PERMISSION_GRANTED : PERMISSION_DENIED; 1781 actual = mContext.checkContentUriPermissionFull(contentUri, myPid, myUid, 1782 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1783 assertEquals(msg, expected, actual); 1784 } 1785 getInternalContentUriErrorMessage(boolean has, String permissions, int packageAccessType, Uri contentUri)1786 private String getInternalContentUriErrorMessage(boolean has, String permissions, 1787 int packageAccessType, Uri contentUri) { 1788 StringBuilder sb = new StringBuilder("Should"); 1789 if (!has) sb.append("n't"); 1790 sb.append(" have "); 1791 sb.append(permissions); 1792 sb.append(" for: "); 1793 sb.append(contentUri); 1794 if (packageAccessType == PKG_ACCESS_TYPE_GRANT) { 1795 sb.append(" via grant"); 1796 } else if (packageAccessType == PKG_ACCESS_TYPE_GENERAL) { 1797 sb.append(" via permission"); 1798 } 1799 return sb.toString(); 1800 } 1801 1802 @Test 1803 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) testCheckCallingUriPermissions()1804 public void testCheckCallingUriPermissions() { 1805 List<Uri> uris = new ArrayList<>(); 1806 Uri uri1 = Uri.parse("content://ctstest1"); 1807 uris.add(uri1); 1808 Uri uri2 = Uri.parse("content://ctstest2"); 1809 uris.add(uri2); 1810 1811 int[] retValue = mContext.checkCallingUriPermissions(uris, 1812 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1813 assertEquals(retValue.length, 2); 1814 // This package does not have access to the given URIs 1815 assertEquals(PERMISSION_DENIED, retValue[0]); 1816 assertEquals(PERMISSION_DENIED, retValue[1]); 1817 } 1818 1819 @Test testCheckCallingUriPermission()1820 public void testCheckCallingUriPermission() { 1821 Uri uri = Uri.parse("content://ctstest"); 1822 1823 int retValue = mContext.checkCallingUriPermission(uri, 1824 Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 1825 assertEquals(PERMISSION_DENIED, retValue); 1826 } 1827 1828 @Test testEnforceCallingUriPermission()1829 public void testEnforceCallingUriPermission() { 1830 try { 1831 Uri uri = Uri.parse("content://ctstest"); 1832 mContext.enforceCallingUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 1833 "enforceCallingUriPermission is not working without possessing an IPC."); 1834 fail("enforceCallingUriPermission is not working without possessing an IPC."); 1835 } catch (SecurityException e) { 1836 // If the function is OK, it should throw a SecurityException here because currently no 1837 // IPC is handled by this process. 1838 } 1839 } 1840 1841 @Test testGetDir()1842 public void testGetDir() { 1843 File dir = mContext.getDir("testpath", Context.MODE_PRIVATE); 1844 assertNotNull(dir); 1845 dir.delete(); 1846 } 1847 1848 @Test testGetPackageManager()1849 public void testGetPackageManager() { 1850 assertSame(mContext.getPackageManager(), mContext.getPackageManager()); 1851 } 1852 1853 @Test testSendBroadcast1()1854 public void testSendBroadcast1() throws InterruptedException { 1855 final ResultReceiver receiver = new ResultReceiver(); 1856 1857 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 1858 1859 mContext.sendBroadcast(new Intent(ResultReceiver.MOCK_ACTION) 1860 .setPackage(mContext.getPackageName())); 1861 1862 new PollingCheck(BROADCAST_TIMEOUT) { 1863 @Override 1864 protected boolean check() { 1865 return receiver.hasReceivedBroadCast(); 1866 } 1867 }.run(); 1868 } 1869 1870 @Test testSendBroadcast2()1871 public void testSendBroadcast2() throws InterruptedException { 1872 final ResultReceiver receiver = new ResultReceiver(); 1873 1874 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 1875 1876 mContext.sendBroadcast(new Intent(ResultReceiver.MOCK_ACTION) 1877 .setPackage(mContext.getPackageName()), null); 1878 1879 new PollingCheck(BROADCAST_TIMEOUT) { 1880 @Override 1881 protected boolean check() { 1882 return receiver.hasReceivedBroadCast(); 1883 } 1884 }.run(); 1885 } 1886 1887 /** 1888 * Verify the receiver should get the broadcast since it has all of the required permissions. 1889 */ 1890 @Test testSendBroadcastRequireAllOfPermissions_receiverHasAllPermissions()1891 public void testSendBroadcastRequireAllOfPermissions_receiverHasAllPermissions() 1892 throws Exception { 1893 final ResultReceiver receiver = new ResultReceiver(); 1894 1895 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 1896 BroadcastOptions options = BroadcastOptions.makeBasic(); 1897 options.setRequireAllOfPermissions( 1898 new String[]{ // this test APK has both these permissions 1899 android.Manifest.permission.ACCESS_WIFI_STATE, 1900 android.Manifest.permission.ACCESS_NETWORK_STATE 1901 }); 1902 mContext.sendBroadcast(new Intent(ResultReceiver.MOCK_ACTION) 1903 .setPackage(mContext.getPackageName()), null, options.toBundle()); 1904 1905 new PollingCheck(BROADCAST_TIMEOUT) { 1906 @Override 1907 protected boolean check() { 1908 return receiver.hasReceivedBroadCast(); 1909 } 1910 }.run(); 1911 } 1912 1913 @Test 1914 @RequiresFlagsEnabled(FLAG_USE_PERMISSION_MANAGER_FOR_BROADCAST_DELIVERY_CHECK) testSendBroadcast_requireAppOpPermission_receiverHasPermissionAndDefaultAppOp()1915 public void testSendBroadcast_requireAppOpPermission_receiverHasPermissionAndDefaultAppOp() 1916 throws Exception { 1917 setAppOpMode(AppOpsManager.OP_GET_USAGE_STATS, AppOpsManager.MODE_DEFAULT); 1918 final ResultReceiver receiver = new ResultReceiver(); 1919 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 1920 BroadcastOptions options = BroadcastOptions.makeBasic(); 1921 // The test APK has this AppOp permission. 1922 options.setRequireAllOfPermissions( 1923 new String[]{android.Manifest.permission.PACKAGE_USAGE_STATS}); 1924 1925 mContext.sendBroadcast( 1926 new Intent(ResultReceiver.MOCK_ACTION).setPackage(mContext.getPackageName()), 1927 null /* receiverPermission */, 1928 options.toBundle()); 1929 1930 new PollingCheck(BROADCAST_TIMEOUT) { 1931 @Override 1932 protected boolean check() { 1933 return receiver.hasReceivedBroadCast(); 1934 } 1935 }.run(); 1936 } 1937 1938 @Test testSendBroadcast_requireAppOpPermission_receiverHasPermissionAndAllowedAppOp()1939 public void testSendBroadcast_requireAppOpPermission_receiverHasPermissionAndAllowedAppOp() 1940 throws Exception { 1941 setAppOpMode(AppOpsManager.OP_GET_USAGE_STATS, AppOpsManager.MODE_ALLOWED); 1942 final ResultReceiver receiver = new ResultReceiver(); 1943 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 1944 BroadcastOptions options = BroadcastOptions.makeBasic(); 1945 options.setRequireAllOfPermissions( 1946 new String[]{android.Manifest.permission.PACKAGE_USAGE_STATS}); 1947 1948 mContext.sendBroadcast( 1949 new Intent(ResultReceiver.MOCK_ACTION).setPackage(mContext.getPackageName()), 1950 null /* receiverPermission */, 1951 options.toBundle()); 1952 1953 new PollingCheck(BROADCAST_TIMEOUT) { 1954 @Override 1955 protected boolean check() { 1956 return receiver.hasReceivedBroadCast(); 1957 } 1958 }.run(); 1959 } 1960 1961 @Test testSendBroadcast_requireAppOpPermission_receiverHasPermissionAndErroredAppOp()1962 public void testSendBroadcast_requireAppOpPermission_receiverHasPermissionAndErroredAppOp() 1963 throws Exception { 1964 setAppOpMode(AppOpsManager.OP_GET_USAGE_STATS, AppOpsManager.MODE_ERRORED); 1965 final ResultReceiver receiver = new ResultReceiver(); 1966 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 1967 BroadcastOptions options = BroadcastOptions.makeBasic(); 1968 options.setRequireAllOfPermissions( 1969 new String[]{android.Manifest.permission.PACKAGE_USAGE_STATS}); 1970 1971 mContext.sendBroadcast( 1972 new Intent(ResultReceiver.MOCK_ACTION).setPackage(mContext.getPackageName()), 1973 null /* receiverPermission */, 1974 options.toBundle()); 1975 1976 Thread.sleep(BROADCAST_TIMEOUT); 1977 assertFalse(receiver.hasReceivedBroadCast()); 1978 } 1979 1980 /** The receiver should not get the broadcast if it does not have all the permissions. */ 1981 @Test testSendBroadcastRequireAllOfPermissions_receiverHasSomePermissions()1982 public void testSendBroadcastRequireAllOfPermissions_receiverHasSomePermissions() 1983 throws Exception { 1984 final ResultReceiver receiver = new ResultReceiver(); 1985 1986 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 1987 BroadcastOptions options = BroadcastOptions.makeBasic(); 1988 options.setRequireAllOfPermissions( 1989 new String[]{ // this test APK only has ACCESS_WIFI_STATE 1990 android.Manifest.permission.ACCESS_WIFI_STATE, 1991 android.Manifest.permission.NETWORK_STACK, 1992 }); 1993 1994 mContext.sendBroadcast( 1995 new Intent(ResultReceiver.MOCK_ACTION).setPackage(mContext.getPackageName()), 1996 null, options.toBundle()); 1997 1998 Thread.sleep(BROADCAST_TIMEOUT); 1999 assertFalse(receiver.hasReceivedBroadCast()); 2000 } 2001 2002 /** 2003 * Verify the receiver will get the broadcast since it has none of the excluded permissions. 2004 */ 2005 @Test testSendBroadcastRequireNoneOfPermissions_receiverHasNoneOfExcludedPermissions()2006 public void testSendBroadcastRequireNoneOfPermissions_receiverHasNoneOfExcludedPermissions() 2007 throws Exception { 2008 final ResultReceiver receiver = new ResultReceiver(); 2009 2010 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 2011 BroadcastOptions options = BroadcastOptions.makeBasic(); 2012 options.setRequireAllOfPermissions( 2013 new String[]{ // this test APK has both these permissions 2014 android.Manifest.permission.ACCESS_WIFI_STATE, 2015 android.Manifest.permission.ACCESS_NETWORK_STATE 2016 }); 2017 options.setRequireNoneOfPermissions( 2018 new String[]{ // test package does not have NETWORK_STACK 2019 android.Manifest.permission.NETWORK_STACK 2020 }); 2021 mContext.sendBroadcast(new Intent(ResultReceiver.MOCK_ACTION) 2022 .setPackage(mContext.getPackageName()), null, options.toBundle()); 2023 2024 new PollingCheck(BROADCAST_TIMEOUT) { 2025 @Override 2026 protected boolean check() { 2027 return receiver.hasReceivedBroadCast(); 2028 } 2029 }.run(); 2030 } 2031 2032 /** 2033 * Verify the receiver will not get the broadcast since it has one of the excluded permissions. 2034 */ 2035 @Test testSendBroadcastRequireNoneOfPermissions_receiverHasExcludedPermissions()2036 public void testSendBroadcastRequireNoneOfPermissions_receiverHasExcludedPermissions() 2037 throws Exception { 2038 final ResultReceiver receiver = new ResultReceiver(); 2039 2040 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 2041 BroadcastOptions options = BroadcastOptions.makeBasic(); 2042 options.setRequireAllOfPermissions( 2043 new String[]{ // this test APK has ACCESS_WIFI_STATE 2044 android.Manifest.permission.ACCESS_WIFI_STATE 2045 }); 2046 options.setRequireNoneOfPermissions( 2047 new String[]{ // test package has ACCESS_NETWORK_STATE 2048 android.Manifest.permission.ACCESS_NETWORK_STATE 2049 }); 2050 mContext.sendBroadcast(new Intent(ResultReceiver.MOCK_ACTION) 2051 .setPackage(mContext.getPackageName()), null, 2052 options.toBundle()); 2053 2054 Thread.sleep(BROADCAST_TIMEOUT); 2055 assertFalse(receiver.hasReceivedBroadCast()); 2056 } 2057 2058 /** The receiver should get the broadcast if it has all the permissions. */ 2059 @Test testSendBroadcastWithMultiplePermissions_receiverHasAllPermissions()2060 public void testSendBroadcastWithMultiplePermissions_receiverHasAllPermissions() 2061 throws Exception { 2062 final ResultReceiver receiver = new ResultReceiver(); 2063 2064 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 2065 2066 mContext.sendBroadcastWithMultiplePermissions( 2067 new Intent(ResultReceiver.MOCK_ACTION).setPackage(mContext.getPackageName()), 2068 new String[]{ // this test APK has both these permissions 2069 android.Manifest.permission.ACCESS_WIFI_STATE, 2070 android.Manifest.permission.ACCESS_NETWORK_STATE, 2071 }); 2072 2073 new PollingCheck(BROADCAST_TIMEOUT) { 2074 @Override 2075 protected boolean check() { 2076 return receiver.hasReceivedBroadCast(); 2077 } 2078 }.run(); 2079 } 2080 2081 /** The receiver should not get the broadcast if it does not have all the permissions. */ 2082 @Test testSendBroadcastWithMultiplePermissions_receiverHasSomePermissions()2083 public void testSendBroadcastWithMultiplePermissions_receiverHasSomePermissions() 2084 throws Exception { 2085 final ResultReceiver receiver = new ResultReceiver(); 2086 2087 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 2088 2089 mContext.sendBroadcastWithMultiplePermissions( 2090 new Intent(ResultReceiver.MOCK_ACTION).setPackage(mContext.getPackageName()), 2091 new String[]{ // this test APK only has ACCESS_WIFI_STATE 2092 android.Manifest.permission.ACCESS_WIFI_STATE, 2093 android.Manifest.permission.NETWORK_STACK, 2094 }); 2095 2096 Thread.sleep(BROADCAST_TIMEOUT); 2097 assertFalse(receiver.hasReceivedBroadCast()); 2098 } 2099 2100 /** The receiver should not get the broadcast if it has none of the permissions. */ 2101 @Test testSendBroadcastWithMultiplePermissions_receiverHasNoPermissions()2102 public void testSendBroadcastWithMultiplePermissions_receiverHasNoPermissions() 2103 throws Exception { 2104 final ResultReceiver receiver = new ResultReceiver(); 2105 2106 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION)); 2107 2108 mContext.sendBroadcastWithMultiplePermissions( 2109 new Intent(ResultReceiver.MOCK_ACTION).setPackage(mContext.getPackageName()), 2110 new String[]{ // this test APK has neither of these permissions 2111 android.Manifest.permission.NETWORK_SETTINGS, 2112 android.Manifest.permission.NETWORK_STACK, 2113 }); 2114 2115 Thread.sleep(BROADCAST_TIMEOUT); 2116 assertFalse(receiver.hasReceivedBroadCast()); 2117 } 2118 2119 /** 2120 * Starting from Android 13, a SecurityException is thrown for apps targeting this 2121 * release or later that do not specify {@link Context#RECEIVER_EXPORTED} or {@link 2122 * Context#RECEIVER_NOT_EXPORTED} when registering for non-system broadcasts. 2123 */ 2124 @Test testRegisterReceiver_noFlags_exceptionThrown()2125 public void testRegisterReceiver_noFlags_exceptionThrown() throws Exception { 2126 try { 2127 final ResultReceiver receiver = new ResultReceiver(); 2128 2129 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION), 0); 2130 2131 fail("An app targeting Android 13 and registering a dynamic receiver for a " 2132 + "non-system broadcast must receive a SecurityException if " 2133 + "RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED is not specified"); 2134 } catch (SecurityException expected) { 2135 } 2136 } 2137 2138 /** 2139 * An app targeting Android 13 or later can register for system broadcasts without specifying 2140 * {@link Context#RECEIVER_EXPORTED} or {@link Context@RECEIVER_NOT_EXPORTED}. 2141 */ 2142 @Test testRegisterReceiver_noFlagsProtectedBroadcast_noExceptionThrown()2143 public void testRegisterReceiver_noFlagsProtectedBroadcast_noExceptionThrown() 2144 throws Exception { 2145 final ResultReceiver receiver = new ResultReceiver(); 2146 2147 // Intent.ACTION_SCREEN_OFF is a system broadcast and thus should not require a flag 2148 // indicating whether the receiver is exported. 2149 registerBroadcastReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF), 0); 2150 } 2151 2152 /** 2153 * An app targeting Android 13 or later can request a sticky broadcast via 2154 * {@code Context#registerReceiver} without specifying {@link Context#RECEIVER_EXPORTED} or 2155 * {@link Context#RECEIVER_NOT_EXPORTED}. 2156 */ 2157 @Test testRegisterReceiver_noFlagsStickyBroadcast_noExceptionThrown()2158 public void testRegisterReceiver_noFlagsStickyBroadcast_noExceptionThrown() throws Exception { 2159 // If a null receiver is specified to Context#registerReceiver, it indicates the caller 2160 // is requesting a sticky broadcast without actually registering a receiver; a flag 2161 // must not be required in this case. 2162 mContext.registerReceiver(null, new IntentFilter(ResultReceiver.MOCK_ACTION), 0); 2163 } 2164 2165 /** 2166 * Starting from Android 13, an app targeting this release or later must specify one of either 2167 * {@link Context#RECEIVER_EXPORTED} or {@link Context#RECEIVER_NOT_EXPORTED} when registering 2168 * a receiver for non-system broadcasts; however if both are specified then an 2169 * {@link IllegalArgumentException} should be thrown. 2170 */ 2171 @Test testRegisterReceiver_bothFlags_exceptionThrown()2172 public void testRegisterReceiver_bothFlags_exceptionThrown() throws Exception { 2173 try { 2174 final ResultReceiver receiver = new ResultReceiver(); 2175 2176 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION), 2177 Context.RECEIVER_EXPORTED | Context.RECEIVER_NOT_EXPORTED); 2178 2179 fail("An app invoke invoking Context#registerReceiver with both RECEIVER_EXPORTED and" 2180 + " RECEIVER_NOT_EXPORTED set must receive an IllegalArgumentException"); 2181 } catch (IllegalArgumentException expected) { 2182 } 2183 } 2184 2185 /** 2186 * Verifies a receiver registered with {@link Context#RECEIVER_EXPORTED} can receive a 2187 * broadcast from an external app. 2188 * 2189 * <p>The broadcast is sent as a shell command since this most closely simulates sending a 2190 * broadcast from an external app; sending the broadcast via {@code 2191 * ShellIdentityUtils#invokeMethodWithShellPermissionsNoReturn} is still delivered even to 2192 * apps that use {@link Context#RECEIVER_NOT_EXPORTED}. 2193 */ 2194 @Test testRegisterReceiver_exported_broadcastReceived()2195 public void testRegisterReceiver_exported_broadcastReceived() throws Exception { 2196 final ResultReceiver receiver = new ResultReceiver(); 2197 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION), 2198 Context.RECEIVER_EXPORTED); 2199 2200 SystemUtil.runShellCommand(EXTERNAL_APP_BROADCAST_COMMAND); 2201 2202 new PollingCheck(BROADCAST_TIMEOUT, "The broadcast to the exported receiver" 2203 + " was not received within the timeout window") { 2204 @Override 2205 protected boolean check() { 2206 return receiver.hasReceivedBroadCast(); 2207 } 2208 }.run(); 2209 } 2210 2211 /** 2212 * Verifies a receiver registered with {@link Context#RECEIVER_EXPORTED_UNAUDITED} can receive 2213 * a broadcast from an external app. 2214 * 2215 * <p>{@code Context#RECEIVER_EXPORTED_UNAUDITED} is only intended to be applied to receivers 2216 * that have not yet been audited to determine their intended exported state; this test ensures 2217 * this flag maintains the existing behavior of exporting the receiver until it can be 2218 * evaluated. 2219 */ 2220 @Test testRegisterReceiver_exportedUnaudited_broadcastReceived()2221 public void testRegisterReceiver_exportedUnaudited_broadcastReceived() throws Exception { 2222 final ResultReceiver receiver = new ResultReceiver(); 2223 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION), 2224 Context.RECEIVER_EXPORTED_UNAUDITED); 2225 2226 SystemUtil.runShellCommand(EXTERNAL_APP_BROADCAST_COMMAND); 2227 2228 new PollingCheck(BROADCAST_TIMEOUT, "The broadcast to the exported receiver" 2229 + " was not received within the timeout window") { 2230 @Override 2231 protected boolean check() { 2232 return receiver.hasReceivedBroadCast(); 2233 } 2234 }.run(); 2235 } 2236 2237 /** 2238 * Verifies a receiver registered with {@link Context#RECEIVER_NOT_EXPORTED} does not receive 2239 * a broadcast from an external app. 2240 */ 2241 @Test testRegisterReceiver_notExported_broadcastNotReceived()2242 public void testRegisterReceiver_notExported_broadcastNotReceived() throws Exception { 2243 final ResultReceiver receiver = new ResultReceiver(); 2244 registerBroadcastReceiver(receiver, new IntentFilter(ResultReceiver.MOCK_ACTION), 2245 Context.RECEIVER_NOT_EXPORTED); 2246 2247 SystemUtil.runShellCommand(EXTERNAL_APP_BROADCAST_COMMAND); 2248 2249 Thread.sleep(BROADCAST_TIMEOUT); 2250 assertFalse( 2251 "An external app must not be able to send a broadcast to a dynamic receiver " 2252 + "registered with RECEIVER_NOT_EXPORTED", 2253 receiver.hasReceivedBroadCast()); 2254 } 2255 2256 @Test testRegisterReceiverForSystemBroadcast_notExported_stickyBroadcastReceived()2257 public void testRegisterReceiverForSystemBroadcast_notExported_stickyBroadcastReceived() 2258 throws InterruptedException { 2259 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) { 2260 return; 2261 } 2262 final WifiManager wifiManager = mContext.getSystemService(WifiManager.class); 2263 boolean wifiInitiallyOn = wifiManager.isWifiEnabled(); 2264 // Cycle Wifi to force the WIFI_STATE_CHANGED_ACTION sticky broadcast 2265 if (wifiInitiallyOn) { 2266 SystemUtil.runShellCommand("cmd wifi set-wifi-enabled disabled"); 2267 Thread.sleep(1000); 2268 } 2269 SystemUtil.runShellCommand("cmd wifi set-wifi-enabled enabled"); 2270 Thread.sleep(1000); 2271 2272 try { 2273 TestBroadcastReceiver stickyReceiver = new TestBroadcastReceiver(); 2274 // A receiver registered for sticky broadcasts with the RECEIVER_NOT_EXPORTED flag 2275 // should still receive back a sticky broadcast sent from the system UID. 2276 assertEquals(WifiManager.WIFI_STATE_CHANGED_ACTION, 2277 mContext.registerReceiver(stickyReceiver, 2278 new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION), 2279 Context.RECEIVER_NOT_EXPORTED).getAction()); 2280 synchronized (mLockObj) { 2281 mLockObj.wait(BROADCAST_TIMEOUT); 2282 } 2283 assertTrue("Sticky broadcast not delivered to unexported receiver", 2284 stickyReceiver.hadReceivedBroadCast()); 2285 } finally { 2286 if (wifiInitiallyOn) { 2287 SystemUtil.runShellCommand("cmd wifi set-wifi-enabled enabled"); 2288 } else { 2289 SystemUtil.runShellCommand("cmd wifi set-wifi-enabled disabled"); 2290 } 2291 } 2292 } 2293 2294 @Test testEnforceCallingOrSelfUriPermission()2295 public void testEnforceCallingOrSelfUriPermission() { 2296 try { 2297 Uri uri = Uri.parse("content://ctstest"); 2298 mContext.enforceCallingOrSelfUriPermission(uri, 2299 Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 2300 "enforceCallingOrSelfUriPermission is not working without possessing an IPC."); 2301 fail("enforceCallingOrSelfUriPermission is not working without possessing an IPC."); 2302 } catch (SecurityException e) { 2303 // If the function is OK, it should throw a SecurityException here because currently no 2304 // IPC is handled by this process. 2305 } 2306 } 2307 2308 @Test testGetAssets()2309 public void testGetAssets() { 2310 assertSame(mContext.getAssets(), mContext.getAssets()); 2311 } 2312 2313 @Test testGetResources()2314 public void testGetResources() { 2315 assertSame(mContext.getResources(), mContext.getResources()); 2316 } 2317 2318 @Test testStartInstrumentation()2319 public void testStartInstrumentation() { 2320 // Use wrong name 2321 ComponentName cn = new ComponentName("com.android", 2322 "com.android.content.FalseLocalSampleInstrumentation"); 2323 assertNotNull(cn); 2324 assertNotNull(mContext); 2325 // If the target instrumentation is wrong, the function should return false. 2326 assertFalse(mContext.startInstrumentation(cn, null, null)); 2327 } 2328 bindExpectResult(Context context, Intent service)2329 private void bindExpectResult(Context context, Intent service) 2330 throws InterruptedException { 2331 if (service == null) { 2332 fail("No service created!"); 2333 } 2334 TestConnection conn = new TestConnection(true, false); 2335 2336 context.bindService(service, conn, Context.BIND_AUTO_CREATE); 2337 context.startService(service); 2338 2339 // Wait for a short time, so the service related operations could be 2340 // working. 2341 synchronized (this) { 2342 wait(2500); 2343 } 2344 // Test stop Service 2345 assertTrue(context.stopService(service)); 2346 context.unbindService(conn); 2347 2348 synchronized (this) { 2349 wait(1000); 2350 } 2351 } 2352 2353 private interface Condition { onCondition()2354 public boolean onCondition(); 2355 } 2356 waitForCondition(Condition con)2357 private synchronized void waitForCondition(Condition con) throws InterruptedException { 2358 // check the condition every 1 second until the condition is fulfilled 2359 // and wait for 3 seconds at most 2360 for (int i = 0; !con.onCondition() && i <= 3; i++) { 2361 wait(1000); 2362 } 2363 } 2364 waitForReceiveBroadCast(final ResultReceiver receiver)2365 private void waitForReceiveBroadCast(final ResultReceiver receiver) 2366 throws InterruptedException { 2367 Condition con = new Condition() { 2368 public boolean onCondition() { 2369 return receiver.hasReceivedBroadCast(); 2370 } 2371 }; 2372 waitForCondition(con); 2373 } 2374 waitForFilteredIntent(Context context, final String action)2375 private void waitForFilteredIntent(Context context, final String action) 2376 throws InterruptedException { 2377 context.sendBroadcast(new Intent(action), null); 2378 2379 synchronized (mLockObj) { 2380 mLockObj.wait(BROADCAST_TIMEOUT); 2381 } 2382 } 2383 2384 private final class TestBroadcastReceiver extends BroadcastReceiver { 2385 boolean mHadReceivedBroadCast; 2386 boolean mIsOrderedBroadcasts; 2387 2388 @Override onReceive(Context context, Intent intent)2389 public void onReceive(Context context, Intent intent) { 2390 synchronized (this) { 2391 if (mIsOrderedBroadcasts) { 2392 setResultCode(3); 2393 setResultData(ACTUAL_RESULT); 2394 } 2395 2396 Bundle map = getResultExtras(false); 2397 if (map != null) { 2398 map.remove(KEY_REMOVED); 2399 map.putString(KEY_ADDED, VALUE_ADDED); 2400 } 2401 mHadReceivedBroadCast = true; 2402 this.notifyAll(); 2403 } 2404 2405 synchronized (mLockObj) { 2406 mLockObj.notify(); 2407 } 2408 } 2409 hadReceivedBroadCast()2410 boolean hadReceivedBroadCast() { 2411 return mHadReceivedBroadCast; 2412 } 2413 reset()2414 void reset() { 2415 mHadReceivedBroadCast = false; 2416 } 2417 } 2418 2419 private class FilteredReceiver extends BroadcastReceiver { 2420 private boolean mHadReceivedBroadCast1 = false; 2421 private boolean mHadReceivedBroadCast2 = false; 2422 onReceive(Context context, Intent intent)2423 public void onReceive(Context context, Intent intent) { 2424 String action = intent.getAction(); 2425 if (MOCK_ACTION1.equals(action)) { 2426 mHadReceivedBroadCast1 = true; 2427 } else if (MOCK_ACTION2.equals(action)) { 2428 mHadReceivedBroadCast2 = true; 2429 } 2430 2431 synchronized (mLockObj) { 2432 mLockObj.notify(); 2433 } 2434 } 2435 hadReceivedBroadCast1()2436 public boolean hadReceivedBroadCast1() { 2437 return mHadReceivedBroadCast1; 2438 } 2439 hadReceivedBroadCast2()2440 public boolean hadReceivedBroadCast2() { 2441 return mHadReceivedBroadCast2; 2442 } 2443 reset()2444 public void reset() { 2445 mHadReceivedBroadCast1 = false; 2446 mHadReceivedBroadCast2 = false; 2447 } 2448 } 2449 2450 private class TestConnection implements ServiceConnection { TestConnection(boolean expectDisconnect, boolean setReporter)2451 public TestConnection(boolean expectDisconnect, boolean setReporter) { 2452 } 2453 setMonitor(boolean v)2454 void setMonitor(boolean v) { 2455 } 2456 onServiceConnected(ComponentName name, IBinder service)2457 public void onServiceConnected(ComponentName name, IBinder service) { 2458 } 2459 onServiceDisconnected(ComponentName name)2460 public void onServiceDisconnected(ComponentName name) { 2461 } 2462 } 2463 2464 @Test testOpenFileOutput_mustNotCreateWorldReadableFile()2465 public void testOpenFileOutput_mustNotCreateWorldReadableFile() throws Exception { 2466 try { 2467 mContext.openFileOutput("test.txt", Context.MODE_WORLD_READABLE); 2468 fail("Exception expected"); 2469 } catch (SecurityException expected) { 2470 } 2471 } 2472 2473 @Test testOpenFileOutput_mustNotCreateWorldWriteableFile()2474 public void testOpenFileOutput_mustNotCreateWorldWriteableFile() throws Exception { 2475 try { 2476 mContext.openFileOutput("test.txt", Context.MODE_WORLD_WRITEABLE); 2477 fail("Exception expected"); 2478 } catch (SecurityException expected) { 2479 } 2480 } 2481 2482 @Test testOpenFileOutput_mustNotWriteToParentDirectory()2483 public void testOpenFileOutput_mustNotWriteToParentDirectory() throws Exception { 2484 try { 2485 // Created files must be under the application's private directory. 2486 mContext.openFileOutput("../test.txt", Context.MODE_PRIVATE); 2487 fail("Exception expected"); 2488 } catch (IllegalArgumentException expected) { 2489 } 2490 } 2491 2492 @Test testOpenFileOutput_mustNotUseAbsolutePath()2493 public void testOpenFileOutput_mustNotUseAbsolutePath() throws Exception { 2494 try { 2495 // Created files must be under the application's private directory. 2496 mContext.openFileOutput("/tmp/test.txt", Context.MODE_PRIVATE); 2497 fail("Exception expected"); 2498 } catch (IllegalArgumentException expected) { 2499 } 2500 } 2501 isWallpaperSupported()2502 private boolean isWallpaperSupported() { 2503 return WallpaperManager.getInstance(mContext).isWallpaperSupported(); 2504 } 2505 setAppOpMode(int appOpCode, @AppOpsManager.Mode int appOpMode)2506 private void setAppOpMode(int appOpCode, @AppOpsManager.Mode int appOpMode) { 2507 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn( 2508 (AppOpsManager) getContextUnderTest().getSystemService(Context.APP_OPS_SERVICE), 2509 (appOpsMan) -> appOpsMan.setUidMode(appOpCode, Process.myUid(), appOpMode)); 2510 } 2511 setAppOpMode(String appOp, @AppOpsManager.Mode int appOpMode)2512 private void setAppOpMode(String appOp, @AppOpsManager.Mode int appOpMode) { 2513 ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn( 2514 (AppOpsManager) getContextUnderTest().getSystemService(Context.APP_OPS_SERVICE), 2515 (appOpsMan) -> appOpsMan.setUidMode(appOp, Process.myUid(), appOpMode)); 2516 } 2517 } 2518