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