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