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