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