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