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