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