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