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