1 /*
2  * Copyright (C) 2006 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.app;
18 
19 import static android.content.pm.PackageManager.PERMISSION_DENIED;
20 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21 import static android.os.StrictMode.vmIncorrectContextUseEnabled;
22 import static android.view.WindowManager.LayoutParams.WindowType;
23 
24 import android.annotation.IntDef;
25 import android.annotation.NonNull;
26 import android.annotation.Nullable;
27 import android.annotation.UiContext;
28 import android.compat.annotation.UnsupportedAppUsage;
29 import android.content.AttributionSource;
30 import android.content.AutofillOptions;
31 import android.content.BroadcastReceiver;
32 import android.content.ComponentName;
33 import android.content.ContentCaptureOptions;
34 import android.content.ContentProvider;
35 import android.content.ContentResolver;
36 import android.content.Context;
37 import android.content.ContextParams;
38 import android.content.ContextWrapper;
39 import android.content.IContentProvider;
40 import android.content.IIntentReceiver;
41 import android.content.Intent;
42 import android.content.IntentFilter;
43 import android.content.IntentSender;
44 import android.content.ReceiverCallNotAllowedException;
45 import android.content.ServiceConnection;
46 import android.content.SharedPreferences;
47 import android.content.pm.ActivityInfo;
48 import android.content.pm.ApplicationInfo;
49 import android.content.pm.IPackageManager;
50 import android.content.pm.PackageManager;
51 import android.content.pm.PackageManager.NameNotFoundException;
52 import android.content.res.AssetManager;
53 import android.content.res.CompatResources;
54 import android.content.res.CompatibilityInfo;
55 import android.content.res.Configuration;
56 import android.content.res.Resources;
57 import android.content.res.loader.ResourcesLoader;
58 import android.database.DatabaseErrorHandler;
59 import android.database.sqlite.SQLiteDatabase;
60 import android.database.sqlite.SQLiteDatabase.CursorFactory;
61 import android.graphics.Bitmap;
62 import android.graphics.drawable.Drawable;
63 import android.net.Uri;
64 import android.os.Binder;
65 import android.os.Build;
66 import android.os.Bundle;
67 import android.os.Debug;
68 import android.os.Environment;
69 import android.os.FileUtils;
70 import android.os.Handler;
71 import android.os.IBinder;
72 import android.os.Looper;
73 import android.os.Process;
74 import android.os.RemoteException;
75 import android.os.StrictMode;
76 import android.os.Trace;
77 import android.os.UserHandle;
78 import android.os.UserManager;
79 import android.os.storage.StorageManager;
80 import android.permission.PermissionManager;
81 import android.system.ErrnoException;
82 import android.system.Os;
83 import android.system.OsConstants;
84 import android.system.StructStat;
85 import android.text.TextUtils;
86 import android.util.AndroidRuntimeException;
87 import android.util.ArrayMap;
88 import android.util.Log;
89 import android.util.Slog;
90 import android.view.Display;
91 import android.view.DisplayAdjustments;
92 import android.view.autofill.AutofillManager.AutofillClient;
93 import android.window.WindowContext;
94 import android.window.WindowTokenClient;
95 
96 import com.android.internal.annotations.GuardedBy;
97 import com.android.internal.util.Preconditions;
98 
99 import dalvik.system.BlockGuard;
100 
101 import libcore.io.Memory;
102 
103 import java.io.File;
104 import java.io.FileInputStream;
105 import java.io.FileNotFoundException;
106 import java.io.FileOutputStream;
107 import java.io.FilenameFilter;
108 import java.io.IOException;
109 import java.io.InputStream;
110 import java.lang.annotation.Retention;
111 import java.lang.annotation.RetentionPolicy;
112 import java.nio.ByteOrder;
113 import java.nio.file.Path;
114 import java.util.ArrayList;
115 import java.util.Arrays;
116 import java.util.List;
117 import java.util.Objects;
118 import java.util.Set;
119 import java.util.concurrent.Executor;
120 
121 class ReceiverRestrictedContext extends ContextWrapper {
122     @UnsupportedAppUsage
ReceiverRestrictedContext(Context base)123     ReceiverRestrictedContext(Context base) {
124         super(base);
125     }
126 
127     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)128     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
129         return registerReceiver(receiver, filter, null, null);
130     }
131 
132     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)133     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
134             String broadcastPermission, Handler scheduler) {
135         if (receiver == null) {
136             // Allow retrieving current sticky broadcast; this is safe since we
137             // aren't actually registering a receiver.
138             return super.registerReceiver(null, filter, broadcastPermission, scheduler);
139         } else {
140             throw new ReceiverCallNotAllowedException(
141                     "BroadcastReceiver components are not allowed to register to receive intents");
142         }
143     }
144 
145     @Override
registerReceiverForAllUsers(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)146     public Intent registerReceiverForAllUsers(BroadcastReceiver receiver, IntentFilter filter,
147             String broadcastPermission, Handler scheduler) {
148         return registerReceiverAsUser(
149                 receiver, UserHandle.ALL, filter, broadcastPermission, scheduler);
150     }
151 
152     @Override
registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler)153     public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
154             IntentFilter filter, String broadcastPermission, Handler scheduler) {
155         if (receiver == null) {
156             // Allow retrieving current sticky broadcast; this is safe since we
157             // aren't actually registering a receiver.
158             return super.registerReceiverAsUser(null, user, filter, broadcastPermission, scheduler);
159         } else {
160             throw new ReceiverCallNotAllowedException(
161                     "BroadcastReceiver components are not allowed to register to receive intents");
162         }
163     }
164 
165     @Override
bindService(Intent service, ServiceConnection conn, int flags)166     public boolean bindService(Intent service, ServiceConnection conn, int flags) {
167         throw new ReceiverCallNotAllowedException(
168                 "BroadcastReceiver components are not allowed to bind to services");
169     }
170 
171     @Override
bindService( Intent service, int flags, Executor executor, ServiceConnection conn)172     public boolean bindService(
173           Intent service, int flags, Executor executor, ServiceConnection conn) {
174         throw new ReceiverCallNotAllowedException(
175             "BroadcastReceiver components are not allowed to bind to services");
176     }
177 
178     @Override
bindIsolatedService(Intent service, int flags, String instanceName, Executor executor, ServiceConnection conn)179     public boolean bindIsolatedService(Intent service, int flags, String instanceName,
180             Executor executor, ServiceConnection conn) {
181         throw new ReceiverCallNotAllowedException(
182             "BroadcastReceiver components are not allowed to bind to services");
183     }
184 }
185 
186 /**
187  * Common implementation of Context API, which provides the base
188  * context object for Activity and other application components.
189  */
190 class ContextImpl extends Context {
191     private final static String TAG = "ContextImpl";
192     private final static boolean DEBUG = false;
193 
194     private static final String XATTR_INODE_CACHE = "user.inode_cache";
195     private static final String XATTR_INODE_CODE_CACHE = "user.inode_code_cache";
196 
197     /**
198      * Map from package name, to preference name, to cached preferences.
199      */
200     @GuardedBy("ContextImpl.class")
201     @UnsupportedAppUsage
202     private static ArrayMap<String, ArrayMap<File, SharedPreferencesImpl>> sSharedPrefsCache;
203 
204     /**
205      * Map from preference name to generated path.
206      */
207     @GuardedBy("ContextImpl.class")
208     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
209     private ArrayMap<String, File> mSharedPrefsPaths;
210 
211     @UnsupportedAppUsage
212     final @NonNull ActivityThread mMainThread;
213     @UnsupportedAppUsage
214     final @NonNull LoadedApk mPackageInfo;
215     @UnsupportedAppUsage
216     private @Nullable ClassLoader mClassLoader;
217 
218     private final @Nullable IBinder mToken;
219 
220     private final @NonNull UserHandle mUser;
221 
222     @UnsupportedAppUsage
223     private final ApplicationContentResolver mContentResolver;
224 
225     @UnsupportedAppUsage
226     private final String mBasePackageName;
227     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
228     private final String mOpPackageName;
229     private final @NonNull ContextParams mParams;
230     private final @NonNull AttributionSource mAttributionSource;
231 
232     private final @NonNull ResourcesManager mResourcesManager;
233     @UnsupportedAppUsage
234     private @NonNull Resources mResources;
235     private @Nullable Display mDisplay; // may be null if invalid display or not initialized yet.
236 
237     /**
238      * If set to {@code true} the resources for this context will be configured for mDisplay which
239      * will override the display configuration inherited from {@link #mToken} (or the global
240      * configuration if mToken is null). Typically set for display contexts and contexts derived
241      * from display contexts where changes to the activity display and the global configuration
242      * display should not impact their resources.
243      */
244     private boolean mForceDisplayOverrideInResources;
245 
246     /** @see Context#isConfigurationContext() */
247     private boolean mIsConfigurationBasedContext;
248 
249     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
250     private final int mFlags;
251 
252     @UnsupportedAppUsage
253     private Context mOuterContext;
254     @UnsupportedAppUsage
255     private int mThemeResource = 0;
256     @UnsupportedAppUsage
257     private Resources.Theme mTheme = null;
258     @UnsupportedAppUsage
259     private PackageManager mPackageManager;
260     private Context mReceiverRestrictedContext = null;
261 
262     // The name of the split this Context is representing. May be null.
263     private @Nullable String mSplitName = null;
264 
265     private @Nullable AutofillClient mAutofillClient = null;
266     private @Nullable AutofillOptions mAutofillOptions;
267 
268     private ContentCaptureOptions mContentCaptureOptions = null;
269 
270     private final Object mSync = new Object();
271     /**
272      * Indicates this {@link Context} can not handle UI components properly and is not associated
273      * with a {@link Display} instance.
274      */
275     private static final int CONTEXT_TYPE_NON_UI = 0;
276     /**
277      * Indicates this {@link Context} is associated with a {@link Display} instance but should not
278      * be handled UI components properly because it doesn't receive configuration changes
279      * regardless of display property updates.
280      */
281     private static final int CONTEXT_TYPE_DISPLAY_CONTEXT = 1;
282     /**
283      * Indicates this {@link Context} is an {@link Activity} or {@link Activity} derived
284      * {@link Context}.
285      */
286     private static final int CONTEXT_TYPE_ACTIVITY = 2;
287     /**
288      * Indicates this {@link Context} is a {@link WindowContext} or {@link WindowContext} derived
289      * {@link Context}.
290      */
291     private static final int CONTEXT_TYPE_WINDOW_CONTEXT = 3;
292 
293     // TODO(b/170369943): Remove after WindowContext migration
294     /**
295      * Indicates this {@link Context} is created from {@link #createSystemContext(ActivityThread)}
296      * or {@link #createSystemUiContext(ContextImpl, int)} or any {@link Context} that system UI
297      * uses.
298      */
299     private static final int CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI = 4;
300 
301     @IntDef(prefix = "CONTEXT_TYPE_", value = {
302             CONTEXT_TYPE_NON_UI,
303             CONTEXT_TYPE_DISPLAY_CONTEXT,
304             CONTEXT_TYPE_ACTIVITY,
305             CONTEXT_TYPE_WINDOW_CONTEXT,
306             CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI
307     })
308     @Retention(RetentionPolicy.SOURCE)
309     private @interface ContextType {}
310 
311     @ContextType
312     private int mContextType;
313 
314     /**
315      * {@code true} to indicate that the {@link Context} owns the {@link #getWindowContextToken()}
316      * and is responsible for detaching the token when the Context is released.
317      *
318      * @see #finalize()
319      */
320     private boolean mOwnsToken = false;
321 
322     @GuardedBy("mSync")
323     private File mDatabasesDir;
324     @GuardedBy("mSync")
325     @UnsupportedAppUsage
326     private File mPreferencesDir;
327     @GuardedBy("mSync")
328     private File mFilesDir;
329     @GuardedBy("mSync")
330     private File mCratesDir;
331     @GuardedBy("mSync")
332     private File mNoBackupFilesDir;
333     @GuardedBy("mSync")
334     private File mCacheDir;
335     @GuardedBy("mSync")
336     private File mCodeCacheDir;
337 
338     // The system service cache for the system services that are cached per-ContextImpl.
339     @UnsupportedAppUsage
340     final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();
341 
342     static final int STATE_UNINITIALIZED = 0;
343     static final int STATE_INITIALIZING = 1;
344     static final int STATE_READY = 2;
345     static final int STATE_NOT_FOUND = 3;
346 
347     /** @hide */
348     @IntDef(prefix = { "STATE_" }, value = {
349             STATE_UNINITIALIZED,
350             STATE_INITIALIZING,
351             STATE_READY,
352             STATE_NOT_FOUND,
353     })
354     @Retention(RetentionPolicy.SOURCE)
355     @interface ServiceInitializationState {}
356 
357     /**
358      * Initialization state for each service. Any of {@link #STATE_UNINITIALIZED},
359      * {@link #STATE_INITIALIZING} or {@link #STATE_READY},
360      */
361     @ServiceInitializationState
362     final int[] mServiceInitializationStateArray = new int[mServiceCache.length];
363 
364     @UnsupportedAppUsage
getImpl(Context context)365     static ContextImpl getImpl(Context context) {
366         Context nextContext;
367         while ((context instanceof ContextWrapper) &&
368                 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
369             context = nextContext;
370         }
371         return (ContextImpl)context;
372     }
373 
374     @Override
getAssets()375     public AssetManager getAssets() {
376         return getResources().getAssets();
377     }
378 
379     @Override
getResources()380     public Resources getResources() {
381         return mResources;
382     }
383 
384     @Override
getPackageManager()385     public PackageManager getPackageManager() {
386         if (mPackageManager != null) {
387             return mPackageManager;
388         }
389 
390         final IPackageManager pm = ActivityThread.getPackageManager();
391         if (pm != null) {
392             // Doesn't matter if we make more than one instance.
393             return (mPackageManager = new ApplicationPackageManager(this, pm));
394         }
395 
396         return null;
397     }
398 
399     @Override
getContentResolver()400     public ContentResolver getContentResolver() {
401         return mContentResolver;
402     }
403 
404     @Override
getMainLooper()405     public Looper getMainLooper() {
406         return mMainThread.getLooper();
407     }
408 
409     @Override
getMainExecutor()410     public Executor getMainExecutor() {
411         return mMainThread.getExecutor();
412     }
413 
414     @Override
getApplicationContext()415     public Context getApplicationContext() {
416         return (mPackageInfo != null) ?
417                 mPackageInfo.getApplication() : mMainThread.getApplication();
418     }
419 
420     @Override
setTheme(int resId)421     public void setTheme(int resId) {
422         synchronized (mSync) {
423             if (mThemeResource != resId) {
424                 mThemeResource = resId;
425                 initializeTheme();
426             }
427         }
428     }
429 
430     @Override
getThemeResId()431     public int getThemeResId() {
432         synchronized (mSync) {
433             return mThemeResource;
434         }
435     }
436 
437     @Override
getTheme()438     public Resources.Theme getTheme() {
439         synchronized (mSync) {
440             if (mTheme != null) {
441                 return mTheme;
442             }
443 
444             mThemeResource = Resources.selectDefaultTheme(mThemeResource,
445                     getOuterContext().getApplicationInfo().targetSdkVersion);
446             initializeTheme();
447 
448             return mTheme;
449         }
450     }
451 
initializeTheme()452     private void initializeTheme() {
453         if (mTheme == null) {
454             mTheme = mResources.newTheme();
455         }
456         mTheme.applyStyle(mThemeResource, true);
457     }
458 
459     @Override
getClassLoader()460     public ClassLoader getClassLoader() {
461         return mClassLoader != null ? mClassLoader : (mPackageInfo != null ? mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader());
462     }
463 
464     @Override
getPackageName()465     public String getPackageName() {
466         if (mPackageInfo != null) {
467             return mPackageInfo.getPackageName();
468         }
469         // No mPackageInfo means this is a Context for the system itself,
470         // and this here is its name.
471         return "android";
472     }
473 
474     /** @hide */
475     @Override
getBasePackageName()476     public String getBasePackageName() {
477         return mBasePackageName != null ? mBasePackageName : getPackageName();
478     }
479 
480     /** @hide */
481     @Override
getOpPackageName()482     public String getOpPackageName() {
483         return mAttributionSource.getPackageName();
484     }
485 
486     /** @hide */
487     @Override
getAttributionTag()488     public @Nullable String getAttributionTag() {
489         return mAttributionSource.getAttributionTag();
490     }
491 
492     @Override
getParams()493     public @Nullable ContextParams getParams() {
494         return mParams;
495     }
496 
497     @Override
getAttributionSource()498     public @NonNull AttributionSource getAttributionSource() {
499         return mAttributionSource;
500     }
501 
502     @Override
getApplicationInfo()503     public ApplicationInfo getApplicationInfo() {
504         if (mPackageInfo != null) {
505             return mPackageInfo.getApplicationInfo();
506         }
507         throw new RuntimeException("Not supported in system context");
508     }
509 
510     @Override
getPackageResourcePath()511     public String getPackageResourcePath() {
512         if (mPackageInfo != null) {
513             return mPackageInfo.getResDir();
514         }
515         throw new RuntimeException("Not supported in system context");
516     }
517 
518     @Override
getPackageCodePath()519     public String getPackageCodePath() {
520         if (mPackageInfo != null) {
521             return mPackageInfo.getAppDir();
522         }
523         throw new RuntimeException("Not supported in system context");
524     }
525 
526     @Override
getSharedPreferences(String name, int mode)527     public SharedPreferences getSharedPreferences(String name, int mode) {
528         // At least one application in the world actually passes in a null
529         // name.  This happened to work because when we generated the file name
530         // we would stringify it to "null.xml".  Nice.
531         if (mPackageInfo.getApplicationInfo().targetSdkVersion <
532                 Build.VERSION_CODES.KITKAT) {
533             if (name == null) {
534                 name = "null";
535             }
536         }
537 
538         File file;
539         synchronized (ContextImpl.class) {
540             if (mSharedPrefsPaths == null) {
541                 mSharedPrefsPaths = new ArrayMap<>();
542             }
543             file = mSharedPrefsPaths.get(name);
544             if (file == null) {
545                 file = getSharedPreferencesPath(name);
546                 mSharedPrefsPaths.put(name, file);
547             }
548         }
549         return getSharedPreferences(file, mode);
550     }
551 
552     @Override
getSharedPreferences(File file, int mode)553     public SharedPreferences getSharedPreferences(File file, int mode) {
554         SharedPreferencesImpl sp;
555         synchronized (ContextImpl.class) {
556             final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
557             sp = cache.get(file);
558             if (sp == null) {
559                 checkMode(mode);
560                 if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
561                     if (isCredentialProtectedStorage()
562                             && !getSystemService(UserManager.class)
563                                     .isUserUnlockingOrUnlocked(UserHandle.myUserId())) {
564                         throw new IllegalStateException("SharedPreferences in credential encrypted "
565                                 + "storage are not available until after user is unlocked");
566                     }
567                 }
568                 sp = new SharedPreferencesImpl(file, mode);
569                 cache.put(file, sp);
570                 return sp;
571             }
572         }
573         if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
574             getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
575             // If somebody else (some other process) changed the prefs
576             // file behind our back, we reload it.  This has been the
577             // historical (if undocumented) behavior.
578             sp.startReloadIfChangedUnexpectedly();
579         }
580         return sp;
581     }
582 
583     @GuardedBy("ContextImpl.class")
getSharedPreferencesCacheLocked()584     private ArrayMap<File, SharedPreferencesImpl> getSharedPreferencesCacheLocked() {
585         if (sSharedPrefsCache == null) {
586             sSharedPrefsCache = new ArrayMap<>();
587         }
588 
589         final String packageName = getPackageName();
590         ArrayMap<File, SharedPreferencesImpl> packagePrefs = sSharedPrefsCache.get(packageName);
591         if (packagePrefs == null) {
592             packagePrefs = new ArrayMap<>();
593             sSharedPrefsCache.put(packageName, packagePrefs);
594         }
595 
596         return packagePrefs;
597     }
598 
599     @Override
reloadSharedPreferences()600     public void reloadSharedPreferences() {
601         // Build the list of all per-context impls (i.e. caches) we know about
602         ArrayList<SharedPreferencesImpl> spImpls = new ArrayList<>();
603         synchronized (ContextImpl.class) {
604             final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
605             for (int i = 0; i < cache.size(); i++) {
606                 final SharedPreferencesImpl sp = cache.valueAt(i);
607                 if (sp != null) {
608                     spImpls.add(sp);
609                 }
610             }
611         }
612 
613         // Issue the reload outside the cache lock
614         for (int i = 0; i < spImpls.size(); i++) {
615             spImpls.get(i).startReloadIfChangedUnexpectedly();
616         }
617     }
618 
619     /**
620      * Try our best to migrate all files from source to target that match
621      * requested prefix.
622      *
623      * @return the number of files moved, or -1 if there was trouble.
624      */
moveFiles(File sourceDir, File targetDir, final String prefix)625     private static int moveFiles(File sourceDir, File targetDir, final String prefix) {
626         final File[] sourceFiles = FileUtils.listFilesOrEmpty(sourceDir, new FilenameFilter() {
627             @Override
628             public boolean accept(File dir, String name) {
629                 return name.startsWith(prefix);
630             }
631         });
632 
633         int res = 0;
634         for (File sourceFile : sourceFiles) {
635             final File targetFile = new File(targetDir, sourceFile.getName());
636             Log.d(TAG, "Migrating " + sourceFile + " to " + targetFile);
637             try {
638                 FileUtils.copyFileOrThrow(sourceFile, targetFile);
639                 FileUtils.copyPermissions(sourceFile, targetFile);
640                 if (!sourceFile.delete()) {
641                     throw new IOException("Failed to clean up " + sourceFile);
642                 }
643                 if (res != -1) {
644                     res++;
645                 }
646             } catch (IOException e) {
647                 Log.w(TAG, "Failed to migrate " + sourceFile + ": " + e);
648                 res = -1;
649             }
650         }
651         return res;
652     }
653 
654     @Override
moveSharedPreferencesFrom(Context sourceContext, String name)655     public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
656         synchronized (ContextImpl.class) {
657             final File source = sourceContext.getSharedPreferencesPath(name);
658             final File target = getSharedPreferencesPath(name);
659 
660             final int res = moveFiles(source.getParentFile(), target.getParentFile(),
661                     source.getName());
662             if (res > 0) {
663                 // We moved at least one file, so evict any in-memory caches for
664                 // either location
665                 final ArrayMap<File, SharedPreferencesImpl> cache =
666                         getSharedPreferencesCacheLocked();
667                 cache.remove(source);
668                 cache.remove(target);
669             }
670             return res != -1;
671         }
672     }
673 
674     @Override
deleteSharedPreferences(String name)675     public boolean deleteSharedPreferences(String name) {
676         synchronized (ContextImpl.class) {
677             final File prefs = getSharedPreferencesPath(name);
678             final File prefsBackup = SharedPreferencesImpl.makeBackupFile(prefs);
679 
680             // Evict any in-memory caches
681             final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
682             cache.remove(prefs);
683 
684             prefs.delete();
685             prefsBackup.delete();
686 
687             // We failed if files are still lingering
688             return !(prefs.exists() || prefsBackup.exists());
689         }
690     }
691 
692     @UnsupportedAppUsage
getPreferencesDir()693     private File getPreferencesDir() {
694         synchronized (mSync) {
695             if (mPreferencesDir == null) {
696                 mPreferencesDir = new File(getDataDir(), "shared_prefs");
697             }
698             return ensurePrivateDirExists(mPreferencesDir);
699         }
700     }
701 
702     @Override
openFileInput(String name)703     public FileInputStream openFileInput(String name)
704         throws FileNotFoundException {
705         File f = makeFilename(getFilesDir(), name);
706         return new FileInputStream(f);
707     }
708 
709     @Override
openFileOutput(String name, int mode)710     public FileOutputStream openFileOutput(String name, int mode) throws FileNotFoundException {
711         checkMode(mode);
712         final boolean append = (mode&MODE_APPEND) != 0;
713         File f = makeFilename(getFilesDir(), name);
714         try {
715             FileOutputStream fos = new FileOutputStream(f, append);
716             setFilePermissionsFromMode(f.getPath(), mode, 0);
717             return fos;
718         } catch (FileNotFoundException e) {
719         }
720 
721         File parent = f.getParentFile();
722         parent.mkdir();
723         FileUtils.setPermissions(
724             parent.getPath(),
725             FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
726             -1, -1);
727         FileOutputStream fos = new FileOutputStream(f, append);
728         setFilePermissionsFromMode(f.getPath(), mode, 0);
729         return fos;
730     }
731 
732     @Override
deleteFile(String name)733     public boolean deleteFile(String name) {
734         File f = makeFilename(getFilesDir(), name);
735         return f.delete();
736     }
737 
738     /**
739      * Common-path handling of app data dir creation
740      */
ensurePrivateDirExists(File file)741     private static File ensurePrivateDirExists(File file) {
742         return ensurePrivateDirExists(file, 0771, -1, null);
743     }
744 
ensurePrivateCacheDirExists(File file, String xattr)745     private static File ensurePrivateCacheDirExists(File file, String xattr) {
746         final int gid = UserHandle.getCacheAppGid(Process.myUid());
747         return ensurePrivateDirExists(file, 02771, gid, xattr);
748     }
749 
ensurePrivateDirExists(File file, int mode, int gid, String xattr)750     private static File ensurePrivateDirExists(File file, int mode, int gid, String xattr) {
751         if (!file.exists()) {
752             final String path = file.getAbsolutePath();
753             try {
754                 Os.mkdir(path, mode);
755                 Os.chmod(path, mode);
756                 if (gid != -1) {
757                     Os.chown(path, -1, gid);
758                 }
759             } catch (ErrnoException e) {
760                 if (e.errno == OsConstants.EEXIST) {
761                     // We must have raced with someone; that's okay
762                 } else {
763                     Log.w(TAG, "Failed to ensure " + file + ": " + e.getMessage());
764                 }
765             }
766 
767             if (xattr != null) {
768                 try {
769                     final StructStat stat = Os.stat(file.getAbsolutePath());
770                     final byte[] value = new byte[8];
771                     Memory.pokeLong(value, 0, stat.st_ino, ByteOrder.nativeOrder());
772                     Os.setxattr(file.getParentFile().getAbsolutePath(), xattr, value, 0);
773                 } catch (ErrnoException e) {
774                     Log.w(TAG, "Failed to update " + xattr + ": " + e.getMessage());
775                 }
776             }
777         }
778         return file;
779     }
780 
781     @Override
getFilesDir()782     public File getFilesDir() {
783         synchronized (mSync) {
784             if (mFilesDir == null) {
785                 mFilesDir = new File(getDataDir(), "files");
786             }
787             return ensurePrivateDirExists(mFilesDir);
788         }
789     }
790 
791     @Override
getCrateDir(@onNull String crateId)792     public File getCrateDir(@NonNull String crateId) {
793         Preconditions.checkArgument(FileUtils.isValidExtFilename(crateId), "invalidated crateId");
794         final Path cratesRootPath = getDataDir().toPath().resolve("crates");
795         final Path absoluteNormalizedCratePath = cratesRootPath.resolve(crateId)
796                 .toAbsolutePath().normalize();
797 
798         synchronized (mSync) {
799             if (mCratesDir == null) {
800                 mCratesDir = cratesRootPath.toFile();
801             }
802             ensurePrivateDirExists(mCratesDir);
803         }
804 
805         File cratedDir = absoluteNormalizedCratePath.toFile();
806         return ensurePrivateDirExists(cratedDir);
807     }
808 
809     @Override
getNoBackupFilesDir()810     public File getNoBackupFilesDir() {
811         synchronized (mSync) {
812             if (mNoBackupFilesDir == null) {
813                 mNoBackupFilesDir = new File(getDataDir(), "no_backup");
814             }
815             return ensurePrivateDirExists(mNoBackupFilesDir);
816         }
817     }
818 
819     @Override
getExternalFilesDir(String type)820     public File getExternalFilesDir(String type) {
821         // Operates on primary external storage
822         final File[] dirs = getExternalFilesDirs(type);
823         return (dirs != null && dirs.length > 0) ? dirs[0] : null;
824     }
825 
826     @Override
getExternalFilesDirs(String type)827     public File[] getExternalFilesDirs(String type) {
828         synchronized (mSync) {
829             File[] dirs = Environment.buildExternalStorageAppFilesDirs(getPackageName());
830             if (type != null) {
831                 dirs = Environment.buildPaths(dirs, type);
832             }
833             return ensureExternalDirsExistOrFilter(dirs, true /* tryCreateInProcess */);
834         }
835     }
836 
837     @Override
getObbDir()838     public File getObbDir() {
839         // Operates on primary external storage
840         final File[] dirs = getObbDirs();
841         return (dirs != null && dirs.length > 0) ? dirs[0] : null;
842     }
843 
844     @Override
getObbDirs()845     public File[] getObbDirs() {
846         synchronized (mSync) {
847             File[] dirs = Environment.buildExternalStorageAppObbDirs(getPackageName());
848             return ensureExternalDirsExistOrFilter(dirs, true /* tryCreateInProcess */);
849         }
850     }
851 
852     @Override
getCacheDir()853     public File getCacheDir() {
854         synchronized (mSync) {
855             if (mCacheDir == null) {
856                 mCacheDir = new File(getDataDir(), "cache");
857             }
858             return ensurePrivateCacheDirExists(mCacheDir, XATTR_INODE_CACHE);
859         }
860     }
861 
862     @Override
getCodeCacheDir()863     public File getCodeCacheDir() {
864         synchronized (mSync) {
865             if (mCodeCacheDir == null) {
866                 mCodeCacheDir = getCodeCacheDirBeforeBind(getDataDir());
867             }
868             return ensurePrivateCacheDirExists(mCodeCacheDir, XATTR_INODE_CODE_CACHE);
869         }
870     }
871 
872     /**
873      * Helper for getting code-cache dir potentially before application bind.
874      *
875      * @hide
876      */
getCodeCacheDirBeforeBind(File dataDir)877     static File getCodeCacheDirBeforeBind(File dataDir) {
878         return new File(dataDir, "code_cache");
879     }
880 
881     @Override
getExternalCacheDir()882     public File getExternalCacheDir() {
883         // Operates on primary external storage
884         final File[] dirs = getExternalCacheDirs();
885         return (dirs != null && dirs.length > 0) ? dirs[0] : null;
886     }
887 
888     @Override
getExternalCacheDirs()889     public File[] getExternalCacheDirs() {
890         synchronized (mSync) {
891             File[] dirs = Environment.buildExternalStorageAppCacheDirs(getPackageName());
892             // We don't try to create cache directories in-process, because they need special
893             // setup for accurate quota tracking. This ensures the cache dirs are always
894             // created through StorageManagerService.
895             return ensureExternalDirsExistOrFilter(dirs, false /* tryCreateInProcess */);
896         }
897     }
898 
899     @Override
getExternalMediaDirs()900     public File[] getExternalMediaDirs() {
901         synchronized (mSync) {
902             File[] dirs = Environment.buildExternalStorageAppMediaDirs(getPackageName());
903             return ensureExternalDirsExistOrFilter(dirs, true /* tryCreateInProcess */);
904         }
905     }
906 
907     /**
908      * @hide
909      */
910     @Nullable
911     @Override
getPreloadsFileCache()912     public File getPreloadsFileCache() {
913         return Environment.getDataPreloadsFileCacheDirectory(getPackageName());
914     }
915 
916     @Override
getFileStreamPath(String name)917     public File getFileStreamPath(String name) {
918         return makeFilename(getFilesDir(), name);
919     }
920 
921     @Override
getSharedPreferencesPath(String name)922     public File getSharedPreferencesPath(String name) {
923         return makeFilename(getPreferencesDir(), name + ".xml");
924     }
925 
926     @Override
fileList()927     public String[] fileList() {
928         return FileUtils.listOrEmpty(getFilesDir());
929     }
930 
931     @Override
openOrCreateDatabase(String name, int mode, CursorFactory factory)932     public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
933         return openOrCreateDatabase(name, mode, factory, null);
934     }
935 
936     @Override
openOrCreateDatabase(String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler)937     public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
938             DatabaseErrorHandler errorHandler) {
939         checkMode(mode);
940         File f = getDatabasePath(name);
941         int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
942         if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
943             flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
944         }
945         if ((mode & MODE_NO_LOCALIZED_COLLATORS) != 0) {
946             flags |= SQLiteDatabase.NO_LOCALIZED_COLLATORS;
947         }
948         SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
949         setFilePermissionsFromMode(f.getPath(), mode, 0);
950         return db;
951     }
952 
953     @Override
moveDatabaseFrom(Context sourceContext, String name)954     public boolean moveDatabaseFrom(Context sourceContext, String name) {
955         synchronized (ContextImpl.class) {
956             final File source = sourceContext.getDatabasePath(name);
957             final File target = getDatabasePath(name);
958             return moveFiles(source.getParentFile(), target.getParentFile(),
959                     source.getName()) != -1;
960         }
961     }
962 
963     @Override
deleteDatabase(String name)964     public boolean deleteDatabase(String name) {
965         try {
966             File f = getDatabasePath(name);
967             return SQLiteDatabase.deleteDatabase(f);
968         } catch (Exception e) {
969         }
970         return false;
971     }
972 
973     @Override
getDatabasePath(String name)974     public File getDatabasePath(String name) {
975         File dir;
976         File f;
977 
978         if (name.charAt(0) == File.separatorChar) {
979             String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
980             dir = new File(dirPath);
981             name = name.substring(name.lastIndexOf(File.separatorChar));
982             f = new File(dir, name);
983 
984             if (!dir.isDirectory() && dir.mkdir()) {
985                 FileUtils.setPermissions(dir.getPath(),
986                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
987                     -1, -1);
988             }
989         } else {
990             dir = getDatabasesDir();
991             f = makeFilename(dir, name);
992         }
993 
994         return f;
995     }
996 
997     @Override
databaseList()998     public String[] databaseList() {
999         return FileUtils.listOrEmpty(getDatabasesDir());
1000     }
1001 
getDatabasesDir()1002     private File getDatabasesDir() {
1003         synchronized (mSync) {
1004             if (mDatabasesDir == null) {
1005                 if ("android".equals(getPackageName())) {
1006                     mDatabasesDir = new File("/data/system");
1007                 } else {
1008                     mDatabasesDir = new File(getDataDir(), "databases");
1009                 }
1010             }
1011             return ensurePrivateDirExists(mDatabasesDir);
1012         }
1013     }
1014 
1015     @Override
1016     @Deprecated
getWallpaper()1017     public Drawable getWallpaper() {
1018         return getWallpaperManager().getDrawable();
1019     }
1020 
1021     @Override
1022     @Deprecated
peekWallpaper()1023     public Drawable peekWallpaper() {
1024         return getWallpaperManager().peekDrawable();
1025     }
1026 
1027     @Override
1028     @Deprecated
getWallpaperDesiredMinimumWidth()1029     public int getWallpaperDesiredMinimumWidth() {
1030         return getWallpaperManager().getDesiredMinimumWidth();
1031     }
1032 
1033     @Override
1034     @Deprecated
getWallpaperDesiredMinimumHeight()1035     public int getWallpaperDesiredMinimumHeight() {
1036         return getWallpaperManager().getDesiredMinimumHeight();
1037     }
1038 
1039     @Override
1040     @Deprecated
setWallpaper(Bitmap bitmap)1041     public void setWallpaper(Bitmap bitmap) throws IOException {
1042         getWallpaperManager().setBitmap(bitmap);
1043     }
1044 
1045     @Override
1046     @Deprecated
setWallpaper(InputStream data)1047     public void setWallpaper(InputStream data) throws IOException {
1048         getWallpaperManager().setStream(data);
1049     }
1050 
1051     @Override
1052     @Deprecated
clearWallpaper()1053     public void clearWallpaper() throws IOException {
1054         getWallpaperManager().clear();
1055     }
1056 
getWallpaperManager()1057     private WallpaperManager getWallpaperManager() {
1058         return getSystemService(WallpaperManager.class);
1059     }
1060 
1061     @Override
startActivity(Intent intent)1062     public void startActivity(Intent intent) {
1063         warnIfCallingFromSystemProcess();
1064         startActivity(intent, null);
1065     }
1066 
1067     /** @hide */
1068     @Override
startActivityAsUser(Intent intent, UserHandle user)1069     public void startActivityAsUser(Intent intent, UserHandle user) {
1070         startActivityAsUser(intent, null, user);
1071     }
1072 
1073     @Override
startActivity(Intent intent, Bundle options)1074     public void startActivity(Intent intent, Bundle options) {
1075         warnIfCallingFromSystemProcess();
1076 
1077         // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
1078         // generally not allowed, except if the caller specifies the task id the activity should
1079         // be launched in. A bug was existed between N and O-MR1 which allowed this to work. We
1080         // maintain this for backwards compatibility.
1081         final int targetSdkVersion = getApplicationInfo().targetSdkVersion;
1082 
1083         if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
1084                 && (targetSdkVersion < Build.VERSION_CODES.N
1085                         || targetSdkVersion >= Build.VERSION_CODES.P)
1086                 && (options == null
1087                         || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
1088             throw new AndroidRuntimeException(
1089                     "Calling startActivity() from outside of an Activity "
1090                             + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
1091                             + " Is this really what you want?");
1092         }
1093         mMainThread.getInstrumentation().execStartActivity(
1094                 getOuterContext(), mMainThread.getApplicationThread(), null,
1095                 (Activity) null, intent, -1, options);
1096     }
1097 
1098     /** @hide */
1099     @Override
startActivityAsUser(Intent intent, Bundle options, UserHandle user)1100     public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
1101         try {
1102             ActivityTaskManager.getService().startActivityAsUser(
1103                     mMainThread.getApplicationThread(), getOpPackageName(), getAttributionTag(),
1104                     intent, intent.resolveTypeIfNeeded(getContentResolver()),
1105                     null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options,
1106                     user.getIdentifier());
1107         } catch (RemoteException e) {
1108             throw e.rethrowFromSystemServer();
1109         }
1110     }
1111 
1112     @Override
startActivities(Intent[] intents)1113     public void startActivities(Intent[] intents) {
1114         warnIfCallingFromSystemProcess();
1115         startActivities(intents, null);
1116     }
1117 
1118     /** @hide */
1119     @Override
startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle)1120     public int startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) {
1121         if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1122             throw new AndroidRuntimeException(
1123                     "Calling startActivities() from outside of an Activity "
1124                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
1125                     + " Is this really what you want?");
1126         }
1127         return mMainThread.getInstrumentation().execStartActivitiesAsUser(
1128                 getOuterContext(), mMainThread.getApplicationThread(), null,
1129                 (Activity) null, intents, options, userHandle.getIdentifier());
1130     }
1131 
1132     @Override
startActivities(Intent[] intents, Bundle options)1133     public void startActivities(Intent[] intents, Bundle options) {
1134         warnIfCallingFromSystemProcess();
1135         if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1136             throw new AndroidRuntimeException(
1137                     "Calling startActivities() from outside of an Activity "
1138                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
1139                     + " Is this really what you want?");
1140         }
1141         mMainThread.getInstrumentation().execStartActivities(
1142                 getOuterContext(), mMainThread.getApplicationThread(), null,
1143                 (Activity) null, intents, options);
1144     }
1145 
1146     @Override
startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)1147     public void startIntentSender(IntentSender intent,
1148             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
1149             throws IntentSender.SendIntentException {
1150         startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null);
1151     }
1152 
1153     @Override
startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options)1154     public void startIntentSender(IntentSender intent, Intent fillInIntent,
1155             int flagsMask, int flagsValues, int extraFlags, Bundle options)
1156             throws IntentSender.SendIntentException {
1157         try {
1158             String resolvedType = null;
1159             if (fillInIntent != null) {
1160                 fillInIntent.migrateExtraStreamToClipData(this);
1161                 fillInIntent.prepareToLeaveProcess(this);
1162                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
1163             }
1164             int result = ActivityTaskManager.getService()
1165                 .startActivityIntentSender(mMainThread.getApplicationThread(),
1166                         intent != null ? intent.getTarget() : null,
1167                         intent != null ? intent.getWhitelistToken() : null,
1168                         fillInIntent, resolvedType, null, null,
1169                         0, flagsMask, flagsValues, options);
1170             if (result == ActivityManager.START_CANCELED) {
1171                 throw new IntentSender.SendIntentException();
1172             }
1173             Instrumentation.checkStartActivityResult(result, null);
1174         } catch (RemoteException e) {
1175             throw e.rethrowFromSystemServer();
1176         }
1177     }
1178 
1179     @Override
sendBroadcast(Intent intent)1180     public void sendBroadcast(Intent intent) {
1181         warnIfCallingFromSystemProcess();
1182         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1183         try {
1184             intent.prepareToLeaveProcess(this);
1185             ActivityManager.getService().broadcastIntentWithFeature(
1186                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1187                     null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/,
1188                     AppOpsManager.OP_NONE, null, false, false, getUserId());
1189         } catch (RemoteException e) {
1190             throw e.rethrowFromSystemServer();
1191         }
1192     }
1193 
1194     @Override
sendBroadcast(Intent intent, String receiverPermission)1195     public void sendBroadcast(Intent intent, String receiverPermission) {
1196         warnIfCallingFromSystemProcess();
1197         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1198         String[] receiverPermissions = receiverPermission == null ? null
1199                 : new String[] {receiverPermission};
1200         try {
1201             intent.prepareToLeaveProcess(this);
1202             ActivityManager.getService().broadcastIntentWithFeature(
1203                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1204                     null, Activity.RESULT_OK, null, null, receiverPermissions,
1205                     null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false,
1206                     getUserId());
1207         } catch (RemoteException e) {
1208             throw e.rethrowFromSystemServer();
1209         }
1210     }
1211 
1212     @Override
sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions)1213     public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
1214         warnIfCallingFromSystemProcess();
1215         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1216         try {
1217             intent.prepareToLeaveProcess(this);
1218             ActivityManager.getService().broadcastIntentWithFeature(
1219                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1220                     null, Activity.RESULT_OK, null, null, receiverPermissions,
1221                     null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false,
1222                     getUserId());
1223         } catch (RemoteException e) {
1224             throw e.rethrowFromSystemServer();
1225         }
1226     }
1227 
1228     @Override
sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, Bundle options)1229     public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions,
1230             Bundle options) {
1231         warnIfCallingFromSystemProcess();
1232         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1233         try {
1234             intent.prepareToLeaveProcess(this);
1235             ActivityManager.getService().broadcastIntentWithFeature(
1236                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1237                     null, Activity.RESULT_OK, null, null, receiverPermissions,
1238                     null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false,
1239                     getUserId());
1240         } catch (RemoteException e) {
1241             throw e.rethrowFromSystemServer();
1242         }
1243     }
1244 
1245     @Override
sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user, String[] receiverPermissions)1246     public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
1247             String[] receiverPermissions) {
1248         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1249         try {
1250             intent.prepareToLeaveProcess(this);
1251             ActivityManager.getService().broadcastIntentWithFeature(
1252                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1253                     null, Activity.RESULT_OK, null, null, receiverPermissions,
1254                     null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false,
1255                     user.getIdentifier());
1256         } catch (RemoteException e) {
1257             throw e.rethrowFromSystemServer();
1258         }
1259     }
1260 
1261     @Override
sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, String[] excludedPermissions)1262     public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions,
1263             String[] excludedPermissions) {
1264         warnIfCallingFromSystemProcess();
1265         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1266         try {
1267             intent.prepareToLeaveProcess(this);
1268             ActivityManager.getService().broadcastIntentWithFeature(
1269                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1270                     null, Activity.RESULT_OK, null, null, receiverPermissions, excludedPermissions,
1271                     AppOpsManager.OP_NONE, null, false, false, getUserId());
1272         } catch (RemoteException e) {
1273             throw e.rethrowFromSystemServer();
1274         }
1275     }
1276 
1277     @Override
sendBroadcast(Intent intent, String receiverPermission, Bundle options)1278     public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
1279         warnIfCallingFromSystemProcess();
1280         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1281         String[] receiverPermissions = receiverPermission == null ? null
1282                 : new String[] {receiverPermission};
1283         try {
1284             intent.prepareToLeaveProcess(this);
1285             ActivityManager.getService().broadcastIntentWithFeature(
1286                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1287                     null, Activity.RESULT_OK, null, null, receiverPermissions,
1288                     null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false,
1289                     getUserId());
1290         } catch (RemoteException e) {
1291             throw e.rethrowFromSystemServer();
1292         }
1293     }
1294 
1295     @Override
sendBroadcast(Intent intent, String receiverPermission, int appOp)1296     public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
1297         warnIfCallingFromSystemProcess();
1298         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1299         String[] receiverPermissions = receiverPermission == null ? null
1300                 : new String[] {receiverPermission};
1301         try {
1302             intent.prepareToLeaveProcess(this);
1303             ActivityManager.getService().broadcastIntentWithFeature(
1304                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1305                     null, Activity.RESULT_OK, null, null, receiverPermissions,
1306                     null /*excludedPermissions=*/, appOp, null, false, false, getUserId());
1307         } catch (RemoteException e) {
1308             throw e.rethrowFromSystemServer();
1309         }
1310     }
1311 
1312     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission)1313     public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
1314         warnIfCallingFromSystemProcess();
1315         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1316         String[] receiverPermissions = receiverPermission == null ? null
1317                 : new String[] {receiverPermission};
1318         try {
1319             intent.prepareToLeaveProcess(this);
1320             ActivityManager.getService().broadcastIntentWithFeature(
1321                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1322                     null, Activity.RESULT_OK, null, null, receiverPermissions,
1323                     null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, false,
1324                     getUserId());
1325         } catch (RemoteException e) {
1326             throw e.rethrowFromSystemServer();
1327         }
1328     }
1329 
1330     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1331     public void sendOrderedBroadcast(Intent intent,
1332             String receiverPermission, BroadcastReceiver resultReceiver,
1333             Handler scheduler, int initialCode, String initialData,
1334             Bundle initialExtras) {
1335         sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
1336                 resultReceiver, scheduler, initialCode, initialData, initialExtras, null);
1337     }
1338 
1339     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1340     public void sendOrderedBroadcast(Intent intent,
1341             String receiverPermission, Bundle options, BroadcastReceiver resultReceiver,
1342             Handler scheduler, int initialCode, String initialData,
1343             Bundle initialExtras) {
1344         sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
1345                 resultReceiver, scheduler, initialCode, initialData, initialExtras, options);
1346     }
1347 
1348     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1349     public void sendOrderedBroadcast(Intent intent,
1350             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
1351             Handler scheduler, int initialCode, String initialData,
1352             Bundle initialExtras) {
1353         sendOrderedBroadcast(intent, receiverPermission, appOp,
1354                 resultReceiver, scheduler, initialCode, initialData, initialExtras, null);
1355     }
1356 
sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras, Bundle options)1357     void sendOrderedBroadcast(Intent intent,
1358             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
1359             Handler scheduler, int initialCode, String initialData,
1360             Bundle initialExtras, Bundle options) {
1361         warnIfCallingFromSystemProcess();
1362         IIntentReceiver rd = null;
1363         if (resultReceiver != null) {
1364             if (mPackageInfo != null) {
1365                 if (scheduler == null) {
1366                     scheduler = mMainThread.getHandler();
1367                 }
1368                 rd = mPackageInfo.getReceiverDispatcher(
1369                     resultReceiver, getOuterContext(), scheduler,
1370                     mMainThread.getInstrumentation(), false);
1371             } else {
1372                 if (scheduler == null) {
1373                     scheduler = mMainThread.getHandler();
1374                 }
1375                 rd = new LoadedApk.ReceiverDispatcher(
1376                         resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1377             }
1378         }
1379         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1380         String[] receiverPermissions = receiverPermission == null ? null
1381                 : new String[] {receiverPermission};
1382         try {
1383             intent.prepareToLeaveProcess(this);
1384             ActivityManager.getService().broadcastIntentWithFeature(
1385                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1386                     rd, initialCode, initialData, initialExtras, receiverPermissions,
1387                     null /*excludedPermissions=*/, appOp, options, true, false, getUserId());
1388         } catch (RemoteException e) {
1389             throw e.rethrowFromSystemServer();
1390         }
1391     }
1392 
1393     @Override
sendBroadcastAsUser(Intent intent, UserHandle user)1394     public void sendBroadcastAsUser(Intent intent, UserHandle user) {
1395         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1396         try {
1397             intent.prepareToLeaveProcess(this);
1398             ActivityManager.getService().broadcastIntentWithFeature(
1399                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1400                     null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/,
1401                     AppOpsManager.OP_NONE, null, false, false, user.getIdentifier());
1402         } catch (RemoteException e) {
1403             throw e.rethrowFromSystemServer();
1404         }
1405     }
1406 
1407     @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission)1408     public void sendBroadcastAsUser(Intent intent, UserHandle user,
1409             String receiverPermission) {
1410         sendBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE);
1411     }
1412 
1413     @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, Bundle options)1414     public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
1415             Bundle options) {
1416         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1417         String[] receiverPermissions = receiverPermission == null ? null
1418                 : new String[] {receiverPermission};
1419         try {
1420             intent.prepareToLeaveProcess(this);
1421             ActivityManager.getService().broadcastIntentWithFeature(
1422                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1423                     null, Activity.RESULT_OK, null, null, receiverPermissions,
1424                     null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false,
1425                     user.getIdentifier());
1426         } catch (RemoteException e) {
1427             throw e.rethrowFromSystemServer();
1428         }
1429     }
1430 
1431     @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp)1432     public void sendBroadcastAsUser(Intent intent, UserHandle user,
1433             String receiverPermission, int appOp) {
1434         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1435         String[] receiverPermissions = receiverPermission == null ? null
1436                 : new String[] {receiverPermission};
1437         try {
1438             intent.prepareToLeaveProcess(this);
1439             ActivityManager.getService().broadcastIntentWithFeature(
1440                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1441                     null, Activity.RESULT_OK, null, null, receiverPermissions,
1442                     null /*excludedPermissions=*/, appOp, null, false, false, user.getIdentifier());
1443         } catch (RemoteException e) {
1444             throw e.rethrowFromSystemServer();
1445         }
1446     }
1447 
1448     @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1449     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1450             String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
1451             int initialCode, String initialData, Bundle initialExtras) {
1452         sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE,
1453                 null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
1454     }
1455 
1456     @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1457     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1458             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
1459             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
1460         sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp,
1461                 null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
1462     }
1463 
1464     @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1465     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1466             String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
1467             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
1468         IIntentReceiver rd = null;
1469         if (resultReceiver != null) {
1470             if (mPackageInfo != null) {
1471                 if (scheduler == null) {
1472                     scheduler = mMainThread.getHandler();
1473                 }
1474                 rd = mPackageInfo.getReceiverDispatcher(
1475                     resultReceiver, getOuterContext(), scheduler,
1476                     mMainThread.getInstrumentation(), false);
1477             } else {
1478                 if (scheduler == null) {
1479                     scheduler = mMainThread.getHandler();
1480                 }
1481                 rd = new LoadedApk.ReceiverDispatcher(resultReceiver, getOuterContext(),
1482                         scheduler, null, false).getIIntentReceiver();
1483             }
1484         }
1485         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1486         String[] receiverPermissions = receiverPermission == null ? null
1487                 : new String[] {receiverPermission};
1488         try {
1489             intent.prepareToLeaveProcess(this);
1490             ActivityManager.getService().broadcastIntentWithFeature(
1491                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1492                     rd, initialCode, initialData, initialExtras, receiverPermissions,
1493                     null /*excludedPermissions=*/, appOp, options, true, false,
1494                     user.getIdentifier());
1495         } catch (RemoteException e) {
1496             throw e.rethrowFromSystemServer();
1497         }
1498     }
1499 
1500     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, @Nullable Bundle initialExtras)1501     public void sendOrderedBroadcast(Intent intent, String receiverPermission,
1502             String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
1503             int initialCode, String initialData, @Nullable Bundle initialExtras) {
1504         int intAppOp = AppOpsManager.OP_NONE;
1505         if (!TextUtils.isEmpty(receiverAppOp)) {
1506             intAppOp = AppOpsManager.strOpToOp(receiverAppOp);
1507         }
1508         sendOrderedBroadcastAsUser(intent, getUser(),
1509                 receiverPermission, intAppOp, resultReceiver, scheduler, initialCode, initialData,
1510                 initialExtras);
1511     }
1512 
1513     @Override
sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission, String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, String initialData, @Nullable Bundle initialExtras, Bundle options)1514     public void sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission,
1515             String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
1516             String initialData, @Nullable Bundle initialExtras, Bundle options) {
1517         int intAppOp = AppOpsManager.OP_NONE;
1518         if (!TextUtils.isEmpty(receiverAppOp)) {
1519             intAppOp = AppOpsManager.strOpToOp(receiverAppOp);
1520         }
1521         sendOrderedBroadcastAsUser(intent, getUser(), receiverPermission, intAppOp, options,
1522                 resultReceiver, scheduler, initialCode, initialData, initialExtras);
1523     }
1524 
1525     @Override
1526     @Deprecated
sendStickyBroadcast(Intent intent)1527     public void sendStickyBroadcast(Intent intent) {
1528         warnIfCallingFromSystemProcess();
1529         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1530         try {
1531             intent.prepareToLeaveProcess(this);
1532             ActivityManager.getService().broadcastIntentWithFeature(
1533                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1534                     null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/,
1535                     AppOpsManager.OP_NONE, null, false, true, getUserId());
1536         } catch (RemoteException e) {
1537             throw e.rethrowFromSystemServer();
1538         }
1539     }
1540 
1541     /**
1542      * <p>Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the
1543      * Intent you are sending stays around after the broadcast is complete,
1544      * so that others can quickly retrieve that data through the return
1545      * value of {@link #registerReceiver(BroadcastReceiver, IntentFilter)}.  In
1546      * all other ways, this behaves the same as
1547      * {@link #sendBroadcast(Intent)}.
1548      *
1549      * @deprecated Sticky broadcasts should not be used.  They provide no security (anyone
1550      * can access them), no protection (anyone can modify them), and many other problems.
1551      * The recommended pattern is to use a non-sticky broadcast to report that <em>something</em>
1552      * has changed, with another mechanism for apps to retrieve the current value whenever
1553      * desired.
1554      *
1555      * @param intent The Intent to broadcast; all receivers matching this
1556      * Intent will receive the broadcast, and the Intent will be held to
1557      * be re-broadcast to future receivers.
1558      * @param options (optional) Additional sending options, generated from a
1559      * {@link android.app.BroadcastOptions}.
1560      *
1561      * @see #sendBroadcast(Intent)
1562      * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
1563      */
1564     @Override
1565     @Deprecated
sendStickyBroadcast(@onNull Intent intent, @Nullable Bundle options)1566     public void sendStickyBroadcast(@NonNull Intent intent, @Nullable Bundle options) {
1567         warnIfCallingFromSystemProcess();
1568         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1569         try {
1570             intent.prepareToLeaveProcess(this);
1571             ActivityManager.getService().broadcastIntentWithFeature(
1572                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1573                     null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/,
1574                     AppOpsManager.OP_NONE, options, false, true, getUserId());
1575         } catch (RemoteException e) {
1576             throw e.rethrowFromSystemServer();
1577         }
1578     }
1579 
1580     @Override
1581     @Deprecated
sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1582     public void sendStickyOrderedBroadcast(Intent intent,
1583             BroadcastReceiver resultReceiver,
1584             Handler scheduler, int initialCode, String initialData,
1585             Bundle initialExtras) {
1586         warnIfCallingFromSystemProcess();
1587         IIntentReceiver rd = null;
1588         if (resultReceiver != null) {
1589             if (mPackageInfo != null) {
1590                 if (scheduler == null) {
1591                     scheduler = mMainThread.getHandler();
1592                 }
1593                 rd = mPackageInfo.getReceiverDispatcher(
1594                     resultReceiver, getOuterContext(), scheduler,
1595                     mMainThread.getInstrumentation(), false);
1596             } else {
1597                 if (scheduler == null) {
1598                     scheduler = mMainThread.getHandler();
1599                 }
1600                 rd = new LoadedApk.ReceiverDispatcher(
1601                         resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1602             }
1603         }
1604         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1605         try {
1606             intent.prepareToLeaveProcess(this);
1607             ActivityManager.getService().broadcastIntentWithFeature(
1608                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1609                     rd, initialCode, initialData, initialExtras, null,
1610                     null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, true,
1611                     getUserId());
1612         } catch (RemoteException e) {
1613             throw e.rethrowFromSystemServer();
1614         }
1615     }
1616 
1617     @Override
1618     @Deprecated
removeStickyBroadcast(Intent intent)1619     public void removeStickyBroadcast(Intent intent) {
1620         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1621         if (resolvedType != null) {
1622             intent = new Intent(intent);
1623             intent.setDataAndType(intent.getData(), resolvedType);
1624         }
1625         try {
1626             intent.prepareToLeaveProcess(this);
1627             ActivityManager.getService().unbroadcastIntent(
1628                     mMainThread.getApplicationThread(), intent, getUserId());
1629         } catch (RemoteException e) {
1630             throw e.rethrowFromSystemServer();
1631         }
1632     }
1633 
1634     @Override
1635     @Deprecated
sendStickyBroadcastAsUser(Intent intent, UserHandle user)1636     public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
1637         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1638         try {
1639             intent.prepareToLeaveProcess(this);
1640             ActivityManager.getService().broadcastIntentWithFeature(
1641                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1642                     null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/,
1643                     AppOpsManager.OP_NONE, null, false, true, user.getIdentifier());
1644         } catch (RemoteException e) {
1645             throw e.rethrowFromSystemServer();
1646         }
1647     }
1648 
1649     @Override
1650     @Deprecated
sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options)1651     public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
1652         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1653         try {
1654             intent.prepareToLeaveProcess(this);
1655             ActivityManager.getService().broadcastIntentWithFeature(
1656                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1657                     null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/,
1658                     AppOpsManager.OP_NONE, options, false, true, user.getIdentifier());
1659         } catch (RemoteException e) {
1660             throw e.rethrowFromSystemServer();
1661         }
1662     }
1663 
1664     @Override
1665     @Deprecated
sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1666     public void sendStickyOrderedBroadcastAsUser(Intent intent,
1667             UserHandle user, BroadcastReceiver resultReceiver,
1668             Handler scheduler, int initialCode, String initialData,
1669             Bundle initialExtras) {
1670         IIntentReceiver rd = null;
1671         if (resultReceiver != null) {
1672             if (mPackageInfo != null) {
1673                 if (scheduler == null) {
1674                     scheduler = mMainThread.getHandler();
1675                 }
1676                 rd = mPackageInfo.getReceiverDispatcher(
1677                     resultReceiver, getOuterContext(), scheduler,
1678                     mMainThread.getInstrumentation(), false);
1679             } else {
1680                 if (scheduler == null) {
1681                     scheduler = mMainThread.getHandler();
1682                 }
1683                 rd = new LoadedApk.ReceiverDispatcher(
1684                         resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1685             }
1686         }
1687         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1688         try {
1689             intent.prepareToLeaveProcess(this);
1690             ActivityManager.getService().broadcastIntentWithFeature(
1691                     mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
1692                     rd, initialCode, initialData, initialExtras, null,
1693                     null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, true,
1694                     user.getIdentifier());
1695         } catch (RemoteException e) {
1696             throw e.rethrowFromSystemServer();
1697         }
1698     }
1699 
1700     @Override
1701     @Deprecated
removeStickyBroadcastAsUser(Intent intent, UserHandle user)1702     public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
1703         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1704         if (resolvedType != null) {
1705             intent = new Intent(intent);
1706             intent.setDataAndType(intent.getData(), resolvedType);
1707         }
1708         try {
1709             intent.prepareToLeaveProcess(this);
1710             ActivityManager.getService().unbroadcastIntent(
1711                     mMainThread.getApplicationThread(), intent, user.getIdentifier());
1712         } catch (RemoteException e) {
1713             throw e.rethrowFromSystemServer();
1714         }
1715     }
1716 
1717     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)1718     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1719         return registerReceiver(receiver, filter, null, null);
1720     }
1721 
1722     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags)1723     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1724             int flags) {
1725         return registerReceiver(receiver, filter, null, null, flags);
1726     }
1727 
1728     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)1729     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1730             String broadcastPermission, Handler scheduler) {
1731         return registerReceiverInternal(receiver, getUserId(),
1732                 filter, broadcastPermission, scheduler, getOuterContext(), 0);
1733     }
1734 
1735     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags)1736     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1737             String broadcastPermission, Handler scheduler, int flags) {
1738         return registerReceiverInternal(receiver, getUserId(),
1739                 filter, broadcastPermission, scheduler, getOuterContext(), flags);
1740     }
1741 
1742     @Override
registerReceiverForAllUsers(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)1743     public Intent registerReceiverForAllUsers(BroadcastReceiver receiver,
1744             IntentFilter filter, String broadcastPermission, Handler scheduler) {
1745         return registerReceiverAsUser(receiver, UserHandle.ALL,
1746                 filter, broadcastPermission, scheduler);
1747     }
1748 
1749     @Override
registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler)1750     public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
1751             IntentFilter filter, String broadcastPermission, Handler scheduler) {
1752         return registerReceiverInternal(receiver, user.getIdentifier(),
1753                 filter, broadcastPermission, scheduler, getOuterContext(), 0);
1754     }
1755 
registerReceiverInternal(BroadcastReceiver receiver, int userId, IntentFilter filter, String broadcastPermission, Handler scheduler, Context context, int flags)1756     private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
1757             IntentFilter filter, String broadcastPermission,
1758             Handler scheduler, Context context, int flags) {
1759         IIntentReceiver rd = null;
1760         if (receiver != null) {
1761             if (mPackageInfo != null && context != null) {
1762                 if (scheduler == null) {
1763                     scheduler = mMainThread.getHandler();
1764                 }
1765                 rd = mPackageInfo.getReceiverDispatcher(
1766                     receiver, context, scheduler,
1767                     mMainThread.getInstrumentation(), true);
1768             } else {
1769                 if (scheduler == null) {
1770                     scheduler = mMainThread.getHandler();
1771                 }
1772                 rd = new LoadedApk.ReceiverDispatcher(
1773                         receiver, context, scheduler, null, true).getIIntentReceiver();
1774             }
1775         }
1776         try {
1777             final Intent intent = ActivityManager.getService().registerReceiverWithFeature(
1778                     mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(),
1779                     AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, userId,
1780                     flags);
1781             if (intent != null) {
1782                 intent.setExtrasClassLoader(getClassLoader());
1783                 // TODO: determine at registration time if caller is
1784                 // protecting themselves with signature permission
1785                 intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
1786                         getAttributionSource());
1787             }
1788             return intent;
1789         } catch (RemoteException e) {
1790             throw e.rethrowFromSystemServer();
1791         }
1792     }
1793 
1794     @Override
unregisterReceiver(BroadcastReceiver receiver)1795     public void unregisterReceiver(BroadcastReceiver receiver) {
1796         if (mPackageInfo != null) {
1797             IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1798                     getOuterContext(), receiver);
1799             try {
1800                 ActivityManager.getService().unregisterReceiver(rd);
1801             } catch (RemoteException e) {
1802                 throw e.rethrowFromSystemServer();
1803             }
1804         } else {
1805             throw new RuntimeException("Not supported in system context");
1806         }
1807     }
1808 
validateServiceIntent(Intent service)1809     private void validateServiceIntent(Intent service) {
1810         if (service.getComponent() == null && service.getPackage() == null) {
1811             if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
1812                 IllegalArgumentException ex = new IllegalArgumentException(
1813                         "Service Intent must be explicit: " + service);
1814                 throw ex;
1815             } else {
1816                 Log.w(TAG, "Implicit intents with startService are not safe: " + service
1817                         + " " + Debug.getCallers(2, 3));
1818             }
1819         }
1820     }
1821 
1822     @Override
startService(Intent service)1823     public ComponentName startService(Intent service) {
1824         warnIfCallingFromSystemProcess();
1825         return startServiceCommon(service, false, mUser);
1826     }
1827 
1828     @Override
startForegroundService(Intent service)1829     public ComponentName startForegroundService(Intent service) {
1830         warnIfCallingFromSystemProcess();
1831         return startServiceCommon(service, true, mUser);
1832     }
1833 
1834     @Override
stopService(Intent service)1835     public boolean stopService(Intent service) {
1836         warnIfCallingFromSystemProcess();
1837         return stopServiceCommon(service, mUser);
1838     }
1839 
1840     @Override
startServiceAsUser(Intent service, UserHandle user)1841     public ComponentName startServiceAsUser(Intent service, UserHandle user) {
1842         return startServiceCommon(service, false, user);
1843     }
1844 
1845     @Override
startForegroundServiceAsUser(Intent service, UserHandle user)1846     public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
1847         return startServiceCommon(service, true, user);
1848     }
1849 
startServiceCommon(Intent service, boolean requireForeground, UserHandle user)1850     private ComponentName startServiceCommon(Intent service, boolean requireForeground,
1851             UserHandle user) {
1852         try {
1853             validateServiceIntent(service);
1854             service.prepareToLeaveProcess(this);
1855             ComponentName cn = ActivityManager.getService().startService(
1856                     mMainThread.getApplicationThread(), service,
1857                     service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
1858                     getOpPackageName(), getAttributionTag(), user.getIdentifier());
1859             if (cn != null) {
1860                 if (cn.getPackageName().equals("!")) {
1861                     throw new SecurityException(
1862                             "Not allowed to start service " + service
1863                             + " without permission " + cn.getClassName());
1864                 } else if (cn.getPackageName().equals("!!")) {
1865                     throw new SecurityException(
1866                             "Unable to start service " + service
1867                             + ": " + cn.getClassName());
1868                 } else if (cn.getPackageName().equals("?")) {
1869                     throw ServiceStartNotAllowedException.newInstance(requireForeground,
1870                             "Not allowed to start service " + service + ": " + cn.getClassName());
1871                 }
1872             }
1873             // If we started a foreground service in the same package, remember the stack trace.
1874             if (cn != null && requireForeground) {
1875                 if (cn.getPackageName().equals(getOpPackageName())) {
1876                     Service.setStartForegroundServiceStackTrace(cn.getClassName(),
1877                             new StackTrace("Last startServiceCommon() call for this service was "
1878                                     + "made here"));
1879                 }
1880             }
1881             return cn;
1882         } catch (RemoteException e) {
1883             throw e.rethrowFromSystemServer();
1884         }
1885     }
1886 
1887     @Override
stopServiceAsUser(Intent service, UserHandle user)1888     public boolean stopServiceAsUser(Intent service, UserHandle user) {
1889         return stopServiceCommon(service, user);
1890     }
1891 
stopServiceCommon(Intent service, UserHandle user)1892     private boolean stopServiceCommon(Intent service, UserHandle user) {
1893         try {
1894             validateServiceIntent(service);
1895             service.prepareToLeaveProcess(this);
1896             int res = ActivityManager.getService().stopService(
1897                 mMainThread.getApplicationThread(), service,
1898                 service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
1899             if (res < 0) {
1900                 throw new SecurityException(
1901                         "Not allowed to stop service " + service);
1902             }
1903             return res != 0;
1904         } catch (RemoteException e) {
1905             throw e.rethrowFromSystemServer();
1906         }
1907     }
1908 
1909     @Override
bindService(Intent service, ServiceConnection conn, int flags)1910     public boolean bindService(Intent service, ServiceConnection conn, int flags) {
1911         warnIfCallingFromSystemProcess();
1912         return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
1913                 getUser());
1914     }
1915 
1916     @Override
bindService( Intent service, int flags, Executor executor, ServiceConnection conn)1917     public boolean bindService(
1918             Intent service, int flags, Executor executor, ServiceConnection conn) {
1919         return bindServiceCommon(service, conn, flags, null, null, executor, getUser());
1920     }
1921 
1922     @Override
bindIsolatedService(Intent service, int flags, String instanceName, Executor executor, ServiceConnection conn)1923     public boolean bindIsolatedService(Intent service, int flags, String instanceName,
1924             Executor executor, ServiceConnection conn) {
1925         warnIfCallingFromSystemProcess();
1926         if (instanceName == null) {
1927             throw new NullPointerException("null instanceName");
1928         }
1929         return bindServiceCommon(service, conn, flags, instanceName, null, executor, getUser());
1930     }
1931 
1932     @Override
bindServiceAsUser(Intent service, ServiceConnection conn, int flags, UserHandle user)1933     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
1934             UserHandle user) {
1935         return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, user);
1936     }
1937 
1938     /** @hide */
1939     @Override
bindServiceAsUser(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user)1940     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
1941             Handler handler, UserHandle user) {
1942         if (handler == null) {
1943             throw new IllegalArgumentException("handler must not be null.");
1944         }
1945         return bindServiceCommon(service, conn, flags, null, handler, null, user);
1946     }
1947 
1948     /** @hide */
1949     @Override
getServiceDispatcher(ServiceConnection conn, Handler handler, int flags)1950     public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler,
1951             int flags) {
1952         return mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
1953     }
1954 
1955     /** @hide */
1956     @Override
getIApplicationThread()1957     public IApplicationThread getIApplicationThread() {
1958         return mMainThread.getApplicationThread();
1959     }
1960 
1961     /** @hide */
1962     @Override
getMainThreadHandler()1963     public Handler getMainThreadHandler() {
1964         return mMainThread.getHandler();
1965     }
1966 
bindServiceCommon(Intent service, ServiceConnection conn, int flags, String instanceName, Handler handler, Executor executor, UserHandle user)1967     private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
1968             String instanceName, Handler handler, Executor executor, UserHandle user) {
1969         // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
1970         IServiceConnection sd;
1971         if (conn == null) {
1972             throw new IllegalArgumentException("connection is null");
1973         }
1974         if (handler != null && executor != null) {
1975             throw new IllegalArgumentException("Handler and Executor both supplied");
1976         }
1977         if (mPackageInfo != null) {
1978             if (executor != null) {
1979                 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
1980             } else {
1981                 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
1982             }
1983         } else {
1984             throw new RuntimeException("Not supported in system context");
1985         }
1986         validateServiceIntent(service);
1987         try {
1988             IBinder token = getActivityToken();
1989             if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1990                     && mPackageInfo.getApplicationInfo().targetSdkVersion
1991                     < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1992                 flags |= BIND_WAIVE_PRIORITY;
1993             }
1994             service.prepareToLeaveProcess(this);
1995             int res = ActivityManager.getService().bindIsolatedService(
1996                 mMainThread.getApplicationThread(), getActivityToken(), service,
1997                 service.resolveTypeIfNeeded(getContentResolver()),
1998                 sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
1999             if (res < 0) {
2000                 throw new SecurityException(
2001                         "Not allowed to bind to service " + service);
2002             }
2003             return res != 0;
2004         } catch (RemoteException e) {
2005             throw e.rethrowFromSystemServer();
2006         }
2007     }
2008 
2009     @Override
updateServiceGroup(@onNull ServiceConnection conn, int group, int importance)2010     public void updateServiceGroup(@NonNull ServiceConnection conn, int group, int importance) {
2011         if (conn == null) {
2012             throw new IllegalArgumentException("connection is null");
2013         }
2014         if (mPackageInfo != null) {
2015             IServiceConnection sd = mPackageInfo.lookupServiceDispatcher(conn, getOuterContext());
2016             if (sd == null) {
2017                 throw new IllegalArgumentException("ServiceConnection not currently bound: "
2018                         + conn);
2019             }
2020             try {
2021                 ActivityManager.getService().updateServiceGroup(sd, group, importance);
2022             } catch (RemoteException e) {
2023                 throw e.rethrowFromSystemServer();
2024             }
2025         } else {
2026             throw new RuntimeException("Not supported in system context");
2027         }
2028     }
2029 
2030     @Override
unbindService(ServiceConnection conn)2031     public void unbindService(ServiceConnection conn) {
2032         if (conn == null) {
2033             throw new IllegalArgumentException("connection is null");
2034         }
2035         if (mPackageInfo != null) {
2036             IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
2037                     getOuterContext(), conn);
2038             try {
2039                 ActivityManager.getService().unbindService(sd);
2040             } catch (RemoteException e) {
2041                 throw e.rethrowFromSystemServer();
2042             }
2043         } else {
2044             throw new RuntimeException("Not supported in system context");
2045         }
2046     }
2047 
2048     @Override
startInstrumentation(ComponentName className, String profileFile, Bundle arguments)2049     public boolean startInstrumentation(ComponentName className,
2050             String profileFile, Bundle arguments) {
2051         try {
2052             if (arguments != null) {
2053                 arguments.setAllowFds(false);
2054             }
2055             return ActivityManager.getService().startInstrumentation(
2056                     className, profileFile, 0, arguments, null, null, getUserId(),
2057                     null /* ABI override */);
2058         } catch (RemoteException e) {
2059             throw e.rethrowFromSystemServer();
2060         }
2061     }
2062 
2063     @Override
getSystemService(String name)2064     public Object getSystemService(String name) {
2065         if (vmIncorrectContextUseEnabled()) {
2066             // Check incorrect Context usage.
2067             if (WINDOW_SERVICE.equals(name) && !isUiContext()) {
2068                 final String errorMessage = "Tried to access visual service "
2069                         + SystemServiceRegistry.getSystemServiceClassName(name)
2070                         + " from a non-visual Context:" + getOuterContext();
2071                 final String message = "WindowManager should be accessed from Activity or other "
2072                         + "visual Context. Use an Activity or a Context created with "
2073                         + "Context#createWindowContext(int, Bundle), which are adjusted to "
2074                         + "the configuration and visual bounds of an area on screen.";
2075                 final Exception exception = new IllegalAccessException(errorMessage);
2076                 StrictMode.onIncorrectContextUsed(message, exception);
2077                 Log.e(TAG, errorMessage + " " + message, exception);
2078             }
2079         }
2080         return SystemServiceRegistry.getSystemService(this, name);
2081     }
2082 
2083     @Override
getSystemServiceName(Class<?> serviceClass)2084     public String getSystemServiceName(Class<?> serviceClass) {
2085         return SystemServiceRegistry.getSystemServiceName(serviceClass);
2086     }
2087 
2088     /** @hide */
2089     @Override
isUiContext()2090     public boolean isUiContext() {
2091         switch (mContextType) {
2092             case CONTEXT_TYPE_ACTIVITY:
2093             case CONTEXT_TYPE_WINDOW_CONTEXT:
2094             case CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI:
2095                 return true;
2096             case CONTEXT_TYPE_DISPLAY_CONTEXT:
2097             case CONTEXT_TYPE_NON_UI: {
2098                 return false;
2099             }
2100             default:
2101                 return false;
2102         }
2103     }
2104 
2105     /** @hide */
2106     @Override
isConfigurationContext()2107     public boolean isConfigurationContext() {
2108         return isUiContext() || mIsConfigurationBasedContext;
2109     }
2110 
2111     /**
2112      * Temporary workaround to permit incorrect usages of Context by SystemUI.
2113      * TODO(b/147647877): Fix usages and remove.
2114      */
2115     @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck")
isSystemOrSystemUI(Context context)2116     private static boolean isSystemOrSystemUI(Context context) {
2117         return ActivityThread.isSystem() || context.checkPermission(
2118                 "android.permission.STATUS_BAR_SERVICE",
2119                 Binder.getCallingPid(),
2120                 Binder.getCallingUid()) == PERMISSION_GRANTED;
2121     }
2122 
2123     @Override
checkPermission(String permission, int pid, int uid)2124     public int checkPermission(String permission, int pid, int uid) {
2125         if (permission == null) {
2126             throw new IllegalArgumentException("permission is null");
2127         }
2128         if (mParams.isRenouncedPermission(permission)
2129                 && pid == android.os.Process.myPid() && uid == android.os.Process.myUid()) {
2130             Log.v(TAG, "Treating renounced permission " + permission + " as denied");
2131             return PERMISSION_DENIED;
2132         }
2133         return PermissionManager.checkPermission(permission, pid, uid);
2134     }
2135 
2136     /** @hide */
2137     @Override
checkPermission(String permission, int pid, int uid, IBinder callerToken)2138     public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
2139         if (permission == null) {
2140             throw new IllegalArgumentException("permission is null");
2141         }
2142         if (mParams.isRenouncedPermission(permission)
2143                 && pid == android.os.Process.myPid() && uid == android.os.Process.myUid()) {
2144             Log.v(TAG, "Treating renounced permission " + permission + " as denied");
2145             return PERMISSION_DENIED;
2146         }
2147         return checkPermission(permission, pid, uid);
2148     }
2149 
2150     @Override
checkCallingPermission(String permission)2151     public int checkCallingPermission(String permission) {
2152         if (permission == null) {
2153             throw new IllegalArgumentException("permission is null");
2154         }
2155 
2156         int pid = Binder.getCallingPid();
2157         if (pid != Process.myPid()) {
2158             return checkPermission(permission, pid, Binder.getCallingUid());
2159         }
2160         return PackageManager.PERMISSION_DENIED;
2161     }
2162 
2163     @Override
checkCallingOrSelfPermission(String permission)2164     public int checkCallingOrSelfPermission(String permission) {
2165         if (permission == null) {
2166             throw new IllegalArgumentException("permission is null");
2167         }
2168 
2169         return checkPermission(permission, Binder.getCallingPid(),
2170                 Binder.getCallingUid());
2171     }
2172 
2173     @Override
checkSelfPermission(String permission)2174     public int checkSelfPermission(String permission) {
2175         if (permission == null) {
2176             throw new IllegalArgumentException("permission is null");
2177         }
2178         if (mParams.isRenouncedPermission(permission)) {
2179             Log.v(TAG, "Treating renounced permission " + permission + " as denied");
2180             return PERMISSION_DENIED;
2181         }
2182 
2183         return checkPermission(permission, Process.myPid(), Process.myUid());
2184     }
2185 
enforce( String permission, int resultOfCheck, boolean selfToo, int uid, String message)2186     private void enforce(
2187             String permission, int resultOfCheck,
2188             boolean selfToo, int uid, String message) {
2189         if (resultOfCheck != PERMISSION_GRANTED) {
2190             throw new SecurityException(
2191                     (message != null ? (message + ": ") : "") +
2192                     (selfToo
2193                      ? "Neither user " + uid + " nor current process has "
2194                      : "uid " + uid + " does not have ") +
2195                     permission +
2196                     ".");
2197         }
2198     }
2199 
2200     @Override
enforcePermission( String permission, int pid, int uid, String message)2201     public void enforcePermission(
2202             String permission, int pid, int uid, String message) {
2203         enforce(permission,
2204                 checkPermission(permission, pid, uid),
2205                 false,
2206                 uid,
2207                 message);
2208     }
2209 
2210     @Override
enforceCallingPermission(String permission, String message)2211     public void enforceCallingPermission(String permission, String message) {
2212         enforce(permission,
2213                 checkCallingPermission(permission),
2214                 false,
2215                 Binder.getCallingUid(),
2216                 message);
2217     }
2218 
2219     @Override
enforceCallingOrSelfPermission( String permission, String message)2220     public void enforceCallingOrSelfPermission(
2221             String permission, String message) {
2222         enforce(permission,
2223                 checkCallingOrSelfPermission(permission),
2224                 true,
2225                 Binder.getCallingUid(),
2226                 message);
2227     }
2228 
2229     @Override
grantUriPermission(String toPackage, Uri uri, int modeFlags)2230     public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
2231          try {
2232             ActivityManager.getService().grantUriPermission(
2233                     mMainThread.getApplicationThread(), toPackage,
2234                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
2235         } catch (RemoteException e) {
2236             throw e.rethrowFromSystemServer();
2237         }
2238     }
2239 
2240     @Override
revokeUriPermission(Uri uri, int modeFlags)2241     public void revokeUriPermission(Uri uri, int modeFlags) {
2242          try {
2243             ActivityManager.getService().revokeUriPermission(
2244                     mMainThread.getApplicationThread(), null,
2245                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
2246         } catch (RemoteException e) {
2247             throw e.rethrowFromSystemServer();
2248         }
2249     }
2250 
2251     @Override
revokeUriPermission(String targetPackage, Uri uri, int modeFlags)2252     public void revokeUriPermission(String targetPackage, Uri uri, int modeFlags) {
2253         try {
2254             ActivityManager.getService().revokeUriPermission(
2255                     mMainThread.getApplicationThread(), targetPackage,
2256                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
2257         } catch (RemoteException e) {
2258             throw e.rethrowFromSystemServer();
2259         }
2260     }
2261 
2262     @Override
checkUriPermission(Uri uri, int pid, int uid, int modeFlags)2263     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
2264         try {
2265             return ActivityManager.getService().checkUriPermission(
2266                     ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
2267                     resolveUserId(uri), null);
2268         } catch (RemoteException e) {
2269             throw e.rethrowFromSystemServer();
2270         }
2271     }
2272 
2273     @NonNull
2274     @Override
checkUriPermissions(@onNull List<Uri> uris, int pid, int uid, int modeFlags)2275     public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
2276             int modeFlags) {
2277         try {
2278             return ActivityManager.getService().checkUriPermissions(uris, pid, uid, modeFlags,
2279                     null);
2280         } catch (RemoteException e) {
2281             throw e.rethrowFromSystemServer();
2282         }
2283     }
2284 
2285     /** @hide */
2286     @Override
checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken)2287     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
2288         try {
2289             return ActivityManager.getService().checkUriPermission(
2290                     ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
2291                     resolveUserId(uri), callerToken);
2292         } catch (RemoteException e) {
2293             throw e.rethrowFromSystemServer();
2294         }
2295     }
2296 
resolveUserId(Uri uri)2297     private int resolveUserId(Uri uri) {
2298         return ContentProvider.getUserIdFromUri(uri, getUserId());
2299     }
2300 
2301     @Override
checkCallingUriPermission(Uri uri, int modeFlags)2302     public int checkCallingUriPermission(Uri uri, int modeFlags) {
2303         int pid = Binder.getCallingPid();
2304         if (pid != Process.myPid()) {
2305             return checkUriPermission(uri, pid,
2306                     Binder.getCallingUid(), modeFlags);
2307         }
2308         return PackageManager.PERMISSION_DENIED;
2309     }
2310 
2311     @NonNull
2312     @Override
checkCallingUriPermissions(@onNull List<Uri> uris, int modeFlags)2313     public int[] checkCallingUriPermissions(@NonNull List<Uri> uris, int modeFlags) {
2314         int pid = Binder.getCallingPid();
2315         if (pid != Process.myPid()) {
2316             return checkUriPermissions(uris, pid, Binder.getCallingUid(), modeFlags);
2317         }
2318         int[] res = new int[uris.size()];
2319         Arrays.fill(res, PERMISSION_DENIED);
2320         return res;
2321     }
2322 
2323     @Override
checkCallingOrSelfUriPermission(Uri uri, int modeFlags)2324     public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
2325         return checkUriPermission(uri, Binder.getCallingPid(),
2326                 Binder.getCallingUid(), modeFlags);
2327     }
2328 
2329     @NonNull
2330     @Override
checkCallingOrSelfUriPermissions(@onNull List<Uri> uris, int modeFlags)2331     public int[] checkCallingOrSelfUriPermissions(@NonNull List<Uri> uris, int modeFlags) {
2332         return checkUriPermissions(uris, Binder.getCallingPid(), Binder.getCallingUid(), modeFlags);
2333     }
2334 
2335     @Override
checkUriPermission(Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags)2336     public int checkUriPermission(Uri uri, String readPermission,
2337             String writePermission, int pid, int uid, int modeFlags) {
2338         if (DEBUG) {
2339             Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
2340                     + readPermission + " writePermission=" + writePermission
2341                     + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
2342         }
2343         if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
2344             if (readPermission == null
2345                     || checkPermission(readPermission, pid, uid)
2346                     == PERMISSION_GRANTED) {
2347                 return PERMISSION_GRANTED;
2348             }
2349         }
2350         if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
2351             if (writePermission == null
2352                     || checkPermission(writePermission, pid, uid)
2353                     == PERMISSION_GRANTED) {
2354                 return PERMISSION_GRANTED;
2355             }
2356         }
2357         return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
2358                 : PackageManager.PERMISSION_DENIED;
2359     }
2360 
uriModeFlagToString(int uriModeFlags)2361     private String uriModeFlagToString(int uriModeFlags) {
2362         StringBuilder builder = new StringBuilder();
2363         if ((uriModeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
2364             builder.append("read and ");
2365         }
2366         if ((uriModeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
2367             builder.append("write and ");
2368         }
2369         if ((uriModeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
2370             builder.append("persistable and ");
2371         }
2372         if ((uriModeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
2373             builder.append("prefix and ");
2374         }
2375 
2376         if (builder.length() > 5) {
2377             builder.setLength(builder.length() - 5);
2378             return builder.toString();
2379         } else {
2380             throw new IllegalArgumentException("Unknown permission mode flags: " + uriModeFlags);
2381         }
2382     }
2383 
enforceForUri( int modeFlags, int resultOfCheck, boolean selfToo, int uid, Uri uri, String message)2384     private void enforceForUri(
2385             int modeFlags, int resultOfCheck, boolean selfToo,
2386             int uid, Uri uri, String message) {
2387         if (resultOfCheck != PERMISSION_GRANTED) {
2388             throw new SecurityException(
2389                     (message != null ? (message + ": ") : "") +
2390                     (selfToo
2391                      ? "Neither user " + uid + " nor current process has "
2392                      : "User " + uid + " does not have ") +
2393                     uriModeFlagToString(modeFlags) +
2394                     " permission on " +
2395                     uri +
2396                     ".");
2397         }
2398     }
2399 
2400     @Override
enforceUriPermission( Uri uri, int pid, int uid, int modeFlags, String message)2401     public void enforceUriPermission(
2402             Uri uri, int pid, int uid, int modeFlags, String message) {
2403         enforceForUri(
2404                 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
2405                 false, uid, uri, message);
2406     }
2407 
2408     @Override
enforceCallingUriPermission( Uri uri, int modeFlags, String message)2409     public void enforceCallingUriPermission(
2410             Uri uri, int modeFlags, String message) {
2411         enforceForUri(
2412                 modeFlags, checkCallingUriPermission(uri, modeFlags),
2413                 false,
2414                 Binder.getCallingUid(), uri, message);
2415     }
2416 
2417     @Override
enforceCallingOrSelfUriPermission( Uri uri, int modeFlags, String message)2418     public void enforceCallingOrSelfUriPermission(
2419             Uri uri, int modeFlags, String message) {
2420         enforceForUri(
2421                 modeFlags,
2422                 checkCallingOrSelfUriPermission(uri, modeFlags), true,
2423                 Binder.getCallingUid(), uri, message);
2424     }
2425 
2426     @Override
enforceUriPermission( Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags, String message)2427     public void enforceUriPermission(
2428             Uri uri, String readPermission, String writePermission,
2429             int pid, int uid, int modeFlags, String message) {
2430         enforceForUri(modeFlags,
2431                       checkUriPermission(
2432                               uri, readPermission, writePermission, pid, uid,
2433                               modeFlags),
2434                       false,
2435                       uid,
2436                       uri,
2437                       message);
2438     }
2439 
2440     /**
2441      * Logs a warning if the system process directly called a method such as
2442      * {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
2443      * The "AsUser" variants allow us to properly enforce the user's restrictions.
2444      */
warnIfCallingFromSystemProcess()2445     private void warnIfCallingFromSystemProcess() {
2446         if (Process.myUid() == Process.SYSTEM_UID) {
2447             Slog.w(TAG, "Calling a method in the system process without a qualified user: "
2448                     + Debug.getCallers(5));
2449         }
2450     }
2451 
createResources(IBinder activityToken, LoadedApk pi, String splitName, @Nullable Integer overrideDisplayId, Configuration overrideConfig, CompatibilityInfo compatInfo, List<ResourcesLoader> resourcesLoader)2452     private static Resources createResources(IBinder activityToken, LoadedApk pi, String splitName,
2453             @Nullable Integer overrideDisplayId, Configuration overrideConfig,
2454             CompatibilityInfo compatInfo, List<ResourcesLoader> resourcesLoader) {
2455         final String[] splitResDirs;
2456         final ClassLoader classLoader;
2457         try {
2458             splitResDirs = pi.getSplitPaths(splitName);
2459             classLoader = pi.getSplitClassLoader(splitName);
2460         } catch (NameNotFoundException e) {
2461             throw new RuntimeException(e);
2462         }
2463         return ResourcesManager.getInstance().getResources(activityToken,
2464                 pi.getResDir(),
2465                 splitResDirs,
2466                 pi.getOverlayDirs(),
2467                 pi.getOverlayPaths(),
2468                 pi.getApplicationInfo().sharedLibraryFiles,
2469                 overrideDisplayId,
2470                 overrideConfig,
2471                 compatInfo,
2472                 classLoader,
2473                 resourcesLoader);
2474     }
2475 
2476     @Override
createApplicationContext(ApplicationInfo application, int flags)2477     public Context createApplicationContext(ApplicationInfo application, int flags)
2478             throws NameNotFoundException {
2479         LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
2480                 flags | CONTEXT_REGISTER_PACKAGE);
2481         if (pi != null) {
2482             ContextImpl c = new ContextImpl(this, mMainThread, pi, ContextParams.EMPTY,
2483                     mAttributionSource.getAttributionTag(),
2484                     mAttributionSource.getNext(),
2485                     null, mToken, new UserHandle(UserHandle.getUserId(application.uid)),
2486                     flags, null, null);
2487 
2488             final int displayId = getDisplayId();
2489             final Integer overrideDisplayId = mForceDisplayOverrideInResources
2490                     ? displayId : null;
2491 
2492             c.setResources(createResources(mToken, pi, null, overrideDisplayId, null,
2493                     getDisplayAdjustments(displayId).getCompatibilityInfo(), null));
2494             if (c.mResources != null) {
2495                 return c;
2496             }
2497         }
2498 
2499         throw new PackageManager.NameNotFoundException(
2500                 "Application package " + application.packageName + " not found");
2501     }
2502 
2503     @Override
createPackageContext(String packageName, int flags)2504     public Context createPackageContext(String packageName, int flags)
2505             throws NameNotFoundException {
2506         return createPackageContextAsUser(packageName, flags, mUser);
2507     }
2508 
2509     @Override
createPackageContextAsUser(String packageName, int flags, UserHandle user)2510     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
2511             throws NameNotFoundException {
2512         if (packageName.equals("system") || packageName.equals("android")) {
2513             // The system resources are loaded in every application, so we can safely copy
2514             // the context without reloading Resources.
2515             return new ContextImpl(this, mMainThread, mPackageInfo, mParams,
2516                     mAttributionSource.getAttributionTag(),
2517                     mAttributionSource.getNext(),
2518                     null, mToken, user, flags, null, null);
2519         }
2520 
2521         LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
2522                 flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
2523         if (pi != null) {
2524             ContextImpl c = new ContextImpl(this, mMainThread, pi, mParams,
2525                     mAttributionSource.getAttributionTag(),
2526                     mAttributionSource.getNext(),
2527                     null, mToken, user, flags, null, null);
2528 
2529             final int displayId = getDisplayId();
2530             final Integer overrideDisplayId = mForceDisplayOverrideInResources
2531                     ? displayId : null;
2532 
2533             c.setResources(createResources(mToken, pi, null, overrideDisplayId, null,
2534                     getDisplayAdjustments(displayId).getCompatibilityInfo(), null));
2535             if (c.mResources != null) {
2536                 return c;
2537             }
2538         }
2539 
2540         // Should be a better exception.
2541         throw new PackageManager.NameNotFoundException(
2542                 "Application package " + packageName + " not found");
2543     }
2544 
2545     @Override
createContextAsUser(UserHandle user, @CreatePackageOptions int flags)2546     public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
2547         try {
2548             return createPackageContextAsUser(getPackageName(), flags, user);
2549         } catch (NameNotFoundException e) {
2550             throw new IllegalStateException("Own package not found: package=" + getPackageName());
2551         }
2552     }
2553 
2554     @Override
createContextForSplit(String splitName)2555     public Context createContextForSplit(String splitName) throws NameNotFoundException {
2556         if (!mPackageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) {
2557             // All Splits are always loaded.
2558             return this;
2559         }
2560 
2561         final ClassLoader classLoader = mPackageInfo.getSplitClassLoader(splitName);
2562         final String[] paths = mPackageInfo.getSplitPaths(splitName);
2563 
2564         final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
2565                 mAttributionSource.getAttributionTag(),
2566                 mAttributionSource.getNext(),
2567                 splitName, mToken, mUser, mFlags, classLoader, null);
2568 
2569         context.setResources(ResourcesManager.getInstance().getResources(
2570                 mToken,
2571                 mPackageInfo.getResDir(),
2572                 paths,
2573                 mPackageInfo.getOverlayDirs(),
2574                 mPackageInfo.getOverlayPaths(),
2575                 mPackageInfo.getApplicationInfo().sharedLibraryFiles,
2576                 mForceDisplayOverrideInResources ? getDisplayId() : null,
2577                 null,
2578                 mPackageInfo.getCompatibilityInfo(),
2579                 classLoader,
2580                 mResources.getLoaders()));
2581         return context;
2582     }
2583 
2584     @Override
createConfigurationContext(Configuration overrideConfiguration)2585     public Context createConfigurationContext(Configuration overrideConfiguration) {
2586         if (overrideConfiguration == null) {
2587             throw new IllegalArgumentException("overrideConfiguration must not be null");
2588         }
2589 
2590         if (mForceDisplayOverrideInResources) {
2591             // Ensure the resources display metrics are adjusted to match the display this context
2592             // is based on.
2593             Configuration displayAdjustedConfig = new Configuration();
2594             displayAdjustedConfig.setTo(mDisplay.getDisplayAdjustments().getConfiguration(),
2595                     ActivityInfo.CONFIG_WINDOW_CONFIGURATION, 1);
2596             displayAdjustedConfig.updateFrom(overrideConfiguration);
2597             overrideConfiguration = displayAdjustedConfig;
2598         }
2599 
2600         ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
2601                 mAttributionSource.getAttributionTag(),
2602                 mAttributionSource.getNext(),
2603                 mSplitName, mToken, mUser, mFlags, mClassLoader, null);
2604         context.mIsConfigurationBasedContext = true;
2605 
2606         final int displayId = getDisplayId();
2607         final Integer overrideDisplayId = mForceDisplayOverrideInResources
2608                 ? displayId : null;
2609         context.setResources(createResources(mToken, mPackageInfo, mSplitName, overrideDisplayId,
2610                 overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(),
2611                 mResources.getLoaders()));
2612         return context;
2613     }
2614 
2615     @Override
createDisplayContext(Display display)2616     public Context createDisplayContext(Display display) {
2617         if (display == null) {
2618             throw new IllegalArgumentException("display must not be null");
2619         }
2620 
2621         ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
2622                 mAttributionSource.getAttributionTag(),
2623                 mAttributionSource.getNext(),
2624                 mSplitName, mToken, mUser, mFlags, mClassLoader, null);
2625 
2626         final int displayId = display.getDisplayId();
2627 
2628         // Ensure the resources display metrics are adjusted to match the provided display.
2629         Configuration overrideConfig = new Configuration();
2630         overrideConfig.setTo(display.getDisplayAdjustments().getConfiguration(),
2631                 ActivityInfo.CONFIG_WINDOW_CONFIGURATION, 1);
2632 
2633         context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId,
2634                 overrideConfig, display.getDisplayAdjustments().getCompatibilityInfo(),
2635                 mResources.getLoaders()));
2636         context.mDisplay = display;
2637         // Inherit context type if the container is from System or System UI context to bypass
2638         // UI context check.
2639         context.mContextType = mContextType == CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI
2640                 ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI : CONTEXT_TYPE_DISPLAY_CONTEXT;
2641         // Display contexts and any context derived from a display context should always override
2642         // the display that would otherwise be inherited from mToken (or the global configuration if
2643         // mToken is null).
2644         context.mForceDisplayOverrideInResources = true;
2645         // The configuration is overridden by display adjustments' configuration and won't receive
2646         // configuration changes. This context won't be regarded as having the proper configuration
2647         // anymore.
2648         context.mIsConfigurationBasedContext = false;
2649         return context;
2650     }
2651 
2652     @NonNull
2653     @Override
createWindowContext(@indowType int type, @Nullable Bundle options)2654     public WindowContext createWindowContext(@WindowType int type,
2655             @Nullable Bundle options) {
2656         if (getDisplay() == null) {
2657             throw new UnsupportedOperationException("Please call this API with context associated"
2658                     + " with a display instance, such as Activity or context created via"
2659                     + " Context#createDisplayContext(Display), or try to invoke"
2660                     + " Context#createWindowContext(Display, int, Bundle)");
2661         }
2662         return createWindowContextInternal(getDisplay(), type, options);
2663     }
2664 
2665     @NonNull
2666     @Override
createWindowContext(@onNull Display display, @WindowType int type, @Nullable Bundle options)2667     public WindowContext createWindowContext(@NonNull Display display, @WindowType int type,
2668             @Nullable Bundle options) {
2669         if (display == null) {
2670             throw new IllegalArgumentException("Display must not be null");
2671         }
2672         return createWindowContextInternal(display, type, options);
2673     }
2674 
2675     /**
2676      * The internal implementation of {@link Context#createWindowContext(int, Bundle)} and
2677      * {@link Context#createWindowContext(Display, int, Bundle)}.
2678      *
2679      * @param display The {@link Display} instance to be associated with.
2680      *
2681      * @see Context#createWindowContext(Display, int, Bundle)
2682      * @see Context#createWindowContext(int, Bundle)
2683      */
createWindowContextInternal(@onNull Display display, @WindowType int type, @Nullable Bundle options)2684     private WindowContext createWindowContextInternal(@NonNull Display display,
2685             @WindowType int type, @Nullable Bundle options) {
2686         // Step 1. Create a WindowTokenClient to associate with the WindowContext's Resources
2687         //         instance and it will be later used to receive configuration updates from the
2688         //         server side.
2689         final WindowTokenClient windowTokenClient = new WindowTokenClient();
2690 
2691         // Step 2. Create the base context of the window context, it will also create a Resources
2692         //         associated with the WindowTokenClient and set the token to the base context.
2693         final ContextImpl windowContextBase = createWindowContextBase(windowTokenClient,
2694                 display.getDisplayId());
2695 
2696         // Step 3. Create a WindowContext instance and set it as the outer context of the base
2697         //         context to make the service obtained by #getSystemService(String) able to query
2698         //         the WindowContext's WindowManager instead of the default one.
2699         final WindowContext windowContext = new WindowContext(windowContextBase, type, options);
2700         windowContextBase.setOuterContext(windowContext);
2701 
2702         // Step 4. Attach the WindowContext to the WindowTokenClient. In this way, when there's a
2703         //         configuration update from the server side, the update will then apply to
2704         //         WindowContext's resources.
2705         windowTokenClient.attachContext(windowContext);
2706 
2707         // Step 5. Associate the WindowContext's token to a DisplayArea.
2708         windowContext.attachToDisplayArea();
2709 
2710         return windowContext;
2711     }
2712 
2713     @NonNull
2714     @Override
createTokenContext(@onNull IBinder token, @NonNull Display display)2715     public Context createTokenContext(@NonNull IBinder token, @NonNull Display display) {
2716         if (display == null) {
2717             throw new IllegalArgumentException("Display must not be null");
2718         }
2719         return createWindowContextBase(token, display.getDisplayId());
2720     }
2721 
2722     /**
2723      * Creates the base {@link Context} for UI context to associate with a non-{@link Activity}
2724      * window.
2725      *
2726      * @param token The token to associate with {@link Resources}
2727      * @param displayId The ID of {@link Display} to associate with.
2728      *
2729      * @see #createWindowContext(Display, int, Bundle)
2730      * @see #createTokenContext(IBinder, Display)
2731      */
2732     @UiContext
createWindowContextBase(@onNull IBinder token, int displayId)2733     ContextImpl createWindowContextBase(@NonNull IBinder token, int displayId) {
2734         ContextImpl baseContext = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
2735                 mAttributionSource.getAttributionTag(),
2736                 mAttributionSource.getNext(),
2737                 mSplitName, token, mUser, mFlags, mClassLoader, null);
2738         // Window contexts receive configurations directly from the server and as such do not
2739         // need to override their display in ResourcesManager.
2740         baseContext.mForceDisplayOverrideInResources = false;
2741         baseContext.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT;
2742 
2743         final Resources windowContextResources = createWindowContextResources(baseContext);
2744         baseContext.setResources(windowContextResources);
2745         // Associate the display with window context resources so that configuration update from
2746         // the server side will also apply to the display's metrics.
2747         baseContext.mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(displayId,
2748                 windowContextResources);
2749 
2750         return baseContext;
2751     }
2752 
2753     /**
2754      * Creates the {@link Resources} to associate with the {@link WindowContext}'s token.
2755      *
2756      * When there's a {@link Configuration} update, this Resources instance will be updated to match
2757      * the new configuration.
2758      *
2759      * @see WindowTokenClient
2760      * @see #getWindowContextToken()
2761      */
createWindowContextResources(@onNull ContextImpl windowContextBase)2762     private static Resources createWindowContextResources(@NonNull ContextImpl windowContextBase) {
2763         final LoadedApk packageInfo = windowContextBase.mPackageInfo;
2764         final ClassLoader classLoader = windowContextBase.getClassLoader();
2765         final IBinder token = windowContextBase.getWindowContextToken();
2766 
2767         final String resDir = packageInfo.getResDir();
2768         final String[] splitResDirs = packageInfo.getSplitResDirs();
2769         final String[] legacyOverlayDirs = packageInfo.getOverlayDirs();
2770         final String[] overlayPaths = packageInfo.getOverlayPaths();
2771         final String[] libDirs = packageInfo.getApplicationInfo().sharedLibraryFiles;
2772         final int displayId = windowContextBase.getDisplayId();
2773         final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
2774                 ? packageInfo.getCompatibilityInfo()
2775                 : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
2776         final List<ResourcesLoader> loaders = windowContextBase.mResources.getLoaders();
2777 
2778         return windowContextBase.mResourcesManager.createBaseTokenResources(token, resDir,
2779                 splitResDirs, legacyOverlayDirs, overlayPaths, libDirs, displayId,
2780                 null /* overrideConfig */, compatInfo, classLoader, loaders);
2781     }
2782 
2783     @NonNull
2784     @Override
createContext(@onNull ContextParams contextParams)2785     public Context createContext(@NonNull ContextParams contextParams) {
2786         return new ContextImpl(this, mMainThread, mPackageInfo, contextParams,
2787                 contextParams.getAttributionTag(), contextParams.getNextAttributionSource(),
2788                 mSplitName, mToken, mUser, mFlags, mClassLoader, null);
2789     }
2790 
2791     @Override
createAttributionContext(@ullable String attributionTag)2792     public @NonNull Context createAttributionContext(@Nullable String attributionTag) {
2793         return createContext(
2794                 new ContextParams.Builder(mParams).setAttributionTag(attributionTag).build());
2795     }
2796 
2797     @Override
createDeviceProtectedStorageContext()2798     public Context createDeviceProtectedStorageContext() {
2799         final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE)
2800                 | Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
2801         return new ContextImpl(this, mMainThread, mPackageInfo, mParams,
2802                 mAttributionSource.getAttributionTag(),
2803                 mAttributionSource.getNext(),
2804                 mSplitName, mToken, mUser, flags, mClassLoader, null);
2805     }
2806 
2807     @Override
createCredentialProtectedStorageContext()2808     public Context createCredentialProtectedStorageContext() {
2809         final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE)
2810                 | Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
2811         return new ContextImpl(this, mMainThread, mPackageInfo, mParams,
2812                 mAttributionSource.getAttributionTag(),
2813                 mAttributionSource.getNext(),
2814                 mSplitName, mToken, mUser, flags, mClassLoader, null);
2815     }
2816 
2817     @Override
isRestricted()2818     public boolean isRestricted() {
2819         return (mFlags & Context.CONTEXT_RESTRICTED) != 0;
2820     }
2821 
2822     @Override
isDeviceProtectedStorage()2823     public boolean isDeviceProtectedStorage() {
2824         return (mFlags & Context.CONTEXT_DEVICE_PROTECTED_STORAGE) != 0;
2825     }
2826 
2827     @Override
isCredentialProtectedStorage()2828     public boolean isCredentialProtectedStorage() {
2829         return (mFlags & Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) != 0;
2830     }
2831 
2832     @Override
canLoadUnsafeResources()2833     public boolean canLoadUnsafeResources() {
2834         if (getPackageName().equals(getOpPackageName())) {
2835             return true;
2836         }
2837         return (mFlags & Context.CONTEXT_IGNORE_SECURITY) != 0;
2838     }
2839 
2840     @Override
getDisplay()2841     public Display getDisplay() {
2842         if (!isAssociatedWithDisplay()) {
2843             throw new UnsupportedOperationException("Tried to obtain display from a Context not "
2844                     + "associated with one. Only visual Contexts (such as Activity or one created "
2845                     + "with Context#createWindowContext) or ones created with "
2846                     + "Context#createDisplayContext are associated with displays. Other types of "
2847                     + "Contexts are typically related to background entities and may return an "
2848                     + "arbitrary display.");
2849         }
2850         return getDisplayNoVerify();
2851     }
2852 
isAssociatedWithDisplay()2853     private boolean isAssociatedWithDisplay() {
2854         switch (mContextType) {
2855             case CONTEXT_TYPE_DISPLAY_CONTEXT:
2856             case CONTEXT_TYPE_ACTIVITY:
2857             case CONTEXT_TYPE_WINDOW_CONTEXT:
2858             // TODO(b/170369943): Remove after WindowContext migration
2859             case CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI:
2860                 return true;
2861             default:
2862                 return false;
2863         }
2864     }
2865 
2866     @Override
getDisplayNoVerify()2867     public Display getDisplayNoVerify() {
2868         if (mDisplay == null) {
2869             return mResourcesManager.getAdjustedDisplay(Display.DEFAULT_DISPLAY,
2870                     mResources);
2871         }
2872 
2873         return mDisplay;
2874     }
2875 
2876     @Override
getDisplayId()2877     public int getDisplayId() {
2878         final Display display = getDisplayNoVerify();
2879         return display != null ? display.getDisplayId() : Display.DEFAULT_DISPLAY;
2880     }
2881 
2882     @Override
updateDisplay(int displayId)2883     public void updateDisplay(int displayId) {
2884         mDisplay = mResourcesManager.getAdjustedDisplay(displayId, mResources);
2885         if (mContextType == CONTEXT_TYPE_NON_UI) {
2886             mContextType = CONTEXT_TYPE_DISPLAY_CONTEXT;
2887         }
2888     }
2889 
2890     @Override
getDisplayAdjustments(int displayId)2891     public DisplayAdjustments getDisplayAdjustments(int displayId) {
2892         return mResources.getDisplayAdjustments();
2893     }
2894 
2895     @Override
getDataDir()2896     public File getDataDir() {
2897         if (mPackageInfo != null) {
2898             File res = null;
2899             if (isCredentialProtectedStorage()) {
2900                 res = mPackageInfo.getCredentialProtectedDataDirFile();
2901             } else if (isDeviceProtectedStorage()) {
2902                 res = mPackageInfo.getDeviceProtectedDataDirFile();
2903             } else {
2904                 res = mPackageInfo.getDataDirFile();
2905             }
2906 
2907             if (res != null) {
2908                 if (!res.exists() && android.os.Process.myUid() == android.os.Process.SYSTEM_UID) {
2909                     Log.wtf(TAG, "Data directory doesn't exist for package " + getPackageName(),
2910                             new Throwable());
2911                 }
2912                 return res;
2913             } else {
2914                 throw new RuntimeException(
2915                         "No data directory found for package " + getPackageName());
2916             }
2917         } else {
2918             throw new RuntimeException(
2919                     "No package details found for package " + getPackageName());
2920         }
2921     }
2922 
2923     @Override
getDir(String name, int mode)2924     public File getDir(String name, int mode) {
2925         checkMode(mode);
2926         name = "app_" + name;
2927         File file = makeFilename(getDataDir(), name);
2928         if (!file.exists()) {
2929             file.mkdir();
2930             setFilePermissionsFromMode(file.getPath(), mode,
2931                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
2932         }
2933         return file;
2934     }
2935 
2936     /** {@hide} */
2937     @Override
getUser()2938     public UserHandle getUser() {
2939         return mUser;
2940     }
2941 
2942     /** {@hide} */
2943     @Override
getUserId()2944     public int getUserId() {
2945         return mUser.getIdentifier();
2946     }
2947 
2948     /** @hide */
2949     @Override
getAutofillClient()2950     public AutofillClient getAutofillClient() {
2951         return mAutofillClient;
2952     }
2953 
2954     /** @hide */
2955     @Override
setAutofillClient(AutofillClient client)2956     public void setAutofillClient(AutofillClient client) {
2957         mAutofillClient = client;
2958     }
2959 
2960     /** @hide */
2961     @Override
getAutofillOptions()2962     public AutofillOptions getAutofillOptions() {
2963         return mAutofillOptions;
2964     }
2965 
2966     /** @hide */
2967     @Override
setAutofillOptions(AutofillOptions options)2968     public void setAutofillOptions(AutofillOptions options) {
2969         mAutofillOptions = options;
2970     }
2971 
2972     /** @hide */
2973     @Override
getContentCaptureOptions()2974     public ContentCaptureOptions getContentCaptureOptions() {
2975         return mContentCaptureOptions;
2976     }
2977 
2978     /** @hide */
2979     @Override
setContentCaptureOptions(ContentCaptureOptions options)2980     public void setContentCaptureOptions(ContentCaptureOptions options) {
2981         mContentCaptureOptions = options;
2982     }
2983 
2984     @Override
finalize()2985     protected void finalize() throws Throwable {
2986         // If mToken is a WindowTokenClient, the Context is usually associated with a
2987         // WindowContainer. We should detach from WindowContainer when the Context is finalized
2988         // if this Context is not a WindowContext. WindowContext finalization is handled in
2989         // WindowContext class.
2990         if (mToken instanceof WindowTokenClient && mOwnsToken) {
2991             ((WindowTokenClient) mToken).detachFromWindowContainerIfNeeded();
2992         }
2993         super.finalize();
2994     }
2995 
2996     @UnsupportedAppUsage
createSystemContext(ActivityThread mainThread)2997     static ContextImpl createSystemContext(ActivityThread mainThread) {
2998         LoadedApk packageInfo = new LoadedApk(mainThread);
2999         ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
3000                 ContextParams.EMPTY, null, null, null, null, null, 0, null, null);
3001         context.setResources(packageInfo.getResources());
3002         context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
3003                 context.mResourcesManager.getDisplayMetrics());
3004         context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
3005         return context;
3006     }
3007 
3008     /**
3009      * System Context to be used for UI. This Context has resources that can be themed.
3010      * Make sure that the created system UI context shares the same LoadedApk as the system context.
3011      * @param systemContext The system context which created by
3012      *                      {@link #createSystemContext(ActivityThread)}.
3013      * @param displayId The ID of the display where the UI is shown.
3014      */
createSystemUiContext(ContextImpl systemContext, int displayId)3015     static ContextImpl createSystemUiContext(ContextImpl systemContext, int displayId) {
3016         final WindowTokenClient token = new WindowTokenClient();
3017         final ContextImpl context = systemContext.createWindowContextBase(token, displayId);
3018         token.attachContext(context);
3019         token.attachToDisplayContent(displayId);
3020         context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
3021         context.mOwnsToken = true;
3022 
3023         return context;
3024     }
3025 
3026     @UnsupportedAppUsage
createAppContext(ActivityThread mainThread, LoadedApk packageInfo)3027     static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
3028         return createAppContext(mainThread, packageInfo, null);
3029     }
3030 
createAppContext(ActivityThread mainThread, LoadedApk packageInfo, String opPackageName)3031     static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
3032             String opPackageName) {
3033         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
3034         ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
3035             ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName);
3036         context.setResources(packageInfo.getResources());
3037         context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI
3038                 : CONTEXT_TYPE_NON_UI;
3039         return context;
3040     }
3041 
3042     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration)3043     static ContextImpl createActivityContext(ActivityThread mainThread,
3044             LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
3045             Configuration overrideConfiguration) {
3046         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
3047 
3048         String[] splitDirs = packageInfo.getSplitResDirs();
3049         ClassLoader classLoader = packageInfo.getClassLoader();
3050 
3051         if (packageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) {
3052             Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "SplitDependencies");
3053             try {
3054                 classLoader = packageInfo.getSplitClassLoader(activityInfo.splitName);
3055                 splitDirs = packageInfo.getSplitPaths(activityInfo.splitName);
3056             } catch (NameNotFoundException e) {
3057                 // Nothing above us can handle a NameNotFoundException, better crash.
3058                 throw new RuntimeException(e);
3059             } finally {
3060                 Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
3061             }
3062         }
3063 
3064         final String attributionTag;
3065         if (activityInfo.attributionTags != null && activityInfo.attributionTags.length > 0) {
3066             attributionTag = activityInfo.attributionTags[0];
3067         } else {
3068             attributionTag = null;
3069         }
3070 
3071         ContextImpl context = new ContextImpl(null, mainThread, packageInfo, ContextParams.EMPTY,
3072                 attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader,
3073                 null);
3074         context.mContextType = CONTEXT_TYPE_ACTIVITY;
3075         context.mIsConfigurationBasedContext = true;
3076 
3077         // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
3078         displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
3079 
3080         final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
3081                 ? packageInfo.getCompatibilityInfo()
3082                 : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
3083 
3084         final ResourcesManager resourcesManager = ResourcesManager.getInstance();
3085 
3086         // Create the base resources for which all configuration contexts for this Activity
3087         // will be rebased upon.
3088         context.setResources(resourcesManager.createBaseTokenResources(activityToken,
3089                 packageInfo.getResDir(),
3090                 splitDirs,
3091                 packageInfo.getOverlayDirs(),
3092                 packageInfo.getOverlayPaths(),
3093                 packageInfo.getApplicationInfo().sharedLibraryFiles,
3094                 displayId,
3095                 overrideConfiguration,
3096                 compatInfo,
3097                 classLoader,
3098                 packageInfo.getApplication() == null ? null
3099                         : packageInfo.getApplication().getResources().getLoaders()));
3100         context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
3101                 context.getResources());
3102         return context;
3103     }
3104 
ContextImpl(@ullable ContextImpl container, @NonNull ActivityThread mainThread, @NonNull LoadedApk packageInfo, @NonNull ContextParams params, @Nullable String attributionTag, @Nullable AttributionSource nextAttributionSource, @Nullable String splitName, @Nullable IBinder token, @Nullable UserHandle user, int flags, @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName)3105     private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
3106             @NonNull LoadedApk packageInfo, @NonNull ContextParams params,
3107             @Nullable String attributionTag, @Nullable AttributionSource nextAttributionSource,
3108             @Nullable String splitName, @Nullable IBinder token, @Nullable UserHandle user,
3109             int flags, @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) {
3110         mOuterContext = this;
3111 
3112         // If creator didn't specify which storage to use, use the default
3113         // location for application.
3114         if ((flags & (Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE
3115                 | Context.CONTEXT_DEVICE_PROTECTED_STORAGE)) == 0) {
3116             final File dataDir = packageInfo.getDataDirFile();
3117             if (Objects.equals(dataDir, packageInfo.getCredentialProtectedDataDirFile())) {
3118                 flags |= Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
3119             } else if (Objects.equals(dataDir, packageInfo.getDeviceProtectedDataDirFile())) {
3120                 flags |= Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
3121             }
3122         }
3123 
3124         mMainThread = mainThread;
3125         mToken = token;
3126         mFlags = flags;
3127 
3128         if (user == null) {
3129             user = Process.myUserHandle();
3130         }
3131         mUser = user;
3132 
3133         mPackageInfo = packageInfo;
3134         mSplitName = splitName;
3135         mClassLoader = classLoader;
3136         mResourcesManager = ResourcesManager.getInstance();
3137 
3138         String opPackageName;
3139 
3140         if (container != null) {
3141             mBasePackageName = container.mBasePackageName;
3142             opPackageName = container.mOpPackageName;
3143             setResources(container.mResources);
3144             mDisplay = container.mDisplay;
3145             mForceDisplayOverrideInResources = container.mForceDisplayOverrideInResources;
3146             mIsConfigurationBasedContext = container.mIsConfigurationBasedContext;
3147             mContextType = container.mContextType;
3148             mContentCaptureOptions = container.mContentCaptureOptions;
3149         } else {
3150             mBasePackageName = packageInfo.mPackageName;
3151             ApplicationInfo ainfo = packageInfo.getApplicationInfo();
3152             if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
3153                 // Special case: system components allow themselves to be loaded in to other
3154                 // processes.  For purposes of app ops, we must then consider the context as
3155                 // belonging to the package of this process, not the system itself, otherwise
3156                 // the package+uid verifications in app ops will fail.
3157                 opPackageName = ActivityThread.currentPackageName();
3158             } else {
3159                 opPackageName = mBasePackageName;
3160             }
3161         }
3162 
3163         mOpPackageName = overrideOpPackageName != null ? overrideOpPackageName : opPackageName;
3164         mParams = Objects.requireNonNull(params);
3165         mAttributionSource = createAttributionSource(attributionTag, nextAttributionSource,
3166                 params.getRenouncedPermissions());
3167         mContentResolver = new ApplicationContentResolver(this, mainThread);
3168     }
3169 
createAttributionSource(@ullable String attributionTag, @Nullable AttributionSource nextAttributionSource, @Nullable Set<String> renouncedPermissions)3170     private @NonNull AttributionSource createAttributionSource(@Nullable String attributionTag,
3171             @Nullable AttributionSource nextAttributionSource,
3172             @Nullable Set<String> renouncedPermissions) {
3173         AttributionSource attributionSource = new AttributionSource(Process.myUid(),
3174                 mOpPackageName, attributionTag, renouncedPermissions, nextAttributionSource);
3175         // If we want to access protected data on behalf of another app we need to
3176         // tell the OS that we opt in to participate in the attribution chain.
3177         if (nextAttributionSource != null) {
3178             attributionSource = getSystemService(PermissionManager.class)
3179                     .registerAttributionSource(attributionSource);
3180         }
3181         return attributionSource;
3182     }
3183 
setResources(Resources r)3184     void setResources(Resources r) {
3185         if (r instanceof CompatResources) {
3186             ((CompatResources) r).setContext(this);
3187         }
3188         mResources = r;
3189     }
3190 
installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader)3191     void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
3192         mPackageInfo.installSystemApplicationInfo(info, classLoader);
3193     }
3194 
3195     @UnsupportedAppUsage
scheduleFinalCleanup(String who, String what)3196     final void scheduleFinalCleanup(String who, String what) {
3197         mMainThread.scheduleContextCleanup(this, who, what);
3198     }
3199 
performFinalCleanup(String who, String what)3200     final void performFinalCleanup(String who, String what) {
3201         //Log.i(TAG, "Cleanup up context: " + this);
3202         mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
3203         if (mContextType == CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI
3204                 && mToken instanceof WindowTokenClient) {
3205             mMainThread.onSystemUiContextCleanup(this);
3206         }
3207     }
3208 
3209     @UnsupportedAppUsage
getReceiverRestrictedContext()3210     final Context getReceiverRestrictedContext() {
3211         if (mReceiverRestrictedContext != null) {
3212             return mReceiverRestrictedContext;
3213         }
3214         return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
3215     }
3216 
3217     @UnsupportedAppUsage
setOuterContext(@onNull Context context)3218     final void setOuterContext(@NonNull Context context) {
3219         mOuterContext = context;
3220     }
3221 
3222     @UnsupportedAppUsage
getOuterContext()3223     final Context getOuterContext() {
3224         return mOuterContext;
3225     }
3226 
3227     @Override
3228     @UnsupportedAppUsage
getActivityToken()3229     public IBinder getActivityToken() {
3230         return mContextType == CONTEXT_TYPE_ACTIVITY ? mToken : null;
3231     }
3232 
3233     @Override
getWindowContextToken()3234     public IBinder getWindowContextToken() {
3235         switch (mContextType) {
3236             case CONTEXT_TYPE_WINDOW_CONTEXT:
3237             case CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI:
3238                 return mToken;
3239             default:
3240                 return null;
3241         }
3242     }
3243 
checkMode(int mode)3244     private void checkMode(int mode) {
3245         if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.N) {
3246             if ((mode & MODE_WORLD_READABLE) != 0) {
3247                 throw new SecurityException("MODE_WORLD_READABLE no longer supported");
3248             }
3249             if ((mode & MODE_WORLD_WRITEABLE) != 0) {
3250                 throw new SecurityException("MODE_WORLD_WRITEABLE no longer supported");
3251             }
3252         }
3253     }
3254 
3255     @SuppressWarnings("deprecation")
setFilePermissionsFromMode(String name, int mode, int extraPermissions)3256     static void setFilePermissionsFromMode(String name, int mode,
3257             int extraPermissions) {
3258         int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
3259             |FileUtils.S_IRGRP|FileUtils.S_IWGRP
3260             |extraPermissions;
3261         if ((mode&MODE_WORLD_READABLE) != 0) {
3262             perms |= FileUtils.S_IROTH;
3263         }
3264         if ((mode&MODE_WORLD_WRITEABLE) != 0) {
3265             perms |= FileUtils.S_IWOTH;
3266         }
3267         if (DEBUG) {
3268             Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
3269                   + ", perms=0x" + Integer.toHexString(perms));
3270         }
3271         FileUtils.setPermissions(name, perms, -1, -1);
3272     }
3273 
makeFilename(File base, String name)3274     private File makeFilename(File base, String name) {
3275         if (name.indexOf(File.separatorChar) < 0) {
3276             final File res = new File(base, name);
3277             // We report as filesystem access here to give us the best shot at
3278             // detecting apps that will pass the path down to native code.
3279             BlockGuard.getVmPolicy().onPathAccess(res.getPath());
3280             return res;
3281         }
3282         throw new IllegalArgumentException(
3283                 "File " + name + " contains a path separator");
3284     }
3285 
3286     /**
3287      * Ensure that given directories exist, trying to create them if missing. If
3288      * unable to create, they are filtered by replacing with {@code null}.
3289      */
ensureExternalDirsExistOrFilter(File[] dirs, boolean tryCreateInProcess)3290     private File[] ensureExternalDirsExistOrFilter(File[] dirs, boolean tryCreateInProcess) {
3291         final StorageManager sm = getSystemService(StorageManager.class);
3292         final File[] result = new File[dirs.length];
3293         for (int i = 0; i < dirs.length; i++) {
3294             File dir = dirs[i];
3295             if (!dir.exists()) {
3296                 try {
3297                     if (!tryCreateInProcess || !dir.mkdirs()) {
3298                         // recheck existence in case of cross-process race
3299                         if (!dir.exists()) {
3300                             // Failing to mkdir() may be okay, since we might not have
3301                             // enough permissions; ask vold to create on our behalf.
3302                             sm.mkdirs(dir);
3303                         }
3304                     }
3305                 } catch (Exception e) {
3306                     Log.w(TAG, "Failed to ensure " + dir + ": " + e);
3307                     dir = null;
3308                 }
3309             }
3310             if (dir != null && !dir.canWrite()) {
3311                 // Older versions of the MediaProvider mainline module had a rare early boot race
3312                 // condition where app-private dirs could be created with the wrong permissions;
3313                 // fix this up here. This check should be very fast, because dir.exists() above
3314                 // will already have loaded the dentry in the cache.
3315                 sm.fixupAppDir(dir);
3316             }
3317             result[i] = dir;
3318         }
3319         return result;
3320     }
3321 
3322     @Override
destroy()3323     public void destroy() {
3324         // The final clean-up is to release BroadcastReceiver registrations. It is called in
3325         // ActivityThread for Activity and Service. For the context, such as WindowContext,
3326         // without lifecycle concept, it should be called once the context is released.
3327         scheduleFinalCleanup(getClass().getName(), getOuterContext().getClass().getSimpleName());
3328     }
3329 
3330     // ----------------------------------------------------------------------
3331     // ----------------------------------------------------------------------
3332     // ----------------------------------------------------------------------
3333 
3334     private static final class ApplicationContentResolver extends ContentResolver {
3335         @UnsupportedAppUsage
3336         private final ActivityThread mMainThread;
3337 
ApplicationContentResolver(Context context, ActivityThread mainThread)3338         public ApplicationContentResolver(Context context, ActivityThread mainThread) {
3339             super(context);
3340             mMainThread = Objects.requireNonNull(mainThread);
3341         }
3342 
3343         @Override
3344         @UnsupportedAppUsage
acquireProvider(Context context, String auth)3345         protected IContentProvider acquireProvider(Context context, String auth) {
3346             return mMainThread.acquireProvider(context,
3347                     ContentProvider.getAuthorityWithoutUserId(auth),
3348                     resolveUserIdFromAuthority(auth), true);
3349         }
3350 
3351         @Override
acquireExistingProvider(Context context, String auth)3352         protected IContentProvider acquireExistingProvider(Context context, String auth) {
3353             return mMainThread.acquireExistingProvider(context,
3354                     ContentProvider.getAuthorityWithoutUserId(auth),
3355                     resolveUserIdFromAuthority(auth), true);
3356         }
3357 
3358         @Override
releaseProvider(IContentProvider provider)3359         public boolean releaseProvider(IContentProvider provider) {
3360             return mMainThread.releaseProvider(provider, true);
3361         }
3362 
3363         @Override
acquireUnstableProvider(Context c, String auth)3364         protected IContentProvider acquireUnstableProvider(Context c, String auth) {
3365             return mMainThread.acquireProvider(c,
3366                     ContentProvider.getAuthorityWithoutUserId(auth),
3367                     resolveUserIdFromAuthority(auth), false);
3368         }
3369 
3370         @Override
releaseUnstableProvider(IContentProvider icp)3371         public boolean releaseUnstableProvider(IContentProvider icp) {
3372             return mMainThread.releaseProvider(icp, false);
3373         }
3374 
3375         @Override
unstableProviderDied(IContentProvider icp)3376         public void unstableProviderDied(IContentProvider icp) {
3377             mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
3378         }
3379 
3380         @Override
appNotRespondingViaProvider(IContentProvider icp)3381         public void appNotRespondingViaProvider(IContentProvider icp) {
3382             mMainThread.appNotRespondingViaProvider(icp.asBinder());
3383         }
3384 
3385         /** @hide */
resolveUserIdFromAuthority(String auth)3386         protected int resolveUserIdFromAuthority(String auth) {
3387             return ContentProvider.getUserIdFromAuthority(auth, getUserId());
3388         }
3389     }
3390 }
3391