xref: /aosp_15_r20/cts/tests/tests/content/src/android/content/cts/ContextTest.java (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
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