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