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