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