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