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