ContextImpl.java revision 1abb1cb3a8fe17f7866150604c2fd73751da787e
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 StaticServiceFetcher() {
371                public Object createStaticService() {
372                    IBinder b = ServiceManager.getService(LOCATION_SERVICE);
373                    return new LocationManager(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(ctx.mPackageInfo.mCompatibilityInfo);
493                }});
494    }
495
496    static ContextImpl getImpl(Context context) {
497        Context nextContext;
498        while ((context instanceof ContextWrapper) &&
499                (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
500            context = nextContext;
501        }
502        return (ContextImpl)context;
503    }
504
505    // The system service cache for the system services that are
506    // cached per-ContextImpl.  Package-scoped to avoid accessor
507    // methods.
508    final ArrayList<Object> mServiceCache = new ArrayList<Object>();
509
510    @Override
511    public AssetManager getAssets() {
512        return mResources.getAssets();
513    }
514
515    @Override
516    public Resources getResources() {
517        return mResources;
518    }
519
520    @Override
521    public PackageManager getPackageManager() {
522        if (mPackageManager != null) {
523            return mPackageManager;
524        }
525
526        IPackageManager pm = ActivityThread.getPackageManager();
527        if (pm != null) {
528            // Doesn't matter if we make more than one instance.
529            return (mPackageManager = new ApplicationPackageManager(this, pm));
530        }
531
532        return null;
533    }
534
535    @Override
536    public ContentResolver getContentResolver() {
537        return mContentResolver;
538    }
539
540    @Override
541    public Looper getMainLooper() {
542        return mMainThread.getLooper();
543    }
544
545    @Override
546    public Context getApplicationContext() {
547        return (mPackageInfo != null) ?
548                mPackageInfo.getApplication() : mMainThread.getApplication();
549    }
550
551    @Override
552    public void setTheme(int resid) {
553        mThemeResource = resid;
554    }
555
556    @Override
557    public int getThemeResId() {
558        return mThemeResource;
559    }
560
561    @Override
562    public Resources.Theme getTheme() {
563        if (mTheme == null) {
564            mThemeResource = Resources.selectDefaultTheme(mThemeResource,
565                    getOuterContext().getApplicationInfo().targetSdkVersion);
566            mTheme = mResources.newTheme();
567            mTheme.applyStyle(mThemeResource, true);
568        }
569        return mTheme;
570    }
571
572    @Override
573    public ClassLoader getClassLoader() {
574        return mPackageInfo != null ?
575                mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
576    }
577
578    @Override
579    public String getPackageName() {
580        if (mPackageInfo != null) {
581            return mPackageInfo.getPackageName();
582        }
583        throw new RuntimeException("Not supported in system context");
584    }
585
586    @Override
587    public ApplicationInfo getApplicationInfo() {
588        if (mPackageInfo != null) {
589            return mPackageInfo.getApplicationInfo();
590        }
591        throw new RuntimeException("Not supported in system context");
592    }
593
594    @Override
595    public String getPackageResourcePath() {
596        if (mPackageInfo != null) {
597            return mPackageInfo.getResDir();
598        }
599        throw new RuntimeException("Not supported in system context");
600    }
601
602    @Override
603    public String getPackageCodePath() {
604        if (mPackageInfo != null) {
605            return mPackageInfo.getAppDir();
606        }
607        throw new RuntimeException("Not supported in system context");
608    }
609
610    public File getSharedPrefsFile(String name) {
611        return makeFilename(getPreferencesDir(), name + ".xml");
612    }
613
614    @Override
615    public SharedPreferences getSharedPreferences(String name, int mode) {
616        SharedPreferencesImpl sp;
617        synchronized (sSharedPrefs) {
618            sp = sSharedPrefs.get(name);
619            if (sp == null) {
620                File prefsFile = getSharedPrefsFile(name);
621                sp = new SharedPreferencesImpl(prefsFile, mode);
622                sSharedPrefs.put(name, sp);
623                return sp;
624            }
625        }
626        if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
627            getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
628            // If somebody else (some other process) changed the prefs
629            // file behind our back, we reload it.  This has been the
630            // historical (if undocumented) behavior.
631            sp.startReloadIfChangedUnexpectedly();
632        }
633        return sp;
634    }
635
636    private File getPreferencesDir() {
637        synchronized (mSync) {
638            if (mPreferencesDir == null) {
639                mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
640            }
641            return mPreferencesDir;
642        }
643    }
644
645    @Override
646    public FileInputStream openFileInput(String name)
647        throws FileNotFoundException {
648        File f = makeFilename(getFilesDir(), name);
649        return new FileInputStream(f);
650    }
651
652    @Override
653    public FileOutputStream openFileOutput(String name, int mode)
654        throws FileNotFoundException {
655        final boolean append = (mode&MODE_APPEND) != 0;
656        File f = makeFilename(getFilesDir(), name);
657        try {
658            FileOutputStream fos = new FileOutputStream(f, append);
659            setFilePermissionsFromMode(f.getPath(), mode, 0);
660            return fos;
661        } catch (FileNotFoundException e) {
662        }
663
664        File parent = f.getParentFile();
665        parent.mkdir();
666        FileUtils.setPermissions(
667            parent.getPath(),
668            FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
669            -1, -1);
670        FileOutputStream fos = new FileOutputStream(f, append);
671        setFilePermissionsFromMode(f.getPath(), mode, 0);
672        return fos;
673    }
674
675    @Override
676    public boolean deleteFile(String name) {
677        File f = makeFilename(getFilesDir(), name);
678        return f.delete();
679    }
680
681    @Override
682    public File getFilesDir() {
683        synchronized (mSync) {
684            if (mFilesDir == null) {
685                mFilesDir = new File(getDataDirFile(), "files");
686            }
687            if (!mFilesDir.exists()) {
688                if(!mFilesDir.mkdirs()) {
689                    Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
690                    return null;
691                }
692                FileUtils.setPermissions(
693                        mFilesDir.getPath(),
694                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
695                        -1, -1);
696            }
697            return mFilesDir;
698        }
699    }
700
701    @Override
702    public File getExternalFilesDir(String type) {
703        synchronized (mSync) {
704            if (mExternalFilesDir == null) {
705                mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
706                        getPackageName());
707            }
708            if (!mExternalFilesDir.exists()) {
709                try {
710                    (new File(Environment.getExternalStorageAndroidDataDir(),
711                            ".nomedia")).createNewFile();
712                } catch (IOException e) {
713                }
714                if (!mExternalFilesDir.mkdirs()) {
715                    Log.w(TAG, "Unable to create external files directory");
716                    return null;
717                }
718            }
719            if (type == null) {
720                return mExternalFilesDir;
721            }
722            File dir = new File(mExternalFilesDir, type);
723            if (!dir.exists()) {
724                if (!dir.mkdirs()) {
725                    Log.w(TAG, "Unable to create external media directory " + dir);
726                    return null;
727                }
728            }
729            return dir;
730        }
731    }
732
733    @Override
734    public File getObbDir() {
735        synchronized (mSync) {
736            if (mObbDir == null) {
737                mObbDir = Environment.getExternalStorageAppObbDirectory(
738                        getPackageName());
739            }
740            return mObbDir;
741        }
742    }
743
744    @Override
745    public File getCacheDir() {
746        synchronized (mSync) {
747            if (mCacheDir == null) {
748                mCacheDir = new File(getDataDirFile(), "cache");
749            }
750            if (!mCacheDir.exists()) {
751                if(!mCacheDir.mkdirs()) {
752                    Log.w(TAG, "Unable to create cache directory");
753                    return null;
754                }
755                FileUtils.setPermissions(
756                        mCacheDir.getPath(),
757                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
758                        -1, -1);
759            }
760        }
761        return mCacheDir;
762    }
763
764    @Override
765    public File getExternalCacheDir() {
766        synchronized (mSync) {
767            if (mExternalCacheDir == null) {
768                mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
769                        getPackageName());
770            }
771            if (!mExternalCacheDir.exists()) {
772                try {
773                    (new File(Environment.getExternalStorageAndroidDataDir(),
774                            ".nomedia")).createNewFile();
775                } catch (IOException e) {
776                }
777                if (!mExternalCacheDir.mkdirs()) {
778                    Log.w(TAG, "Unable to create external cache directory");
779                    return null;
780                }
781            }
782            return mExternalCacheDir;
783        }
784    }
785
786    @Override
787    public File getFileStreamPath(String name) {
788        return makeFilename(getFilesDir(), name);
789    }
790
791    @Override
792    public String[] fileList() {
793        final String[] list = getFilesDir().list();
794        return (list != null) ? list : EMPTY_FILE_LIST;
795    }
796
797    @Override
798    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
799        return openOrCreateDatabase(name, mode, factory, null);
800    }
801
802    @Override
803    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
804            DatabaseErrorHandler errorHandler) {
805        File f = validateFilePath(name, true);
806        int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
807        if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
808            flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
809        }
810        SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
811        setFilePermissionsFromMode(f.getPath(), mode, 0);
812        return db;
813    }
814
815    @Override
816    public boolean deleteDatabase(String name) {
817        try {
818            File f = validateFilePath(name, false);
819            return SQLiteDatabase.deleteDatabase(f);
820        } catch (Exception e) {
821        }
822        return false;
823    }
824
825    @Override
826    public File getDatabasePath(String name) {
827        return validateFilePath(name, false);
828    }
829
830    @Override
831    public String[] databaseList() {
832        final String[] list = getDatabasesDir().list();
833        return (list != null) ? list : EMPTY_FILE_LIST;
834    }
835
836
837    private File getDatabasesDir() {
838        synchronized (mSync) {
839            if (mDatabasesDir == null) {
840                mDatabasesDir = new File(getDataDirFile(), "databases");
841            }
842            if (mDatabasesDir.getPath().equals("databases")) {
843                mDatabasesDir = new File("/data/system");
844            }
845            return mDatabasesDir;
846        }
847    }
848
849    @Override
850    public Drawable getWallpaper() {
851        return getWallpaperManager().getDrawable();
852    }
853
854    @Override
855    public Drawable peekWallpaper() {
856        return getWallpaperManager().peekDrawable();
857    }
858
859    @Override
860    public int getWallpaperDesiredMinimumWidth() {
861        return getWallpaperManager().getDesiredMinimumWidth();
862    }
863
864    @Override
865    public int getWallpaperDesiredMinimumHeight() {
866        return getWallpaperManager().getDesiredMinimumHeight();
867    }
868
869    @Override
870    public void setWallpaper(Bitmap bitmap) throws IOException  {
871        getWallpaperManager().setBitmap(bitmap);
872    }
873
874    @Override
875    public void setWallpaper(InputStream data) throws IOException {
876        getWallpaperManager().setStream(data);
877    }
878
879    @Override
880    public void clearWallpaper() throws IOException {
881        getWallpaperManager().clear();
882    }
883
884    @Override
885    public void startActivity(Intent intent) {
886        startActivity(intent, null);
887    }
888
889    @Override
890    public void startActivity(Intent intent, Bundle options) {
891        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
892            throw new AndroidRuntimeException(
893                    "Calling startActivity() from outside of an Activity "
894                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
895                    + " Is this really what you want?");
896        }
897        mMainThread.getInstrumentation().execStartActivity(
898            getOuterContext(), mMainThread.getApplicationThread(), null,
899            (Activity)null, intent, -1, options);
900    }
901
902    @Override
903    public void startActivities(Intent[] intents) {
904        startActivities(intents, null);
905    }
906
907    @Override
908    public void startActivities(Intent[] intents, Bundle options) {
909        if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
910            throw new AndroidRuntimeException(
911                    "Calling startActivities() from outside of an Activity "
912                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
913                    + " Is this really what you want?");
914        }
915        mMainThread.getInstrumentation().execStartActivities(
916            getOuterContext(), mMainThread.getApplicationThread(), null,
917            (Activity)null, intents, options);
918    }
919
920    @Override
921    public void startIntentSender(IntentSender intent,
922            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
923            throws IntentSender.SendIntentException {
924        startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null);
925    }
926
927    @Override
928    public void startIntentSender(IntentSender intent, Intent fillInIntent,
929            int flagsMask, int flagsValues, int extraFlags, Bundle options)
930            throws IntentSender.SendIntentException {
931        try {
932            String resolvedType = null;
933            if (fillInIntent != null) {
934                fillInIntent.setAllowFds(false);
935                resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
936            }
937            int result = ActivityManagerNative.getDefault()
938                .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
939                        fillInIntent, resolvedType, null, null,
940                        0, flagsMask, flagsValues, options);
941            if (result == ActivityManager.START_CANCELED) {
942                throw new IntentSender.SendIntentException();
943            }
944            Instrumentation.checkStartActivityResult(result, null);
945        } catch (RemoteException e) {
946        }
947    }
948
949    @Override
950    public void sendBroadcast(Intent intent) {
951        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
952        try {
953            intent.setAllowFds(false);
954            ActivityManagerNative.getDefault().broadcastIntent(
955                mMainThread.getApplicationThread(), intent, resolvedType, null,
956                Activity.RESULT_OK, null, null, null, false, false,
957                Binder.getOrigCallingUser());
958        } catch (RemoteException e) {
959        }
960    }
961
962    /** @hide */
963    @Override
964    public void sendBroadcast(Intent intent, int userId) {
965        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
966        try {
967            intent.setAllowFds(false);
968            ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
969                    intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, false,
970                    userId);
971        } catch (RemoteException e) {
972        }
973    }
974
975    @Override
976    public void sendBroadcast(Intent intent, String receiverPermission) {
977        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
978        try {
979            intent.setAllowFds(false);
980            ActivityManagerNative.getDefault().broadcastIntent(
981                mMainThread.getApplicationThread(), intent, resolvedType, null,
982                Activity.RESULT_OK, null, null, receiverPermission, false, false,
983                Binder.getOrigCallingUser());
984        } catch (RemoteException e) {
985        }
986    }
987
988    @Override
989    public void sendOrderedBroadcast(Intent intent,
990            String receiverPermission) {
991        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
992        try {
993            intent.setAllowFds(false);
994            ActivityManagerNative.getDefault().broadcastIntent(
995                mMainThread.getApplicationThread(), intent, resolvedType, null,
996                Activity.RESULT_OK, null, null, receiverPermission, true, false,
997                Binder.getOrigCallingUser());
998        } catch (RemoteException e) {
999        }
1000    }
1001
1002    @Override
1003    public void sendOrderedBroadcast(Intent intent,
1004            String receiverPermission, BroadcastReceiver resultReceiver,
1005            Handler scheduler, int initialCode, String initialData,
1006            Bundle initialExtras) {
1007        IIntentReceiver rd = null;
1008        if (resultReceiver != null) {
1009            if (mPackageInfo != null) {
1010                if (scheduler == null) {
1011                    scheduler = mMainThread.getHandler();
1012                }
1013                rd = mPackageInfo.getReceiverDispatcher(
1014                    resultReceiver, getOuterContext(), scheduler,
1015                    mMainThread.getInstrumentation(), false);
1016            } else {
1017                if (scheduler == null) {
1018                    scheduler = mMainThread.getHandler();
1019                }
1020                rd = new LoadedApk.ReceiverDispatcher(
1021                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1022            }
1023        }
1024        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1025        try {
1026            intent.setAllowFds(false);
1027            ActivityManagerNative.getDefault().broadcastIntent(
1028                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1029                initialCode, initialData, initialExtras, receiverPermission,
1030                true, false, Binder.getOrigCallingUser());
1031        } catch (RemoteException e) {
1032        }
1033    }
1034
1035    @Override
1036    public void sendStickyBroadcast(Intent intent) {
1037        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1038        try {
1039            intent.setAllowFds(false);
1040            ActivityManagerNative.getDefault().broadcastIntent(
1041                mMainThread.getApplicationThread(), intent, resolvedType, null,
1042                Activity.RESULT_OK, null, null, null, false, true,
1043                Binder.getOrigCallingUser());
1044        } catch (RemoteException e) {
1045        }
1046    }
1047
1048    @Override
1049    public void sendStickyOrderedBroadcast(Intent intent,
1050            BroadcastReceiver resultReceiver,
1051            Handler scheduler, int initialCode, String initialData,
1052            Bundle initialExtras) {
1053        IIntentReceiver rd = null;
1054        if (resultReceiver != null) {
1055            if (mPackageInfo != null) {
1056                if (scheduler == null) {
1057                    scheduler = mMainThread.getHandler();
1058                }
1059                rd = mPackageInfo.getReceiverDispatcher(
1060                    resultReceiver, getOuterContext(), scheduler,
1061                    mMainThread.getInstrumentation(), false);
1062            } else {
1063                if (scheduler == null) {
1064                    scheduler = mMainThread.getHandler();
1065                }
1066                rd = new LoadedApk.ReceiverDispatcher(
1067                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1068            }
1069        }
1070        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1071        try {
1072            intent.setAllowFds(false);
1073            ActivityManagerNative.getDefault().broadcastIntent(
1074                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1075                initialCode, initialData, initialExtras, null,
1076                true, true, Binder.getOrigCallingUser());
1077        } catch (RemoteException e) {
1078        }
1079    }
1080
1081    @Override
1082    public void removeStickyBroadcast(Intent intent) {
1083        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1084        if (resolvedType != null) {
1085            intent = new Intent(intent);
1086            intent.setDataAndType(intent.getData(), resolvedType);
1087        }
1088        try {
1089            intent.setAllowFds(false);
1090            ActivityManagerNative.getDefault().unbroadcastIntent(
1091                    mMainThread.getApplicationThread(), intent, Binder.getOrigCallingUser());
1092        } catch (RemoteException e) {
1093        }
1094    }
1095
1096    @Override
1097    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1098        return registerReceiver(receiver, filter, null, null);
1099    }
1100
1101    @Override
1102    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1103            String broadcastPermission, Handler scheduler) {
1104        return registerReceiverInternal(receiver, filter, broadcastPermission,
1105                scheduler, getOuterContext());
1106    }
1107
1108    private Intent registerReceiverInternal(BroadcastReceiver receiver,
1109            IntentFilter filter, String broadcastPermission,
1110            Handler scheduler, Context context) {
1111        IIntentReceiver rd = null;
1112        if (receiver != null) {
1113            if (mPackageInfo != null && context != null) {
1114                if (scheduler == null) {
1115                    scheduler = mMainThread.getHandler();
1116                }
1117                rd = mPackageInfo.getReceiverDispatcher(
1118                    receiver, context, scheduler,
1119                    mMainThread.getInstrumentation(), true);
1120            } else {
1121                if (scheduler == null) {
1122                    scheduler = mMainThread.getHandler();
1123                }
1124                rd = new LoadedApk.ReceiverDispatcher(
1125                        receiver, context, scheduler, null, true).getIIntentReceiver();
1126            }
1127        }
1128        try {
1129            return ActivityManagerNative.getDefault().registerReceiver(
1130                    mMainThread.getApplicationThread(), mBasePackageName,
1131                    rd, filter, broadcastPermission);
1132        } catch (RemoteException e) {
1133            return null;
1134        }
1135    }
1136
1137    @Override
1138    public void unregisterReceiver(BroadcastReceiver receiver) {
1139        if (mPackageInfo != null) {
1140            IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1141                    getOuterContext(), receiver);
1142            try {
1143                ActivityManagerNative.getDefault().unregisterReceiver(rd);
1144            } catch (RemoteException e) {
1145            }
1146        } else {
1147            throw new RuntimeException("Not supported in system context");
1148        }
1149    }
1150
1151    @Override
1152    public ComponentName startService(Intent service) {
1153        try {
1154            service.setAllowFds(false);
1155            ComponentName cn = ActivityManagerNative.getDefault().startService(
1156                mMainThread.getApplicationThread(), service,
1157                service.resolveTypeIfNeeded(getContentResolver()));
1158            if (cn != null && cn.getPackageName().equals("!")) {
1159                throw new SecurityException(
1160                        "Not allowed to start service " + service
1161                        + " without permission " + cn.getClassName());
1162            }
1163            return cn;
1164        } catch (RemoteException e) {
1165            return null;
1166        }
1167    }
1168
1169    @Override
1170    public boolean stopService(Intent service) {
1171        try {
1172            service.setAllowFds(false);
1173            int res = ActivityManagerNative.getDefault().stopService(
1174                mMainThread.getApplicationThread(), service,
1175                service.resolveTypeIfNeeded(getContentResolver()));
1176            if (res < 0) {
1177                throw new SecurityException(
1178                        "Not allowed to stop service " + service);
1179            }
1180            return res != 0;
1181        } catch (RemoteException e) {
1182            return false;
1183        }
1184    }
1185
1186    @Override
1187    public boolean bindService(Intent service, ServiceConnection conn,
1188            int flags) {
1189        return bindService(service, conn, flags, UserId.getUserId(Process.myUid()));
1190    }
1191
1192    /** @hide */
1193    @Override
1194    public boolean bindService(Intent service, ServiceConnection conn, int flags, int userId) {
1195        IServiceConnection sd;
1196        if (conn == null) {
1197            throw new IllegalArgumentException("connection is null");
1198        }
1199        if (mPackageInfo != null) {
1200            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1201                    mMainThread.getHandler(), flags);
1202        } else {
1203            throw new RuntimeException("Not supported in system context");
1204        }
1205        try {
1206            IBinder token = getActivityToken();
1207            if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1208                    && mPackageInfo.getApplicationInfo().targetSdkVersion
1209                    < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1210                flags |= BIND_WAIVE_PRIORITY;
1211            }
1212            service.setAllowFds(false);
1213            int res = ActivityManagerNative.getDefault().bindService(
1214                mMainThread.getApplicationThread(), getActivityToken(),
1215                service, service.resolveTypeIfNeeded(getContentResolver()),
1216                sd, flags, userId);
1217            if (res < 0) {
1218                throw new SecurityException(
1219                        "Not allowed to bind to service " + service);
1220            }
1221            return res != 0;
1222        } catch (RemoteException e) {
1223            return false;
1224        }
1225    }
1226
1227    @Override
1228    public void unbindService(ServiceConnection conn) {
1229        if (conn == null) {
1230            throw new IllegalArgumentException("connection is null");
1231        }
1232        if (mPackageInfo != null) {
1233            IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1234                    getOuterContext(), conn);
1235            try {
1236                ActivityManagerNative.getDefault().unbindService(sd);
1237            } catch (RemoteException e) {
1238            }
1239        } else {
1240            throw new RuntimeException("Not supported in system context");
1241        }
1242    }
1243
1244    @Override
1245    public boolean startInstrumentation(ComponentName className,
1246            String profileFile, Bundle arguments) {
1247        try {
1248            if (arguments != null) {
1249                arguments.setAllowFds(false);
1250            }
1251            return ActivityManagerNative.getDefault().startInstrumentation(
1252                    className, profileFile, 0, arguments, null);
1253        } catch (RemoteException e) {
1254            // System has crashed, nothing we can do.
1255        }
1256        return false;
1257    }
1258
1259    @Override
1260    public Object getSystemService(String name) {
1261        ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1262        return fetcher == null ? null : fetcher.getService(this);
1263    }
1264
1265    private WallpaperManager getWallpaperManager() {
1266        return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
1267    }
1268
1269    /* package */ static DropBoxManager createDropBoxManager() {
1270        IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1271        IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1272        if (service == null) {
1273            // Don't return a DropBoxManager that will NPE upon use.
1274            // This also avoids caching a broken DropBoxManager in
1275            // getDropBoxManager during early boot, before the
1276            // DROPBOX_SERVICE is registered.
1277            return null;
1278        }
1279        return new DropBoxManager(service);
1280    }
1281
1282    @Override
1283    public int checkPermission(String permission, int pid, int uid) {
1284        if (permission == null) {
1285            throw new IllegalArgumentException("permission is null");
1286        }
1287
1288        try {
1289            return ActivityManagerNative.getDefault().checkPermission(
1290                    permission, pid, uid);
1291        } catch (RemoteException e) {
1292            return PackageManager.PERMISSION_DENIED;
1293        }
1294    }
1295
1296    @Override
1297    public int checkCallingPermission(String permission) {
1298        if (permission == null) {
1299            throw new IllegalArgumentException("permission is null");
1300        }
1301
1302        int pid = Binder.getCallingPid();
1303        if (pid != Process.myPid()) {
1304            return checkPermission(permission, pid, Binder.getCallingUid());
1305        }
1306        return PackageManager.PERMISSION_DENIED;
1307    }
1308
1309    @Override
1310    public int checkCallingOrSelfPermission(String permission) {
1311        if (permission == null) {
1312            throw new IllegalArgumentException("permission is null");
1313        }
1314
1315        return checkPermission(permission, Binder.getCallingPid(),
1316                Binder.getCallingUid());
1317    }
1318
1319    private void enforce(
1320            String permission, int resultOfCheck,
1321            boolean selfToo, int uid, String message) {
1322        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1323            throw new SecurityException(
1324                    (message != null ? (message + ": ") : "") +
1325                    (selfToo
1326                     ? "Neither user " + uid + " nor current process has "
1327                     : "User " + uid + " does not have ") +
1328                    permission +
1329                    ".");
1330        }
1331    }
1332
1333    public void enforcePermission(
1334            String permission, int pid, int uid, String message) {
1335        enforce(permission,
1336                checkPermission(permission, pid, uid),
1337                false,
1338                uid,
1339                message);
1340    }
1341
1342    public void enforceCallingPermission(String permission, String message) {
1343        enforce(permission,
1344                checkCallingPermission(permission),
1345                false,
1346                Binder.getCallingUid(),
1347                message);
1348    }
1349
1350    public void enforceCallingOrSelfPermission(
1351            String permission, String message) {
1352        enforce(permission,
1353                checkCallingOrSelfPermission(permission),
1354                true,
1355                Binder.getCallingUid(),
1356                message);
1357    }
1358
1359    @Override
1360    public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1361         try {
1362            ActivityManagerNative.getDefault().grantUriPermission(
1363                    mMainThread.getApplicationThread(), toPackage, uri,
1364                    modeFlags);
1365        } catch (RemoteException e) {
1366        }
1367    }
1368
1369    @Override
1370    public void revokeUriPermission(Uri uri, int modeFlags) {
1371         try {
1372            ActivityManagerNative.getDefault().revokeUriPermission(
1373                    mMainThread.getApplicationThread(), uri,
1374                    modeFlags);
1375        } catch (RemoteException e) {
1376        }
1377    }
1378
1379    @Override
1380    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1381        try {
1382            return ActivityManagerNative.getDefault().checkUriPermission(
1383                    uri, pid, uid, modeFlags);
1384        } catch (RemoteException e) {
1385            return PackageManager.PERMISSION_DENIED;
1386        }
1387    }
1388
1389    @Override
1390    public int checkCallingUriPermission(Uri uri, int modeFlags) {
1391        int pid = Binder.getCallingPid();
1392        if (pid != Process.myPid()) {
1393            return checkUriPermission(uri, pid,
1394                    Binder.getCallingUid(), modeFlags);
1395        }
1396        return PackageManager.PERMISSION_DENIED;
1397    }
1398
1399    @Override
1400    public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1401        return checkUriPermission(uri, Binder.getCallingPid(),
1402                Binder.getCallingUid(), modeFlags);
1403    }
1404
1405    @Override
1406    public int checkUriPermission(Uri uri, String readPermission,
1407            String writePermission, int pid, int uid, int modeFlags) {
1408        if (DEBUG) {
1409            Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1410                    + readPermission + " writePermission=" + writePermission
1411                    + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1412        }
1413        if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1414            if (readPermission == null
1415                    || checkPermission(readPermission, pid, uid)
1416                    == PackageManager.PERMISSION_GRANTED) {
1417                return PackageManager.PERMISSION_GRANTED;
1418            }
1419        }
1420        if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1421            if (writePermission == null
1422                    || checkPermission(writePermission, pid, uid)
1423                    == PackageManager.PERMISSION_GRANTED) {
1424                return PackageManager.PERMISSION_GRANTED;
1425            }
1426        }
1427        return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1428                : PackageManager.PERMISSION_DENIED;
1429    }
1430
1431    private String uriModeFlagToString(int uriModeFlags) {
1432        switch (uriModeFlags) {
1433            case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1434                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1435                return "read and write";
1436            case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1437                return "read";
1438            case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1439                return "write";
1440        }
1441        throw new IllegalArgumentException(
1442                "Unknown permission mode flags: " + uriModeFlags);
1443    }
1444
1445    private void enforceForUri(
1446            int modeFlags, int resultOfCheck, boolean selfToo,
1447            int uid, Uri uri, String message) {
1448        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1449            throw new SecurityException(
1450                    (message != null ? (message + ": ") : "") +
1451                    (selfToo
1452                     ? "Neither user " + uid + " nor current process has "
1453                     : "User " + uid + " does not have ") +
1454                    uriModeFlagToString(modeFlags) +
1455                    " permission on " +
1456                    uri +
1457                    ".");
1458        }
1459    }
1460
1461    public void enforceUriPermission(
1462            Uri uri, int pid, int uid, int modeFlags, String message) {
1463        enforceForUri(
1464                modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1465                false, uid, uri, message);
1466    }
1467
1468    public void enforceCallingUriPermission(
1469            Uri uri, int modeFlags, String message) {
1470        enforceForUri(
1471                modeFlags, checkCallingUriPermission(uri, modeFlags),
1472                false,
1473                Binder.getCallingUid(), uri, message);
1474    }
1475
1476    public void enforceCallingOrSelfUriPermission(
1477            Uri uri, int modeFlags, String message) {
1478        enforceForUri(
1479                modeFlags,
1480                checkCallingOrSelfUriPermission(uri, modeFlags), true,
1481                Binder.getCallingUid(), uri, message);
1482    }
1483
1484    public void enforceUriPermission(
1485            Uri uri, String readPermission, String writePermission,
1486            int pid, int uid, int modeFlags, String message) {
1487        enforceForUri(modeFlags,
1488                      checkUriPermission(
1489                              uri, readPermission, writePermission, pid, uid,
1490                              modeFlags),
1491                      false,
1492                      uid,
1493                      uri,
1494                      message);
1495    }
1496
1497    @Override
1498    public Context createPackageContext(String packageName, int flags)
1499        throws PackageManager.NameNotFoundException {
1500        if (packageName.equals("system") || packageName.equals("android")) {
1501            final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
1502            context.mBasePackageName = mBasePackageName;
1503            return context;
1504        }
1505
1506        LoadedApk pi =
1507            mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
1508        if (pi != null) {
1509            ContextImpl c = new ContextImpl();
1510            c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1511            c.init(pi, null, mMainThread, mResources, mBasePackageName);
1512            if (c.mResources != null) {
1513                return c;
1514            }
1515        }
1516
1517        // Should be a better exception.
1518        throw new PackageManager.NameNotFoundException(
1519            "Application package " + packageName + " not found");
1520    }
1521
1522    @Override
1523    public boolean isRestricted() {
1524        return mRestricted;
1525    }
1526
1527    private File getDataDirFile() {
1528        if (mPackageInfo != null) {
1529            return mPackageInfo.getDataDirFile();
1530        }
1531        throw new RuntimeException("Not supported in system context");
1532    }
1533
1534    @Override
1535    public File getDir(String name, int mode) {
1536        name = "app_" + name;
1537        File file = makeFilename(getDataDirFile(), name);
1538        if (!file.exists()) {
1539            file.mkdir();
1540            setFilePermissionsFromMode(file.getPath(), mode,
1541                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1542        }
1543        return file;
1544    }
1545
1546    static ContextImpl createSystemContext(ActivityThread mainThread) {
1547        ContextImpl context = new ContextImpl();
1548        context.init(Resources.getSystem(), mainThread);
1549        return context;
1550    }
1551
1552    ContextImpl() {
1553        mOuterContext = this;
1554    }
1555
1556    /**
1557     * Create a new ApplicationContext from an existing one.  The new one
1558     * works and operates the same as the one it is copying.
1559     *
1560     * @param context Existing application context.
1561     */
1562    public ContextImpl(ContextImpl context) {
1563        mPackageInfo = context.mPackageInfo;
1564        mBasePackageName = context.mBasePackageName;
1565        mResources = context.mResources;
1566        mMainThread = context.mMainThread;
1567        mContentResolver = context.mContentResolver;
1568        mOuterContext = this;
1569    }
1570
1571    final void init(LoadedApk packageInfo,
1572            IBinder activityToken, ActivityThread mainThread) {
1573        init(packageInfo, activityToken, mainThread, null, null);
1574    }
1575
1576    final void init(LoadedApk packageInfo,
1577                IBinder activityToken, ActivityThread mainThread,
1578                Resources container, String basePackageName) {
1579        mPackageInfo = packageInfo;
1580        mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
1581        mResources = mPackageInfo.getResources(mainThread);
1582
1583        if (mResources != null && container != null
1584                && container.getCompatibilityInfo().applicationScale !=
1585                        mResources.getCompatibilityInfo().applicationScale) {
1586            if (DEBUG) {
1587                Log.d(TAG, "loaded context has different scaling. Using container's" +
1588                        " compatiblity info:" + container.getDisplayMetrics());
1589            }
1590            mResources = mainThread.getTopLevelResources(
1591                    mPackageInfo.getResDir(), container.getCompatibilityInfo());
1592        }
1593        mMainThread = mainThread;
1594        mContentResolver = new ApplicationContentResolver(this, mainThread);
1595
1596        setActivityToken(activityToken);
1597    }
1598
1599    final void init(Resources resources, ActivityThread mainThread) {
1600        mPackageInfo = null;
1601        mBasePackageName = null;
1602        mResources = resources;
1603        mMainThread = mainThread;
1604        mContentResolver = new ApplicationContentResolver(this, mainThread);
1605    }
1606
1607    final void scheduleFinalCleanup(String who, String what) {
1608        mMainThread.scheduleContextCleanup(this, who, what);
1609    }
1610
1611    final void performFinalCleanup(String who, String what) {
1612        //Log.i(TAG, "Cleanup up context: " + this);
1613        mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1614    }
1615
1616    final Context getReceiverRestrictedContext() {
1617        if (mReceiverRestrictedContext != null) {
1618            return mReceiverRestrictedContext;
1619        }
1620        return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1621    }
1622
1623    final void setActivityToken(IBinder token) {
1624        mActivityToken = token;
1625    }
1626
1627    final void setOuterContext(Context context) {
1628        mOuterContext = context;
1629    }
1630
1631    final Context getOuterContext() {
1632        return mOuterContext;
1633    }
1634
1635    final IBinder getActivityToken() {
1636        return mActivityToken;
1637    }
1638
1639    static void setFilePermissionsFromMode(String name, int mode,
1640            int extraPermissions) {
1641        int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1642            |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1643            |extraPermissions;
1644        if ((mode&MODE_WORLD_READABLE) != 0) {
1645            perms |= FileUtils.S_IROTH;
1646        }
1647        if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1648            perms |= FileUtils.S_IWOTH;
1649        }
1650        if (DEBUG) {
1651            Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1652                  + ", perms=0x" + Integer.toHexString(perms));
1653        }
1654        FileUtils.setPermissions(name, perms, -1, -1);
1655    }
1656
1657    private File validateFilePath(String name, boolean createDirectory) {
1658        File dir;
1659        File f;
1660
1661        if (name.charAt(0) == File.separatorChar) {
1662            String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1663            dir = new File(dirPath);
1664            name = name.substring(name.lastIndexOf(File.separatorChar));
1665            f = new File(dir, name);
1666        } else {
1667            dir = getDatabasesDir();
1668            f = makeFilename(dir, name);
1669        }
1670
1671        if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1672            FileUtils.setPermissions(dir.getPath(),
1673                FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1674                -1, -1);
1675        }
1676
1677        return f;
1678    }
1679
1680    private File makeFilename(File base, String name) {
1681        if (name.indexOf(File.separatorChar) < 0) {
1682            return new File(base, name);
1683        }
1684        throw new IllegalArgumentException(
1685                "File " + name + " contains a path separator");
1686    }
1687
1688    // ----------------------------------------------------------------------
1689    // ----------------------------------------------------------------------
1690    // ----------------------------------------------------------------------
1691
1692    private static final class ApplicationContentResolver extends ContentResolver {
1693        public ApplicationContentResolver(Context context, ActivityThread mainThread) {
1694            super(context);
1695            mMainThread = mainThread;
1696        }
1697
1698        @Override
1699        protected IContentProvider acquireProvider(Context context, String name) {
1700            return mMainThread.acquireProvider(context, name, true);
1701        }
1702
1703        @Override
1704        protected IContentProvider acquireExistingProvider(Context context, String name) {
1705            return mMainThread.acquireExistingProvider(context, name, true);
1706        }
1707
1708        @Override
1709        public boolean releaseProvider(IContentProvider provider) {
1710            return mMainThread.releaseProvider(provider, true);
1711        }
1712
1713        @Override
1714        protected IContentProvider acquireUnstableProvider(Context c, String name) {
1715            return mMainThread.acquireProvider(c, name, false);
1716        }
1717
1718        @Override
1719        public boolean releaseUnstableProvider(IContentProvider icp) {
1720            return mMainThread.releaseProvider(icp, false);
1721        }
1722
1723        @Override
1724        public void unstableProviderDied(IContentProvider icp) {
1725            mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
1726        }
1727
1728        private final ActivityThread mMainThread;
1729    }
1730}
1731