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