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