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