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