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