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