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