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