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             // We may override this API from outer context.
1905             final boolean isUiContext = isUiContext() || isOuterUiContext();
1906             // Check incorrect Context usage.
1907             if (isUiComponent(name) && !isUiContext) {
1908                 final String errorMessage = "Tried to access visual service "
1909                         + SystemServiceRegistry.getSystemServiceClassName(name)
1910                         + " from a non-visual Context:" + getOuterContext();
1911                 final String message = "Visual services, such as WindowManager, WallpaperService "
1912                         + "or LayoutInflater should be accessed from Activity or other visual "
1913                         + "Context. Use an Activity or a Context created with "
1914                         + "Context#createWindowContext(int, Bundle), which are adjusted to "
1915                         + "the configuration and visual bounds of an area on screen.";
1916                 final Exception exception = new IllegalAccessException(errorMessage);
1917                 StrictMode.onIncorrectContextUsed(message, exception);
1918                 Log.e(TAG, errorMessage + " " + message, exception);
1919             }
1920         }
1921         return SystemServiceRegistry.getSystemService(this, name);
1922     }
1923 
isOuterUiContext()1924     private boolean isOuterUiContext() {
1925         return getOuterContext() != null && getOuterContext().isUiContext();
1926     }
1927 
1928     @Override
getSystemServiceName(Class<?> serviceClass)1929     public String getSystemServiceName(Class<?> serviceClass) {
1930         return SystemServiceRegistry.getSystemServiceName(serviceClass);
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         context.mIsUiContext = isUiContext() || isOuterUiContext();
2380         return context;
2381     }
2382 
2383     @Override
createDisplayContext(Display display)2384     public Context createDisplayContext(Display display) {
2385         if (display == null) {
2386             throw new IllegalArgumentException("display must not be null");
2387         }
2388 
2389         ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag,
2390                 mSplitName, mToken, mUser, mFlags, mClassLoader, null);
2391 
2392         final int displayId = display.getDisplayId();
2393 
2394         context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId,
2395                 null, getDisplayAdjustments(displayId).getCompatibilityInfo(),
2396                 mResources.getLoaders()));
2397         context.mDisplay = display;
2398         context.mIsAssociatedWithDisplay = true;
2399         return context;
2400     }
2401 
2402     @Override
createWindowContext(int type, Bundle options)2403     public @NonNull WindowContext createWindowContext(int type, Bundle options) {
2404         if (getDisplay() == null) {
2405             throw new UnsupportedOperationException("WindowContext can only be created from "
2406                     + "other visual contexts, such as Activity or one created with "
2407                     + "Context#createDisplayContext(Display)");
2408         }
2409         return new WindowContext(this, type, options);
2410     }
2411 
createBaseWindowContext(IBinder token)2412     ContextImpl createBaseWindowContext(IBinder token) {
2413         ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag,
2414                 mSplitName, token, mUser, mFlags, mClassLoader, null);
2415         context.mIsUiContext = true;
2416 
2417         context.mIsAssociatedWithDisplay = true;
2418         return context;
2419     }
2420 
createWindowContextResources()2421     Resources createWindowContextResources() {
2422         final String resDir = mPackageInfo.getResDir();
2423         final String[] splitResDirs = mPackageInfo.getSplitResDirs();
2424         final String[] overlayDirs = mPackageInfo.getOverlayDirs();
2425         final String[] libDirs = mPackageInfo.getApplicationInfo().sharedLibraryFiles;
2426         final int displayId = getDisplayId();
2427         final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
2428                 ? mPackageInfo.getCompatibilityInfo()
2429                 : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
2430         final List<ResourcesLoader> loaders = mResources.getLoaders();
2431 
2432         return mResourcesManager.createBaseTokenResources(mToken, resDir, splitResDirs,
2433                 overlayDirs, libDirs, displayId, null /* overrideConfig */,
2434                 compatInfo, mClassLoader, loaders);
2435     }
2436 
2437     @Override
createAttributionContext(@ullable String attributionTag)2438     public @NonNull Context createAttributionContext(@Nullable String attributionTag) {
2439         return new ContextImpl(this, mMainThread, mPackageInfo, attributionTag, mSplitName,
2440                 mToken, mUser, mFlags, mClassLoader, null);
2441     }
2442 
2443     @Override
createDeviceProtectedStorageContext()2444     public Context createDeviceProtectedStorageContext() {
2445         final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE)
2446                 | Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
2447         return new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag, mSplitName,
2448                 mToken, mUser, flags, mClassLoader, null);
2449     }
2450 
2451     @Override
createCredentialProtectedStorageContext()2452     public Context createCredentialProtectedStorageContext() {
2453         final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE)
2454                 | Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
2455         return new ContextImpl(this, mMainThread, mPackageInfo, mAttributionTag, mSplitName,
2456                 mToken, mUser, flags, mClassLoader, null);
2457     }
2458 
2459     @Override
isRestricted()2460     public boolean isRestricted() {
2461         return (mFlags & Context.CONTEXT_RESTRICTED) != 0;
2462     }
2463 
2464     @Override
isDeviceProtectedStorage()2465     public boolean isDeviceProtectedStorage() {
2466         return (mFlags & Context.CONTEXT_DEVICE_PROTECTED_STORAGE) != 0;
2467     }
2468 
2469     @Override
isCredentialProtectedStorage()2470     public boolean isCredentialProtectedStorage() {
2471         return (mFlags & Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) != 0;
2472     }
2473 
2474     @Override
canLoadUnsafeResources()2475     public boolean canLoadUnsafeResources() {
2476         if (getPackageName().equals(getOpPackageName())) {
2477             return true;
2478         }
2479         return (mFlags & Context.CONTEXT_IGNORE_SECURITY) != 0;
2480     }
2481 
2482     @Override
getDisplay()2483     public Display getDisplay() {
2484         if (!mIsSystemOrSystemUiContext && !mIsAssociatedWithDisplay) {
2485             throw new UnsupportedOperationException("Tried to obtain display from a Context not "
2486                     + "associated with  one. Only visual Contexts (such as Activity or one created "
2487                     + "with Context#createWindowContext) or ones created with "
2488                     + "Context#createDisplayContext are associated with displays. Other types of "
2489                     + "Contexts are typically related to background entities and may return an "
2490                     + "arbitrary display.");
2491         }
2492         return getDisplayNoVerify();
2493     }
2494 
2495     @Override
getDisplayNoVerify()2496     public Display getDisplayNoVerify() {
2497         if (mDisplay == null) {
2498             return mResourcesManager.getAdjustedDisplay(Display.DEFAULT_DISPLAY,
2499                     mResources);
2500         }
2501 
2502         return mDisplay;
2503     }
2504 
2505     @Override
getDisplayId()2506     public int getDisplayId() {
2507         final Display display = getDisplayNoVerify();
2508         return display != null ? display.getDisplayId() : Display.DEFAULT_DISPLAY;
2509     }
2510 
2511     @Override
updateDisplay(int displayId)2512     public void updateDisplay(int displayId) {
2513         mDisplay = mResourcesManager.getAdjustedDisplay(displayId, mResources);
2514         mIsAssociatedWithDisplay = true;
2515     }
2516 
2517     @Override
getDisplayAdjustments(int displayId)2518     public DisplayAdjustments getDisplayAdjustments(int displayId) {
2519         return mResources.getDisplayAdjustments();
2520     }
2521 
2522     @Override
getDataDir()2523     public File getDataDir() {
2524         if (mPackageInfo != null) {
2525             File res = null;
2526             if (isCredentialProtectedStorage()) {
2527                 res = mPackageInfo.getCredentialProtectedDataDirFile();
2528             } else if (isDeviceProtectedStorage()) {
2529                 res = mPackageInfo.getDeviceProtectedDataDirFile();
2530             } else {
2531                 res = mPackageInfo.getDataDirFile();
2532             }
2533 
2534             if (res != null) {
2535                 if (!res.exists() && android.os.Process.myUid() == android.os.Process.SYSTEM_UID) {
2536                     Log.wtf(TAG, "Data directory doesn't exist for package " + getPackageName(),
2537                             new Throwable());
2538                 }
2539                 return res;
2540             } else {
2541                 throw new RuntimeException(
2542                         "No data directory found for package " + getPackageName());
2543             }
2544         } else {
2545             throw new RuntimeException(
2546                     "No package details found for package " + getPackageName());
2547         }
2548     }
2549 
2550     @Override
getDir(String name, int mode)2551     public File getDir(String name, int mode) {
2552         checkMode(mode);
2553         name = "app_" + name;
2554         File file = makeFilename(getDataDir(), name);
2555         if (!file.exists()) {
2556             file.mkdir();
2557             setFilePermissionsFromMode(file.getPath(), mode,
2558                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
2559         }
2560         return file;
2561     }
2562 
2563     /** {@hide} */
2564     @Override
getUser()2565     public UserHandle getUser() {
2566         return mUser;
2567     }
2568 
2569     /** {@hide} */
2570     @Override
getUserId()2571     public int getUserId() {
2572         return mUser.getIdentifier();
2573     }
2574 
2575     /** @hide */
2576     @Override
getAutofillClient()2577     public AutofillClient getAutofillClient() {
2578         return mAutofillClient;
2579     }
2580 
2581     /** @hide */
2582     @Override
setAutofillClient(AutofillClient client)2583     public void setAutofillClient(AutofillClient client) {
2584         mAutofillClient = client;
2585     }
2586 
2587     /** @hide */
2588     @Override
getAutofillOptions()2589     public AutofillOptions getAutofillOptions() {
2590         return mAutofillOptions;
2591     }
2592 
2593     /** @hide */
2594     @Override
setAutofillOptions(AutofillOptions options)2595     public void setAutofillOptions(AutofillOptions options) {
2596         mAutofillOptions = options;
2597     }
2598 
2599     /** @hide */
2600     @Override
getContentCaptureOptions()2601     public ContentCaptureOptions getContentCaptureOptions() {
2602         return mContentCaptureOptions;
2603     }
2604 
2605     /** @hide */
2606     @Override
setContentCaptureOptions(ContentCaptureOptions options)2607     public void setContentCaptureOptions(ContentCaptureOptions options) {
2608         mContentCaptureOptions = options;
2609     }
2610 
2611     @UnsupportedAppUsage
createSystemContext(ActivityThread mainThread)2612     static ContextImpl createSystemContext(ActivityThread mainThread) {
2613         LoadedApk packageInfo = new LoadedApk(mainThread);
2614         ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, null,
2615                 0, null, null);
2616         context.setResources(packageInfo.getResources());
2617         context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
2618                 context.mResourcesManager.getDisplayMetrics());
2619         context.mIsSystemOrSystemUiContext = true;
2620         return context;
2621     }
2622 
2623     /**
2624      * System Context to be used for UI. This Context has resources that can be themed.
2625      * Make sure that the created system UI context shares the same LoadedApk as the system context.
2626      * @param systemContext The system context which created by
2627      *                      {@link #createSystemContext(ActivityThread)}.
2628      * @param displayId The ID of the display where the UI is shown.
2629      */
createSystemUiContext(ContextImpl systemContext, int displayId)2630     static ContextImpl createSystemUiContext(ContextImpl systemContext, int displayId) {
2631         final LoadedApk packageInfo = systemContext.mPackageInfo;
2632         ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo, null,
2633                 null, null, null, 0, null, null);
2634         context.setResources(createResources(null, packageInfo, null, displayId, null,
2635                 packageInfo.getCompatibilityInfo(), null));
2636         context.updateDisplay(displayId);
2637         context.mIsSystemOrSystemUiContext = true;
2638         return context;
2639     }
2640 
2641     /**
2642      * The overloaded method of {@link #createSystemUiContext(ContextImpl, int)}.
2643      * Uses {@Code Display.DEFAULT_DISPLAY} as the target display.
2644      */
createSystemUiContext(ContextImpl systemContext)2645     static ContextImpl createSystemUiContext(ContextImpl systemContext) {
2646         return createSystemUiContext(systemContext, Display.DEFAULT_DISPLAY);
2647     }
2648 
2649     @UnsupportedAppUsage
createAppContext(ActivityThread mainThread, LoadedApk packageInfo)2650     static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
2651         return createAppContext(mainThread, packageInfo, null);
2652     }
2653 
createAppContext(ActivityThread mainThread, LoadedApk packageInfo, String opPackageName)2654     static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
2655             String opPackageName) {
2656         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
2657         ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, null,
2658                 0, null, opPackageName);
2659         context.setResources(packageInfo.getResources());
2660         context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context);
2661         return context;
2662     }
2663 
2664     @UnsupportedAppUsage
createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration)2665     static ContextImpl createActivityContext(ActivityThread mainThread,
2666             LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
2667             Configuration overrideConfiguration) {
2668         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
2669 
2670         String[] splitDirs = packageInfo.getSplitResDirs();
2671         ClassLoader classLoader = packageInfo.getClassLoader();
2672 
2673         if (packageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) {
2674             Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "SplitDependencies");
2675             try {
2676                 classLoader = packageInfo.getSplitClassLoader(activityInfo.splitName);
2677                 splitDirs = packageInfo.getSplitPaths(activityInfo.splitName);
2678             } catch (NameNotFoundException e) {
2679                 // Nothing above us can handle a NameNotFoundException, better crash.
2680                 throw new RuntimeException(e);
2681             } finally {
2682                 Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
2683             }
2684         }
2685 
2686         ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null,
2687                 activityInfo.splitName, activityToken, null, 0, classLoader, null);
2688         context.mIsUiContext = true;
2689         context.mIsAssociatedWithDisplay = true;
2690         context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context);
2691 
2692         // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
2693         displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
2694 
2695         final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
2696                 ? packageInfo.getCompatibilityInfo()
2697                 : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
2698 
2699         final ResourcesManager resourcesManager = ResourcesManager.getInstance();
2700 
2701         // Create the base resources for which all configuration contexts for this Activity
2702         // will be rebased upon.
2703         context.setResources(resourcesManager.createBaseTokenResources(activityToken,
2704                 packageInfo.getResDir(),
2705                 splitDirs,
2706                 packageInfo.getOverlayDirs(),
2707                 packageInfo.getApplicationInfo().sharedLibraryFiles,
2708                 displayId,
2709                 overrideConfiguration,
2710                 compatInfo,
2711                 classLoader,
2712                 packageInfo.getApplication() == null ? null
2713                         : packageInfo.getApplication().getResources().getLoaders()));
2714         context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
2715                 context.getResources());
2716         return context;
2717     }
2718 
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)2719     private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
2720             @NonNull LoadedApk packageInfo, @Nullable String attributionTag,
2721             @Nullable String splitName, @Nullable IBinder activityToken, @Nullable UserHandle user,
2722             int flags, @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) {
2723         mOuterContext = this;
2724 
2725         // If creator didn't specify which storage to use, use the default
2726         // location for application.
2727         if ((flags & (Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE
2728                 | Context.CONTEXT_DEVICE_PROTECTED_STORAGE)) == 0) {
2729             final File dataDir = packageInfo.getDataDirFile();
2730             if (Objects.equals(dataDir, packageInfo.getCredentialProtectedDataDirFile())) {
2731                 flags |= Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
2732             } else if (Objects.equals(dataDir, packageInfo.getDeviceProtectedDataDirFile())) {
2733                 flags |= Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
2734             }
2735         }
2736 
2737         mMainThread = mainThread;
2738         mToken = activityToken;
2739         mFlags = flags;
2740 
2741         if (user == null) {
2742             user = Process.myUserHandle();
2743         }
2744         mUser = user;
2745 
2746         mPackageInfo = packageInfo;
2747         mSplitName = splitName;
2748         mClassLoader = classLoader;
2749         mResourcesManager = ResourcesManager.getInstance();
2750 
2751         String opPackageName;
2752 
2753         if (container != null) {
2754             mBasePackageName = container.mBasePackageName;
2755             opPackageName = container.mOpPackageName;
2756             setResources(container.mResources);
2757             mDisplay = container.mDisplay;
2758             mIsAssociatedWithDisplay = container.mIsAssociatedWithDisplay;
2759             mIsSystemOrSystemUiContext = container.mIsSystemOrSystemUiContext;
2760         } else {
2761             mBasePackageName = packageInfo.mPackageName;
2762             ApplicationInfo ainfo = packageInfo.getApplicationInfo();
2763             if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
2764                 // Special case: system components allow themselves to be loaded in to other
2765                 // processes.  For purposes of app ops, we must then consider the context as
2766                 // belonging to the package of this process, not the system itself, otherwise
2767                 // the package+uid verifications in app ops will fail.
2768                 opPackageName = ActivityThread.currentPackageName();
2769             } else {
2770                 opPackageName = mBasePackageName;
2771             }
2772         }
2773 
2774         mOpPackageName = overrideOpPackageName != null ? overrideOpPackageName : opPackageName;
2775         mAttributionTag = attributionTag;
2776         mContentResolver = new ApplicationContentResolver(this, mainThread);
2777     }
2778 
setResources(Resources r)2779     void setResources(Resources r) {
2780         if (r instanceof CompatResources) {
2781             ((CompatResources) r).setContext(this);
2782         }
2783         mResources = r;
2784     }
2785 
installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader)2786     void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
2787         mPackageInfo.installSystemApplicationInfo(info, classLoader);
2788     }
2789 
2790     @UnsupportedAppUsage
scheduleFinalCleanup(String who, String what)2791     final void scheduleFinalCleanup(String who, String what) {
2792         mMainThread.scheduleContextCleanup(this, who, what);
2793     }
2794 
performFinalCleanup(String who, String what)2795     final void performFinalCleanup(String who, String what) {
2796         //Log.i(TAG, "Cleanup up context: " + this);
2797         mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
2798     }
2799 
2800     @UnsupportedAppUsage
getReceiverRestrictedContext()2801     final Context getReceiverRestrictedContext() {
2802         if (mReceiverRestrictedContext != null) {
2803             return mReceiverRestrictedContext;
2804         }
2805         return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
2806     }
2807 
2808     @UnsupportedAppUsage
setOuterContext(Context context)2809     final void setOuterContext(Context context) {
2810         mOuterContext = context;
2811     }
2812 
2813     @UnsupportedAppUsage
getOuterContext()2814     final Context getOuterContext() {
2815         return mOuterContext;
2816     }
2817 
2818     @Override
2819     @UnsupportedAppUsage
getActivityToken()2820     public IBinder getActivityToken() {
2821         return mToken;
2822     }
2823 
checkMode(int mode)2824     private void checkMode(int mode) {
2825         if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.N) {
2826             if ((mode & MODE_WORLD_READABLE) != 0) {
2827                 throw new SecurityException("MODE_WORLD_READABLE no longer supported");
2828             }
2829             if ((mode & MODE_WORLD_WRITEABLE) != 0) {
2830                 throw new SecurityException("MODE_WORLD_WRITEABLE no longer supported");
2831             }
2832         }
2833     }
2834 
2835     @SuppressWarnings("deprecation")
setFilePermissionsFromMode(String name, int mode, int extraPermissions)2836     static void setFilePermissionsFromMode(String name, int mode,
2837             int extraPermissions) {
2838         int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
2839             |FileUtils.S_IRGRP|FileUtils.S_IWGRP
2840             |extraPermissions;
2841         if ((mode&MODE_WORLD_READABLE) != 0) {
2842             perms |= FileUtils.S_IROTH;
2843         }
2844         if ((mode&MODE_WORLD_WRITEABLE) != 0) {
2845             perms |= FileUtils.S_IWOTH;
2846         }
2847         if (DEBUG) {
2848             Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
2849                   + ", perms=0x" + Integer.toHexString(perms));
2850         }
2851         FileUtils.setPermissions(name, perms, -1, -1);
2852     }
2853 
makeFilename(File base, String name)2854     private File makeFilename(File base, String name) {
2855         if (name.indexOf(File.separatorChar) < 0) {
2856             final File res = new File(base, name);
2857             // We report as filesystem access here to give us the best shot at
2858             // detecting apps that will pass the path down to native code.
2859             BlockGuard.getVmPolicy().onPathAccess(res.getPath());
2860             return res;
2861         }
2862         throw new IllegalArgumentException(
2863                 "File " + name + " contains a path separator");
2864     }
2865 
2866     /**
2867      * Ensure that given directories exist, trying to create them if missing. If
2868      * unable to create, they are filtered by replacing with {@code null}.
2869      */
ensureExternalDirsExistOrFilter(File[] dirs, boolean tryCreateInProcess)2870     private File[] ensureExternalDirsExistOrFilter(File[] dirs, boolean tryCreateInProcess) {
2871         final StorageManager sm = getSystemService(StorageManager.class);
2872         final File[] result = new File[dirs.length];
2873         for (int i = 0; i < dirs.length; i++) {
2874             File dir = dirs[i];
2875             if (!dir.exists()) {
2876                 try {
2877                     if (!tryCreateInProcess || !dir.mkdirs()) {
2878                         // recheck existence in case of cross-process race
2879                         if (!dir.exists()) {
2880                             // Failing to mkdir() may be okay, since we might not have
2881                             // enough permissions; ask vold to create on our behalf.
2882                             sm.mkdirs(dir);
2883                         }
2884                     }
2885                 } catch (Exception e) {
2886                     Log.w(TAG, "Failed to ensure " + dir + ": " + e);
2887                     dir = null;
2888                 }
2889             }
2890             result[i] = dir;
2891         }
2892         return result;
2893     }
2894 
2895     // ----------------------------------------------------------------------
2896     // ----------------------------------------------------------------------
2897     // ----------------------------------------------------------------------
2898 
2899     private static final class ApplicationContentResolver extends ContentResolver {
2900         @UnsupportedAppUsage
2901         private final ActivityThread mMainThread;
2902 
ApplicationContentResolver(Context context, ActivityThread mainThread)2903         public ApplicationContentResolver(Context context, ActivityThread mainThread) {
2904             super(context);
2905             mMainThread = Objects.requireNonNull(mainThread);
2906         }
2907 
2908         @Override
2909         @UnsupportedAppUsage
acquireProvider(Context context, String auth)2910         protected IContentProvider acquireProvider(Context context, String auth) {
2911             return mMainThread.acquireProvider(context,
2912                     ContentProvider.getAuthorityWithoutUserId(auth),
2913                     resolveUserIdFromAuthority(auth), true);
2914         }
2915 
2916         @Override
acquireExistingProvider(Context context, String auth)2917         protected IContentProvider acquireExistingProvider(Context context, String auth) {
2918             return mMainThread.acquireExistingProvider(context,
2919                     ContentProvider.getAuthorityWithoutUserId(auth),
2920                     resolveUserIdFromAuthority(auth), true);
2921         }
2922 
2923         @Override
releaseProvider(IContentProvider provider)2924         public boolean releaseProvider(IContentProvider provider) {
2925             return mMainThread.releaseProvider(provider, true);
2926         }
2927 
2928         @Override
acquireUnstableProvider(Context c, String auth)2929         protected IContentProvider acquireUnstableProvider(Context c, String auth) {
2930             return mMainThread.acquireProvider(c,
2931                     ContentProvider.getAuthorityWithoutUserId(auth),
2932                     resolveUserIdFromAuthority(auth), false);
2933         }
2934 
2935         @Override
releaseUnstableProvider(IContentProvider icp)2936         public boolean releaseUnstableProvider(IContentProvider icp) {
2937             return mMainThread.releaseProvider(icp, false);
2938         }
2939 
2940         @Override
unstableProviderDied(IContentProvider icp)2941         public void unstableProviderDied(IContentProvider icp) {
2942             mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
2943         }
2944 
2945         @Override
appNotRespondingViaProvider(IContentProvider icp)2946         public void appNotRespondingViaProvider(IContentProvider icp) {
2947             mMainThread.appNotRespondingViaProvider(icp.asBinder());
2948         }
2949 
2950         /** @hide */
resolveUserIdFromAuthority(String auth)2951         protected int resolveUserIdFromAuthority(String auth) {
2952             return ContentProvider.getUserIdFromAuthority(auth, getUserId());
2953         }
2954     }
2955 }
2956