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