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