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