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