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