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