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