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