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