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 com.android.internal.annotations.GuardedBy;
     20 import com.android.internal.util.Preconditions;
     21 
     22 import android.content.BroadcastReceiver;
     23 import android.content.ComponentName;
     24 import android.content.ContentProvider;
     25 import android.content.ContentResolver;
     26 import android.content.Context;
     27 import android.content.ContextWrapper;
     28 import android.content.IContentProvider;
     29 import android.content.IIntentReceiver;
     30 import android.content.Intent;
     31 import android.content.IntentFilter;
     32 import android.content.IntentSender;
     33 import android.content.ReceiverCallNotAllowedException;
     34 import android.content.ServiceConnection;
     35 import android.content.SharedPreferences;
     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.CompatibilityInfo;
     42 import android.content.res.Configuration;
     43 import android.content.res.Resources;
     44 import android.database.DatabaseErrorHandler;
     45 import android.database.sqlite.SQLiteDatabase;
     46 import android.database.sqlite.SQLiteDatabase.CursorFactory;
     47 import android.graphics.Bitmap;
     48 import android.graphics.drawable.Drawable;
     49 import android.net.Uri;
     50 import android.os.Binder;
     51 import android.os.Build;
     52 import android.os.Bundle;
     53 import android.os.Debug;
     54 import android.os.Environment;
     55 import android.os.FileUtils;
     56 import android.os.Handler;
     57 import android.os.IBinder;
     58 import android.os.Looper;
     59 import android.os.Process;
     60 import android.os.RemoteException;
     61 import android.os.ServiceManager;
     62 import android.os.UserHandle;
     63 import android.os.storage.IMountService;
     64 import android.util.AndroidRuntimeException;
     65 import android.util.ArrayMap;
     66 import android.util.Log;
     67 import android.util.Slog;
     68 import android.view.Display;
     69 import android.view.DisplayAdjustments;
     70 
     71 import java.io.File;
     72 import java.io.FileInputStream;
     73 import java.io.FileNotFoundException;
     74 import java.io.FileOutputStream;
     75 import java.io.IOException;
     76 import java.io.InputStream;
     77 
     78 class ReceiverRestrictedContext extends ContextWrapper {
     79     ReceiverRestrictedContext(Context base) {
     80         super(base);
     81     }
     82 
     83     @Override
     84     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
     85         return registerReceiver(receiver, filter, null, null);
     86     }
     87 
     88     @Override
     89     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
     90             String broadcastPermission, Handler scheduler) {
     91         if (receiver == null) {
     92             // Allow retrieving current sticky broadcast; this is safe since we
     93             // aren't actually registering a receiver.
     94             return super.registerReceiver(null, filter, broadcastPermission, scheduler);
     95         } else {
     96             throw new ReceiverCallNotAllowedException(
     97                     "BroadcastReceiver components are not allowed to register to receive intents");
     98         }
     99     }
    100 
    101     @Override
    102     public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
    103             IntentFilter filter, String broadcastPermission, Handler scheduler) {
    104         if (receiver == null) {
    105             // Allow retrieving current sticky broadcast; this is safe since we
    106             // aren't actually registering a receiver.
    107             return super.registerReceiverAsUser(null, user, filter, broadcastPermission, scheduler);
    108         } else {
    109             throw new ReceiverCallNotAllowedException(
    110                     "BroadcastReceiver components are not allowed to register to receive intents");
    111         }
    112     }
    113 
    114     @Override
    115     public boolean bindService(Intent service, ServiceConnection conn, int flags) {
    116         throw new ReceiverCallNotAllowedException(
    117                 "BroadcastReceiver components are not allowed to bind to services");
    118     }
    119 }
    120 
    121 /**
    122  * Common implementation of Context API, which provides the base
    123  * context object for Activity and other application components.
    124  */
    125 class ContextImpl extends Context {
    126     private final static String TAG = "ContextImpl";
    127     private final static boolean DEBUG = false;
    128 
    129     /**
    130      * Map from package name, to preference name, to cached preferences.
    131      */
    132     private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs;
    133 
    134     final ActivityThread mMainThread;
    135     final LoadedApk mPackageInfo;
    136 
    137     private final IBinder mActivityToken;
    138 
    139     private final UserHandle mUser;
    140 
    141     private final ApplicationContentResolver mContentResolver;
    142 
    143     private final String mBasePackageName;
    144     private final String mOpPackageName;
    145 
    146     private final ResourcesManager mResourcesManager;
    147     private final Resources mResources;
    148     private final Display mDisplay; // may be null if default display
    149     private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
    150 
    151     private final boolean mRestricted;
    152 
    153     private Context mOuterContext;
    154     private int mThemeResource = 0;
    155     private Resources.Theme mTheme = null;
    156     private PackageManager mPackageManager;
    157     private Context mReceiverRestrictedContext = null;
    158 
    159     private final Object mSync = new Object();
    160 
    161     @GuardedBy("mSync")
    162     private File mDatabasesDir;
    163     @GuardedBy("mSync")
    164     private File mPreferencesDir;
    165     @GuardedBy("mSync")
    166     private File mFilesDir;
    167     @GuardedBy("mSync")
    168     private File mNoBackupFilesDir;
    169     @GuardedBy("mSync")
    170     private File mCacheDir;
    171     @GuardedBy("mSync")
    172     private File mCodeCacheDir;
    173 
    174     @GuardedBy("mSync")
    175     private File[] mExternalObbDirs;
    176     @GuardedBy("mSync")
    177     private File[] mExternalFilesDirs;
    178     @GuardedBy("mSync")
    179     private File[] mExternalCacheDirs;
    180     @GuardedBy("mSync")
    181     private File[] mExternalMediaDirs;
    182 
    183     private static final String[] EMPTY_STRING_ARRAY = {};
    184 
    185     // The system service cache for the system services that are cached per-ContextImpl.
    186     final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();
    187 
    188     static ContextImpl getImpl(Context context) {
    189         Context nextContext;
    190         while ((context instanceof ContextWrapper) &&
    191                 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
    192             context = nextContext;
    193         }
    194         return (ContextImpl)context;
    195     }
    196 
    197     @Override
    198     public AssetManager getAssets() {
    199         return getResources().getAssets();
    200     }
    201 
    202     @Override
    203     public Resources getResources() {
    204         return mResources;
    205     }
    206 
    207     @Override
    208     public PackageManager getPackageManager() {
    209         if (mPackageManager != null) {
    210             return mPackageManager;
    211         }
    212 
    213         IPackageManager pm = ActivityThread.getPackageManager();
    214         if (pm != null) {
    215             // Doesn't matter if we make more than one instance.
    216             return (mPackageManager = new ApplicationPackageManager(this, pm));
    217         }
    218 
    219         return null;
    220     }
    221 
    222     @Override
    223     public ContentResolver getContentResolver() {
    224         return mContentResolver;
    225     }
    226 
    227     @Override
    228     public Looper getMainLooper() {
    229         return mMainThread.getLooper();
    230     }
    231 
    232     @Override
    233     public Context getApplicationContext() {
    234         return (mPackageInfo != null) ?
    235                 mPackageInfo.getApplication() : mMainThread.getApplication();
    236     }
    237 
    238     @Override
    239     public void setTheme(int resId) {
    240         if (mThemeResource != resId) {
    241             mThemeResource = resId;
    242             initializeTheme();
    243         }
    244     }
    245 
    246     @Override
    247     public int getThemeResId() {
    248         return mThemeResource;
    249     }
    250 
    251     @Override
    252     public Resources.Theme getTheme() {
    253         if (mTheme != null) {
    254             return mTheme;
    255         }
    256 
    257         mThemeResource = Resources.selectDefaultTheme(mThemeResource,
    258                 getOuterContext().getApplicationInfo().targetSdkVersion);
    259         initializeTheme();
    260 
    261         return mTheme;
    262     }
    263 
    264     private void initializeTheme() {
    265         if (mTheme == null) {
    266             mTheme = mResources.newTheme();
    267         }
    268         mTheme.applyStyle(mThemeResource, true);
    269     }
    270 
    271     @Override
    272     public ClassLoader getClassLoader() {
    273         return mPackageInfo != null ?
    274                 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
    275     }
    276 
    277     @Override
    278     public String getPackageName() {
    279         if (mPackageInfo != null) {
    280             return mPackageInfo.getPackageName();
    281         }
    282         // No mPackageInfo means this is a Context for the system itself,
    283         // and this here is its name.
    284         return "android";
    285     }
    286 
    287     /** @hide */
    288     @Override
    289     public String getBasePackageName() {
    290         return mBasePackageName != null ? mBasePackageName : getPackageName();
    291     }
    292 
    293     /** @hide */
    294     @Override
    295     public String getOpPackageName() {
    296         return mOpPackageName != null ? mOpPackageName : getBasePackageName();
    297     }
    298 
    299     @Override
    300     public ApplicationInfo getApplicationInfo() {
    301         if (mPackageInfo != null) {
    302             return mPackageInfo.getApplicationInfo();
    303         }
    304         throw new RuntimeException("Not supported in system context");
    305     }
    306 
    307     @Override
    308     public String getPackageResourcePath() {
    309         if (mPackageInfo != null) {
    310             return mPackageInfo.getResDir();
    311         }
    312         throw new RuntimeException("Not supported in system context");
    313     }
    314 
    315     @Override
    316     public String getPackageCodePath() {
    317         if (mPackageInfo != null) {
    318             return mPackageInfo.getAppDir();
    319         }
    320         throw new RuntimeException("Not supported in system context");
    321     }
    322 
    323     @Override
    324     public File getSharedPrefsFile(String name) {
    325         return makeFilename(getPreferencesDir(), name + ".xml");
    326     }
    327 
    328     @Override
    329     public SharedPreferences getSharedPreferences(String name, int mode) {
    330         SharedPreferencesImpl sp;
    331         synchronized (ContextImpl.class) {
    332             if (sSharedPrefs == null) {
    333                 sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>();
    334             }
    335 
    336             final String packageName = getPackageName();
    337             ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
    338             if (packagePrefs == null) {
    339                 packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
    340                 sSharedPrefs.put(packageName, packagePrefs);
    341             }
    342 
    343             // At least one application in the world actually passes in a null
    344             // name.  This happened to work because when we generated the file name
    345             // we would stringify it to "null.xml".  Nice.
    346             if (mPackageInfo.getApplicationInfo().targetSdkVersion <
    347                     Build.VERSION_CODES.KITKAT) {
    348                 if (name == null) {
    349                     name = "null";
    350                 }
    351             }
    352 
    353             sp = packagePrefs.get(name);
    354             if (sp == null) {
    355                 File prefsFile = getSharedPrefsFile(name);
    356                 sp = new SharedPreferencesImpl(prefsFile, mode);
    357                 packagePrefs.put(name, sp);
    358                 return sp;
    359             }
    360         }
    361         if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
    362             getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
    363             // If somebody else (some other process) changed the prefs
    364             // file behind our back, we reload it.  This has been the
    365             // historical (if undocumented) behavior.
    366             sp.startReloadIfChangedUnexpectedly();
    367         }
    368         return sp;
    369     }
    370 
    371     private File getPreferencesDir() {
    372         synchronized (mSync) {
    373             if (mPreferencesDir == null) {
    374                 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
    375             }
    376             return mPreferencesDir;
    377         }
    378     }
    379 
    380     @Override
    381     public FileInputStream openFileInput(String name)
    382         throws FileNotFoundException {
    383         File f = makeFilename(getFilesDir(), name);
    384         return new FileInputStream(f);
    385     }
    386 
    387     @Override
    388     public FileOutputStream openFileOutput(String name, int mode)
    389         throws FileNotFoundException {
    390         final boolean append = (mode&MODE_APPEND) != 0;
    391         File f = makeFilename(getFilesDir(), name);
    392         try {
    393             FileOutputStream fos = new FileOutputStream(f, append);
    394             setFilePermissionsFromMode(f.getPath(), mode, 0);
    395             return fos;
    396         } catch (FileNotFoundException e) {
    397         }
    398 
    399         File parent = f.getParentFile();
    400         parent.mkdir();
    401         FileUtils.setPermissions(
    402             parent.getPath(),
    403             FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
    404             -1, -1);
    405         FileOutputStream fos = new FileOutputStream(f, append);
    406         setFilePermissionsFromMode(f.getPath(), mode, 0);
    407         return fos;
    408     }
    409 
    410     @Override
    411     public boolean deleteFile(String name) {
    412         File f = makeFilename(getFilesDir(), name);
    413         return f.delete();
    414     }
    415 
    416     // Common-path handling of app data dir creation
    417     private static File createFilesDirLocked(File file) {
    418         if (!file.exists()) {
    419             if (!file.mkdirs()) {
    420                 if (file.exists()) {
    421                     // spurious failure; probably racing with another process for this app
    422                     return file;
    423                 }
    424                 Log.w(TAG, "Unable to create files subdir " + file.getPath());
    425                 return null;
    426             }
    427             FileUtils.setPermissions(
    428                     file.getPath(),
    429                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
    430                     -1, -1);
    431         }
    432         return file;
    433     }
    434 
    435     @Override
    436     public File getFilesDir() {
    437         synchronized (mSync) {
    438             if (mFilesDir == null) {
    439                 mFilesDir = new File(getDataDirFile(), "files");
    440             }
    441             return createFilesDirLocked(mFilesDir);
    442         }
    443     }
    444 
    445     @Override
    446     public File getNoBackupFilesDir() {
    447         synchronized (mSync) {
    448             if (mNoBackupFilesDir == null) {
    449                 mNoBackupFilesDir = new File(getDataDirFile(), "no_backup");
    450             }
    451             return createFilesDirLocked(mNoBackupFilesDir);
    452         }
    453     }
    454 
    455     @Override
    456     public File getExternalFilesDir(String type) {
    457         // Operates on primary external storage
    458         return getExternalFilesDirs(type)[0];
    459     }
    460 
    461     @Override
    462     public File[] getExternalFilesDirs(String type) {
    463         synchronized (mSync) {
    464             if (mExternalFilesDirs == null) {
    465                 mExternalFilesDirs = Environment.buildExternalStorageAppFilesDirs(getPackageName());
    466             }
    467 
    468             // Splice in requested type, if any
    469             File[] dirs = mExternalFilesDirs;
    470             if (type != null) {
    471                 dirs = Environment.buildPaths(dirs, type);
    472             }
    473 
    474             // Create dirs if needed
    475             return ensureDirsExistOrFilter(dirs);
    476         }
    477     }
    478 
    479     @Override
    480     public File getObbDir() {
    481         // Operates on primary external storage
    482         return getObbDirs()[0];
    483     }
    484 
    485     @Override
    486     public File[] getObbDirs() {
    487         synchronized (mSync) {
    488             if (mExternalObbDirs == null) {
    489                 mExternalObbDirs = Environment.buildExternalStorageAppObbDirs(getPackageName());
    490             }
    491 
    492             // Create dirs if needed
    493             return ensureDirsExistOrFilter(mExternalObbDirs);
    494         }
    495     }
    496 
    497     @Override
    498     public File getCacheDir() {
    499         synchronized (mSync) {
    500             if (mCacheDir == null) {
    501                 mCacheDir = new File(getDataDirFile(), "cache");
    502             }
    503             return createFilesDirLocked(mCacheDir);
    504         }
    505     }
    506 
    507     @Override
    508     public File getCodeCacheDir() {
    509         synchronized (mSync) {
    510             if (mCodeCacheDir == null) {
    511                 mCodeCacheDir = new File(getDataDirFile(), "code_cache");
    512             }
    513             return createFilesDirLocked(mCodeCacheDir);
    514         }
    515     }
    516 
    517     @Override
    518     public File getExternalCacheDir() {
    519         // Operates on primary external storage
    520         return getExternalCacheDirs()[0];
    521     }
    522 
    523     @Override
    524     public File[] getExternalCacheDirs() {
    525         synchronized (mSync) {
    526             if (mExternalCacheDirs == null) {
    527                 mExternalCacheDirs = Environment.buildExternalStorageAppCacheDirs(getPackageName());
    528             }
    529 
    530             // Create dirs if needed
    531             return ensureDirsExistOrFilter(mExternalCacheDirs);
    532         }
    533     }
    534 
    535     @Override
    536     public File[] getExternalMediaDirs() {
    537         synchronized (mSync) {
    538             if (mExternalMediaDirs == null) {
    539                 mExternalMediaDirs = Environment.buildExternalStorageAppMediaDirs(getPackageName());
    540             }
    541 
    542             // Create dirs if needed
    543             return ensureDirsExistOrFilter(mExternalMediaDirs);
    544         }
    545     }
    546 
    547     @Override
    548     public File getFileStreamPath(String name) {
    549         return makeFilename(getFilesDir(), name);
    550     }
    551 
    552     @Override
    553     public String[] fileList() {
    554         final String[] list = getFilesDir().list();
    555         return (list != null) ? list : EMPTY_STRING_ARRAY;
    556     }
    557 
    558     @Override
    559     public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
    560         return openOrCreateDatabase(name, mode, factory, null);
    561     }
    562 
    563     @Override
    564     public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
    565             DatabaseErrorHandler errorHandler) {
    566         File f = validateFilePath(name, true);
    567         int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
    568         if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
    569             flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
    570         }
    571         SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
    572         setFilePermissionsFromMode(f.getPath(), mode, 0);
    573         return db;
    574     }
    575 
    576     @Override
    577     public boolean deleteDatabase(String name) {
    578         try {
    579             File f = validateFilePath(name, false);
    580             return SQLiteDatabase.deleteDatabase(f);
    581         } catch (Exception e) {
    582         }
    583         return false;
    584     }
    585 
    586     @Override
    587     public File getDatabasePath(String name) {
    588         return validateFilePath(name, false);
    589     }
    590 
    591     @Override
    592     public String[] databaseList() {
    593         final String[] list = getDatabasesDir().list();
    594         return (list != null) ? list : EMPTY_STRING_ARRAY;
    595     }
    596 
    597 
    598     private File getDatabasesDir() {
    599         synchronized (mSync) {
    600             if (mDatabasesDir == null) {
    601                 mDatabasesDir = new File(getDataDirFile(), "databases");
    602             }
    603             if (mDatabasesDir.getPath().equals("databases")) {
    604                 mDatabasesDir = new File("/data/system");
    605             }
    606             return mDatabasesDir;
    607         }
    608     }
    609 
    610     @Override
    611     @Deprecated
    612     public Drawable getWallpaper() {
    613         return getWallpaperManager().getDrawable();
    614     }
    615 
    616     @Override
    617     @Deprecated
    618     public Drawable peekWallpaper() {
    619         return getWallpaperManager().peekDrawable();
    620     }
    621 
    622     @Override
    623     @Deprecated
    624     public int getWallpaperDesiredMinimumWidth() {
    625         return getWallpaperManager().getDesiredMinimumWidth();
    626     }
    627 
    628     @Override
    629     @Deprecated
    630     public int getWallpaperDesiredMinimumHeight() {
    631         return getWallpaperManager().getDesiredMinimumHeight();
    632     }
    633 
    634     @Override
    635     @Deprecated
    636     public void setWallpaper(Bitmap bitmap) throws IOException {
    637         getWallpaperManager().setBitmap(bitmap);
    638     }
    639 
    640     @Override
    641     @Deprecated
    642     public void setWallpaper(InputStream data) throws IOException {
    643         getWallpaperManager().setStream(data);
    644     }
    645 
    646     @Override
    647     @Deprecated
    648     public void clearWallpaper() throws IOException {
    649         getWallpaperManager().clear();
    650     }
    651 
    652     private WallpaperManager getWallpaperManager() {
    653         return getSystemService(WallpaperManager.class);
    654     }
    655 
    656     @Override
    657     public void startActivity(Intent intent) {
    658         warnIfCallingFromSystemProcess();
    659         startActivity(intent, null);
    660     }
    661 
    662     /** @hide */
    663     @Override
    664     public void startActivityAsUser(Intent intent, UserHandle user) {
    665         startActivityAsUser(intent, null, user);
    666     }
    667 
    668     @Override
    669     public void startActivity(Intent intent, Bundle options) {
    670         warnIfCallingFromSystemProcess();
    671         if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
    672             throw new AndroidRuntimeException(
    673                     "Calling startActivity() from outside of an Activity "
    674                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
    675                     + " Is this really what you want?");
    676         }
    677         mMainThread.getInstrumentation().execStartActivity(
    678                 getOuterContext(), mMainThread.getApplicationThread(), null,
    679                 (Activity) null, intent, -1, options);
    680     }
    681 
    682     /** @hide */
    683     @Override
    684     public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
    685         try {
    686             ActivityManagerNative.getDefault().startActivityAsUser(
    687                 mMainThread.getApplicationThread(), getBasePackageName(), intent,
    688                 intent.resolveTypeIfNeeded(getContentResolver()),
    689                 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options,
    690                 user.getIdentifier());
    691         } catch (RemoteException e) {
    692             throw new RuntimeException("Failure from system", e);
    693         }
    694     }
    695 
    696     @Override
    697     public void startActivities(Intent[] intents) {
    698         warnIfCallingFromSystemProcess();
    699         startActivities(intents, null);
    700     }
    701 
    702     /** @hide */
    703     @Override
    704     public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) {
    705         if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
    706             throw new AndroidRuntimeException(
    707                     "Calling startActivities() from outside of an Activity "
    708                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
    709                     + " Is this really what you want?");
    710         }
    711         mMainThread.getInstrumentation().execStartActivitiesAsUser(
    712                 getOuterContext(), mMainThread.getApplicationThread(), null,
    713                 (Activity) null, intents, options, userHandle.getIdentifier());
    714     }
    715 
    716     @Override
    717     public void startActivities(Intent[] intents, Bundle options) {
    718         warnIfCallingFromSystemProcess();
    719         if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
    720             throw new AndroidRuntimeException(
    721                     "Calling startActivities() from outside of an Activity "
    722                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
    723                     + " Is this really what you want?");
    724         }
    725         mMainThread.getInstrumentation().execStartActivities(
    726                 getOuterContext(), mMainThread.getApplicationThread(), null,
    727                 (Activity) null, intents, options);
    728     }
    729 
    730     @Override
    731     public void startIntentSender(IntentSender intent,
    732             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
    733             throws IntentSender.SendIntentException {
    734         startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null);
    735     }
    736 
    737     @Override
    738     public void startIntentSender(IntentSender intent, Intent fillInIntent,
    739             int flagsMask, int flagsValues, int extraFlags, Bundle options)
    740             throws IntentSender.SendIntentException {
    741         try {
    742             String resolvedType = null;
    743             if (fillInIntent != null) {
    744                 fillInIntent.migrateExtraStreamToClipData();
    745                 fillInIntent.prepareToLeaveProcess();
    746                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
    747             }
    748             int result = ActivityManagerNative.getDefault()
    749                 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
    750                         fillInIntent, resolvedType, null, null,
    751                         0, flagsMask, flagsValues, options);
    752             if (result == ActivityManager.START_CANCELED) {
    753                 throw new IntentSender.SendIntentException();
    754             }
    755             Instrumentation.checkStartActivityResult(result, null);
    756         } catch (RemoteException e) {
    757             throw new RuntimeException("Failure from system", e);
    758         }
    759     }
    760 
    761     @Override
    762     public void sendBroadcast(Intent intent) {
    763         warnIfCallingFromSystemProcess();
    764         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    765         try {
    766             intent.prepareToLeaveProcess();
    767             ActivityManagerNative.getDefault().broadcastIntent(
    768                     mMainThread.getApplicationThread(), intent, resolvedType, null,
    769                     Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
    770                     getUserId());
    771         } catch (RemoteException e) {
    772             throw new RuntimeException("Failure from system", e);
    773         }
    774     }
    775 
    776     @Override
    777     public void sendBroadcast(Intent intent, String receiverPermission) {
    778         warnIfCallingFromSystemProcess();
    779         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    780         String[] receiverPermissions = receiverPermission == null ? null
    781                 : new String[] {receiverPermission};
    782         try {
    783             intent.prepareToLeaveProcess();
    784             ActivityManagerNative.getDefault().broadcastIntent(
    785                     mMainThread.getApplicationThread(), intent, resolvedType, null,
    786                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
    787                     null, false, false, getUserId());
    788         } catch (RemoteException e) {
    789             throw new RuntimeException("Failure from system", e);
    790         }
    791     }
    792 
    793     @Override
    794     public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
    795         warnIfCallingFromSystemProcess();
    796         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    797         try {
    798             intent.prepareToLeaveProcess();
    799             ActivityManagerNative.getDefault().broadcastIntent(
    800                     mMainThread.getApplicationThread(), intent, resolvedType, null,
    801                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
    802                     null, false, false, getUserId());
    803         } catch (RemoteException e) {
    804             throw new RuntimeException("Failure from system", e);
    805         }
    806     }
    807 
    808     @Override
    809     public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
    810         warnIfCallingFromSystemProcess();
    811         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    812         String[] receiverPermissions = receiverPermission == null ? null
    813                 : new String[] {receiverPermission};
    814         try {
    815             intent.prepareToLeaveProcess();
    816             ActivityManagerNative.getDefault().broadcastIntent(
    817                     mMainThread.getApplicationThread(), intent, resolvedType, null,
    818                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
    819                     options, false, false, getUserId());
    820         } catch (RemoteException e) {
    821             throw new RuntimeException("Failure from system", e);
    822         }
    823     }
    824 
    825     @Override
    826     public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
    827         warnIfCallingFromSystemProcess();
    828         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    829         String[] receiverPermissions = receiverPermission == null ? null
    830                 : new String[] {receiverPermission};
    831         try {
    832             intent.prepareToLeaveProcess();
    833             ActivityManagerNative.getDefault().broadcastIntent(
    834                     mMainThread.getApplicationThread(), intent, resolvedType, null,
    835                     Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
    836                     getUserId());
    837         } catch (RemoteException e) {
    838             throw new RuntimeException("Failure from system", e);
    839         }
    840     }
    841 
    842     @Override
    843     public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
    844         warnIfCallingFromSystemProcess();
    845         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    846         String[] receiverPermissions = receiverPermission == null ? null
    847                 : new String[] {receiverPermission};
    848         try {
    849             intent.prepareToLeaveProcess();
    850             ActivityManagerNative.getDefault().broadcastIntent(
    851                     mMainThread.getApplicationThread(), intent, resolvedType, null,
    852                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
    853                     null, true, false, getUserId());
    854         } catch (RemoteException e) {
    855             throw new RuntimeException("Failure from system", e);
    856         }
    857     }
    858 
    859     @Override
    860     public void sendOrderedBroadcast(Intent intent,
    861             String receiverPermission, BroadcastReceiver resultReceiver,
    862             Handler scheduler, int initialCode, String initialData,
    863             Bundle initialExtras) {
    864         sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
    865                 resultReceiver, scheduler, initialCode, initialData, initialExtras, null);
    866     }
    867 
    868     @Override
    869     public void sendOrderedBroadcast(Intent intent,
    870             String receiverPermission, Bundle options, BroadcastReceiver resultReceiver,
    871             Handler scheduler, int initialCode, String initialData,
    872             Bundle initialExtras) {
    873         sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
    874                 resultReceiver, scheduler, initialCode, initialData, initialExtras, options);
    875     }
    876 
    877     @Override
    878     public void sendOrderedBroadcast(Intent intent,
    879             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
    880             Handler scheduler, int initialCode, String initialData,
    881             Bundle initialExtras) {
    882         sendOrderedBroadcast(intent, receiverPermission, appOp,
    883                 resultReceiver, scheduler, initialCode, initialData, initialExtras, null);
    884     }
    885 
    886     void sendOrderedBroadcast(Intent intent,
    887             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
    888             Handler scheduler, int initialCode, String initialData,
    889             Bundle initialExtras, Bundle options) {
    890         warnIfCallingFromSystemProcess();
    891         IIntentReceiver rd = null;
    892         if (resultReceiver != null) {
    893             if (mPackageInfo != null) {
    894                 if (scheduler == null) {
    895                     scheduler = mMainThread.getHandler();
    896                 }
    897                 rd = mPackageInfo.getReceiverDispatcher(
    898                     resultReceiver, getOuterContext(), scheduler,
    899                     mMainThread.getInstrumentation(), false);
    900             } else {
    901                 if (scheduler == null) {
    902                     scheduler = mMainThread.getHandler();
    903                 }
    904                 rd = new LoadedApk.ReceiverDispatcher(
    905                         resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
    906             }
    907         }
    908         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    909         String[] receiverPermissions = receiverPermission == null ? null
    910                 : new String[] {receiverPermission};
    911         try {
    912             intent.prepareToLeaveProcess();
    913             ActivityManagerNative.getDefault().broadcastIntent(
    914                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
    915                 initialCode, initialData, initialExtras, receiverPermissions, appOp,
    916                     options, true, false, getUserId());
    917         } catch (RemoteException e) {
    918             throw new RuntimeException("Failure from system", e);
    919         }
    920     }
    921 
    922     @Override
    923     public void sendBroadcastAsUser(Intent intent, UserHandle user) {
    924         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    925         try {
    926             intent.prepareToLeaveProcess();
    927             ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
    928                     intent, resolvedType, null, Activity.RESULT_OK, null, null, null,
    929                     AppOpsManager.OP_NONE, null, false, false, user.getIdentifier());
    930         } catch (RemoteException e) {
    931             throw new RuntimeException("Failure from system", e);
    932         }
    933     }
    934 
    935     @Override
    936     public void sendBroadcastAsUser(Intent intent, UserHandle user,
    937             String receiverPermission) {
    938         sendBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE);
    939     }
    940 
    941     @Override
    942     public void sendBroadcastAsUser(Intent intent, UserHandle user,
    943             String receiverPermission, int appOp) {
    944         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    945         String[] receiverPermissions = receiverPermission == null ? null
    946                 : new String[] {receiverPermission};
    947         try {
    948             intent.prepareToLeaveProcess();
    949             ActivityManagerNative.getDefault().broadcastIntent(
    950                     mMainThread.getApplicationThread(), intent, resolvedType, null,
    951                     Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
    952                     user.getIdentifier());
    953         } catch (RemoteException e) {
    954             throw new RuntimeException("Failure from system", e);
    955         }
    956     }
    957 
    958     @Override
    959     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    960             String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
    961             int initialCode, String initialData, Bundle initialExtras) {
    962         sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE,
    963                 null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
    964     }
    965 
    966     @Override
    967     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    968             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
    969             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
    970         sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp,
    971                 null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
    972     }
    973 
    974     @Override
    975     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    976             String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
    977             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
    978         IIntentReceiver rd = null;
    979         if (resultReceiver != null) {
    980             if (mPackageInfo != null) {
    981                 if (scheduler == null) {
    982                     scheduler = mMainThread.getHandler();
    983                 }
    984                 rd = mPackageInfo.getReceiverDispatcher(
    985                     resultReceiver, getOuterContext(), scheduler,
    986                     mMainThread.getInstrumentation(), false);
    987             } else {
    988                 if (scheduler == null) {
    989                     scheduler = mMainThread.getHandler();
    990                 }
    991                 rd = new LoadedApk.ReceiverDispatcher(resultReceiver, getOuterContext(),
    992                         scheduler, null, false).getIIntentReceiver();
    993             }
    994         }
    995         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    996         String[] receiverPermissions = receiverPermission == null ? null
    997                 : new String[] {receiverPermission};
    998         try {
    999             intent.prepareToLeaveProcess();
   1000             ActivityManagerNative.getDefault().broadcastIntent(
   1001                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
   1002                 initialCode, initialData, initialExtras, receiverPermissions,
   1003                     appOp, options, true, false, user.getIdentifier());
   1004         } catch (RemoteException e) {
   1005             throw new RuntimeException("Failure from system", e);
   1006         }
   1007     }
   1008 
   1009     @Override
   1010     @Deprecated
   1011     public void sendStickyBroadcast(Intent intent) {
   1012         warnIfCallingFromSystemProcess();
   1013         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
   1014         try {
   1015             intent.prepareToLeaveProcess();
   1016             ActivityManagerNative.getDefault().broadcastIntent(
   1017                 mMainThread.getApplicationThread(), intent, resolvedType, null,
   1018                 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true,
   1019                 getUserId());
   1020         } catch (RemoteException e) {
   1021             throw new RuntimeException("Failure from system", e);
   1022         }
   1023     }
   1024 
   1025     @Override
   1026     @Deprecated
   1027     public void sendStickyOrderedBroadcast(Intent intent,
   1028             BroadcastReceiver resultReceiver,
   1029             Handler scheduler, int initialCode, String initialData,
   1030             Bundle initialExtras) {
   1031         warnIfCallingFromSystemProcess();
   1032         IIntentReceiver rd = null;
   1033         if (resultReceiver != null) {
   1034             if (mPackageInfo != null) {
   1035                 if (scheduler == null) {
   1036                     scheduler = mMainThread.getHandler();
   1037                 }
   1038                 rd = mPackageInfo.getReceiverDispatcher(
   1039                     resultReceiver, getOuterContext(), scheduler,
   1040                     mMainThread.getInstrumentation(), false);
   1041             } else {
   1042                 if (scheduler == null) {
   1043                     scheduler = mMainThread.getHandler();
   1044                 }
   1045                 rd = new LoadedApk.ReceiverDispatcher(
   1046                         resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
   1047             }
   1048         }
   1049         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
   1050         try {
   1051             intent.prepareToLeaveProcess();
   1052             ActivityManagerNative.getDefault().broadcastIntent(
   1053                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
   1054                 initialCode, initialData, initialExtras, null,
   1055                     AppOpsManager.OP_NONE, null, true, true, getUserId());
   1056         } catch (RemoteException e) {
   1057             throw new RuntimeException("Failure from system", e);
   1058         }
   1059     }
   1060 
   1061     @Override
   1062     @Deprecated
   1063     public void removeStickyBroadcast(Intent intent) {
   1064         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
   1065         if (resolvedType != null) {
   1066             intent = new Intent(intent);
   1067             intent.setDataAndType(intent.getData(), resolvedType);
   1068         }
   1069         try {
   1070             intent.prepareToLeaveProcess();
   1071             ActivityManagerNative.getDefault().unbroadcastIntent(
   1072                     mMainThread.getApplicationThread(), intent, getUserId());
   1073         } catch (RemoteException e) {
   1074             throw new RuntimeException("Failure from system", e);
   1075         }
   1076     }
   1077 
   1078     @Override
   1079     @Deprecated
   1080     public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
   1081         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
   1082         try {
   1083             intent.prepareToLeaveProcess();
   1084             ActivityManagerNative.getDefault().broadcastIntent(
   1085                 mMainThread.getApplicationThread(), intent, resolvedType, null,
   1086                 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true, user.getIdentifier());
   1087         } catch (RemoteException e) {
   1088             throw new RuntimeException("Failure from system", e);
   1089         }
   1090     }
   1091 
   1092     @Override
   1093     @Deprecated
   1094     public void sendStickyOrderedBroadcastAsUser(Intent intent,
   1095             UserHandle user, BroadcastReceiver resultReceiver,
   1096             Handler scheduler, int initialCode, String initialData,
   1097             Bundle initialExtras) {
   1098         IIntentReceiver rd = null;
   1099         if (resultReceiver != null) {
   1100             if (mPackageInfo != null) {
   1101                 if (scheduler == null) {
   1102                     scheduler = mMainThread.getHandler();
   1103                 }
   1104                 rd = mPackageInfo.getReceiverDispatcher(
   1105                     resultReceiver, getOuterContext(), scheduler,
   1106                     mMainThread.getInstrumentation(), false);
   1107             } else {
   1108                 if (scheduler == null) {
   1109                     scheduler = mMainThread.getHandler();
   1110                 }
   1111                 rd = new LoadedApk.ReceiverDispatcher(
   1112                         resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
   1113             }
   1114         }
   1115         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
   1116         try {
   1117             intent.prepareToLeaveProcess();
   1118             ActivityManagerNative.getDefault().broadcastIntent(
   1119                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
   1120                 initialCode, initialData, initialExtras, null,
   1121                     AppOpsManager.OP_NONE, null, true, true, user.getIdentifier());
   1122         } catch (RemoteException e) {
   1123             throw new RuntimeException("Failure from system", e);
   1124         }
   1125     }
   1126 
   1127     @Override
   1128     @Deprecated
   1129     public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
   1130         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
   1131         if (resolvedType != null) {
   1132             intent = new Intent(intent);
   1133             intent.setDataAndType(intent.getData(), resolvedType);
   1134         }
   1135         try {
   1136             intent.prepareToLeaveProcess();
   1137             ActivityManagerNative.getDefault().unbroadcastIntent(
   1138                     mMainThread.getApplicationThread(), intent, user.getIdentifier());
   1139         } catch (RemoteException e) {
   1140             throw new RuntimeException("Failure from system", e);
   1141         }
   1142     }
   1143 
   1144     @Override
   1145     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
   1146         return registerReceiver(receiver, filter, null, null);
   1147     }
   1148 
   1149     @Override
   1150     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
   1151             String broadcastPermission, Handler scheduler) {
   1152         return registerReceiverInternal(receiver, getUserId(),
   1153                 filter, broadcastPermission, scheduler, getOuterContext());
   1154     }
   1155 
   1156     @Override
   1157     public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
   1158             IntentFilter filter, String broadcastPermission, Handler scheduler) {
   1159         return registerReceiverInternal(receiver, user.getIdentifier(),
   1160                 filter, broadcastPermission, scheduler, getOuterContext());
   1161     }
   1162 
   1163     private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
   1164             IntentFilter filter, String broadcastPermission,
   1165             Handler scheduler, Context context) {
   1166         IIntentReceiver rd = null;
   1167         if (receiver != null) {
   1168             if (mPackageInfo != null && context != null) {
   1169                 if (scheduler == null) {
   1170                     scheduler = mMainThread.getHandler();
   1171                 }
   1172                 rd = mPackageInfo.getReceiverDispatcher(
   1173                     receiver, context, scheduler,
   1174                     mMainThread.getInstrumentation(), true);
   1175             } else {
   1176                 if (scheduler == null) {
   1177                     scheduler = mMainThread.getHandler();
   1178                 }
   1179                 rd = new LoadedApk.ReceiverDispatcher(
   1180                         receiver, context, scheduler, null, true).getIIntentReceiver();
   1181             }
   1182         }
   1183         try {
   1184             return ActivityManagerNative.getDefault().registerReceiver(
   1185                     mMainThread.getApplicationThread(), mBasePackageName,
   1186                     rd, filter, broadcastPermission, userId);
   1187         } catch (RemoteException e) {
   1188             return null;
   1189         }
   1190     }
   1191 
   1192     @Override
   1193     public void unregisterReceiver(BroadcastReceiver receiver) {
   1194         if (mPackageInfo != null) {
   1195             IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
   1196                     getOuterContext(), receiver);
   1197             try {
   1198                 ActivityManagerNative.getDefault().unregisterReceiver(rd);
   1199             } catch (RemoteException e) {
   1200             }
   1201         } else {
   1202             throw new RuntimeException("Not supported in system context");
   1203         }
   1204     }
   1205 
   1206     private void validateServiceIntent(Intent service) {
   1207         if (service.getComponent() == null && service.getPackage() == null) {
   1208             if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
   1209                 IllegalArgumentException ex = new IllegalArgumentException(
   1210                         "Service Intent must be explicit: " + service);
   1211                 throw ex;
   1212             } else {
   1213                 Log.w(TAG, "Implicit intents with startService are not safe: " + service
   1214                         + " " + Debug.getCallers(2, 3));
   1215             }
   1216         }
   1217     }
   1218 
   1219     @Override
   1220     public ComponentName startService(Intent service) {
   1221         warnIfCallingFromSystemProcess();
   1222         return startServiceCommon(service, mUser);
   1223     }
   1224 
   1225     @Override
   1226     public boolean stopService(Intent service) {
   1227         warnIfCallingFromSystemProcess();
   1228         return stopServiceCommon(service, mUser);
   1229     }
   1230 
   1231     @Override
   1232     public ComponentName startServiceAsUser(Intent service, UserHandle user) {
   1233         return startServiceCommon(service, user);
   1234     }
   1235 
   1236     private ComponentName startServiceCommon(Intent service, UserHandle user) {
   1237         try {
   1238             validateServiceIntent(service);
   1239             service.prepareToLeaveProcess();
   1240             ComponentName cn = ActivityManagerNative.getDefault().startService(
   1241                 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
   1242                             getContentResolver()), getOpPackageName(), user.getIdentifier());
   1243             if (cn != null) {
   1244                 if (cn.getPackageName().equals("!")) {
   1245                     throw new SecurityException(
   1246                             "Not allowed to start service " + service
   1247                             + " without permission " + cn.getClassName());
   1248                 } else if (cn.getPackageName().equals("!!")) {
   1249                     throw new SecurityException(
   1250                             "Unable to start service " + service
   1251                             + ": " + cn.getClassName());
   1252                 }
   1253             }
   1254             return cn;
   1255         } catch (RemoteException e) {
   1256             throw new RuntimeException("Failure from system", e);
   1257         }
   1258     }
   1259 
   1260     @Override
   1261     public boolean stopServiceAsUser(Intent service, UserHandle user) {
   1262         return stopServiceCommon(service, user);
   1263     }
   1264 
   1265     private boolean stopServiceCommon(Intent service, UserHandle user) {
   1266         try {
   1267             validateServiceIntent(service);
   1268             service.prepareToLeaveProcess();
   1269             int res = ActivityManagerNative.getDefault().stopService(
   1270                 mMainThread.getApplicationThread(), service,
   1271                 service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
   1272             if (res < 0) {
   1273                 throw new SecurityException(
   1274                         "Not allowed to stop service " + service);
   1275             }
   1276             return res != 0;
   1277         } catch (RemoteException e) {
   1278             throw new RuntimeException("Failure from system", e);
   1279         }
   1280     }
   1281 
   1282     @Override
   1283     public boolean bindService(Intent service, ServiceConnection conn,
   1284             int flags) {
   1285         warnIfCallingFromSystemProcess();
   1286         return bindServiceCommon(service, conn, flags, Process.myUserHandle());
   1287     }
   1288 
   1289     /** @hide */
   1290     @Override
   1291     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
   1292             UserHandle user) {
   1293         return bindServiceCommon(service, conn, flags, user);
   1294     }
   1295 
   1296     private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
   1297             UserHandle user) {
   1298         IServiceConnection sd;
   1299         if (conn == null) {
   1300             throw new IllegalArgumentException("connection is null");
   1301         }
   1302         if (mPackageInfo != null) {
   1303             sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
   1304                     mMainThread.getHandler(), flags);
   1305         } else {
   1306             throw new RuntimeException("Not supported in system context");
   1307         }
   1308         validateServiceIntent(service);
   1309         try {
   1310             IBinder token = getActivityToken();
   1311             if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
   1312                     && mPackageInfo.getApplicationInfo().targetSdkVersion
   1313                     < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
   1314                 flags |= BIND_WAIVE_PRIORITY;
   1315             }
   1316             service.prepareToLeaveProcess();
   1317             int res = ActivityManagerNative.getDefault().bindService(
   1318                 mMainThread.getApplicationThread(), getActivityToken(), service,
   1319                 service.resolveTypeIfNeeded(getContentResolver()),
   1320                 sd, flags, getOpPackageName(), user.getIdentifier());
   1321             if (res < 0) {
   1322                 throw new SecurityException(
   1323                         "Not allowed to bind to service " + service);
   1324             }
   1325             return res != 0;
   1326         } catch (RemoteException e) {
   1327             throw new RuntimeException("Failure from system", e);
   1328         }
   1329     }
   1330 
   1331     @Override
   1332     public void unbindService(ServiceConnection conn) {
   1333         if (conn == null) {
   1334             throw new IllegalArgumentException("connection is null");
   1335         }
   1336         if (mPackageInfo != null) {
   1337             IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
   1338                     getOuterContext(), conn);
   1339             try {
   1340                 ActivityManagerNative.getDefault().unbindService(sd);
   1341             } catch (RemoteException e) {
   1342             }
   1343         } else {
   1344             throw new RuntimeException("Not supported in system context");
   1345         }
   1346     }
   1347 
   1348     @Override
   1349     public boolean startInstrumentation(ComponentName className,
   1350             String profileFile, Bundle arguments) {
   1351         try {
   1352             if (arguments != null) {
   1353                 arguments.setAllowFds(false);
   1354             }
   1355             return ActivityManagerNative.getDefault().startInstrumentation(
   1356                     className, profileFile, 0, arguments, null, null, getUserId(),
   1357                     null /* ABI override */);
   1358         } catch (RemoteException e) {
   1359             throw new RuntimeException("Failure from system", e);
   1360         }
   1361     }
   1362 
   1363     @Override
   1364     public Object getSystemService(String name) {
   1365         return SystemServiceRegistry.getSystemService(this, name);
   1366     }
   1367 
   1368     @Override
   1369     public String getSystemServiceName(Class<?> serviceClass) {
   1370         return SystemServiceRegistry.getSystemServiceName(serviceClass);
   1371     }
   1372 
   1373     @Override
   1374     public int checkPermission(String permission, int pid, int uid) {
   1375         if (permission == null) {
   1376             throw new IllegalArgumentException("permission is null");
   1377         }
   1378 
   1379         try {
   1380             return ActivityManagerNative.getDefault().checkPermission(
   1381                     permission, pid, uid);
   1382         } catch (RemoteException e) {
   1383             return PackageManager.PERMISSION_DENIED;
   1384         }
   1385     }
   1386 
   1387     /** @hide */
   1388     @Override
   1389     public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
   1390         if (permission == null) {
   1391             throw new IllegalArgumentException("permission is null");
   1392         }
   1393 
   1394         try {
   1395             return ActivityManagerNative.getDefault().checkPermissionWithToken(
   1396                     permission, pid, uid, callerToken);
   1397         } catch (RemoteException e) {
   1398             return PackageManager.PERMISSION_DENIED;
   1399         }
   1400     }
   1401 
   1402     @Override
   1403     public int checkCallingPermission(String permission) {
   1404         if (permission == null) {
   1405             throw new IllegalArgumentException("permission is null");
   1406         }
   1407 
   1408         int pid = Binder.getCallingPid();
   1409         if (pid != Process.myPid()) {
   1410             return checkPermission(permission, pid, Binder.getCallingUid());
   1411         }
   1412         return PackageManager.PERMISSION_DENIED;
   1413     }
   1414 
   1415     @Override
   1416     public int checkCallingOrSelfPermission(String permission) {
   1417         if (permission == null) {
   1418             throw new IllegalArgumentException("permission is null");
   1419         }
   1420 
   1421         return checkPermission(permission, Binder.getCallingPid(),
   1422                 Binder.getCallingUid());
   1423     }
   1424 
   1425     @Override
   1426     public int checkSelfPermission(String permission) {
   1427         if (permission == null) {
   1428             throw new IllegalArgumentException("permission is null");
   1429         }
   1430 
   1431         return checkPermission(permission, Process.myPid(), Process.myUid());
   1432     }
   1433 
   1434     private void enforce(
   1435             String permission, int resultOfCheck,
   1436             boolean selfToo, int uid, String message) {
   1437         if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
   1438             throw new SecurityException(
   1439                     (message != null ? (message + ": ") : "") +
   1440                     (selfToo
   1441                      ? "Neither user " + uid + " nor current process has "
   1442                      : "uid " + uid + " does not have ") +
   1443                     permission +
   1444                     ".");
   1445         }
   1446     }
   1447 
   1448     @Override
   1449     public void enforcePermission(
   1450             String permission, int pid, int uid, String message) {
   1451         enforce(permission,
   1452                 checkPermission(permission, pid, uid),
   1453                 false,
   1454                 uid,
   1455                 message);
   1456     }
   1457 
   1458     @Override
   1459     public void enforceCallingPermission(String permission, String message) {
   1460         enforce(permission,
   1461                 checkCallingPermission(permission),
   1462                 false,
   1463                 Binder.getCallingUid(),
   1464                 message);
   1465     }
   1466 
   1467     @Override
   1468     public void enforceCallingOrSelfPermission(
   1469             String permission, String message) {
   1470         enforce(permission,
   1471                 checkCallingOrSelfPermission(permission),
   1472                 true,
   1473                 Binder.getCallingUid(),
   1474                 message);
   1475     }
   1476 
   1477     @Override
   1478     public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
   1479          try {
   1480             ActivityManagerNative.getDefault().grantUriPermission(
   1481                     mMainThread.getApplicationThread(), toPackage,
   1482                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
   1483         } catch (RemoteException e) {
   1484         }
   1485     }
   1486 
   1487     @Override
   1488     public void revokeUriPermission(Uri uri, int modeFlags) {
   1489          try {
   1490             ActivityManagerNative.getDefault().revokeUriPermission(
   1491                     mMainThread.getApplicationThread(),
   1492                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
   1493         } catch (RemoteException e) {
   1494         }
   1495     }
   1496 
   1497     @Override
   1498     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   1499         try {
   1500             return ActivityManagerNative.getDefault().checkUriPermission(
   1501                     ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
   1502                     resolveUserId(uri), null);
   1503         } catch (RemoteException e) {
   1504             return PackageManager.PERMISSION_DENIED;
   1505         }
   1506     }
   1507 
   1508     /** @hide */
   1509     @Override
   1510     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
   1511         try {
   1512             return ActivityManagerNative.getDefault().checkUriPermission(
   1513                     ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
   1514                     resolveUserId(uri), callerToken);
   1515         } catch (RemoteException e) {
   1516             return PackageManager.PERMISSION_DENIED;
   1517         }
   1518     }
   1519 
   1520     private int resolveUserId(Uri uri) {
   1521         return ContentProvider.getUserIdFromUri(uri, getUserId());
   1522     }
   1523 
   1524     @Override
   1525     public int checkCallingUriPermission(Uri uri, int modeFlags) {
   1526         int pid = Binder.getCallingPid();
   1527         if (pid != Process.myPid()) {
   1528             return checkUriPermission(uri, pid,
   1529                     Binder.getCallingUid(), modeFlags);
   1530         }
   1531         return PackageManager.PERMISSION_DENIED;
   1532     }
   1533 
   1534     @Override
   1535     public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
   1536         return checkUriPermission(uri, Binder.getCallingPid(),
   1537                 Binder.getCallingUid(), modeFlags);
   1538     }
   1539 
   1540     @Override
   1541     public int checkUriPermission(Uri uri, String readPermission,
   1542             String writePermission, int pid, int uid, int modeFlags) {
   1543         if (DEBUG) {
   1544             Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
   1545                     + readPermission + " writePermission=" + writePermission
   1546                     + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
   1547         }
   1548         if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   1549             if (readPermission == null
   1550                     || checkPermission(readPermission, pid, uid)
   1551                     == PackageManager.PERMISSION_GRANTED) {
   1552                 return PackageManager.PERMISSION_GRANTED;
   1553             }
   1554         }
   1555         if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   1556             if (writePermission == null
   1557                     || checkPermission(writePermission, pid, uid)
   1558                     == PackageManager.PERMISSION_GRANTED) {
   1559                 return PackageManager.PERMISSION_GRANTED;
   1560             }
   1561         }
   1562         return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
   1563                 : PackageManager.PERMISSION_DENIED;
   1564     }
   1565 
   1566     private String uriModeFlagToString(int uriModeFlags) {
   1567         StringBuilder builder = new StringBuilder();
   1568         if ((uriModeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   1569             builder.append("read and ");
   1570         }
   1571         if ((uriModeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   1572             builder.append("write and ");
   1573         }
   1574         if ((uriModeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
   1575             builder.append("persistable and ");
   1576         }
   1577         if ((uriModeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
   1578             builder.append("prefix and ");
   1579         }
   1580 
   1581         if (builder.length() > 5) {
   1582             builder.setLength(builder.length() - 5);
   1583             return builder.toString();
   1584         } else {
   1585             throw new IllegalArgumentException("Unknown permission mode flags: " + uriModeFlags);
   1586         }
   1587     }
   1588 
   1589     private void enforceForUri(
   1590             int modeFlags, int resultOfCheck, boolean selfToo,
   1591             int uid, Uri uri, String message) {
   1592         if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
   1593             throw new SecurityException(
   1594                     (message != null ? (message + ": ") : "") +
   1595                     (selfToo
   1596                      ? "Neither user " + uid + " nor current process has "
   1597                      : "User " + uid + " does not have ") +
   1598                     uriModeFlagToString(modeFlags) +
   1599                     " permission on " +
   1600                     uri +
   1601                     ".");
   1602         }
   1603     }
   1604 
   1605     @Override
   1606     public void enforceUriPermission(
   1607             Uri uri, int pid, int uid, int modeFlags, String message) {
   1608         enforceForUri(
   1609                 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
   1610                 false, uid, uri, message);
   1611     }
   1612 
   1613     @Override
   1614     public void enforceCallingUriPermission(
   1615             Uri uri, int modeFlags, String message) {
   1616         enforceForUri(
   1617                 modeFlags, checkCallingUriPermission(uri, modeFlags),
   1618                 false,
   1619                 Binder.getCallingUid(), uri, message);
   1620     }
   1621 
   1622     @Override
   1623     public void enforceCallingOrSelfUriPermission(
   1624             Uri uri, int modeFlags, String message) {
   1625         enforceForUri(
   1626                 modeFlags,
   1627                 checkCallingOrSelfUriPermission(uri, modeFlags), true,
   1628                 Binder.getCallingUid(), uri, message);
   1629     }
   1630 
   1631     @Override
   1632     public void enforceUriPermission(
   1633             Uri uri, String readPermission, String writePermission,
   1634             int pid, int uid, int modeFlags, String message) {
   1635         enforceForUri(modeFlags,
   1636                       checkUriPermission(
   1637                               uri, readPermission, writePermission, pid, uid,
   1638                               modeFlags),
   1639                       false,
   1640                       uid,
   1641                       uri,
   1642                       message);
   1643     }
   1644 
   1645     /**
   1646      * Logs a warning if the system process directly called a method such as
   1647      * {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
   1648      * The "AsUser" variants allow us to properly enforce the user's restrictions.
   1649      */
   1650     private void warnIfCallingFromSystemProcess() {
   1651         if (Process.myUid() == Process.SYSTEM_UID) {
   1652             Slog.w(TAG, "Calling a method in the system process without a qualified user: "
   1653                     + Debug.getCallers(5));
   1654         }
   1655     }
   1656 
   1657     @Override
   1658     public Context createApplicationContext(ApplicationInfo application, int flags)
   1659             throws NameNotFoundException {
   1660         LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
   1661                 flags | CONTEXT_REGISTER_PACKAGE);
   1662         if (pi != null) {
   1663             final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
   1664             ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
   1665                     new UserHandle(UserHandle.getUserId(application.uid)), restricted,
   1666                     mDisplay, null, Display.INVALID_DISPLAY);
   1667             if (c.mResources != null) {
   1668                 return c;
   1669             }
   1670         }
   1671 
   1672         throw new PackageManager.NameNotFoundException(
   1673                 "Application package " + application.packageName + " not found");
   1674     }
   1675 
   1676     @Override
   1677     public Context createPackageContext(String packageName, int flags)
   1678             throws NameNotFoundException {
   1679         return createPackageContextAsUser(packageName, flags,
   1680                 mUser != null ? mUser : Process.myUserHandle());
   1681     }
   1682 
   1683     @Override
   1684     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
   1685             throws NameNotFoundException {
   1686         final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
   1687         if (packageName.equals("system") || packageName.equals("android")) {
   1688             return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
   1689                     user, restricted, mDisplay, null, Display.INVALID_DISPLAY);
   1690         }
   1691 
   1692         LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
   1693                 flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
   1694         if (pi != null) {
   1695             ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
   1696                     user, restricted, mDisplay, null, Display.INVALID_DISPLAY);
   1697             if (c.mResources != null) {
   1698                 return c;
   1699             }
   1700         }
   1701 
   1702         // Should be a better exception.
   1703         throw new PackageManager.NameNotFoundException(
   1704                 "Application package " + packageName + " not found");
   1705     }
   1706 
   1707     @Override
   1708     public Context createConfigurationContext(Configuration overrideConfiguration) {
   1709         if (overrideConfiguration == null) {
   1710             throw new IllegalArgumentException("overrideConfiguration must not be null");
   1711         }
   1712 
   1713         return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
   1714                 mUser, mRestricted, mDisplay, overrideConfiguration, Display.INVALID_DISPLAY);
   1715     }
   1716 
   1717     @Override
   1718     public Context createDisplayContext(Display display) {
   1719         if (display == null) {
   1720             throw new IllegalArgumentException("display must not be null");
   1721         }
   1722 
   1723         return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
   1724                 mUser, mRestricted, display, null, Display.INVALID_DISPLAY);
   1725     }
   1726 
   1727     Display getDisplay() {
   1728         if (mDisplay != null) {
   1729             return mDisplay;
   1730         }
   1731         return ResourcesManager.getInstance().getAdjustedDisplay(
   1732                 Display.DEFAULT_DISPLAY, mDisplayAdjustments);
   1733     }
   1734 
   1735     private int getDisplayId() {
   1736         return mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
   1737     }
   1738 
   1739     @Override
   1740     public boolean isRestricted() {
   1741         return mRestricted;
   1742     }
   1743 
   1744     @Override
   1745     public DisplayAdjustments getDisplayAdjustments(int displayId) {
   1746         return mDisplayAdjustments;
   1747     }
   1748 
   1749     private File getDataDirFile() {
   1750         if (mPackageInfo != null) {
   1751             return mPackageInfo.getDataDirFile();
   1752         }
   1753         throw new RuntimeException("Not supported in system context");
   1754     }
   1755 
   1756     @Override
   1757     public File getDir(String name, int mode) {
   1758         name = "app_" + name;
   1759         File file = makeFilename(getDataDirFile(), name);
   1760         if (!file.exists()) {
   1761             file.mkdir();
   1762             setFilePermissionsFromMode(file.getPath(), mode,
   1763                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
   1764         }
   1765         return file;
   1766     }
   1767 
   1768     /** {@hide} */
   1769     @Override
   1770     public int getUserId() {
   1771         return mUser.getIdentifier();
   1772     }
   1773 
   1774     static ContextImpl createSystemContext(ActivityThread mainThread) {
   1775         LoadedApk packageInfo = new LoadedApk(mainThread);
   1776         ContextImpl context = new ContextImpl(null, mainThread,
   1777                 packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
   1778         context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
   1779                 context.mResourcesManager.getDisplayMetricsLocked());
   1780         return context;
   1781     }
   1782 
   1783     static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
   1784         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
   1785         return new ContextImpl(null, mainThread,
   1786                 packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
   1787     }
   1788 
   1789     static ContextImpl createActivityContext(ActivityThread mainThread,
   1790             LoadedApk packageInfo, int displayId, Configuration overrideConfiguration) {
   1791         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
   1792         return new ContextImpl(null, mainThread, packageInfo, null, null, false,
   1793                 null, overrideConfiguration, displayId);
   1794     }
   1795 
   1796     private ContextImpl(ContextImpl container, ActivityThread mainThread,
   1797             LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
   1798             Display display, Configuration overrideConfiguration, int createDisplayWithId) {
   1799         mOuterContext = this;
   1800 
   1801         mMainThread = mainThread;
   1802         mActivityToken = activityToken;
   1803         mRestricted = restricted;
   1804 
   1805         if (user == null) {
   1806             user = Process.myUserHandle();
   1807         }
   1808         mUser = user;
   1809 
   1810         mPackageInfo = packageInfo;
   1811         mResourcesManager = ResourcesManager.getInstance();
   1812 
   1813         final int displayId = (createDisplayWithId != Display.INVALID_DISPLAY)
   1814                 ? createDisplayWithId
   1815                 : (display != null) ? display.getDisplayId() : Display.DEFAULT_DISPLAY;
   1816 
   1817         CompatibilityInfo compatInfo = null;
   1818         if (container != null) {
   1819             compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo();
   1820         }
   1821         if (compatInfo == null) {
   1822             compatInfo = (displayId == Display.DEFAULT_DISPLAY)
   1823                     ? packageInfo.getCompatibilityInfo()
   1824                     : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
   1825         }
   1826         mDisplayAdjustments.setCompatibilityInfo(compatInfo);
   1827         mDisplayAdjustments.setConfiguration(overrideConfiguration);
   1828 
   1829         mDisplay = (createDisplayWithId == Display.INVALID_DISPLAY) ? display
   1830                 : ResourcesManager.getInstance().getAdjustedDisplay(displayId, mDisplayAdjustments);
   1831 
   1832         Resources resources = packageInfo.getResources(mainThread);
   1833         if (resources != null) {
   1834             if (displayId != Display.DEFAULT_DISPLAY
   1835                     || overrideConfiguration != null
   1836                     || (compatInfo != null && compatInfo.applicationScale
   1837                             != resources.getCompatibilityInfo().applicationScale)) {
   1838                 resources = mResourcesManager.getTopLevelResources(packageInfo.getResDir(),
   1839                         packageInfo.getSplitResDirs(), packageInfo.getOverlayDirs(),
   1840                         packageInfo.getApplicationInfo().sharedLibraryFiles, displayId,
   1841                         overrideConfiguration, compatInfo);
   1842             }
   1843         }
   1844         mResources = resources;
   1845 
   1846         if (container != null) {
   1847             mBasePackageName = container.mBasePackageName;
   1848             mOpPackageName = container.mOpPackageName;
   1849         } else {
   1850             mBasePackageName = packageInfo.mPackageName;
   1851             ApplicationInfo ainfo = packageInfo.getApplicationInfo();
   1852             if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
   1853                 // Special case: system components allow themselves to be loaded in to other
   1854                 // processes.  For purposes of app ops, we must then consider the context as
   1855                 // belonging to the package of this process, not the system itself, otherwise
   1856                 // the package+uid verifications in app ops will fail.
   1857                 mOpPackageName = ActivityThread.currentPackageName();
   1858             } else {
   1859                 mOpPackageName = mBasePackageName;
   1860             }
   1861         }
   1862 
   1863         mContentResolver = new ApplicationContentResolver(this, mainThread, user);
   1864     }
   1865 
   1866     void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
   1867         mPackageInfo.installSystemApplicationInfo(info, classLoader);
   1868     }
   1869 
   1870     final void scheduleFinalCleanup(String who, String what) {
   1871         mMainThread.scheduleContextCleanup(this, who, what);
   1872     }
   1873 
   1874     final void performFinalCleanup(String who, String what) {
   1875         //Log.i(TAG, "Cleanup up context: " + this);
   1876         mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
   1877     }
   1878 
   1879     final Context getReceiverRestrictedContext() {
   1880         if (mReceiverRestrictedContext != null) {
   1881             return mReceiverRestrictedContext;
   1882         }
   1883         return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
   1884     }
   1885 
   1886     final void setOuterContext(Context context) {
   1887         mOuterContext = context;
   1888     }
   1889 
   1890     final Context getOuterContext() {
   1891         return mOuterContext;
   1892     }
   1893 
   1894     final IBinder getActivityToken() {
   1895         return mActivityToken;
   1896     }
   1897 
   1898     @SuppressWarnings("deprecation")
   1899     static void setFilePermissionsFromMode(String name, int mode,
   1900             int extraPermissions) {
   1901         int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
   1902             |FileUtils.S_IRGRP|FileUtils.S_IWGRP
   1903             |extraPermissions;
   1904         if ((mode&MODE_WORLD_READABLE) != 0) {
   1905             perms |= FileUtils.S_IROTH;
   1906         }
   1907         if ((mode&MODE_WORLD_WRITEABLE) != 0) {
   1908             perms |= FileUtils.S_IWOTH;
   1909         }
   1910         if (DEBUG) {
   1911             Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
   1912                   + ", perms=0x" + Integer.toHexString(perms));
   1913         }
   1914         FileUtils.setPermissions(name, perms, -1, -1);
   1915     }
   1916 
   1917     private File validateFilePath(String name, boolean createDirectory) {
   1918         File dir;
   1919         File f;
   1920 
   1921         if (name.charAt(0) == File.separatorChar) {
   1922             String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
   1923             dir = new File(dirPath);
   1924             name = name.substring(name.lastIndexOf(File.separatorChar));
   1925             f = new File(dir, name);
   1926         } else {
   1927             dir = getDatabasesDir();
   1928             f = makeFilename(dir, name);
   1929         }
   1930 
   1931         if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
   1932             FileUtils.setPermissions(dir.getPath(),
   1933                 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
   1934                 -1, -1);
   1935         }
   1936 
   1937         return f;
   1938     }
   1939 
   1940     private File makeFilename(File base, String name) {
   1941         if (name.indexOf(File.separatorChar) < 0) {
   1942             return new File(base, name);
   1943         }
   1944         throw new IllegalArgumentException(
   1945                 "File " + name + " contains a path separator");
   1946     }
   1947 
   1948     /**
   1949      * Ensure that given directories exist, trying to create them if missing. If
   1950      * unable to create, they are filtered by replacing with {@code null}.
   1951      */
   1952     private File[] ensureDirsExistOrFilter(File[] dirs) {
   1953         File[] result = new File[dirs.length];
   1954         for (int i = 0; i < dirs.length; i++) {
   1955             File dir = dirs[i];
   1956             if (!dir.exists()) {
   1957                 if (!dir.mkdirs()) {
   1958                     // recheck existence in case of cross-process race
   1959                     if (!dir.exists()) {
   1960                         // Failing to mkdir() may be okay, since we might not have
   1961                         // enough permissions; ask vold to create on our behalf.
   1962                         final IMountService mount = IMountService.Stub.asInterface(
   1963                                 ServiceManager.getService("mount"));
   1964                         try {
   1965                             final int res = mount.mkdirs(getPackageName(), dir.getAbsolutePath());
   1966                             if (res != 0) {
   1967                                 Log.w(TAG, "Failed to ensure " + dir + ": " + res);
   1968                                 dir = null;
   1969                             }
   1970                         } catch (Exception e) {
   1971                             Log.w(TAG, "Failed to ensure " + dir + ": " + e);
   1972                             dir = null;
   1973                         }
   1974                     }
   1975                 }
   1976             }
   1977             result[i] = dir;
   1978         }
   1979         return result;
   1980     }
   1981 
   1982     // ----------------------------------------------------------------------
   1983     // ----------------------------------------------------------------------
   1984     // ----------------------------------------------------------------------
   1985 
   1986     private static final class ApplicationContentResolver extends ContentResolver {
   1987         private final ActivityThread mMainThread;
   1988         private final UserHandle mUser;
   1989 
   1990         public ApplicationContentResolver(
   1991                 Context context, ActivityThread mainThread, UserHandle user) {
   1992             super(context);
   1993             mMainThread = Preconditions.checkNotNull(mainThread);
   1994             mUser = Preconditions.checkNotNull(user);
   1995         }
   1996 
   1997         @Override
   1998         protected IContentProvider acquireProvider(Context context, String auth) {
   1999             return mMainThread.acquireProvider(context,
   2000                     ContentProvider.getAuthorityWithoutUserId(auth),
   2001                     resolveUserIdFromAuthority(auth), true);
   2002         }
   2003 
   2004         @Override
   2005         protected IContentProvider acquireExistingProvider(Context context, String auth) {
   2006             return mMainThread.acquireExistingProvider(context,
   2007                     ContentProvider.getAuthorityWithoutUserId(auth),
   2008                     resolveUserIdFromAuthority(auth), true);
   2009         }
   2010 
   2011         @Override
   2012         public boolean releaseProvider(IContentProvider provider) {
   2013             return mMainThread.releaseProvider(provider, true);
   2014         }
   2015 
   2016         @Override
   2017         protected IContentProvider acquireUnstableProvider(Context c, String auth) {
   2018             return mMainThread.acquireProvider(c,
   2019                     ContentProvider.getAuthorityWithoutUserId(auth),
   2020                     resolveUserIdFromAuthority(auth), false);
   2021         }
   2022 
   2023         @Override
   2024         public boolean releaseUnstableProvider(IContentProvider icp) {
   2025             return mMainThread.releaseProvider(icp, false);
   2026         }
   2027 
   2028         @Override
   2029         public void unstableProviderDied(IContentProvider icp) {
   2030             mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
   2031         }
   2032 
   2033         @Override
   2034         public void appNotRespondingViaProvider(IContentProvider icp) {
   2035             mMainThread.appNotRespondingViaProvider(icp.asBinder());
   2036         }
   2037 
   2038         /** @hide */
   2039         protected int resolveUserIdFromAuthority(String auth) {
   2040             return ContentProvider.getUserIdFromAuthority(auth, mUser.getIdentifier());
   2041         }
   2042     }
   2043 }
   2044