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