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