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