ContextImpl.java revision f51f61269aacdfcf737b2c32b6b216c48ab61e65
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    /** @hide */
632    @Override
633    public String getBasePackageName() {
634        return mBasePackageName != null ? mBasePackageName : getPackageName();
635    }
636
637    @Override
638    public ApplicationInfo getApplicationInfo() {
639        if (mPackageInfo != null) {
640            return mPackageInfo.getApplicationInfo();
641        }
642        throw new RuntimeException("Not supported in system context");
643    }
644
645    @Override
646    public String getPackageResourcePath() {
647        if (mPackageInfo != null) {
648            return mPackageInfo.getResDir();
649        }
650        throw new RuntimeException("Not supported in system context");
651    }
652
653    @Override
654    public String getPackageCodePath() {
655        if (mPackageInfo != null) {
656            return mPackageInfo.getAppDir();
657        }
658        throw new RuntimeException("Not supported in system context");
659    }
660
661    public File getSharedPrefsFile(String name) {
662        return makeFilename(getPreferencesDir(), name + ".xml");
663    }
664
665    @Override
666    public SharedPreferences getSharedPreferences(String name, int mode) {
667        SharedPreferencesImpl sp;
668        synchronized (sSharedPrefs) {
669            sp = sSharedPrefs.get(name);
670            if (sp == null) {
671                File prefsFile = getSharedPrefsFile(name);
672                sp = new SharedPreferencesImpl(prefsFile, mode);
673                sSharedPrefs.put(name, sp);
674                return sp;
675            }
676        }
677        if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
678            getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
679            // If somebody else (some other process) changed the prefs
680            // file behind our back, we reload it.  This has been the
681            // historical (if undocumented) behavior.
682            sp.startReloadIfChangedUnexpectedly();
683        }
684        return sp;
685    }
686
687    private File getPreferencesDir() {
688        synchronized (mSync) {
689            if (mPreferencesDir == null) {
690                mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
691            }
692            return mPreferencesDir;
693        }
694    }
695
696    @Override
697    public FileInputStream openFileInput(String name)
698        throws FileNotFoundException {
699        File f = makeFilename(getFilesDir(), name);
700        return new FileInputStream(f);
701    }
702
703    @Override
704    public FileOutputStream openFileOutput(String name, int mode)
705        throws FileNotFoundException {
706        final boolean append = (mode&MODE_APPEND) != 0;
707        File f = makeFilename(getFilesDir(), name);
708        try {
709            FileOutputStream fos = new FileOutputStream(f, append);
710            setFilePermissionsFromMode(f.getPath(), mode, 0);
711            return fos;
712        } catch (FileNotFoundException e) {
713        }
714
715        File parent = f.getParentFile();
716        parent.mkdir();
717        FileUtils.setPermissions(
718            parent.getPath(),
719            FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
720            -1, -1);
721        FileOutputStream fos = new FileOutputStream(f, append);
722        setFilePermissionsFromMode(f.getPath(), mode, 0);
723        return fos;
724    }
725
726    @Override
727    public boolean deleteFile(String name) {
728        File f = makeFilename(getFilesDir(), name);
729        return f.delete();
730    }
731
732    @Override
733    public File getFilesDir() {
734        synchronized (mSync) {
735            if (mFilesDir == null) {
736                mFilesDir = new File(getDataDirFile(), "files");
737            }
738            if (!mFilesDir.exists()) {
739                if(!mFilesDir.mkdirs()) {
740                    Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
741                    return null;
742                }
743                FileUtils.setPermissions(
744                        mFilesDir.getPath(),
745                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
746                        -1, -1);
747            }
748            return mFilesDir;
749        }
750    }
751
752    @Override
753    public File getExternalFilesDir(String type) {
754        synchronized (mSync) {
755            if (mExternalFilesDir == null) {
756                mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
757                        getPackageName());
758            }
759            if (!mExternalFilesDir.exists()) {
760                try {
761                    (new File(Environment.getExternalStorageAndroidDataDir(),
762                            ".nomedia")).createNewFile();
763                } catch (IOException e) {
764                }
765                if (!mExternalFilesDir.mkdirs()) {
766                    Log.w(TAG, "Unable to create external files directory");
767                    return null;
768                }
769            }
770            if (type == null) {
771                return mExternalFilesDir;
772            }
773            File dir = new File(mExternalFilesDir, type);
774            if (!dir.exists()) {
775                if (!dir.mkdirs()) {
776                    Log.w(TAG, "Unable to create external media directory " + dir);
777                    return null;
778                }
779            }
780            return dir;
781        }
782    }
783
784    @Override
785    public File getObbDir() {
786        synchronized (mSync) {
787            if (mObbDir == null) {
788                mObbDir = Environment.getExternalStorageAppObbDirectory(
789                        getPackageName());
790            }
791            return mObbDir;
792        }
793    }
794
795    @Override
796    public File getCacheDir() {
797        synchronized (mSync) {
798            if (mCacheDir == null) {
799                mCacheDir = new File(getDataDirFile(), "cache");
800            }
801            if (!mCacheDir.exists()) {
802                if(!mCacheDir.mkdirs()) {
803                    Log.w(TAG, "Unable to create cache directory " + mCacheDir.getAbsolutePath());
804                    return null;
805                }
806                FileUtils.setPermissions(
807                        mCacheDir.getPath(),
808                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
809                        -1, -1);
810            }
811        }
812        return mCacheDir;
813    }
814
815    @Override
816    public File getExternalCacheDir() {
817        synchronized (mSync) {
818            if (mExternalCacheDir == null) {
819                mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
820                        getPackageName());
821            }
822            if (!mExternalCacheDir.exists()) {
823                try {
824                    (new File(Environment.getExternalStorageAndroidDataDir(),
825                            ".nomedia")).createNewFile();
826                } catch (IOException e) {
827                }
828                if (!mExternalCacheDir.mkdirs()) {
829                    Log.w(TAG, "Unable to create external cache directory");
830                    return null;
831                }
832            }
833            return mExternalCacheDir;
834        }
835    }
836
837    @Override
838    public File getFileStreamPath(String name) {
839        return makeFilename(getFilesDir(), name);
840    }
841
842    @Override
843    public String[] fileList() {
844        final String[] list = getFilesDir().list();
845        return (list != null) ? list : EMPTY_FILE_LIST;
846    }
847
848    @Override
849    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
850        return openOrCreateDatabase(name, mode, factory, null);
851    }
852
853    @Override
854    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
855            DatabaseErrorHandler errorHandler) {
856        File f = validateFilePath(name, true);
857        int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
858        if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
859            flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
860        }
861        SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
862        setFilePermissionsFromMode(f.getPath(), mode, 0);
863        return db;
864    }
865
866    @Override
867    public boolean deleteDatabase(String name) {
868        try {
869            File f = validateFilePath(name, false);
870            return SQLiteDatabase.deleteDatabase(f);
871        } catch (Exception e) {
872        }
873        return false;
874    }
875
876    @Override
877    public File getDatabasePath(String name) {
878        return validateFilePath(name, false);
879    }
880
881    @Override
882    public String[] databaseList() {
883        final String[] list = getDatabasesDir().list();
884        return (list != null) ? list : EMPTY_FILE_LIST;
885    }
886
887
888    private File getDatabasesDir() {
889        synchronized (mSync) {
890            if (mDatabasesDir == null) {
891                mDatabasesDir = new File(getDataDirFile(), "databases");
892            }
893            if (mDatabasesDir.getPath().equals("databases")) {
894                mDatabasesDir = new File("/data/system");
895            }
896            return mDatabasesDir;
897        }
898    }
899
900    @Override
901    public Drawable getWallpaper() {
902        return getWallpaperManager().getDrawable();
903    }
904
905    @Override
906    public Drawable peekWallpaper() {
907        return getWallpaperManager().peekDrawable();
908    }
909
910    @Override
911    public int getWallpaperDesiredMinimumWidth() {
912        return getWallpaperManager().getDesiredMinimumWidth();
913    }
914
915    @Override
916    public int getWallpaperDesiredMinimumHeight() {
917        return getWallpaperManager().getDesiredMinimumHeight();
918    }
919
920    @Override
921    public void setWallpaper(Bitmap bitmap) throws IOException  {
922        getWallpaperManager().setBitmap(bitmap);
923    }
924
925    @Override
926    public void setWallpaper(InputStream data) throws IOException {
927        getWallpaperManager().setStream(data);
928    }
929
930    @Override
931    public void clearWallpaper() throws IOException {
932        getWallpaperManager().clear();
933    }
934
935    @Override
936    public void startActivity(Intent intent) {
937        warnIfCallingFromSystemProcess();
938        startActivity(intent, null);
939    }
940
941    /** @hide */
942    @Override
943    public void startActivityAsUser(Intent intent, UserHandle user) {
944        startActivityAsUser(intent, null, user);
945    }
946
947    @Override
948    public void startActivity(Intent intent, Bundle options) {
949        warnIfCallingFromSystemProcess();
950        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
951            throw new AndroidRuntimeException(
952                    "Calling startActivity() from outside of an Activity "
953                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
954                    + " Is this really what you want?");
955        }
956        mMainThread.getInstrumentation().execStartActivity(
957            getOuterContext(), mMainThread.getApplicationThread(), null,
958            (Activity)null, intent, -1, options);
959    }
960
961    /** @hide */
962    @Override
963    public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
964        try {
965            ActivityManagerNative.getDefault().startActivityAsUser(
966                mMainThread.getApplicationThread(), getBasePackageName(), intent,
967                intent.resolveTypeIfNeeded(getContentResolver()),
968                null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, options,
969                user.getIdentifier());
970        } catch (RemoteException re) {
971        }
972    }
973
974    @Override
975    public void startActivities(Intent[] intents) {
976        warnIfCallingFromSystemProcess();
977        startActivities(intents, null);
978    }
979
980    /** @hide */
981    @Override
982    public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) {
983        if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
984            throw new AndroidRuntimeException(
985                    "Calling startActivities() from outside of an Activity "
986                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
987                    + " Is this really what you want?");
988        }
989        mMainThread.getInstrumentation().execStartActivitiesAsUser(
990            getOuterContext(), mMainThread.getApplicationThread(), null,
991            (Activity)null, intents, options, userHandle.getIdentifier());
992    }
993
994    @Override
995    public void startActivities(Intent[] intents, Bundle options) {
996        warnIfCallingFromSystemProcess();
997        if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
998            throw new AndroidRuntimeException(
999                    "Calling startActivities() from outside of an Activity "
1000                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
1001                    + " Is this really what you want?");
1002        }
1003        mMainThread.getInstrumentation().execStartActivities(
1004            getOuterContext(), mMainThread.getApplicationThread(), null,
1005            (Activity)null, intents, options);
1006    }
1007
1008    @Override
1009    public void startIntentSender(IntentSender intent,
1010            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
1011            throws IntentSender.SendIntentException {
1012        startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null);
1013    }
1014
1015    @Override
1016    public void startIntentSender(IntentSender intent, Intent fillInIntent,
1017            int flagsMask, int flagsValues, int extraFlags, Bundle options)
1018            throws IntentSender.SendIntentException {
1019        try {
1020            String resolvedType = null;
1021            if (fillInIntent != null) {
1022                fillInIntent.setAllowFds(false);
1023                resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
1024            }
1025            int result = ActivityManagerNative.getDefault()
1026                .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
1027                        fillInIntent, resolvedType, null, null,
1028                        0, flagsMask, flagsValues, options);
1029            if (result == ActivityManager.START_CANCELED) {
1030                throw new IntentSender.SendIntentException();
1031            }
1032            Instrumentation.checkStartActivityResult(result, null);
1033        } catch (RemoteException e) {
1034        }
1035    }
1036
1037    @Override
1038    public void sendBroadcast(Intent intent) {
1039        warnIfCallingFromSystemProcess();
1040        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1041        try {
1042            intent.setAllowFds(false);
1043            ActivityManagerNative.getDefault().broadcastIntent(
1044                mMainThread.getApplicationThread(), intent, resolvedType, null,
1045                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false,
1046                getUserId());
1047        } catch (RemoteException e) {
1048        }
1049    }
1050
1051    @Override
1052    public void sendBroadcast(Intent intent, String receiverPermission) {
1053        warnIfCallingFromSystemProcess();
1054        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1055        try {
1056            intent.setAllowFds(false);
1057            ActivityManagerNative.getDefault().broadcastIntent(
1058                mMainThread.getApplicationThread(), intent, resolvedType, null,
1059                Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
1060                false, false, getUserId());
1061        } catch (RemoteException e) {
1062        }
1063    }
1064
1065    @Override
1066    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
1067        warnIfCallingFromSystemProcess();
1068        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1069        try {
1070            intent.setAllowFds(false);
1071            ActivityManagerNative.getDefault().broadcastIntent(
1072                mMainThread.getApplicationThread(), intent, resolvedType, null,
1073                Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false,
1074                getUserId());
1075        } catch (RemoteException e) {
1076        }
1077    }
1078
1079    @Override
1080    public void sendOrderedBroadcast(Intent intent,
1081            String receiverPermission) {
1082        warnIfCallingFromSystemProcess();
1083        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1084        try {
1085            intent.setAllowFds(false);
1086            ActivityManagerNative.getDefault().broadcastIntent(
1087                mMainThread.getApplicationThread(), intent, resolvedType, null,
1088                Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, true, false,
1089                getUserId());
1090        } catch (RemoteException e) {
1091        }
1092    }
1093
1094    @Override
1095    public void sendOrderedBroadcast(Intent intent,
1096            String receiverPermission, BroadcastReceiver resultReceiver,
1097            Handler scheduler, int initialCode, String initialData,
1098            Bundle initialExtras) {
1099        sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
1100                resultReceiver, scheduler, initialCode, initialData, initialExtras);
1101    }
1102
1103    @Override
1104    public void sendOrderedBroadcast(Intent intent,
1105            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
1106            Handler scheduler, int initialCode, String initialData,
1107            Bundle initialExtras) {
1108        warnIfCallingFromSystemProcess();
1109        IIntentReceiver rd = null;
1110        if (resultReceiver != null) {
1111            if (mPackageInfo != null) {
1112                if (scheduler == null) {
1113                    scheduler = mMainThread.getHandler();
1114                }
1115                rd = mPackageInfo.getReceiverDispatcher(
1116                    resultReceiver, getOuterContext(), scheduler,
1117                    mMainThread.getInstrumentation(), false);
1118            } else {
1119                if (scheduler == null) {
1120                    scheduler = mMainThread.getHandler();
1121                }
1122                rd = new LoadedApk.ReceiverDispatcher(
1123                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1124            }
1125        }
1126        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1127        try {
1128            intent.setAllowFds(false);
1129            ActivityManagerNative.getDefault().broadcastIntent(
1130                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1131                initialCode, initialData, initialExtras, receiverPermission, appOp,
1132                    true, false, getUserId());
1133        } catch (RemoteException e) {
1134        }
1135    }
1136
1137    @Override
1138    public void sendBroadcastAsUser(Intent intent, UserHandle user) {
1139        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1140        try {
1141            intent.setAllowFds(false);
1142            ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
1143                    intent, resolvedType, null, Activity.RESULT_OK, null, null, null,
1144                    AppOpsManager.OP_NONE, false, false, user.getIdentifier());
1145        } catch (RemoteException e) {
1146        }
1147    }
1148
1149    @Override
1150    public void sendBroadcastAsUser(Intent intent, UserHandle user,
1151            String receiverPermission) {
1152        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1153        try {
1154            intent.setAllowFds(false);
1155            ActivityManagerNative.getDefault().broadcastIntent(
1156                mMainThread.getApplicationThread(), intent, resolvedType, null,
1157                Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, false, false,
1158                user.getIdentifier());
1159        } catch (RemoteException e) {
1160        }
1161    }
1162
1163    @Override
1164    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1165            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
1166            int initialCode, String initialData, Bundle initialExtras) {
1167        IIntentReceiver rd = null;
1168        if (resultReceiver != null) {
1169            if (mPackageInfo != null) {
1170                if (scheduler == null) {
1171                    scheduler = mMainThread.getHandler();
1172                }
1173                rd = mPackageInfo.getReceiverDispatcher(
1174                    resultReceiver, getOuterContext(), scheduler,
1175                    mMainThread.getInstrumentation(), false);
1176            } else {
1177                if (scheduler == null) {
1178                    scheduler = mMainThread.getHandler();
1179                }
1180                rd = new LoadedApk.ReceiverDispatcher(
1181                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1182            }
1183        }
1184        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1185        try {
1186            intent.setAllowFds(false);
1187            ActivityManagerNative.getDefault().broadcastIntent(
1188                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1189                initialCode, initialData, initialExtras, receiverPermission,
1190                    AppOpsManager.OP_NONE, true, false, user.getIdentifier());
1191        } catch (RemoteException e) {
1192        }
1193    }
1194
1195    @Override
1196    public void sendStickyBroadcast(Intent intent) {
1197        warnIfCallingFromSystemProcess();
1198        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1199        try {
1200            intent.setAllowFds(false);
1201            ActivityManagerNative.getDefault().broadcastIntent(
1202                mMainThread.getApplicationThread(), intent, resolvedType, null,
1203                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true,
1204                getUserId());
1205        } catch (RemoteException e) {
1206        }
1207    }
1208
1209    @Override
1210    public void sendStickyOrderedBroadcast(Intent intent,
1211            BroadcastReceiver resultReceiver,
1212            Handler scheduler, int initialCode, String initialData,
1213            Bundle initialExtras) {
1214        warnIfCallingFromSystemProcess();
1215        IIntentReceiver rd = null;
1216        if (resultReceiver != null) {
1217            if (mPackageInfo != null) {
1218                if (scheduler == null) {
1219                    scheduler = mMainThread.getHandler();
1220                }
1221                rd = mPackageInfo.getReceiverDispatcher(
1222                    resultReceiver, getOuterContext(), scheduler,
1223                    mMainThread.getInstrumentation(), false);
1224            } else {
1225                if (scheduler == null) {
1226                    scheduler = mMainThread.getHandler();
1227                }
1228                rd = new LoadedApk.ReceiverDispatcher(
1229                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1230            }
1231        }
1232        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1233        try {
1234            intent.setAllowFds(false);
1235            ActivityManagerNative.getDefault().broadcastIntent(
1236                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1237                initialCode, initialData, initialExtras, null,
1238                    AppOpsManager.OP_NONE, true, true, getUserId());
1239        } catch (RemoteException e) {
1240        }
1241    }
1242
1243    @Override
1244    public void removeStickyBroadcast(Intent intent) {
1245        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1246        if (resolvedType != null) {
1247            intent = new Intent(intent);
1248            intent.setDataAndType(intent.getData(), resolvedType);
1249        }
1250        try {
1251            intent.setAllowFds(false);
1252            ActivityManagerNative.getDefault().unbroadcastIntent(
1253                    mMainThread.getApplicationThread(), intent, getUserId());
1254        } catch (RemoteException e) {
1255        }
1256    }
1257
1258    @Override
1259    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
1260        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1261        try {
1262            intent.setAllowFds(false);
1263            ActivityManagerNative.getDefault().broadcastIntent(
1264                mMainThread.getApplicationThread(), intent, resolvedType, null,
1265                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, user.getIdentifier());
1266        } catch (RemoteException e) {
1267        }
1268    }
1269
1270    @Override
1271    public void sendStickyOrderedBroadcastAsUser(Intent intent,
1272            UserHandle user, BroadcastReceiver resultReceiver,
1273            Handler scheduler, int initialCode, String initialData,
1274            Bundle initialExtras) {
1275        IIntentReceiver rd = null;
1276        if (resultReceiver != null) {
1277            if (mPackageInfo != null) {
1278                if (scheduler == null) {
1279                    scheduler = mMainThread.getHandler();
1280                }
1281                rd = mPackageInfo.getReceiverDispatcher(
1282                    resultReceiver, getOuterContext(), scheduler,
1283                    mMainThread.getInstrumentation(), false);
1284            } else {
1285                if (scheduler == null) {
1286                    scheduler = mMainThread.getHandler();
1287                }
1288                rd = new LoadedApk.ReceiverDispatcher(
1289                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1290            }
1291        }
1292        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1293        try {
1294            intent.setAllowFds(false);
1295            ActivityManagerNative.getDefault().broadcastIntent(
1296                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1297                initialCode, initialData, initialExtras, null,
1298                    AppOpsManager.OP_NONE, true, true, user.getIdentifier());
1299        } catch (RemoteException e) {
1300        }
1301    }
1302
1303    @Override
1304    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
1305        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1306        if (resolvedType != null) {
1307            intent = new Intent(intent);
1308            intent.setDataAndType(intent.getData(), resolvedType);
1309        }
1310        try {
1311            intent.setAllowFds(false);
1312            ActivityManagerNative.getDefault().unbroadcastIntent(
1313                    mMainThread.getApplicationThread(), intent, user.getIdentifier());
1314        } catch (RemoteException e) {
1315        }
1316    }
1317
1318    @Override
1319    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1320        return registerReceiver(receiver, filter, null, null);
1321    }
1322
1323    @Override
1324    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1325            String broadcastPermission, Handler scheduler) {
1326        return registerReceiverInternal(receiver, getUserId(),
1327                filter, broadcastPermission, scheduler, getOuterContext());
1328    }
1329
1330    @Override
1331    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
1332            IntentFilter filter, String broadcastPermission, Handler scheduler) {
1333        return registerReceiverInternal(receiver, user.getIdentifier(),
1334                filter, broadcastPermission, scheduler, getOuterContext());
1335    }
1336
1337    private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
1338            IntentFilter filter, String broadcastPermission,
1339            Handler scheduler, Context context) {
1340        IIntentReceiver rd = null;
1341        if (receiver != null) {
1342            if (mPackageInfo != null && context != null) {
1343                if (scheduler == null) {
1344                    scheduler = mMainThread.getHandler();
1345                }
1346                rd = mPackageInfo.getReceiverDispatcher(
1347                    receiver, context, scheduler,
1348                    mMainThread.getInstrumentation(), true);
1349            } else {
1350                if (scheduler == null) {
1351                    scheduler = mMainThread.getHandler();
1352                }
1353                rd = new LoadedApk.ReceiverDispatcher(
1354                        receiver, context, scheduler, null, true).getIIntentReceiver();
1355            }
1356        }
1357        try {
1358            return ActivityManagerNative.getDefault().registerReceiver(
1359                    mMainThread.getApplicationThread(), mBasePackageName,
1360                    rd, filter, broadcastPermission, userId);
1361        } catch (RemoteException e) {
1362            return null;
1363        }
1364    }
1365
1366    @Override
1367    public void unregisterReceiver(BroadcastReceiver receiver) {
1368        if (mPackageInfo != null) {
1369            IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1370                    getOuterContext(), receiver);
1371            try {
1372                ActivityManagerNative.getDefault().unregisterReceiver(rd);
1373            } catch (RemoteException e) {
1374            }
1375        } else {
1376            throw new RuntimeException("Not supported in system context");
1377        }
1378    }
1379
1380    @Override
1381    public ComponentName startService(Intent service) {
1382        warnIfCallingFromSystemProcess();
1383        return startServiceAsUser(service, mUser);
1384    }
1385
1386    @Override
1387    public boolean stopService(Intent service) {
1388        warnIfCallingFromSystemProcess();
1389        return stopServiceAsUser(service, mUser);
1390    }
1391
1392    @Override
1393    public ComponentName startServiceAsUser(Intent service, UserHandle user) {
1394        try {
1395            service.setAllowFds(false);
1396            ComponentName cn = ActivityManagerNative.getDefault().startService(
1397                mMainThread.getApplicationThread(), service,
1398                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
1399            if (cn != null) {
1400                if (cn.getPackageName().equals("!")) {
1401                    throw new SecurityException(
1402                            "Not allowed to start service " + service
1403                            + " without permission " + cn.getClassName());
1404                } else if (cn.getPackageName().equals("!!")) {
1405                    throw new SecurityException(
1406                            "Unable to start service " + service
1407                            + ": " + cn.getClassName());
1408                }
1409            }
1410            return cn;
1411        } catch (RemoteException e) {
1412            return null;
1413        }
1414    }
1415
1416    @Override
1417    public boolean stopServiceAsUser(Intent service, UserHandle user) {
1418        try {
1419            service.setAllowFds(false);
1420            int res = ActivityManagerNative.getDefault().stopService(
1421                mMainThread.getApplicationThread(), service,
1422                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
1423            if (res < 0) {
1424                throw new SecurityException(
1425                        "Not allowed to stop service " + service);
1426            }
1427            return res != 0;
1428        } catch (RemoteException e) {
1429            return false;
1430        }
1431    }
1432
1433    @Override
1434    public boolean bindService(Intent service, ServiceConnection conn,
1435            int flags) {
1436        warnIfCallingFromSystemProcess();
1437        return bindServiceAsUser(service, conn, flags, Process.myUserHandle());
1438    }
1439
1440    /** @hide */
1441    @Override
1442    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
1443            UserHandle user) {
1444        IServiceConnection sd;
1445        if (conn == null) {
1446            throw new IllegalArgumentException("connection is null");
1447        }
1448        if (mPackageInfo != null) {
1449            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1450                    mMainThread.getHandler(), flags);
1451        } else {
1452            throw new RuntimeException("Not supported in system context");
1453        }
1454        try {
1455            IBinder token = getActivityToken();
1456            if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1457                    && mPackageInfo.getApplicationInfo().targetSdkVersion
1458                    < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1459                flags |= BIND_WAIVE_PRIORITY;
1460            }
1461            service.setAllowFds(false);
1462            int res = ActivityManagerNative.getDefault().bindService(
1463                mMainThread.getApplicationThread(), getActivityToken(),
1464                service, service.resolveTypeIfNeeded(getContentResolver()),
1465                sd, flags, user.getIdentifier());
1466            if (res < 0) {
1467                throw new SecurityException(
1468                        "Not allowed to bind to service " + service);
1469            }
1470            return res != 0;
1471        } catch (RemoteException e) {
1472            return false;
1473        }
1474    }
1475
1476    @Override
1477    public void unbindService(ServiceConnection conn) {
1478        if (conn == null) {
1479            throw new IllegalArgumentException("connection is null");
1480        }
1481        if (mPackageInfo != null) {
1482            IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1483                    getOuterContext(), conn);
1484            try {
1485                ActivityManagerNative.getDefault().unbindService(sd);
1486            } catch (RemoteException e) {
1487            }
1488        } else {
1489            throw new RuntimeException("Not supported in system context");
1490        }
1491    }
1492
1493    @Override
1494    public boolean startInstrumentation(ComponentName className,
1495            String profileFile, Bundle arguments) {
1496        try {
1497            if (arguments != null) {
1498                arguments.setAllowFds(false);
1499            }
1500            return ActivityManagerNative.getDefault().startInstrumentation(
1501                    className, profileFile, 0, arguments, null, null, getUserId());
1502        } catch (RemoteException e) {
1503            // System has crashed, nothing we can do.
1504        }
1505        return false;
1506    }
1507
1508    @Override
1509    public Object getSystemService(String name) {
1510        ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1511        return fetcher == null ? null : fetcher.getService(this);
1512    }
1513
1514    private WallpaperManager getWallpaperManager() {
1515        return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
1516    }
1517
1518    /* package */ static DropBoxManager createDropBoxManager() {
1519        IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1520        IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1521        if (service == null) {
1522            // Don't return a DropBoxManager that will NPE upon use.
1523            // This also avoids caching a broken DropBoxManager in
1524            // getDropBoxManager during early boot, before the
1525            // DROPBOX_SERVICE is registered.
1526            return null;
1527        }
1528        return new DropBoxManager(service);
1529    }
1530
1531    @Override
1532    public int checkPermission(String permission, int pid, int uid) {
1533        if (permission == null) {
1534            throw new IllegalArgumentException("permission is null");
1535        }
1536
1537        try {
1538            return ActivityManagerNative.getDefault().checkPermission(
1539                    permission, pid, uid);
1540        } catch (RemoteException e) {
1541            return PackageManager.PERMISSION_DENIED;
1542        }
1543    }
1544
1545    @Override
1546    public int checkCallingPermission(String permission) {
1547        if (permission == null) {
1548            throw new IllegalArgumentException("permission is null");
1549        }
1550
1551        int pid = Binder.getCallingPid();
1552        if (pid != Process.myPid()) {
1553            return checkPermission(permission, pid, Binder.getCallingUid());
1554        }
1555        return PackageManager.PERMISSION_DENIED;
1556    }
1557
1558    @Override
1559    public int checkCallingOrSelfPermission(String permission) {
1560        if (permission == null) {
1561            throw new IllegalArgumentException("permission is null");
1562        }
1563
1564        return checkPermission(permission, Binder.getCallingPid(),
1565                Binder.getCallingUid());
1566    }
1567
1568    private void enforce(
1569            String permission, int resultOfCheck,
1570            boolean selfToo, int uid, String message) {
1571        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1572            throw new SecurityException(
1573                    (message != null ? (message + ": ") : "") +
1574                    (selfToo
1575                     ? "Neither user " + uid + " nor current process has "
1576                     : "uid " + uid + " does not have ") +
1577                    permission +
1578                    ".");
1579        }
1580    }
1581
1582    public void enforcePermission(
1583            String permission, int pid, int uid, String message) {
1584        enforce(permission,
1585                checkPermission(permission, pid, uid),
1586                false,
1587                uid,
1588                message);
1589    }
1590
1591    public void enforceCallingPermission(String permission, String message) {
1592        enforce(permission,
1593                checkCallingPermission(permission),
1594                false,
1595                Binder.getCallingUid(),
1596                message);
1597    }
1598
1599    public void enforceCallingOrSelfPermission(
1600            String permission, String message) {
1601        enforce(permission,
1602                checkCallingOrSelfPermission(permission),
1603                true,
1604                Binder.getCallingUid(),
1605                message);
1606    }
1607
1608    @Override
1609    public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1610         try {
1611            ActivityManagerNative.getDefault().grantUriPermission(
1612                    mMainThread.getApplicationThread(), toPackage, uri,
1613                    modeFlags);
1614        } catch (RemoteException e) {
1615        }
1616    }
1617
1618    @Override
1619    public void revokeUriPermission(Uri uri, int modeFlags) {
1620         try {
1621            ActivityManagerNative.getDefault().revokeUriPermission(
1622                    mMainThread.getApplicationThread(), uri,
1623                    modeFlags);
1624        } catch (RemoteException e) {
1625        }
1626    }
1627
1628    @Override
1629    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1630        try {
1631            return ActivityManagerNative.getDefault().checkUriPermission(
1632                    uri, pid, uid, modeFlags);
1633        } catch (RemoteException e) {
1634            return PackageManager.PERMISSION_DENIED;
1635        }
1636    }
1637
1638    @Override
1639    public int checkCallingUriPermission(Uri uri, int modeFlags) {
1640        int pid = Binder.getCallingPid();
1641        if (pid != Process.myPid()) {
1642            return checkUriPermission(uri, pid,
1643                    Binder.getCallingUid(), modeFlags);
1644        }
1645        return PackageManager.PERMISSION_DENIED;
1646    }
1647
1648    @Override
1649    public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1650        return checkUriPermission(uri, Binder.getCallingPid(),
1651                Binder.getCallingUid(), modeFlags);
1652    }
1653
1654    @Override
1655    public int checkUriPermission(Uri uri, String readPermission,
1656            String writePermission, int pid, int uid, int modeFlags) {
1657        if (DEBUG) {
1658            Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1659                    + readPermission + " writePermission=" + writePermission
1660                    + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1661        }
1662        if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1663            if (readPermission == null
1664                    || checkPermission(readPermission, pid, uid)
1665                    == PackageManager.PERMISSION_GRANTED) {
1666                return PackageManager.PERMISSION_GRANTED;
1667            }
1668        }
1669        if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1670            if (writePermission == null
1671                    || checkPermission(writePermission, pid, uid)
1672                    == PackageManager.PERMISSION_GRANTED) {
1673                return PackageManager.PERMISSION_GRANTED;
1674            }
1675        }
1676        return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1677                : PackageManager.PERMISSION_DENIED;
1678    }
1679
1680    private String uriModeFlagToString(int uriModeFlags) {
1681        switch (uriModeFlags) {
1682            case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1683                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1684                return "read and write";
1685            case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1686                return "read";
1687            case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1688                return "write";
1689        }
1690        throw new IllegalArgumentException(
1691                "Unknown permission mode flags: " + uriModeFlags);
1692    }
1693
1694    private void enforceForUri(
1695            int modeFlags, int resultOfCheck, boolean selfToo,
1696            int uid, Uri uri, String message) {
1697        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1698            throw new SecurityException(
1699                    (message != null ? (message + ": ") : "") +
1700                    (selfToo
1701                     ? "Neither user " + uid + " nor current process has "
1702                     : "User " + uid + " does not have ") +
1703                    uriModeFlagToString(modeFlags) +
1704                    " permission on " +
1705                    uri +
1706                    ".");
1707        }
1708    }
1709
1710    public void enforceUriPermission(
1711            Uri uri, int pid, int uid, int modeFlags, String message) {
1712        enforceForUri(
1713                modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1714                false, uid, uri, message);
1715    }
1716
1717    public void enforceCallingUriPermission(
1718            Uri uri, int modeFlags, String message) {
1719        enforceForUri(
1720                modeFlags, checkCallingUriPermission(uri, modeFlags),
1721                false,
1722                Binder.getCallingUid(), uri, message);
1723    }
1724
1725    public void enforceCallingOrSelfUriPermission(
1726            Uri uri, int modeFlags, String message) {
1727        enforceForUri(
1728                modeFlags,
1729                checkCallingOrSelfUriPermission(uri, modeFlags), true,
1730                Binder.getCallingUid(), uri, message);
1731    }
1732
1733    public void enforceUriPermission(
1734            Uri uri, String readPermission, String writePermission,
1735            int pid, int uid, int modeFlags, String message) {
1736        enforceForUri(modeFlags,
1737                      checkUriPermission(
1738                              uri, readPermission, writePermission, pid, uid,
1739                              modeFlags),
1740                      false,
1741                      uid,
1742                      uri,
1743                      message);
1744    }
1745
1746    private void warnIfCallingFromSystemProcess() {
1747        if (Process.myUid() == Process.SYSTEM_UID) {
1748            Slog.w(TAG, "Calling a method in the system process without a qualified user: "
1749                    + Debug.getCallers(5));
1750        }
1751    }
1752
1753    @Override
1754    public Context createPackageContext(String packageName, int flags)
1755            throws NameNotFoundException {
1756        return createPackageContextAsUser(packageName, flags,
1757                mUser != null ? mUser : Process.myUserHandle());
1758    }
1759
1760    @Override
1761    public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
1762            throws NameNotFoundException {
1763        if (packageName.equals("system") || packageName.equals("android")) {
1764            final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
1765            context.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1766            context.init(mPackageInfo, null, mMainThread, mResources, mBasePackageName, user);
1767            return context;
1768        }
1769
1770        LoadedApk pi =
1771            mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags,
1772                    user.getIdentifier());
1773        if (pi != null) {
1774            ContextImpl c = new ContextImpl();
1775            c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1776            c.init(pi, null, mMainThread, mResources, mBasePackageName, user);
1777            if (c.mResources != null) {
1778                return c;
1779            }
1780        }
1781
1782        // Should be a better exception.
1783        throw new PackageManager.NameNotFoundException(
1784            "Application package " + packageName + " not found");
1785    }
1786
1787    @Override
1788    public Context createConfigurationContext(Configuration overrideConfiguration) {
1789        if (overrideConfiguration == null) {
1790            throw new IllegalArgumentException("overrideConfiguration must not be null");
1791        }
1792
1793        ContextImpl c = new ContextImpl();
1794        c.init(mPackageInfo, null, mMainThread);
1795        c.mResources = mMainThread.getTopLevelResources(
1796                mPackageInfo.getResDir(),
1797                getDisplayId(), overrideConfiguration,
1798                mResources.getCompatibilityInfo());
1799        return c;
1800    }
1801
1802    @Override
1803    public Context createDisplayContext(Display display) {
1804        if (display == null) {
1805            throw new IllegalArgumentException("display must not be null");
1806        }
1807
1808        int displayId = display.getDisplayId();
1809        CompatibilityInfo ci = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
1810        CompatibilityInfoHolder cih = getCompatibilityInfo(displayId);
1811        if (cih != null) {
1812            ci = cih.get();
1813        }
1814
1815        ContextImpl context = new ContextImpl();
1816        context.init(mPackageInfo, null, mMainThread);
1817        context.mDisplay = display;
1818        context.mResources = mMainThread.getTopLevelResources(
1819                mPackageInfo.getResDir(), displayId, null, ci);
1820        return context;
1821    }
1822
1823    private int getDisplayId() {
1824        return mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
1825    }
1826
1827    @Override
1828    public boolean isRestricted() {
1829        return mRestricted;
1830    }
1831
1832    @Override
1833    public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
1834        return displayId == Display.DEFAULT_DISPLAY ? mPackageInfo.mCompatibilityInfo : null;
1835    }
1836
1837    private File getDataDirFile() {
1838        if (mPackageInfo != null) {
1839            return mPackageInfo.getDataDirFile();
1840        }
1841        throw new RuntimeException("Not supported in system context");
1842    }
1843
1844    @Override
1845    public File getDir(String name, int mode) {
1846        name = "app_" + name;
1847        File file = makeFilename(getDataDirFile(), name);
1848        if (!file.exists()) {
1849            file.mkdir();
1850            setFilePermissionsFromMode(file.getPath(), mode,
1851                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1852        }
1853        return file;
1854    }
1855
1856    /** {@hide} */
1857    public int getUserId() {
1858        return mUser.getIdentifier();
1859    }
1860
1861    static ContextImpl createSystemContext(ActivityThread mainThread) {
1862        final ContextImpl context = new ContextImpl();
1863        context.init(Resources.getSystem(), mainThread, Process.myUserHandle());
1864        return context;
1865    }
1866
1867    ContextImpl() {
1868        mOuterContext = this;
1869    }
1870
1871    /**
1872     * Create a new ApplicationContext from an existing one.  The new one
1873     * works and operates the same as the one it is copying.
1874     *
1875     * @param context Existing application context.
1876     */
1877    public ContextImpl(ContextImpl context) {
1878        mPackageInfo = context.mPackageInfo;
1879        mBasePackageName = context.mBasePackageName;
1880        mResources = context.mResources;
1881        mMainThread = context.mMainThread;
1882        mContentResolver = context.mContentResolver;
1883        mUser = context.mUser;
1884        mDisplay = context.mDisplay;
1885        mOuterContext = this;
1886    }
1887
1888    final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {
1889        init(packageInfo, activityToken, mainThread, null, null, Process.myUserHandle());
1890    }
1891
1892    final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,
1893            Resources container, String basePackageName, UserHandle user) {
1894        mPackageInfo = packageInfo;
1895        mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
1896        mResources = mPackageInfo.getResources(mainThread);
1897
1898        if (mResources != null && container != null
1899                && container.getCompatibilityInfo().applicationScale !=
1900                        mResources.getCompatibilityInfo().applicationScale) {
1901            if (DEBUG) {
1902                Log.d(TAG, "loaded context has different scaling. Using container's" +
1903                        " compatiblity info:" + container.getDisplayMetrics());
1904            }
1905            mResources = mainThread.getTopLevelResources(
1906                    mPackageInfo.getResDir(), Display.DEFAULT_DISPLAY,
1907                    null, container.getCompatibilityInfo());
1908        }
1909        mMainThread = mainThread;
1910        mActivityToken = activityToken;
1911        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
1912        mUser = user;
1913    }
1914
1915    final void init(Resources resources, ActivityThread mainThread, UserHandle user) {
1916        mPackageInfo = null;
1917        mBasePackageName = null;
1918        mResources = resources;
1919        mMainThread = mainThread;
1920        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
1921        mUser = user;
1922    }
1923
1924    final void scheduleFinalCleanup(String who, String what) {
1925        mMainThread.scheduleContextCleanup(this, who, what);
1926    }
1927
1928    final void performFinalCleanup(String who, String what) {
1929        //Log.i(TAG, "Cleanup up context: " + this);
1930        mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1931    }
1932
1933    final Context getReceiverRestrictedContext() {
1934        if (mReceiverRestrictedContext != null) {
1935            return mReceiverRestrictedContext;
1936        }
1937        return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1938    }
1939
1940    final void setOuterContext(Context context) {
1941        mOuterContext = context;
1942    }
1943
1944    final Context getOuterContext() {
1945        return mOuterContext;
1946    }
1947
1948    final IBinder getActivityToken() {
1949        return mActivityToken;
1950    }
1951
1952    static void setFilePermissionsFromMode(String name, int mode,
1953            int extraPermissions) {
1954        int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1955            |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1956            |extraPermissions;
1957        if ((mode&MODE_WORLD_READABLE) != 0) {
1958            perms |= FileUtils.S_IROTH;
1959        }
1960        if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1961            perms |= FileUtils.S_IWOTH;
1962        }
1963        if (DEBUG) {
1964            Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1965                  + ", perms=0x" + Integer.toHexString(perms));
1966        }
1967        FileUtils.setPermissions(name, perms, -1, -1);
1968    }
1969
1970    private File validateFilePath(String name, boolean createDirectory) {
1971        File dir;
1972        File f;
1973
1974        if (name.charAt(0) == File.separatorChar) {
1975            String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1976            dir = new File(dirPath);
1977            name = name.substring(name.lastIndexOf(File.separatorChar));
1978            f = new File(dir, name);
1979        } else {
1980            dir = getDatabasesDir();
1981            f = makeFilename(dir, name);
1982        }
1983
1984        if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1985            FileUtils.setPermissions(dir.getPath(),
1986                FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1987                -1, -1);
1988        }
1989
1990        return f;
1991    }
1992
1993    private File makeFilename(File base, String name) {
1994        if (name.indexOf(File.separatorChar) < 0) {
1995            return new File(base, name);
1996        }
1997        throw new IllegalArgumentException(
1998                "File " + name + " contains a path separator");
1999    }
2000
2001    // ----------------------------------------------------------------------
2002    // ----------------------------------------------------------------------
2003    // ----------------------------------------------------------------------
2004
2005    private static final class ApplicationContentResolver extends ContentResolver {
2006        private final ActivityThread mMainThread;
2007        private final UserHandle mUser;
2008
2009        public ApplicationContentResolver(
2010                Context context, ActivityThread mainThread, UserHandle user) {
2011            super(context);
2012            mMainThread = Preconditions.checkNotNull(mainThread);
2013            mUser = Preconditions.checkNotNull(user);
2014        }
2015
2016        @Override
2017        protected IContentProvider acquireProvider(Context context, String auth) {
2018            return mMainThread.acquireProvider(context, auth, mUser.getIdentifier(), true);
2019        }
2020
2021        @Override
2022        protected IContentProvider acquireExistingProvider(Context context, String auth) {
2023            return mMainThread.acquireExistingProvider(context, auth, mUser.getIdentifier(), true);
2024        }
2025
2026        @Override
2027        public boolean releaseProvider(IContentProvider provider) {
2028            return mMainThread.releaseProvider(provider, true);
2029        }
2030
2031        @Override
2032        protected IContentProvider acquireUnstableProvider(Context c, String auth) {
2033            return mMainThread.acquireProvider(c, auth, mUser.getIdentifier(), false);
2034        }
2035
2036        @Override
2037        public boolean releaseUnstableProvider(IContentProvider icp) {
2038            return mMainThread.releaseProvider(icp, false);
2039        }
2040
2041        @Override
2042        public void unstableProviderDied(IContentProvider icp) {
2043            mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
2044        }
2045    }
2046}
2047