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                null, 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, int initialCode, String initialData, Bundle initialExtras) {
970        sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp,
971                null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
972    }
973
974    @Override
975    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
976            String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
977            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
978        IIntentReceiver rd = null;
979        if (resultReceiver != null) {
980            if (mPackageInfo != null) {
981                if (scheduler == null) {
982                    scheduler = mMainThread.getHandler();
983                }
984                rd = mPackageInfo.getReceiverDispatcher(
985                    resultReceiver, getOuterContext(), scheduler,
986                    mMainThread.getInstrumentation(), false);
987            } else {
988                if (scheduler == null) {
989                    scheduler = mMainThread.getHandler();
990                }
991                rd = new LoadedApk.ReceiverDispatcher(resultReceiver, getOuterContext(),
992                        scheduler, null, false).getIIntentReceiver();
993            }
994        }
995        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
996        String[] receiverPermissions = receiverPermission == null ? null
997                : new String[] {receiverPermission};
998        try {
999            intent.prepareToLeaveProcess();
1000            ActivityManagerNative.getDefault().broadcastIntent(
1001                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1002                initialCode, initialData, initialExtras, receiverPermissions,
1003                    appOp, options, true, false, user.getIdentifier());
1004        } catch (RemoteException e) {
1005            throw new RuntimeException("Failure from system", e);
1006        }
1007    }
1008
1009    @Override
1010    @Deprecated
1011    public void sendStickyBroadcast(Intent intent) {
1012        warnIfCallingFromSystemProcess();
1013        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1014        try {
1015            intent.prepareToLeaveProcess();
1016            ActivityManagerNative.getDefault().broadcastIntent(
1017                mMainThread.getApplicationThread(), intent, resolvedType, null,
1018                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true,
1019                getUserId());
1020        } catch (RemoteException e) {
1021            throw new RuntimeException("Failure from system", e);
1022        }
1023    }
1024
1025    @Override
1026    @Deprecated
1027    public void sendStickyOrderedBroadcast(Intent intent,
1028            BroadcastReceiver resultReceiver,
1029            Handler scheduler, int initialCode, String initialData,
1030            Bundle initialExtras) {
1031        warnIfCallingFromSystemProcess();
1032        IIntentReceiver rd = null;
1033        if (resultReceiver != null) {
1034            if (mPackageInfo != null) {
1035                if (scheduler == null) {
1036                    scheduler = mMainThread.getHandler();
1037                }
1038                rd = mPackageInfo.getReceiverDispatcher(
1039                    resultReceiver, getOuterContext(), scheduler,
1040                    mMainThread.getInstrumentation(), false);
1041            } else {
1042                if (scheduler == null) {
1043                    scheduler = mMainThread.getHandler();
1044                }
1045                rd = new LoadedApk.ReceiverDispatcher(
1046                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1047            }
1048        }
1049        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1050        try {
1051            intent.prepareToLeaveProcess();
1052            ActivityManagerNative.getDefault().broadcastIntent(
1053                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1054                initialCode, initialData, initialExtras, null,
1055                    AppOpsManager.OP_NONE, null, true, true, getUserId());
1056        } catch (RemoteException e) {
1057            throw new RuntimeException("Failure from system", e);
1058        }
1059    }
1060
1061    @Override
1062    @Deprecated
1063    public void removeStickyBroadcast(Intent intent) {
1064        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1065        if (resolvedType != null) {
1066            intent = new Intent(intent);
1067            intent.setDataAndType(intent.getData(), resolvedType);
1068        }
1069        try {
1070            intent.prepareToLeaveProcess();
1071            ActivityManagerNative.getDefault().unbroadcastIntent(
1072                    mMainThread.getApplicationThread(), intent, getUserId());
1073        } catch (RemoteException e) {
1074            throw new RuntimeException("Failure from system", e);
1075        }
1076    }
1077
1078    @Override
1079    @Deprecated
1080    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
1081        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1082        try {
1083            intent.prepareToLeaveProcess();
1084            ActivityManagerNative.getDefault().broadcastIntent(
1085                mMainThread.getApplicationThread(), intent, resolvedType, null,
1086                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true, user.getIdentifier());
1087        } catch (RemoteException e) {
1088            throw new RuntimeException("Failure from system", e);
1089        }
1090    }
1091
1092    @Override
1093    @Deprecated
1094    public void sendStickyOrderedBroadcastAsUser(Intent intent,
1095            UserHandle user, BroadcastReceiver resultReceiver,
1096            Handler scheduler, int initialCode, String initialData,
1097            Bundle initialExtras) {
1098        IIntentReceiver rd = null;
1099        if (resultReceiver != null) {
1100            if (mPackageInfo != null) {
1101                if (scheduler == null) {
1102                    scheduler = mMainThread.getHandler();
1103                }
1104                rd = mPackageInfo.getReceiverDispatcher(
1105                    resultReceiver, getOuterContext(), scheduler,
1106                    mMainThread.getInstrumentation(), false);
1107            } else {
1108                if (scheduler == null) {
1109                    scheduler = mMainThread.getHandler();
1110                }
1111                rd = new LoadedApk.ReceiverDispatcher(
1112                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1113            }
1114        }
1115        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1116        try {
1117            intent.prepareToLeaveProcess();
1118            ActivityManagerNative.getDefault().broadcastIntent(
1119                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1120                initialCode, initialData, initialExtras, null,
1121                    AppOpsManager.OP_NONE, null, true, true, user.getIdentifier());
1122        } catch (RemoteException e) {
1123            throw new RuntimeException("Failure from system", e);
1124        }
1125    }
1126
1127    @Override
1128    @Deprecated
1129    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
1130        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1131        if (resolvedType != null) {
1132            intent = new Intent(intent);
1133            intent.setDataAndType(intent.getData(), resolvedType);
1134        }
1135        try {
1136            intent.prepareToLeaveProcess();
1137            ActivityManagerNative.getDefault().unbroadcastIntent(
1138                    mMainThread.getApplicationThread(), intent, user.getIdentifier());
1139        } catch (RemoteException e) {
1140            throw new RuntimeException("Failure from system", e);
1141        }
1142    }
1143
1144    @Override
1145    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1146        return registerReceiver(receiver, filter, null, null);
1147    }
1148
1149    @Override
1150    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1151            String broadcastPermission, Handler scheduler) {
1152        return registerReceiverInternal(receiver, getUserId(),
1153                filter, broadcastPermission, scheduler, getOuterContext());
1154    }
1155
1156    @Override
1157    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
1158            IntentFilter filter, String broadcastPermission, Handler scheduler) {
1159        return registerReceiverInternal(receiver, user.getIdentifier(),
1160                filter, broadcastPermission, scheduler, getOuterContext());
1161    }
1162
1163    private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
1164            IntentFilter filter, String broadcastPermission,
1165            Handler scheduler, Context context) {
1166        IIntentReceiver rd = null;
1167        if (receiver != null) {
1168            if (mPackageInfo != null && context != null) {
1169                if (scheduler == null) {
1170                    scheduler = mMainThread.getHandler();
1171                }
1172                rd = mPackageInfo.getReceiverDispatcher(
1173                    receiver, context, scheduler,
1174                    mMainThread.getInstrumentation(), true);
1175            } else {
1176                if (scheduler == null) {
1177                    scheduler = mMainThread.getHandler();
1178                }
1179                rd = new LoadedApk.ReceiverDispatcher(
1180                        receiver, context, scheduler, null, true).getIIntentReceiver();
1181            }
1182        }
1183        try {
1184            return ActivityManagerNative.getDefault().registerReceiver(
1185                    mMainThread.getApplicationThread(), mBasePackageName,
1186                    rd, filter, broadcastPermission, userId);
1187        } catch (RemoteException e) {
1188            return null;
1189        }
1190    }
1191
1192    @Override
1193    public void unregisterReceiver(BroadcastReceiver receiver) {
1194        if (mPackageInfo != null) {
1195            IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1196                    getOuterContext(), receiver);
1197            try {
1198                ActivityManagerNative.getDefault().unregisterReceiver(rd);
1199            } catch (RemoteException e) {
1200            }
1201        } else {
1202            throw new RuntimeException("Not supported in system context");
1203        }
1204    }
1205
1206    private void validateServiceIntent(Intent service) {
1207        if (service.getComponent() == null && service.getPackage() == null) {
1208            if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
1209                IllegalArgumentException ex = new IllegalArgumentException(
1210                        "Service Intent must be explicit: " + service);
1211                throw ex;
1212            } else {
1213                Log.w(TAG, "Implicit intents with startService are not safe: " + service
1214                        + " " + Debug.getCallers(2, 3));
1215            }
1216        }
1217    }
1218
1219    @Override
1220    public ComponentName startService(Intent service) {
1221        warnIfCallingFromSystemProcess();
1222        return startServiceCommon(service, mUser);
1223    }
1224
1225    @Override
1226    public boolean stopService(Intent service) {
1227        warnIfCallingFromSystemProcess();
1228        return stopServiceCommon(service, mUser);
1229    }
1230
1231    @Override
1232    public ComponentName startServiceAsUser(Intent service, UserHandle user) {
1233        return startServiceCommon(service, user);
1234    }
1235
1236    private ComponentName startServiceCommon(Intent service, UserHandle user) {
1237        try {
1238            validateServiceIntent(service);
1239            service.prepareToLeaveProcess();
1240            ComponentName cn = ActivityManagerNative.getDefault().startService(
1241                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
1242                            getContentResolver()), getOpPackageName(), user.getIdentifier());
1243            if (cn != null) {
1244                if (cn.getPackageName().equals("!")) {
1245                    throw new SecurityException(
1246                            "Not allowed to start service " + service
1247                            + " without permission " + cn.getClassName());
1248                } else if (cn.getPackageName().equals("!!")) {
1249                    throw new SecurityException(
1250                            "Unable to start service " + service
1251                            + ": " + cn.getClassName());
1252                }
1253            }
1254            return cn;
1255        } catch (RemoteException e) {
1256            throw new RuntimeException("Failure from system", e);
1257        }
1258    }
1259
1260    @Override
1261    public boolean stopServiceAsUser(Intent service, UserHandle user) {
1262        return stopServiceCommon(service, user);
1263    }
1264
1265    private boolean stopServiceCommon(Intent service, UserHandle user) {
1266        try {
1267            validateServiceIntent(service);
1268            service.prepareToLeaveProcess();
1269            int res = ActivityManagerNative.getDefault().stopService(
1270                mMainThread.getApplicationThread(), service,
1271                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
1272            if (res < 0) {
1273                throw new SecurityException(
1274                        "Not allowed to stop service " + service);
1275            }
1276            return res != 0;
1277        } catch (RemoteException e) {
1278            throw new RuntimeException("Failure from system", e);
1279        }
1280    }
1281
1282    @Override
1283    public boolean bindService(Intent service, ServiceConnection conn,
1284            int flags) {
1285        warnIfCallingFromSystemProcess();
1286        return bindServiceCommon(service, conn, flags, Process.myUserHandle());
1287    }
1288
1289    /** @hide */
1290    @Override
1291    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
1292            UserHandle user) {
1293        return bindServiceCommon(service, conn, flags, user);
1294    }
1295
1296    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
1297            UserHandle user) {
1298        IServiceConnection sd;
1299        if (conn == null) {
1300            throw new IllegalArgumentException("connection is null");
1301        }
1302        if (mPackageInfo != null) {
1303            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1304                    mMainThread.getHandler(), flags);
1305        } else {
1306            throw new RuntimeException("Not supported in system context");
1307        }
1308        validateServiceIntent(service);
1309        try {
1310            IBinder token = getActivityToken();
1311            if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1312                    && mPackageInfo.getApplicationInfo().targetSdkVersion
1313                    < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1314                flags |= BIND_WAIVE_PRIORITY;
1315            }
1316            service.prepareToLeaveProcess();
1317            int res = ActivityManagerNative.getDefault().bindService(
1318                mMainThread.getApplicationThread(), getActivityToken(), service,
1319                service.resolveTypeIfNeeded(getContentResolver()),
1320                sd, flags, getOpPackageName(), user.getIdentifier());
1321            if (res < 0) {
1322                throw new SecurityException(
1323                        "Not allowed to bind to service " + service);
1324            }
1325            return res != 0;
1326        } catch (RemoteException e) {
1327            throw new RuntimeException("Failure from system", e);
1328        }
1329    }
1330
1331    @Override
1332    public void unbindService(ServiceConnection conn) {
1333        if (conn == null) {
1334            throw new IllegalArgumentException("connection is null");
1335        }
1336        if (mPackageInfo != null) {
1337            IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1338                    getOuterContext(), conn);
1339            try {
1340                ActivityManagerNative.getDefault().unbindService(sd);
1341            } catch (RemoteException e) {
1342            }
1343        } else {
1344            throw new RuntimeException("Not supported in system context");
1345        }
1346    }
1347
1348    @Override
1349    public boolean startInstrumentation(ComponentName className,
1350            String profileFile, Bundle arguments) {
1351        try {
1352            if (arguments != null) {
1353                arguments.setAllowFds(false);
1354            }
1355            return ActivityManagerNative.getDefault().startInstrumentation(
1356                    className, profileFile, 0, arguments, null, null, getUserId(),
1357                    null /* ABI override */);
1358        } catch (RemoteException e) {
1359            throw new RuntimeException("Failure from system", e);
1360        }
1361    }
1362
1363    @Override
1364    public Object getSystemService(String name) {
1365        return SystemServiceRegistry.getSystemService(this, name);
1366    }
1367
1368    @Override
1369    public String getSystemServiceName(Class<?> serviceClass) {
1370        return SystemServiceRegistry.getSystemServiceName(serviceClass);
1371    }
1372
1373    @Override
1374    public int checkPermission(String permission, int pid, int uid) {
1375        if (permission == null) {
1376            throw new IllegalArgumentException("permission is null");
1377        }
1378
1379        try {
1380            return ActivityManagerNative.getDefault().checkPermission(
1381                    permission, pid, uid);
1382        } catch (RemoteException e) {
1383            return PackageManager.PERMISSION_DENIED;
1384        }
1385    }
1386
1387    /** @hide */
1388    @Override
1389    public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
1390        if (permission == null) {
1391            throw new IllegalArgumentException("permission is null");
1392        }
1393
1394        try {
1395            return ActivityManagerNative.getDefault().checkPermissionWithToken(
1396                    permission, pid, uid, callerToken);
1397        } catch (RemoteException e) {
1398            return PackageManager.PERMISSION_DENIED;
1399        }
1400    }
1401
1402    @Override
1403    public int checkCallingPermission(String permission) {
1404        if (permission == null) {
1405            throw new IllegalArgumentException("permission is null");
1406        }
1407
1408        int pid = Binder.getCallingPid();
1409        if (pid != Process.myPid()) {
1410            return checkPermission(permission, pid, Binder.getCallingUid());
1411        }
1412        return PackageManager.PERMISSION_DENIED;
1413    }
1414
1415    @Override
1416    public int checkCallingOrSelfPermission(String permission) {
1417        if (permission == null) {
1418            throw new IllegalArgumentException("permission is null");
1419        }
1420
1421        return checkPermission(permission, Binder.getCallingPid(),
1422                Binder.getCallingUid());
1423    }
1424
1425    @Override
1426    public int checkSelfPermission(String permission) {
1427        if (permission == null) {
1428            throw new IllegalArgumentException("permission is null");
1429        }
1430
1431        return checkPermission(permission, Process.myPid(), Process.myUid());
1432    }
1433
1434    private void enforce(
1435            String permission, int resultOfCheck,
1436            boolean selfToo, int uid, String message) {
1437        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1438            throw new SecurityException(
1439                    (message != null ? (message + ": ") : "") +
1440                    (selfToo
1441                     ? "Neither user " + uid + " nor current process has "
1442                     : "uid " + uid + " does not have ") +
1443                    permission +
1444                    ".");
1445        }
1446    }
1447
1448    @Override
1449    public void enforcePermission(
1450            String permission, int pid, int uid, String message) {
1451        enforce(permission,
1452                checkPermission(permission, pid, uid),
1453                false,
1454                uid,
1455                message);
1456    }
1457
1458    @Override
1459    public void enforceCallingPermission(String permission, String message) {
1460        enforce(permission,
1461                checkCallingPermission(permission),
1462                false,
1463                Binder.getCallingUid(),
1464                message);
1465    }
1466
1467    @Override
1468    public void enforceCallingOrSelfPermission(
1469            String permission, String message) {
1470        enforce(permission,
1471                checkCallingOrSelfPermission(permission),
1472                true,
1473                Binder.getCallingUid(),
1474                message);
1475    }
1476
1477    @Override
1478    public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1479         try {
1480            ActivityManagerNative.getDefault().grantUriPermission(
1481                    mMainThread.getApplicationThread(), toPackage,
1482                    ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
1483        } catch (RemoteException e) {
1484        }
1485    }
1486
1487    @Override
1488    public void revokeUriPermission(Uri uri, int modeFlags) {
1489         try {
1490            ActivityManagerNative.getDefault().revokeUriPermission(
1491                    mMainThread.getApplicationThread(),
1492                    ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
1493        } catch (RemoteException e) {
1494        }
1495    }
1496
1497    @Override
1498    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1499        try {
1500            return ActivityManagerNative.getDefault().checkUriPermission(
1501                    ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
1502                    resolveUserId(uri), null);
1503        } catch (RemoteException e) {
1504            return PackageManager.PERMISSION_DENIED;
1505        }
1506    }
1507
1508    /** @hide */
1509    @Override
1510    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
1511        try {
1512            return ActivityManagerNative.getDefault().checkUriPermission(
1513                    ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
1514                    resolveUserId(uri), callerToken);
1515        } catch (RemoteException e) {
1516            return PackageManager.PERMISSION_DENIED;
1517        }
1518    }
1519
1520    private int resolveUserId(Uri uri) {
1521        return ContentProvider.getUserIdFromUri(uri, getUserId());
1522    }
1523
1524    @Override
1525    public int checkCallingUriPermission(Uri uri, int modeFlags) {
1526        int pid = Binder.getCallingPid();
1527        if (pid != Process.myPid()) {
1528            return checkUriPermission(uri, pid,
1529                    Binder.getCallingUid(), modeFlags);
1530        }
1531        return PackageManager.PERMISSION_DENIED;
1532    }
1533
1534    @Override
1535    public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1536        return checkUriPermission(uri, Binder.getCallingPid(),
1537                Binder.getCallingUid(), modeFlags);
1538    }
1539
1540    @Override
1541    public int checkUriPermission(Uri uri, String readPermission,
1542            String writePermission, int pid, int uid, int modeFlags) {
1543        if (DEBUG) {
1544            Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1545                    + readPermission + " writePermission=" + writePermission
1546                    + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1547        }
1548        if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1549            if (readPermission == null
1550                    || checkPermission(readPermission, pid, uid)
1551                    == PackageManager.PERMISSION_GRANTED) {
1552                return PackageManager.PERMISSION_GRANTED;
1553            }
1554        }
1555        if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1556            if (writePermission == null
1557                    || checkPermission(writePermission, pid, uid)
1558                    == PackageManager.PERMISSION_GRANTED) {
1559                return PackageManager.PERMISSION_GRANTED;
1560            }
1561        }
1562        return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1563                : PackageManager.PERMISSION_DENIED;
1564    }
1565
1566    private String uriModeFlagToString(int uriModeFlags) {
1567        StringBuilder builder = new StringBuilder();
1568        if ((uriModeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1569            builder.append("read and ");
1570        }
1571        if ((uriModeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1572            builder.append("write and ");
1573        }
1574        if ((uriModeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
1575            builder.append("persistable and ");
1576        }
1577        if ((uriModeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
1578            builder.append("prefix and ");
1579        }
1580
1581        if (builder.length() > 5) {
1582            builder.setLength(builder.length() - 5);
1583            return builder.toString();
1584        } else {
1585            throw new IllegalArgumentException("Unknown permission mode flags: " + uriModeFlags);
1586        }
1587    }
1588
1589    private void enforceForUri(
1590            int modeFlags, int resultOfCheck, boolean selfToo,
1591            int uid, Uri uri, String message) {
1592        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1593            throw new SecurityException(
1594                    (message != null ? (message + ": ") : "") +
1595                    (selfToo
1596                     ? "Neither user " + uid + " nor current process has "
1597                     : "User " + uid + " does not have ") +
1598                    uriModeFlagToString(modeFlags) +
1599                    " permission on " +
1600                    uri +
1601                    ".");
1602        }
1603    }
1604
1605    @Override
1606    public void enforceUriPermission(
1607            Uri uri, int pid, int uid, int modeFlags, String message) {
1608        enforceForUri(
1609                modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1610                false, uid, uri, message);
1611    }
1612
1613    @Override
1614    public void enforceCallingUriPermission(
1615            Uri uri, int modeFlags, String message) {
1616        enforceForUri(
1617                modeFlags, checkCallingUriPermission(uri, modeFlags),
1618                false,
1619                Binder.getCallingUid(), uri, message);
1620    }
1621
1622    @Override
1623    public void enforceCallingOrSelfUriPermission(
1624            Uri uri, int modeFlags, String message) {
1625        enforceForUri(
1626                modeFlags,
1627                checkCallingOrSelfUriPermission(uri, modeFlags), true,
1628                Binder.getCallingUid(), uri, message);
1629    }
1630
1631    @Override
1632    public void enforceUriPermission(
1633            Uri uri, String readPermission, String writePermission,
1634            int pid, int uid, int modeFlags, String message) {
1635        enforceForUri(modeFlags,
1636                      checkUriPermission(
1637                              uri, readPermission, writePermission, pid, uid,
1638                              modeFlags),
1639                      false,
1640                      uid,
1641                      uri,
1642                      message);
1643    }
1644
1645    /**
1646     * Logs a warning if the system process directly called a method such as
1647     * {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
1648     * The "AsUser" variants allow us to properly enforce the user's restrictions.
1649     */
1650    private void warnIfCallingFromSystemProcess() {
1651        if (Process.myUid() == Process.SYSTEM_UID) {
1652            Slog.w(TAG, "Calling a method in the system process without a qualified user: "
1653                    + Debug.getCallers(5));
1654        }
1655    }
1656
1657    @Override
1658    public Context createApplicationContext(ApplicationInfo application, int flags)
1659            throws NameNotFoundException {
1660        LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
1661                flags | CONTEXT_REGISTER_PACKAGE);
1662        if (pi != null) {
1663            final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1664            ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
1665                    new UserHandle(UserHandle.getUserId(application.uid)), restricted,
1666                    mDisplay, null, Display.INVALID_DISPLAY);
1667            if (c.mResources != null) {
1668                return c;
1669            }
1670        }
1671
1672        throw new PackageManager.NameNotFoundException(
1673                "Application package " + application.packageName + " not found");
1674    }
1675
1676    @Override
1677    public Context createPackageContext(String packageName, int flags)
1678            throws NameNotFoundException {
1679        return createPackageContextAsUser(packageName, flags,
1680                mUser != null ? mUser : Process.myUserHandle());
1681    }
1682
1683    @Override
1684    public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
1685            throws NameNotFoundException {
1686        final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1687        if (packageName.equals("system") || packageName.equals("android")) {
1688            return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
1689                    user, restricted, mDisplay, null, Display.INVALID_DISPLAY);
1690        }
1691
1692        LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
1693                flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
1694        if (pi != null) {
1695            ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
1696                    user, restricted, mDisplay, null, Display.INVALID_DISPLAY);
1697            if (c.mResources != null) {
1698                return c;
1699            }
1700        }
1701
1702        // Should be a better exception.
1703        throw new PackageManager.NameNotFoundException(
1704                "Application package " + packageName + " not found");
1705    }
1706
1707    @Override
1708    public Context createConfigurationContext(Configuration overrideConfiguration) {
1709        if (overrideConfiguration == null) {
1710            throw new IllegalArgumentException("overrideConfiguration must not be null");
1711        }
1712
1713        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
1714                mUser, mRestricted, mDisplay, overrideConfiguration, Display.INVALID_DISPLAY);
1715    }
1716
1717    @Override
1718    public Context createDisplayContext(Display display) {
1719        if (display == null) {
1720            throw new IllegalArgumentException("display must not be null");
1721        }
1722
1723        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
1724                mUser, mRestricted, display, null, Display.INVALID_DISPLAY);
1725    }
1726
1727    Display getDisplay() {
1728        if (mDisplay != null) {
1729            return mDisplay;
1730        }
1731        return ResourcesManager.getInstance().getAdjustedDisplay(
1732                Display.DEFAULT_DISPLAY, mDisplayAdjustments);
1733    }
1734
1735    private int getDisplayId() {
1736        return mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
1737    }
1738
1739    @Override
1740    public boolean isRestricted() {
1741        return mRestricted;
1742    }
1743
1744    @Override
1745    public DisplayAdjustments getDisplayAdjustments(int displayId) {
1746        return mDisplayAdjustments;
1747    }
1748
1749    private File getDataDirFile() {
1750        if (mPackageInfo != null) {
1751            return mPackageInfo.getDataDirFile();
1752        }
1753        throw new RuntimeException("Not supported in system context");
1754    }
1755
1756    @Override
1757    public File getDir(String name, int mode) {
1758        name = "app_" + name;
1759        File file = makeFilename(getDataDirFile(), name);
1760        if (!file.exists()) {
1761            file.mkdir();
1762            setFilePermissionsFromMode(file.getPath(), mode,
1763                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1764        }
1765        return file;
1766    }
1767
1768    /** {@hide} */
1769    @Override
1770    public int getUserId() {
1771        return mUser.getIdentifier();
1772    }
1773
1774    static ContextImpl createSystemContext(ActivityThread mainThread) {
1775        LoadedApk packageInfo = new LoadedApk(mainThread);
1776        ContextImpl context = new ContextImpl(null, mainThread,
1777                packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
1778        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
1779                context.mResourcesManager.getDisplayMetricsLocked());
1780        return context;
1781    }
1782
1783    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
1784        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
1785        return new ContextImpl(null, mainThread,
1786                packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
1787    }
1788
1789    static ContextImpl createActivityContext(ActivityThread mainThread,
1790            LoadedApk packageInfo, int displayId, Configuration overrideConfiguration) {
1791        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
1792        return new ContextImpl(null, mainThread, packageInfo, null, null, false,
1793                null, overrideConfiguration, displayId);
1794    }
1795
1796    private ContextImpl(ContextImpl container, ActivityThread mainThread,
1797            LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
1798            Display display, Configuration overrideConfiguration, int createDisplayWithId) {
1799        mOuterContext = this;
1800
1801        mMainThread = mainThread;
1802        mActivityToken = activityToken;
1803        mRestricted = restricted;
1804
1805        if (user == null) {
1806            user = Process.myUserHandle();
1807        }
1808        mUser = user;
1809
1810        mPackageInfo = packageInfo;
1811        mResourcesManager = ResourcesManager.getInstance();
1812
1813        final int displayId = (createDisplayWithId != Display.INVALID_DISPLAY)
1814                ? createDisplayWithId
1815                : (display != null) ? display.getDisplayId() : Display.DEFAULT_DISPLAY;
1816
1817        CompatibilityInfo compatInfo = null;
1818        if (container != null) {
1819            compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo();
1820        }
1821        if (compatInfo == null) {
1822            compatInfo = (displayId == Display.DEFAULT_DISPLAY)
1823                    ? packageInfo.getCompatibilityInfo()
1824                    : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
1825        }
1826        mDisplayAdjustments.setCompatibilityInfo(compatInfo);
1827        mDisplayAdjustments.setConfiguration(overrideConfiguration);
1828
1829        mDisplay = (createDisplayWithId == Display.INVALID_DISPLAY) ? display
1830                : ResourcesManager.getInstance().getAdjustedDisplay(displayId, mDisplayAdjustments);
1831
1832        Resources resources = packageInfo.getResources(mainThread);
1833        if (resources != null) {
1834            if (displayId != Display.DEFAULT_DISPLAY
1835                    || overrideConfiguration != null
1836                    || (compatInfo != null && compatInfo.applicationScale
1837                            != resources.getCompatibilityInfo().applicationScale)) {
1838                resources = mResourcesManager.getTopLevelResources(packageInfo.getResDir(),
1839                        packageInfo.getSplitResDirs(), packageInfo.getOverlayDirs(),
1840                        packageInfo.getApplicationInfo().sharedLibraryFiles, displayId,
1841                        overrideConfiguration, compatInfo);
1842            }
1843        }
1844        mResources = resources;
1845
1846        if (container != null) {
1847            mBasePackageName = container.mBasePackageName;
1848            mOpPackageName = container.mOpPackageName;
1849        } else {
1850            mBasePackageName = packageInfo.mPackageName;
1851            ApplicationInfo ainfo = packageInfo.getApplicationInfo();
1852            if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
1853                // Special case: system components allow themselves to be loaded in to other
1854                // processes.  For purposes of app ops, we must then consider the context as
1855                // belonging to the package of this process, not the system itself, otherwise
1856                // the package+uid verifications in app ops will fail.
1857                mOpPackageName = ActivityThread.currentPackageName();
1858            } else {
1859                mOpPackageName = mBasePackageName;
1860            }
1861        }
1862
1863        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
1864    }
1865
1866    void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
1867        mPackageInfo.installSystemApplicationInfo(info, classLoader);
1868    }
1869
1870    final void scheduleFinalCleanup(String who, String what) {
1871        mMainThread.scheduleContextCleanup(this, who, what);
1872    }
1873
1874    final void performFinalCleanup(String who, String what) {
1875        //Log.i(TAG, "Cleanup up context: " + this);
1876        mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1877    }
1878
1879    final Context getReceiverRestrictedContext() {
1880        if (mReceiverRestrictedContext != null) {
1881            return mReceiverRestrictedContext;
1882        }
1883        return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1884    }
1885
1886    final void setOuterContext(Context context) {
1887        mOuterContext = context;
1888    }
1889
1890    final Context getOuterContext() {
1891        return mOuterContext;
1892    }
1893
1894    final IBinder getActivityToken() {
1895        return mActivityToken;
1896    }
1897
1898    @SuppressWarnings("deprecation")
1899    static void setFilePermissionsFromMode(String name, int mode,
1900            int extraPermissions) {
1901        int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1902            |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1903            |extraPermissions;
1904        if ((mode&MODE_WORLD_READABLE) != 0) {
1905            perms |= FileUtils.S_IROTH;
1906        }
1907        if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1908            perms |= FileUtils.S_IWOTH;
1909        }
1910        if (DEBUG) {
1911            Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1912                  + ", perms=0x" + Integer.toHexString(perms));
1913        }
1914        FileUtils.setPermissions(name, perms, -1, -1);
1915    }
1916
1917    private File validateFilePath(String name, boolean createDirectory) {
1918        File dir;
1919        File f;
1920
1921        if (name.charAt(0) == File.separatorChar) {
1922            String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1923            dir = new File(dirPath);
1924            name = name.substring(name.lastIndexOf(File.separatorChar));
1925            f = new File(dir, name);
1926        } else {
1927            dir = getDatabasesDir();
1928            f = makeFilename(dir, name);
1929        }
1930
1931        if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1932            FileUtils.setPermissions(dir.getPath(),
1933                FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1934                -1, -1);
1935        }
1936
1937        return f;
1938    }
1939
1940    private File makeFilename(File base, String name) {
1941        if (name.indexOf(File.separatorChar) < 0) {
1942            return new File(base, name);
1943        }
1944        throw new IllegalArgumentException(
1945                "File " + name + " contains a path separator");
1946    }
1947
1948    /**
1949     * Ensure that given directories exist, trying to create them if missing. If
1950     * unable to create, they are filtered by replacing with {@code null}.
1951     */
1952    private File[] ensureDirsExistOrFilter(File[] dirs) {
1953        File[] result = new File[dirs.length];
1954        for (int i = 0; i < dirs.length; i++) {
1955            File dir = dirs[i];
1956            if (!dir.exists()) {
1957                if (!dir.mkdirs()) {
1958                    // recheck existence in case of cross-process race
1959                    if (!dir.exists()) {
1960                        // Failing to mkdir() may be okay, since we might not have
1961                        // enough permissions; ask vold to create on our behalf.
1962                        final IMountService mount = IMountService.Stub.asInterface(
1963                                ServiceManager.getService("mount"));
1964                        try {
1965                            final int res = mount.mkdirs(getPackageName(), dir.getAbsolutePath());
1966                            if (res != 0) {
1967                                Log.w(TAG, "Failed to ensure " + dir + ": " + res);
1968                                dir = null;
1969                            }
1970                        } catch (Exception e) {
1971                            Log.w(TAG, "Failed to ensure " + dir + ": " + e);
1972                            dir = null;
1973                        }
1974                    }
1975                }
1976            }
1977            result[i] = dir;
1978        }
1979        return result;
1980    }
1981
1982    // ----------------------------------------------------------------------
1983    // ----------------------------------------------------------------------
1984    // ----------------------------------------------------------------------
1985
1986    private static final class ApplicationContentResolver extends ContentResolver {
1987        private final ActivityThread mMainThread;
1988        private final UserHandle mUser;
1989
1990        public ApplicationContentResolver(
1991                Context context, ActivityThread mainThread, UserHandle user) {
1992            super(context);
1993            mMainThread = Preconditions.checkNotNull(mainThread);
1994            mUser = Preconditions.checkNotNull(user);
1995        }
1996
1997        @Override
1998        protected IContentProvider acquireProvider(Context context, String auth) {
1999            return mMainThread.acquireProvider(context,
2000                    ContentProvider.getAuthorityWithoutUserId(auth),
2001                    resolveUserIdFromAuthority(auth), true);
2002        }
2003
2004        @Override
2005        protected IContentProvider acquireExistingProvider(Context context, String auth) {
2006            return mMainThread.acquireExistingProvider(context,
2007                    ContentProvider.getAuthorityWithoutUserId(auth),
2008                    resolveUserIdFromAuthority(auth), true);
2009        }
2010
2011        @Override
2012        public boolean releaseProvider(IContentProvider provider) {
2013            return mMainThread.releaseProvider(provider, true);
2014        }
2015
2016        @Override
2017        protected IContentProvider acquireUnstableProvider(Context c, String auth) {
2018            return mMainThread.acquireProvider(c,
2019                    ContentProvider.getAuthorityWithoutUserId(auth),
2020                    resolveUserIdFromAuthority(auth), false);
2021        }
2022
2023        @Override
2024        public boolean releaseUnstableProvider(IContentProvider icp) {
2025            return mMainThread.releaseProvider(icp, false);
2026        }
2027
2028        @Override
2029        public void unstableProviderDied(IContentProvider icp) {
2030            mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
2031        }
2032
2033        @Override
2034        public void appNotRespondingViaProvider(IContentProvider icp) {
2035            mMainThread.appNotRespondingViaProvider(icp.asBinder());
2036        }
2037
2038        /** @hide */
2039        protected int resolveUserIdFromAuthority(String auth) {
2040            return ContentProvider.getUserIdFromAuthority(auth, mUser.getIdentifier());
2041        }
2042    }
2043}
2044