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