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