ContextImpl.java revision 4c14a0f13fb9f5d796b505991e0178b60efbaccf
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;
21import com.google.android.collect.Maps;
22
23import org.xmlpull.v1.XmlPullParserException;
24
25import android.content.BroadcastReceiver;
26import android.content.ComponentName;
27import android.content.ContentResolver;
28import android.content.Context;
29import android.content.ContextWrapper;
30import android.content.IContentProvider;
31import android.content.Intent;
32import android.content.IntentFilter;
33import android.content.IIntentReceiver;
34import android.content.IntentSender;
35import android.content.ReceiverCallNotAllowedException;
36import android.content.ServiceConnection;
37import android.content.SharedPreferences;
38import android.content.pm.ActivityInfo;
39import android.content.pm.ApplicationInfo;
40import android.content.pm.ComponentInfo;
41import android.content.pm.FeatureInfo;
42import android.content.pm.IPackageDataObserver;
43import android.content.pm.IPackageDeleteObserver;
44import android.content.pm.IPackageInstallObserver;
45import android.content.pm.IPackageMoveObserver;
46import android.content.pm.IPackageManager;
47import android.content.pm.IPackageStatsObserver;
48import android.content.pm.InstrumentationInfo;
49import android.content.pm.PackageInfo;
50import android.content.pm.PackageManager;
51import android.content.pm.PermissionGroupInfo;
52import android.content.pm.PermissionInfo;
53import android.content.pm.ProviderInfo;
54import android.content.pm.ResolveInfo;
55import android.content.pm.ServiceInfo;
56import android.content.res.AssetManager;
57import android.content.res.Resources;
58import android.content.res.XmlResourceParser;
59import android.database.DatabaseErrorHandler;
60import android.database.sqlite.SQLiteDatabase;
61import android.database.sqlite.SQLiteDatabase.CursorFactory;
62import android.graphics.Bitmap;
63import android.graphics.drawable.Drawable;
64import android.hardware.SensorManager;
65import android.location.ILocationManager;
66import android.location.LocationManager;
67import android.media.AudioManager;
68import android.net.ConnectivityManager;
69import android.net.IConnectivityManager;
70import android.net.DownloadManager;
71import android.net.ThrottleManager;
72import android.net.IThrottleManager;
73import android.net.Uri;
74import android.net.wifi.IWifiManager;
75import android.net.wifi.WifiManager;
76import android.os.Binder;
77import android.os.Bundle;
78import android.os.DropBoxManager;
79import android.os.Environment;
80import android.os.FileUtils;
81import android.os.Handler;
82import android.os.IBinder;
83import android.os.IPowerManager;
84import android.os.Looper;
85import android.os.PowerManager;
86import android.os.Process;
87import android.os.RemoteException;
88import android.os.ServiceManager;
89import android.os.Vibrator;
90import android.os.FileUtils.FileStatus;
91import android.os.storage.StorageManager;
92import android.telephony.TelephonyManager;
93import android.text.ClipboardManager;
94import android.util.AndroidRuntimeException;
95import android.util.Log;
96import android.view.ContextThemeWrapper;
97import android.view.LayoutInflater;
98import android.view.WindowManagerImpl;
99import android.view.accessibility.AccessibilityManager;
100import android.view.inputmethod.InputMethodManager;
101import android.accounts.AccountManager;
102import android.accounts.IAccountManager;
103import android.app.admin.DevicePolicyManager;
104
105import com.android.internal.os.IDropBoxManagerService;
106
107import java.io.File;
108import java.io.FileInputStream;
109import java.io.FileNotFoundException;
110import java.io.FileOutputStream;
111import java.io.IOException;
112import java.io.InputStream;
113import java.lang.ref.WeakReference;
114import java.util.ArrayList;
115import java.util.HashMap;
116import java.util.HashSet;
117import java.util.Iterator;
118import java.util.List;
119import java.util.Map;
120import java.util.Set;
121import java.util.WeakHashMap;
122import java.util.Map.Entry;
123
124class ReceiverRestrictedContext extends ContextWrapper {
125    ReceiverRestrictedContext(Context base) {
126        super(base);
127    }
128
129    @Override
130    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
131        return registerReceiver(receiver, filter, null, null);
132    }
133
134    @Override
135    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
136            String broadcastPermission, Handler scheduler) {
137        throw new ReceiverCallNotAllowedException(
138                "IntentReceiver components are not allowed to register to receive intents");
139        //ex.fillInStackTrace();
140        //Log.e("IntentReceiver", ex.getMessage(), ex);
141        //return mContext.registerReceiver(receiver, filter, broadcastPermission,
142        //        scheduler);
143    }
144
145    @Override
146    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
147        throw new ReceiverCallNotAllowedException(
148                "IntentReceiver components are not allowed to bind to services");
149        //ex.fillInStackTrace();
150        //Log.e("IntentReceiver", ex.getMessage(), ex);
151        //return mContext.bindService(service, interfaceName, conn, flags);
152    }
153}
154
155/**
156 * Common implementation of Context API, which provides the base
157 * context object for Activity and other application components.
158 */
159class ContextImpl extends Context {
160    private final static String TAG = "ApplicationContext";
161    private final static boolean DEBUG = false;
162    private final static boolean DEBUG_ICONS = false;
163
164    private static final Object sSync = new Object();
165    private static AlarmManager sAlarmManager;
166    private static PowerManager sPowerManager;
167    private static ConnectivityManager sConnectivityManager;
168    private static ThrottleManager sThrottleManager;
169    private static WifiManager sWifiManager;
170    private static LocationManager sLocationManager;
171    private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
172            new HashMap<File, SharedPreferencesImpl>();
173
174    private AudioManager mAudioManager;
175    /*package*/ LoadedApk mPackageInfo;
176    private Resources mResources;
177    /*package*/ ActivityThread mMainThread;
178    private Context mOuterContext;
179    private IBinder mActivityToken = null;
180    private ApplicationContentResolver mContentResolver;
181    private int mThemeResource = 0;
182    private Resources.Theme mTheme = null;
183    private PackageManager mPackageManager;
184    private NotificationManager mNotificationManager = null;
185    private ActivityManager mActivityManager = null;
186    private WallpaperManager mWallpaperManager = null;
187    private Context mReceiverRestrictedContext = null;
188    private SearchManager mSearchManager = null;
189    private SensorManager mSensorManager = null;
190    private StorageManager mStorageManager = null;
191    private Vibrator mVibrator = null;
192    private LayoutInflater mLayoutInflater = null;
193    private StatusBarManager mStatusBarManager = null;
194    private TelephonyManager mTelephonyManager = null;
195    private ClipboardManager mClipboardManager = null;
196    private boolean mRestricted;
197    private AccountManager mAccountManager; // protected by mSync
198    private DropBoxManager mDropBoxManager = null;
199    private DevicePolicyManager mDevicePolicyManager = null;
200    private UiModeManager mUiModeManager = null;
201    private DownloadManager mDownloadManager = null;
202
203    private final Object mSync = new Object();
204
205    private File mDatabasesDir;
206    private File mPreferencesDir;
207    private File mFilesDir;
208    private File mCacheDir;
209    private File mExternalFilesDir;
210    private File mExternalCacheDir;
211
212    private static long sInstanceCount = 0;
213
214    private static final String[] EMPTY_FILE_LIST = {};
215
216    // For debug only
217    /*
218    @Override
219    protected void finalize() throws Throwable {
220        super.finalize();
221        --sInstanceCount;
222    }
223    */
224
225    public static long getInstanceCount() {
226        return sInstanceCount;
227    }
228
229    @Override
230    public AssetManager getAssets() {
231        return mResources.getAssets();
232    }
233
234    @Override
235    public Resources getResources() {
236        return mResources;
237    }
238
239    @Override
240    public PackageManager getPackageManager() {
241        if (mPackageManager != null) {
242            return mPackageManager;
243        }
244
245        IPackageManager pm = ActivityThread.getPackageManager();
246        if (pm != null) {
247            // Doesn't matter if we make more than one instance.
248            return (mPackageManager = new ApplicationPackageManager(this, pm));
249        }
250
251        return null;
252    }
253
254    @Override
255    public ContentResolver getContentResolver() {
256        return mContentResolver;
257    }
258
259    @Override
260    public Looper getMainLooper() {
261        return mMainThread.getLooper();
262    }
263
264    @Override
265    public Context getApplicationContext() {
266        return (mPackageInfo != null) ?
267                mPackageInfo.getApplication() : mMainThread.getApplication();
268    }
269
270    @Override
271    public void setTheme(int resid) {
272        mThemeResource = resid;
273    }
274
275    @Override
276    public Resources.Theme getTheme() {
277        if (mTheme == null) {
278            if (mThemeResource == 0) {
279                mThemeResource = com.android.internal.R.style.Theme;
280            }
281            mTheme = mResources.newTheme();
282            mTheme.applyStyle(mThemeResource, true);
283        }
284        return mTheme;
285    }
286
287    @Override
288    public ClassLoader getClassLoader() {
289        return mPackageInfo != null ?
290                mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
291    }
292
293    @Override
294    public String getPackageName() {
295        if (mPackageInfo != null) {
296            return mPackageInfo.getPackageName();
297        }
298        throw new RuntimeException("Not supported in system context");
299    }
300
301    @Override
302    public ApplicationInfo getApplicationInfo() {
303        if (mPackageInfo != null) {
304            return mPackageInfo.getApplicationInfo();
305        }
306        throw new RuntimeException("Not supported in system context");
307    }
308
309    @Override
310    public String getPackageResourcePath() {
311        if (mPackageInfo != null) {
312            return mPackageInfo.getResDir();
313        }
314        throw new RuntimeException("Not supported in system context");
315    }
316
317    @Override
318    public String getPackageCodePath() {
319        if (mPackageInfo != null) {
320            return mPackageInfo.getAppDir();
321        }
322        throw new RuntimeException("Not supported in system context");
323    }
324
325    private static File makeBackupFile(File prefsFile) {
326        return new File(prefsFile.getPath() + ".bak");
327    }
328
329    public File getSharedPrefsFile(String name) {
330        return makeFilename(getPreferencesDir(), name + ".xml");
331    }
332
333    @Override
334    public SharedPreferences getSharedPreferences(String name, int mode) {
335        SharedPreferencesImpl sp;
336        File f = getSharedPrefsFile(name);
337        synchronized (sSharedPrefs) {
338            sp = sSharedPrefs.get(f);
339            if (sp != null && !sp.hasFileChanged()) {
340                //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
341                return sp;
342            }
343        }
344
345        FileInputStream str = null;
346        File backup = makeBackupFile(f);
347        if (backup.exists()) {
348            f.delete();
349            backup.renameTo(f);
350        }
351
352        // Debugging
353        if (f.exists() && !f.canRead()) {
354            Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
355        }
356
357        Map map = null;
358        if (f.exists() && f.canRead()) {
359            try {
360                str = new FileInputStream(f);
361                map = XmlUtils.readMapXml(str);
362                str.close();
363            } catch (org.xmlpull.v1.XmlPullParserException e) {
364                Log.w(TAG, "getSharedPreferences", e);
365            } catch (FileNotFoundException e) {
366                Log.w(TAG, "getSharedPreferences", e);
367            } catch (IOException e) {
368                Log.w(TAG, "getSharedPreferences", e);
369            }
370        }
371
372        synchronized (sSharedPrefs) {
373            if (sp != null) {
374                //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
375                sp.replace(map);
376            } else {
377                sp = sSharedPrefs.get(f);
378                if (sp == null) {
379                    sp = new SharedPreferencesImpl(f, mode, map);
380                    sSharedPrefs.put(f, sp);
381                }
382            }
383            return sp;
384        }
385    }
386
387    private File getPreferencesDir() {
388        synchronized (mSync) {
389            if (mPreferencesDir == null) {
390                mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
391            }
392            return mPreferencesDir;
393        }
394    }
395
396    @Override
397    public FileInputStream openFileInput(String name)
398        throws FileNotFoundException {
399        File f = makeFilename(getFilesDir(), name);
400        return new FileInputStream(f);
401    }
402
403    @Override
404    public FileOutputStream openFileOutput(String name, int mode)
405        throws FileNotFoundException {
406        final boolean append = (mode&MODE_APPEND) != 0;
407        File f = makeFilename(getFilesDir(), name);
408        try {
409            FileOutputStream fos = new FileOutputStream(f, append);
410            setFilePermissionsFromMode(f.getPath(), mode, 0);
411            return fos;
412        } catch (FileNotFoundException e) {
413        }
414
415        File parent = f.getParentFile();
416        parent.mkdir();
417        FileUtils.setPermissions(
418            parent.getPath(),
419            FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
420            -1, -1);
421        FileOutputStream fos = new FileOutputStream(f, append);
422        setFilePermissionsFromMode(f.getPath(), mode, 0);
423        return fos;
424    }
425
426    @Override
427    public boolean deleteFile(String name) {
428        File f = makeFilename(getFilesDir(), name);
429        return f.delete();
430    }
431
432    @Override
433    public File getFilesDir() {
434        synchronized (mSync) {
435            if (mFilesDir == null) {
436                mFilesDir = new File(getDataDirFile(), "files");
437            }
438            if (!mFilesDir.exists()) {
439                if(!mFilesDir.mkdirs()) {
440                    Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
441                    return null;
442                }
443                FileUtils.setPermissions(
444                        mFilesDir.getPath(),
445                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
446                        -1, -1);
447            }
448            return mFilesDir;
449        }
450    }
451
452    @Override
453    public File getExternalFilesDir(String type) {
454        synchronized (mSync) {
455            if (mExternalFilesDir == null) {
456                mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
457                        getPackageName());
458            }
459            if (!mExternalFilesDir.exists()) {
460                try {
461                    (new File(Environment.getExternalStorageAndroidDataDir(),
462                            ".nomedia")).createNewFile();
463                } catch (IOException e) {
464                }
465                if (!mExternalFilesDir.mkdirs()) {
466                    Log.w(TAG, "Unable to create external files directory");
467                    return null;
468                }
469            }
470            if (type == null) {
471                return mExternalFilesDir;
472            }
473            File dir = new File(mExternalFilesDir, type);
474            if (!dir.exists()) {
475                if (!dir.mkdirs()) {
476                    Log.w(TAG, "Unable to create external media directory " + dir);
477                    return null;
478                }
479            }
480            return dir;
481        }
482    }
483
484    @Override
485    public File getCacheDir() {
486        synchronized (mSync) {
487            if (mCacheDir == null) {
488                mCacheDir = new File(getDataDirFile(), "cache");
489            }
490            if (!mCacheDir.exists()) {
491                if(!mCacheDir.mkdirs()) {
492                    Log.w(TAG, "Unable to create cache directory");
493                    return null;
494                }
495                FileUtils.setPermissions(
496                        mCacheDir.getPath(),
497                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
498                        -1, -1);
499            }
500        }
501        return mCacheDir;
502    }
503
504    @Override
505    public File getExternalCacheDir() {
506        synchronized (mSync) {
507            if (mExternalCacheDir == null) {
508                mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
509                        getPackageName());
510            }
511            if (!mExternalCacheDir.exists()) {
512                try {
513                    (new File(Environment.getExternalStorageAndroidDataDir(),
514                            ".nomedia")).createNewFile();
515                } catch (IOException e) {
516                }
517                if (!mExternalCacheDir.mkdirs()) {
518                    Log.w(TAG, "Unable to create external cache directory");
519                    return null;
520                }
521            }
522            return mExternalCacheDir;
523        }
524    }
525
526    @Override
527    public File getFileStreamPath(String name) {
528        return makeFilename(getFilesDir(), name);
529    }
530
531    @Override
532    public String[] fileList() {
533        final String[] list = getFilesDir().list();
534        return (list != null) ? list : EMPTY_FILE_LIST;
535    }
536
537    @Override
538    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
539        File f = validateFilePath(name, true);
540        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
541        setFilePermissionsFromMode(f.getPath(), mode, 0);
542        return db;
543    }
544
545    @Override
546    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
547            DatabaseErrorHandler errorHandler) {
548        File f = validateFilePath(name, true);
549        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
550        setFilePermissionsFromMode(f.getPath(), mode, 0);
551        return db;
552    }
553
554    @Override
555    public boolean deleteDatabase(String name) {
556        try {
557            File f = validateFilePath(name, false);
558            return f.delete();
559        } catch (Exception e) {
560        }
561        return false;
562    }
563
564    @Override
565    public File getDatabasePath(String name) {
566        return validateFilePath(name, false);
567    }
568
569    @Override
570    public String[] databaseList() {
571        final String[] list = getDatabasesDir().list();
572        return (list != null) ? list : EMPTY_FILE_LIST;
573    }
574
575
576    private File getDatabasesDir() {
577        synchronized (mSync) {
578            if (mDatabasesDir == null) {
579                mDatabasesDir = new File(getDataDirFile(), "databases");
580            }
581            if (mDatabasesDir.getPath().equals("databases")) {
582                mDatabasesDir = new File("/data/system");
583            }
584            return mDatabasesDir;
585        }
586    }
587
588    @Override
589    public Drawable getWallpaper() {
590        return getWallpaperManager().getDrawable();
591    }
592
593    @Override
594    public Drawable peekWallpaper() {
595        return getWallpaperManager().peekDrawable();
596    }
597
598    @Override
599    public int getWallpaperDesiredMinimumWidth() {
600        return getWallpaperManager().getDesiredMinimumWidth();
601    }
602
603    @Override
604    public int getWallpaperDesiredMinimumHeight() {
605        return getWallpaperManager().getDesiredMinimumHeight();
606    }
607
608    @Override
609    public void setWallpaper(Bitmap bitmap) throws IOException  {
610        getWallpaperManager().setBitmap(bitmap);
611    }
612
613    @Override
614    public void setWallpaper(InputStream data) throws IOException {
615        getWallpaperManager().setStream(data);
616    }
617
618    @Override
619    public void clearWallpaper() throws IOException {
620        getWallpaperManager().clear();
621    }
622
623    @Override
624    public void startActivity(Intent intent) {
625        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
626            throw new AndroidRuntimeException(
627                    "Calling startActivity() from outside of an Activity "
628                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
629                    + " Is this really what you want?");
630        }
631        mMainThread.getInstrumentation().execStartActivity(
632            getOuterContext(), mMainThread.getApplicationThread(), null,
633            (Activity)null, intent, -1);
634    }
635
636    @Override
637    public void startIntentSender(IntentSender intent,
638            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
639            throws IntentSender.SendIntentException {
640        try {
641            String resolvedType = null;
642            if (fillInIntent != null) {
643                resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
644            }
645            int result = ActivityManagerNative.getDefault()
646                .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
647                        fillInIntent, resolvedType, null, null,
648                        0, flagsMask, flagsValues);
649            if (result == IActivityManager.START_CANCELED) {
650                throw new IntentSender.SendIntentException();
651            }
652            Instrumentation.checkStartActivityResult(result, null);
653        } catch (RemoteException e) {
654        }
655    }
656
657    @Override
658    public void sendBroadcast(Intent intent) {
659        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
660        try {
661            ActivityManagerNative.getDefault().broadcastIntent(
662                mMainThread.getApplicationThread(), intent, resolvedType, null,
663                Activity.RESULT_OK, null, null, null, false, false);
664        } catch (RemoteException e) {
665        }
666    }
667
668    @Override
669    public void sendBroadcast(Intent intent, String receiverPermission) {
670        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
671        try {
672            ActivityManagerNative.getDefault().broadcastIntent(
673                mMainThread.getApplicationThread(), intent, resolvedType, null,
674                Activity.RESULT_OK, null, null, receiverPermission, false, false);
675        } catch (RemoteException e) {
676        }
677    }
678
679    @Override
680    public void sendOrderedBroadcast(Intent intent,
681            String receiverPermission) {
682        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
683        try {
684            ActivityManagerNative.getDefault().broadcastIntent(
685                mMainThread.getApplicationThread(), intent, resolvedType, null,
686                Activity.RESULT_OK, null, null, receiverPermission, true, false);
687        } catch (RemoteException e) {
688        }
689    }
690
691    @Override
692    public void sendOrderedBroadcast(Intent intent,
693            String receiverPermission, BroadcastReceiver resultReceiver,
694            Handler scheduler, int initialCode, String initialData,
695            Bundle initialExtras) {
696        IIntentReceiver rd = null;
697        if (resultReceiver != null) {
698            if (mPackageInfo != null) {
699                if (scheduler == null) {
700                    scheduler = mMainThread.getHandler();
701                }
702                rd = mPackageInfo.getReceiverDispatcher(
703                    resultReceiver, getOuterContext(), scheduler,
704                    mMainThread.getInstrumentation(), false);
705            } else {
706                if (scheduler == null) {
707                    scheduler = mMainThread.getHandler();
708                }
709                rd = new LoadedApk.ReceiverDispatcher(
710                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
711            }
712        }
713        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
714        try {
715            ActivityManagerNative.getDefault().broadcastIntent(
716                mMainThread.getApplicationThread(), intent, resolvedType, rd,
717                initialCode, initialData, initialExtras, receiverPermission,
718                true, false);
719        } catch (RemoteException e) {
720        }
721    }
722
723    @Override
724    public void sendStickyBroadcast(Intent intent) {
725        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
726        try {
727            ActivityManagerNative.getDefault().broadcastIntent(
728                mMainThread.getApplicationThread(), intent, resolvedType, null,
729                Activity.RESULT_OK, null, null, null, false, true);
730        } catch (RemoteException e) {
731        }
732    }
733
734    @Override
735    public void sendStickyOrderedBroadcast(Intent intent,
736            BroadcastReceiver resultReceiver,
737            Handler scheduler, int initialCode, String initialData,
738            Bundle initialExtras) {
739        IIntentReceiver rd = null;
740        if (resultReceiver != null) {
741            if (mPackageInfo != null) {
742                if (scheduler == null) {
743                    scheduler = mMainThread.getHandler();
744                }
745                rd = mPackageInfo.getReceiverDispatcher(
746                    resultReceiver, getOuterContext(), scheduler,
747                    mMainThread.getInstrumentation(), false);
748            } else {
749                if (scheduler == null) {
750                    scheduler = mMainThread.getHandler();
751                }
752                rd = new LoadedApk.ReceiverDispatcher(
753                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
754            }
755        }
756        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
757        try {
758            ActivityManagerNative.getDefault().broadcastIntent(
759                mMainThread.getApplicationThread(), intent, resolvedType, rd,
760                initialCode, initialData, initialExtras, null,
761                true, true);
762        } catch (RemoteException e) {
763        }
764    }
765
766    @Override
767    public void removeStickyBroadcast(Intent intent) {
768        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
769        if (resolvedType != null) {
770            intent = new Intent(intent);
771            intent.setDataAndType(intent.getData(), resolvedType);
772        }
773        try {
774            ActivityManagerNative.getDefault().unbroadcastIntent(
775                mMainThread.getApplicationThread(), intent);
776        } catch (RemoteException e) {
777        }
778    }
779
780    @Override
781    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
782        return registerReceiver(receiver, filter, null, null);
783    }
784
785    @Override
786    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
787            String broadcastPermission, Handler scheduler) {
788        return registerReceiverInternal(receiver, filter, broadcastPermission,
789                scheduler, getOuterContext());
790    }
791
792    private Intent registerReceiverInternal(BroadcastReceiver receiver,
793            IntentFilter filter, String broadcastPermission,
794            Handler scheduler, Context context) {
795        IIntentReceiver rd = null;
796        if (receiver != null) {
797            if (mPackageInfo != null && context != null) {
798                if (scheduler == null) {
799                    scheduler = mMainThread.getHandler();
800                }
801                rd = mPackageInfo.getReceiverDispatcher(
802                    receiver, context, scheduler,
803                    mMainThread.getInstrumentation(), true);
804            } else {
805                if (scheduler == null) {
806                    scheduler = mMainThread.getHandler();
807                }
808                rd = new LoadedApk.ReceiverDispatcher(
809                        receiver, context, scheduler, null, true).getIIntentReceiver();
810            }
811        }
812        try {
813            return ActivityManagerNative.getDefault().registerReceiver(
814                    mMainThread.getApplicationThread(),
815                    rd, filter, broadcastPermission);
816        } catch (RemoteException e) {
817            return null;
818        }
819    }
820
821    @Override
822    public void unregisterReceiver(BroadcastReceiver receiver) {
823        if (mPackageInfo != null) {
824            IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
825                    getOuterContext(), receiver);
826            try {
827                ActivityManagerNative.getDefault().unregisterReceiver(rd);
828            } catch (RemoteException e) {
829            }
830        } else {
831            throw new RuntimeException("Not supported in system context");
832        }
833    }
834
835    @Override
836    public ComponentName startService(Intent service) {
837        try {
838            ComponentName cn = ActivityManagerNative.getDefault().startService(
839                mMainThread.getApplicationThread(), service,
840                service.resolveTypeIfNeeded(getContentResolver()));
841            if (cn != null && cn.getPackageName().equals("!")) {
842                throw new SecurityException(
843                        "Not allowed to start service " + service
844                        + " without permission " + cn.getClassName());
845            }
846            return cn;
847        } catch (RemoteException e) {
848            return null;
849        }
850    }
851
852    @Override
853    public boolean stopService(Intent service) {
854        try {
855            int res = ActivityManagerNative.getDefault().stopService(
856                mMainThread.getApplicationThread(), service,
857                service.resolveTypeIfNeeded(getContentResolver()));
858            if (res < 0) {
859                throw new SecurityException(
860                        "Not allowed to stop service " + service);
861            }
862            return res != 0;
863        } catch (RemoteException e) {
864            return false;
865        }
866    }
867
868    @Override
869    public boolean bindService(Intent service, ServiceConnection conn,
870            int flags) {
871        IServiceConnection sd;
872        if (mPackageInfo != null) {
873            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
874                    mMainThread.getHandler(), flags);
875        } else {
876            throw new RuntimeException("Not supported in system context");
877        }
878        try {
879            int res = ActivityManagerNative.getDefault().bindService(
880                mMainThread.getApplicationThread(), getActivityToken(),
881                service, service.resolveTypeIfNeeded(getContentResolver()),
882                sd, flags);
883            if (res < 0) {
884                throw new SecurityException(
885                        "Not allowed to bind to service " + service);
886            }
887            return res != 0;
888        } catch (RemoteException e) {
889            return false;
890        }
891    }
892
893    @Override
894    public void unbindService(ServiceConnection conn) {
895        if (mPackageInfo != null) {
896            IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
897                    getOuterContext(), conn);
898            try {
899                ActivityManagerNative.getDefault().unbindService(sd);
900            } catch (RemoteException e) {
901            }
902        } else {
903            throw new RuntimeException("Not supported in system context");
904        }
905    }
906
907    @Override
908    public boolean startInstrumentation(ComponentName className,
909            String profileFile, Bundle arguments) {
910        try {
911            return ActivityManagerNative.getDefault().startInstrumentation(
912                    className, profileFile, 0, arguments, null);
913        } catch (RemoteException e) {
914            // System has crashed, nothing we can do.
915        }
916        return false;
917    }
918
919    @Override
920    public Object getSystemService(String name) {
921        if (WINDOW_SERVICE.equals(name)) {
922            return WindowManagerImpl.getDefault();
923        } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
924            synchronized (mSync) {
925                LayoutInflater inflater = mLayoutInflater;
926                if (inflater != null) {
927                    return inflater;
928                }
929                mLayoutInflater = inflater =
930                    PolicyManager.makeNewLayoutInflater(getOuterContext());
931                return inflater;
932            }
933        } else if (ACTIVITY_SERVICE.equals(name)) {
934            return getActivityManager();
935        } else if (INPUT_METHOD_SERVICE.equals(name)) {
936            return InputMethodManager.getInstance(this);
937        } else if (ALARM_SERVICE.equals(name)) {
938            return getAlarmManager();
939        } else if (ACCOUNT_SERVICE.equals(name)) {
940            return getAccountManager();
941        } else if (POWER_SERVICE.equals(name)) {
942            return getPowerManager();
943        } else if (CONNECTIVITY_SERVICE.equals(name)) {
944            return getConnectivityManager();
945        } else if (THROTTLE_SERVICE.equals(name)) {
946            return getThrottleManager();
947        } else if (WIFI_SERVICE.equals(name)) {
948            return getWifiManager();
949        } else if (NOTIFICATION_SERVICE.equals(name)) {
950            return getNotificationManager();
951        } else if (KEYGUARD_SERVICE.equals(name)) {
952            return new KeyguardManager();
953        } else if (ACCESSIBILITY_SERVICE.equals(name)) {
954            return AccessibilityManager.getInstance(this);
955        } else if (LOCATION_SERVICE.equals(name)) {
956            return getLocationManager();
957        } else if (SEARCH_SERVICE.equals(name)) {
958            return getSearchManager();
959        } else if (SENSOR_SERVICE.equals(name)) {
960            return getSensorManager();
961        } else if (STORAGE_SERVICE.equals(name)) {
962            return getStorageManager();
963        } else if (VIBRATOR_SERVICE.equals(name)) {
964            return getVibrator();
965        } else if (STATUS_BAR_SERVICE.equals(name)) {
966            synchronized (mSync) {
967                if (mStatusBarManager == null) {
968                    mStatusBarManager = new StatusBarManager(getOuterContext());
969                }
970                return mStatusBarManager;
971            }
972        } else if (AUDIO_SERVICE.equals(name)) {
973            return getAudioManager();
974        } else if (TELEPHONY_SERVICE.equals(name)) {
975            return getTelephonyManager();
976        } else if (CLIPBOARD_SERVICE.equals(name)) {
977            return getClipboardManager();
978        } else if (WALLPAPER_SERVICE.equals(name)) {
979            return getWallpaperManager();
980        } else if (DROPBOX_SERVICE.equals(name)) {
981            return getDropBoxManager();
982        } else if (DEVICE_POLICY_SERVICE.equals(name)) {
983            return getDevicePolicyManager();
984        } else if (UI_MODE_SERVICE.equals(name)) {
985            return getUiModeManager();
986        } else if (DOWNLOAD_SERVICE.equals(name)) {
987            return getDownloadManager();
988        }
989
990        return null;
991    }
992
993    private AccountManager getAccountManager() {
994        synchronized (mSync) {
995            if (mAccountManager == null) {
996                IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
997                IAccountManager service = IAccountManager.Stub.asInterface(b);
998                mAccountManager = new AccountManager(this, service);
999            }
1000            return mAccountManager;
1001        }
1002    }
1003
1004    private ActivityManager getActivityManager() {
1005        synchronized (mSync) {
1006            if (mActivityManager == null) {
1007                mActivityManager = new ActivityManager(getOuterContext(),
1008                        mMainThread.getHandler());
1009            }
1010        }
1011        return mActivityManager;
1012    }
1013
1014    private AlarmManager getAlarmManager() {
1015        synchronized (sSync) {
1016            if (sAlarmManager == null) {
1017                IBinder b = ServiceManager.getService(ALARM_SERVICE);
1018                IAlarmManager service = IAlarmManager.Stub.asInterface(b);
1019                sAlarmManager = new AlarmManager(service);
1020            }
1021        }
1022        return sAlarmManager;
1023    }
1024
1025    private PowerManager getPowerManager() {
1026        synchronized (sSync) {
1027            if (sPowerManager == null) {
1028                IBinder b = ServiceManager.getService(POWER_SERVICE);
1029                IPowerManager service = IPowerManager.Stub.asInterface(b);
1030                sPowerManager = new PowerManager(service, mMainThread.getHandler());
1031            }
1032        }
1033        return sPowerManager;
1034    }
1035
1036    private ConnectivityManager getConnectivityManager()
1037    {
1038        synchronized (sSync) {
1039            if (sConnectivityManager == null) {
1040                IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
1041                IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
1042                sConnectivityManager = new ConnectivityManager(service);
1043            }
1044        }
1045        return sConnectivityManager;
1046    }
1047
1048    private ThrottleManager getThrottleManager()
1049    {
1050        synchronized (sSync) {
1051            if (sThrottleManager == null) {
1052                IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
1053                IThrottleManager service = IThrottleManager.Stub.asInterface(b);
1054                sThrottleManager = new ThrottleManager(service);
1055            }
1056        }
1057        return sThrottleManager;
1058    }
1059
1060    private WifiManager getWifiManager()
1061    {
1062        synchronized (sSync) {
1063            if (sWifiManager == null) {
1064                IBinder b = ServiceManager.getService(WIFI_SERVICE);
1065                IWifiManager service = IWifiManager.Stub.asInterface(b);
1066                sWifiManager = new WifiManager(service, mMainThread.getHandler());
1067            }
1068        }
1069        return sWifiManager;
1070    }
1071
1072    private NotificationManager getNotificationManager() {
1073        synchronized (mSync) {
1074            if (mNotificationManager == null) {
1075                mNotificationManager = new NotificationManager(
1076                        new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
1077                        mMainThread.getHandler());
1078            }
1079        }
1080        return mNotificationManager;
1081    }
1082
1083    private WallpaperManager getWallpaperManager() {
1084        synchronized (mSync) {
1085            if (mWallpaperManager == null) {
1086                mWallpaperManager = new WallpaperManager(getOuterContext(),
1087                        mMainThread.getHandler());
1088            }
1089        }
1090        return mWallpaperManager;
1091    }
1092
1093    private TelephonyManager getTelephonyManager() {
1094        synchronized (mSync) {
1095            if (mTelephonyManager == null) {
1096                mTelephonyManager = new TelephonyManager(getOuterContext());
1097            }
1098        }
1099        return mTelephonyManager;
1100    }
1101
1102    private ClipboardManager getClipboardManager() {
1103        synchronized (mSync) {
1104            if (mClipboardManager == null) {
1105                mClipboardManager = new ClipboardManager(getOuterContext(),
1106                        mMainThread.getHandler());
1107            }
1108        }
1109        return mClipboardManager;
1110    }
1111
1112    private LocationManager getLocationManager() {
1113        synchronized (sSync) {
1114            if (sLocationManager == null) {
1115                IBinder b = ServiceManager.getService(LOCATION_SERVICE);
1116                ILocationManager service = ILocationManager.Stub.asInterface(b);
1117                sLocationManager = new LocationManager(service);
1118            }
1119        }
1120        return sLocationManager;
1121    }
1122
1123    private SearchManager getSearchManager() {
1124        synchronized (mSync) {
1125            if (mSearchManager == null) {
1126                mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
1127            }
1128        }
1129        return mSearchManager;
1130    }
1131
1132    private SensorManager getSensorManager() {
1133        synchronized (mSync) {
1134            if (mSensorManager == null) {
1135                mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1136            }
1137        }
1138        return mSensorManager;
1139    }
1140
1141    private StorageManager getStorageManager() {
1142        synchronized (mSync) {
1143            if (mStorageManager == null) {
1144                try {
1145                    mStorageManager = new StorageManager(mMainThread.getHandler().getLooper());
1146                } catch (RemoteException rex) {
1147                    Log.e(TAG, "Failed to create StorageManager", rex);
1148                    mStorageManager = null;
1149                }
1150            }
1151        }
1152        return mStorageManager;
1153    }
1154
1155    private Vibrator getVibrator() {
1156        synchronized (mSync) {
1157            if (mVibrator == null) {
1158                mVibrator = new Vibrator();
1159            }
1160        }
1161        return mVibrator;
1162    }
1163
1164    private AudioManager getAudioManager()
1165    {
1166        if (mAudioManager == null) {
1167            mAudioManager = new AudioManager(this);
1168        }
1169        return mAudioManager;
1170    }
1171
1172    /* package */ static DropBoxManager createDropBoxManager() {
1173        IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1174        IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1175        return new DropBoxManager(service);
1176    }
1177
1178    private DropBoxManager getDropBoxManager() {
1179        synchronized (mSync) {
1180            if (mDropBoxManager == null) {
1181                mDropBoxManager = createDropBoxManager();
1182            }
1183        }
1184        return mDropBoxManager;
1185    }
1186
1187    private DevicePolicyManager getDevicePolicyManager() {
1188        synchronized (mSync) {
1189            if (mDevicePolicyManager == null) {
1190                mDevicePolicyManager = DevicePolicyManager.create(this,
1191                        mMainThread.getHandler());
1192            }
1193        }
1194        return mDevicePolicyManager;
1195    }
1196
1197    private UiModeManager getUiModeManager() {
1198        synchronized (mSync) {
1199            if (mUiModeManager == null) {
1200                mUiModeManager = new UiModeManager();
1201            }
1202        }
1203        return mUiModeManager;
1204    }
1205
1206    private DownloadManager getDownloadManager() {
1207        synchronized (mSync) {
1208            if (mDownloadManager == null) {
1209                mDownloadManager = new DownloadManager(getContentResolver());
1210            }
1211        }
1212        return mDownloadManager;
1213    }
1214
1215    @Override
1216    public int checkPermission(String permission, int pid, int uid) {
1217        if (permission == null) {
1218            throw new IllegalArgumentException("permission is null");
1219        }
1220
1221        if (!Process.supportsProcesses()) {
1222            return PackageManager.PERMISSION_GRANTED;
1223        }
1224        try {
1225            return ActivityManagerNative.getDefault().checkPermission(
1226                    permission, pid, uid);
1227        } catch (RemoteException e) {
1228            return PackageManager.PERMISSION_DENIED;
1229        }
1230    }
1231
1232    @Override
1233    public int checkCallingPermission(String permission) {
1234        if (permission == null) {
1235            throw new IllegalArgumentException("permission is null");
1236        }
1237
1238        if (!Process.supportsProcesses()) {
1239            return PackageManager.PERMISSION_GRANTED;
1240        }
1241        int pid = Binder.getCallingPid();
1242        if (pid != Process.myPid()) {
1243            return checkPermission(permission, pid,
1244                    Binder.getCallingUid());
1245        }
1246        return PackageManager.PERMISSION_DENIED;
1247    }
1248
1249    @Override
1250    public int checkCallingOrSelfPermission(String permission) {
1251        if (permission == null) {
1252            throw new IllegalArgumentException("permission is null");
1253        }
1254
1255        return checkPermission(permission, Binder.getCallingPid(),
1256                Binder.getCallingUid());
1257    }
1258
1259    private void enforce(
1260            String permission, int resultOfCheck,
1261            boolean selfToo, int uid, String message) {
1262        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1263            throw new SecurityException(
1264                    (message != null ? (message + ": ") : "") +
1265                    (selfToo
1266                     ? "Neither user " + uid + " nor current process has "
1267                     : "User " + uid + " does not have ") +
1268                    permission +
1269                    ".");
1270        }
1271    }
1272
1273    public void enforcePermission(
1274            String permission, int pid, int uid, String message) {
1275        enforce(permission,
1276                checkPermission(permission, pid, uid),
1277                false,
1278                uid,
1279                message);
1280    }
1281
1282    public void enforceCallingPermission(String permission, String message) {
1283        enforce(permission,
1284                checkCallingPermission(permission),
1285                false,
1286                Binder.getCallingUid(),
1287                message);
1288    }
1289
1290    public void enforceCallingOrSelfPermission(
1291            String permission, String message) {
1292        enforce(permission,
1293                checkCallingOrSelfPermission(permission),
1294                true,
1295                Binder.getCallingUid(),
1296                message);
1297    }
1298
1299    @Override
1300    public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1301         try {
1302            ActivityManagerNative.getDefault().grantUriPermission(
1303                    mMainThread.getApplicationThread(), toPackage, uri,
1304                    modeFlags);
1305        } catch (RemoteException e) {
1306        }
1307    }
1308
1309    @Override
1310    public void revokeUriPermission(Uri uri, int modeFlags) {
1311         try {
1312            ActivityManagerNative.getDefault().revokeUriPermission(
1313                    mMainThread.getApplicationThread(), uri,
1314                    modeFlags);
1315        } catch (RemoteException e) {
1316        }
1317    }
1318
1319    @Override
1320    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1321        if (!Process.supportsProcesses()) {
1322            return PackageManager.PERMISSION_GRANTED;
1323        }
1324        try {
1325            return ActivityManagerNative.getDefault().checkUriPermission(
1326                    uri, pid, uid, modeFlags);
1327        } catch (RemoteException e) {
1328            return PackageManager.PERMISSION_DENIED;
1329        }
1330    }
1331
1332    @Override
1333    public int checkCallingUriPermission(Uri uri, int modeFlags) {
1334        if (!Process.supportsProcesses()) {
1335            return PackageManager.PERMISSION_GRANTED;
1336        }
1337        int pid = Binder.getCallingPid();
1338        if (pid != Process.myPid()) {
1339            return checkUriPermission(uri, pid,
1340                    Binder.getCallingUid(), modeFlags);
1341        }
1342        return PackageManager.PERMISSION_DENIED;
1343    }
1344
1345    @Override
1346    public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1347        return checkUriPermission(uri, Binder.getCallingPid(),
1348                Binder.getCallingUid(), modeFlags);
1349    }
1350
1351    @Override
1352    public int checkUriPermission(Uri uri, String readPermission,
1353            String writePermission, int pid, int uid, int modeFlags) {
1354        if (DEBUG) {
1355            Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1356                    + readPermission + " writePermission=" + writePermission
1357                    + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1358        }
1359        if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1360            if (readPermission == null
1361                    || checkPermission(readPermission, pid, uid)
1362                    == PackageManager.PERMISSION_GRANTED) {
1363                return PackageManager.PERMISSION_GRANTED;
1364            }
1365        }
1366        if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1367            if (writePermission == null
1368                    || checkPermission(writePermission, pid, uid)
1369                    == PackageManager.PERMISSION_GRANTED) {
1370                return PackageManager.PERMISSION_GRANTED;
1371            }
1372        }
1373        return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1374                : PackageManager.PERMISSION_DENIED;
1375    }
1376
1377    private String uriModeFlagToString(int uriModeFlags) {
1378        switch (uriModeFlags) {
1379            case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1380                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1381                return "read and write";
1382            case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1383                return "read";
1384            case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1385                return "write";
1386        }
1387        throw new IllegalArgumentException(
1388                "Unknown permission mode flags: " + uriModeFlags);
1389    }
1390
1391    private void enforceForUri(
1392            int modeFlags, int resultOfCheck, boolean selfToo,
1393            int uid, Uri uri, String message) {
1394        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1395            throw new SecurityException(
1396                    (message != null ? (message + ": ") : "") +
1397                    (selfToo
1398                     ? "Neither user " + uid + " nor current process has "
1399                     : "User " + uid + " does not have ") +
1400                    uriModeFlagToString(modeFlags) +
1401                    " permission on " +
1402                    uri +
1403                    ".");
1404        }
1405    }
1406
1407    public void enforceUriPermission(
1408            Uri uri, int pid, int uid, int modeFlags, String message) {
1409        enforceForUri(
1410                modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1411                false, uid, uri, message);
1412    }
1413
1414    public void enforceCallingUriPermission(
1415            Uri uri, int modeFlags, String message) {
1416        enforceForUri(
1417                modeFlags, checkCallingUriPermission(uri, modeFlags),
1418                false, Binder.getCallingUid(), uri, message);
1419    }
1420
1421    public void enforceCallingOrSelfUriPermission(
1422            Uri uri, int modeFlags, String message) {
1423        enforceForUri(
1424                modeFlags,
1425                checkCallingOrSelfUriPermission(uri, modeFlags), true,
1426                Binder.getCallingUid(), uri, message);
1427    }
1428
1429    public void enforceUriPermission(
1430            Uri uri, String readPermission, String writePermission,
1431            int pid, int uid, int modeFlags, String message) {
1432        enforceForUri(modeFlags,
1433                      checkUriPermission(
1434                              uri, readPermission, writePermission, pid, uid,
1435                              modeFlags),
1436                      false,
1437                      uid,
1438                      uri,
1439                      message);
1440    }
1441
1442    @Override
1443    public Context createPackageContext(String packageName, int flags)
1444        throws PackageManager.NameNotFoundException {
1445        if (packageName.equals("system") || packageName.equals("android")) {
1446            return new ContextImpl(mMainThread.getSystemContext());
1447        }
1448
1449        LoadedApk pi =
1450            mMainThread.getPackageInfo(packageName, flags);
1451        if (pi != null) {
1452            ContextImpl c = new ContextImpl();
1453            c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1454            c.init(pi, null, mMainThread, mResources);
1455            if (c.mResources != null) {
1456                return c;
1457            }
1458        }
1459
1460        // Should be a better exception.
1461        throw new PackageManager.NameNotFoundException(
1462            "Application package " + packageName + " not found");
1463    }
1464
1465    @Override
1466    public boolean isRestricted() {
1467        return mRestricted;
1468    }
1469
1470    private File getDataDirFile() {
1471        if (mPackageInfo != null) {
1472            return mPackageInfo.getDataDirFile();
1473        }
1474        throw new RuntimeException("Not supported in system context");
1475    }
1476
1477    @Override
1478    public File getDir(String name, int mode) {
1479        name = "app_" + name;
1480        File file = makeFilename(getDataDirFile(), name);
1481        if (!file.exists()) {
1482            file.mkdir();
1483            setFilePermissionsFromMode(file.getPath(), mode,
1484                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1485        }
1486        return file;
1487    }
1488
1489    static ContextImpl createSystemContext(ActivityThread mainThread) {
1490        ContextImpl context = new ContextImpl();
1491        context.init(Resources.getSystem(), mainThread);
1492        return context;
1493    }
1494
1495    ContextImpl() {
1496        // For debug only
1497        //++sInstanceCount;
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        ++sInstanceCount;
1509        mPackageInfo = context.mPackageInfo;
1510        mResources = context.mResources;
1511        mMainThread = context.mMainThread;
1512        mContentResolver = context.mContentResolver;
1513        mOuterContext = this;
1514    }
1515
1516    final void init(LoadedApk packageInfo,
1517            IBinder activityToken, ActivityThread mainThread) {
1518        init(packageInfo, activityToken, mainThread, null);
1519    }
1520
1521    final void init(LoadedApk packageInfo,
1522                IBinder activityToken, ActivityThread mainThread,
1523                Resources container) {
1524        mPackageInfo = packageInfo;
1525        mResources = mPackageInfo.getResources(mainThread);
1526
1527        if (mResources != null && container != null
1528                && container.getCompatibilityInfo().applicationScale !=
1529                        mResources.getCompatibilityInfo().applicationScale) {
1530            if (DEBUG) {
1531                Log.d(TAG, "loaded context has different scaling. Using container's" +
1532                        " compatiblity info:" + container.getDisplayMetrics());
1533            }
1534            mResources = mainThread.getTopLevelResources(
1535                    mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1536        }
1537        mMainThread = mainThread;
1538        mContentResolver = new ApplicationContentResolver(this, mainThread);
1539
1540        setActivityToken(activityToken);
1541    }
1542
1543    final void init(Resources resources, ActivityThread mainThread) {
1544        mPackageInfo = null;
1545        mResources = resources;
1546        mMainThread = mainThread;
1547        mContentResolver = new ApplicationContentResolver(this, mainThread);
1548    }
1549
1550    final void scheduleFinalCleanup(String who, String what) {
1551        mMainThread.scheduleContextCleanup(this, who, what);
1552    }
1553
1554    final void performFinalCleanup(String who, String what) {
1555        //Log.i(TAG, "Cleanup up context: " + this);
1556        mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1557    }
1558
1559    final Context getReceiverRestrictedContext() {
1560        if (mReceiverRestrictedContext != null) {
1561            return mReceiverRestrictedContext;
1562        }
1563        return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1564    }
1565
1566    final void setActivityToken(IBinder token) {
1567        mActivityToken = token;
1568    }
1569
1570    final void setOuterContext(Context context) {
1571        mOuterContext = context;
1572    }
1573
1574    final Context getOuterContext() {
1575        return mOuterContext;
1576    }
1577
1578    final IBinder getActivityToken() {
1579        return mActivityToken;
1580    }
1581
1582    private static void setFilePermissionsFromMode(String name, int mode,
1583            int extraPermissions) {
1584        int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1585            |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1586            |extraPermissions;
1587        if ((mode&MODE_WORLD_READABLE) != 0) {
1588            perms |= FileUtils.S_IROTH;
1589        }
1590        if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1591            perms |= FileUtils.S_IWOTH;
1592        }
1593        if (DEBUG) {
1594            Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1595                  + ", perms=0x" + Integer.toHexString(perms));
1596        }
1597        FileUtils.setPermissions(name, perms, -1, -1);
1598    }
1599
1600    private File validateFilePath(String name, boolean createDirectory) {
1601        File dir;
1602        File f;
1603
1604        if (name.charAt(0) == File.separatorChar) {
1605            String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1606            dir = new File(dirPath);
1607            name = name.substring(name.lastIndexOf(File.separatorChar));
1608            f = new File(dir, name);
1609        } else {
1610            dir = getDatabasesDir();
1611            f = makeFilename(dir, name);
1612        }
1613
1614        if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1615            FileUtils.setPermissions(dir.getPath(),
1616                FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1617                -1, -1);
1618        }
1619
1620        return f;
1621    }
1622
1623    private File makeFilename(File base, String name) {
1624        if (name.indexOf(File.separatorChar) < 0) {
1625            return new File(base, name);
1626        }
1627        throw new IllegalArgumentException(
1628                "File " + name + " contains a path separator");
1629    }
1630
1631    // ----------------------------------------------------------------------
1632    // ----------------------------------------------------------------------
1633    // ----------------------------------------------------------------------
1634
1635    private static final class ApplicationContentResolver extends ContentResolver {
1636        public ApplicationContentResolver(Context context,
1637                                          ActivityThread mainThread)
1638        {
1639            super(context);
1640            mMainThread = mainThread;
1641        }
1642
1643        @Override
1644        protected IContentProvider acquireProvider(Context context, String name)
1645        {
1646            return mMainThread.acquireProvider(context, name);
1647        }
1648
1649        @Override
1650        public boolean releaseProvider(IContentProvider provider)
1651        {
1652            return mMainThread.releaseProvider(provider);
1653        }
1654
1655        private final ActivityThread mMainThread;
1656    }
1657
1658    // ----------------------------------------------------------------------
1659    // ----------------------------------------------------------------------
1660    // ----------------------------------------------------------------------
1661
1662    /*package*/
1663    static final class ApplicationPackageManager extends PackageManager {
1664        @Override
1665        public PackageInfo getPackageInfo(String packageName, int flags)
1666                throws NameNotFoundException {
1667            try {
1668                PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1669                if (pi != null) {
1670                    return pi;
1671                }
1672            } catch (RemoteException e) {
1673                throw new RuntimeException("Package manager has died", e);
1674            }
1675
1676            throw new NameNotFoundException(packageName);
1677        }
1678
1679        @Override
1680        public String[] currentToCanonicalPackageNames(String[] names) {
1681            try {
1682                return mPM.currentToCanonicalPackageNames(names);
1683            } catch (RemoteException e) {
1684                throw new RuntimeException("Package manager has died", e);
1685            }
1686        }
1687
1688        @Override
1689        public String[] canonicalToCurrentPackageNames(String[] names) {
1690            try {
1691                return mPM.canonicalToCurrentPackageNames(names);
1692            } catch (RemoteException e) {
1693                throw new RuntimeException("Package manager has died", e);
1694            }
1695        }
1696
1697        @Override
1698        public Intent getLaunchIntentForPackage(String packageName) {
1699            // First see if the package has an INFO activity; the existence of
1700            // such an activity is implied to be the desired front-door for the
1701            // overall package (such as if it has multiple launcher entries).
1702            Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1703            intentToResolve.addCategory(Intent.CATEGORY_INFO);
1704            intentToResolve.setPackage(packageName);
1705            ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
1706
1707            // Otherwise, try to find a main launcher activity.
1708            if (resolveInfo == null) {
1709                // reuse the intent instance
1710                intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1711                intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
1712                intentToResolve.setPackage(packageName);
1713                resolveInfo = resolveActivity(intentToResolve, 0);
1714            }
1715            if (resolveInfo == null) {
1716                return null;
1717            }
1718            Intent intent = new Intent(Intent.ACTION_MAIN);
1719            intent.setClassName(packageName, resolveInfo.activityInfo.name);
1720            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1721            return intent;
1722        }
1723
1724        @Override
1725        public int[] getPackageGids(String packageName)
1726            throws NameNotFoundException {
1727            try {
1728                int[] gids = mPM.getPackageGids(packageName);
1729                if (gids == null || gids.length > 0) {
1730                    return gids;
1731                }
1732            } catch (RemoteException e) {
1733                throw new RuntimeException("Package manager has died", e);
1734            }
1735
1736            throw new NameNotFoundException(packageName);
1737        }
1738
1739        @Override
1740        public PermissionInfo getPermissionInfo(String name, int flags)
1741            throws NameNotFoundException {
1742            try {
1743                PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1744                if (pi != null) {
1745                    return pi;
1746                }
1747            } catch (RemoteException e) {
1748                throw new RuntimeException("Package manager has died", e);
1749            }
1750
1751            throw new NameNotFoundException(name);
1752        }
1753
1754        @Override
1755        public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1756                throws NameNotFoundException {
1757            try {
1758                List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1759                if (pi != null) {
1760                    return pi;
1761                }
1762            } catch (RemoteException e) {
1763                throw new RuntimeException("Package manager has died", e);
1764            }
1765
1766            throw new NameNotFoundException(group);
1767        }
1768
1769        @Override
1770        public PermissionGroupInfo getPermissionGroupInfo(String name,
1771                int flags) throws NameNotFoundException {
1772            try {
1773                PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1774                if (pgi != null) {
1775                    return pgi;
1776                }
1777            } catch (RemoteException e) {
1778                throw new RuntimeException("Package manager has died", e);
1779            }
1780
1781            throw new NameNotFoundException(name);
1782        }
1783
1784        @Override
1785        public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1786            try {
1787                return mPM.getAllPermissionGroups(flags);
1788            } catch (RemoteException e) {
1789                throw new RuntimeException("Package manager has died", e);
1790            }
1791        }
1792
1793        @Override
1794        public ApplicationInfo getApplicationInfo(String packageName, int flags)
1795            throws NameNotFoundException {
1796            try {
1797                ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1798                if (ai != null) {
1799                    return ai;
1800                }
1801            } catch (RemoteException e) {
1802                throw new RuntimeException("Package manager has died", e);
1803            }
1804
1805            throw new NameNotFoundException(packageName);
1806        }
1807
1808        @Override
1809        public ActivityInfo getActivityInfo(ComponentName className, int flags)
1810            throws NameNotFoundException {
1811            try {
1812                ActivityInfo ai = mPM.getActivityInfo(className, flags);
1813                if (ai != null) {
1814                    return ai;
1815                }
1816            } catch (RemoteException e) {
1817                throw new RuntimeException("Package manager has died", e);
1818            }
1819
1820            throw new NameNotFoundException(className.toString());
1821        }
1822
1823        @Override
1824        public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1825            throws NameNotFoundException {
1826            try {
1827                ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1828                if (ai != null) {
1829                    return ai;
1830                }
1831            } catch (RemoteException e) {
1832                throw new RuntimeException("Package manager has died", e);
1833            }
1834
1835            throw new NameNotFoundException(className.toString());
1836        }
1837
1838        @Override
1839        public ServiceInfo getServiceInfo(ComponentName className, int flags)
1840            throws NameNotFoundException {
1841            try {
1842                ServiceInfo si = mPM.getServiceInfo(className, flags);
1843                if (si != null) {
1844                    return si;
1845                }
1846            } catch (RemoteException e) {
1847                throw new RuntimeException("Package manager has died", e);
1848            }
1849
1850            throw new NameNotFoundException(className.toString());
1851        }
1852
1853        @Override
1854        public String[] getSystemSharedLibraryNames() {
1855             try {
1856                 return mPM.getSystemSharedLibraryNames();
1857             } catch (RemoteException e) {
1858                 throw new RuntimeException("Package manager has died", e);
1859             }
1860        }
1861
1862        @Override
1863        public FeatureInfo[] getSystemAvailableFeatures() {
1864            try {
1865                return mPM.getSystemAvailableFeatures();
1866            } catch (RemoteException e) {
1867                throw new RuntimeException("Package manager has died", e);
1868            }
1869        }
1870
1871        @Override
1872        public boolean hasSystemFeature(String name) {
1873            try {
1874                return mPM.hasSystemFeature(name);
1875            } catch (RemoteException e) {
1876                throw new RuntimeException("Package manager has died", e);
1877            }
1878        }
1879
1880        @Override
1881        public int checkPermission(String permName, String pkgName) {
1882            try {
1883                return mPM.checkPermission(permName, pkgName);
1884            } catch (RemoteException e) {
1885                throw new RuntimeException("Package manager has died", e);
1886            }
1887        }
1888
1889        @Override
1890        public boolean addPermission(PermissionInfo info) {
1891            try {
1892                return mPM.addPermission(info);
1893            } catch (RemoteException e) {
1894                throw new RuntimeException("Package manager has died", e);
1895            }
1896        }
1897
1898        @Override
1899        public boolean addPermissionAsync(PermissionInfo info) {
1900            try {
1901                return mPM.addPermissionAsync(info);
1902            } catch (RemoteException e) {
1903                throw new RuntimeException("Package manager has died", e);
1904            }
1905        }
1906
1907        @Override
1908        public void removePermission(String name) {
1909            try {
1910                mPM.removePermission(name);
1911            } catch (RemoteException e) {
1912                throw new RuntimeException("Package manager has died", e);
1913            }
1914        }
1915
1916        @Override
1917        public int checkSignatures(String pkg1, String pkg2) {
1918            try {
1919                return mPM.checkSignatures(pkg1, pkg2);
1920            } catch (RemoteException e) {
1921                throw new RuntimeException("Package manager has died", e);
1922            }
1923        }
1924
1925        @Override
1926        public int checkSignatures(int uid1, int uid2) {
1927            try {
1928                return mPM.checkUidSignatures(uid1, uid2);
1929            } catch (RemoteException e) {
1930                throw new RuntimeException("Package manager has died", e);
1931            }
1932        }
1933
1934        @Override
1935        public String[] getPackagesForUid(int uid) {
1936            try {
1937                return mPM.getPackagesForUid(uid);
1938            } catch (RemoteException e) {
1939                throw new RuntimeException("Package manager has died", e);
1940            }
1941        }
1942
1943        @Override
1944        public String getNameForUid(int uid) {
1945            try {
1946                return mPM.getNameForUid(uid);
1947            } catch (RemoteException e) {
1948                throw new RuntimeException("Package manager has died", e);
1949            }
1950        }
1951
1952        @Override
1953        public int getUidForSharedUser(String sharedUserName)
1954                throws NameNotFoundException {
1955            try {
1956                int uid = mPM.getUidForSharedUser(sharedUserName);
1957                if(uid != -1) {
1958                    return uid;
1959                }
1960            } catch (RemoteException e) {
1961                throw new RuntimeException("Package manager has died", e);
1962            }
1963            throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1964        }
1965
1966        @Override
1967        public List<PackageInfo> getInstalledPackages(int flags) {
1968            try {
1969                return mPM.getInstalledPackages(flags);
1970            } catch (RemoteException e) {
1971                throw new RuntimeException("Package manager has died", e);
1972            }
1973        }
1974
1975        @Override
1976        public List<ApplicationInfo> getInstalledApplications(int flags) {
1977            try {
1978                return mPM.getInstalledApplications(flags);
1979            } catch (RemoteException e) {
1980                throw new RuntimeException("Package manager has died", e);
1981            }
1982        }
1983
1984        @Override
1985        public ResolveInfo resolveActivity(Intent intent, int flags) {
1986            try {
1987                return mPM.resolveIntent(
1988                    intent,
1989                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1990                    flags);
1991            } catch (RemoteException e) {
1992                throw new RuntimeException("Package manager has died", e);
1993            }
1994        }
1995
1996        @Override
1997        public List<ResolveInfo> queryIntentActivities(Intent intent,
1998                int flags) {
1999            try {
2000                return mPM.queryIntentActivities(
2001                    intent,
2002                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2003                    flags);
2004            } catch (RemoteException e) {
2005                throw new RuntimeException("Package manager has died", e);
2006            }
2007        }
2008
2009        @Override
2010        public List<ResolveInfo> queryIntentActivityOptions(
2011                ComponentName caller, Intent[] specifics, Intent intent,
2012                int flags) {
2013            final ContentResolver resolver = mContext.getContentResolver();
2014
2015            String[] specificTypes = null;
2016            if (specifics != null) {
2017                final int N = specifics.length;
2018                for (int i=0; i<N; i++) {
2019                    Intent sp = specifics[i];
2020                    if (sp != null) {
2021                        String t = sp.resolveTypeIfNeeded(resolver);
2022                        if (t != null) {
2023                            if (specificTypes == null) {
2024                                specificTypes = new String[N];
2025                            }
2026                            specificTypes[i] = t;
2027                        }
2028                    }
2029                }
2030            }
2031
2032            try {
2033                return mPM.queryIntentActivityOptions(caller, specifics,
2034                    specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
2035                    flags);
2036            } catch (RemoteException e) {
2037                throw new RuntimeException("Package manager has died", e);
2038            }
2039        }
2040
2041        @Override
2042        public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
2043            try {
2044                return mPM.queryIntentReceivers(
2045                    intent,
2046                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2047                    flags);
2048            } catch (RemoteException e) {
2049                throw new RuntimeException("Package manager has died", e);
2050            }
2051        }
2052
2053        @Override
2054        public ResolveInfo resolveService(Intent intent, int flags) {
2055            try {
2056                return mPM.resolveService(
2057                    intent,
2058                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2059                    flags);
2060            } catch (RemoteException e) {
2061                throw new RuntimeException("Package manager has died", e);
2062            }
2063        }
2064
2065        @Override
2066        public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
2067            try {
2068                return mPM.queryIntentServices(
2069                    intent,
2070                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2071                    flags);
2072            } catch (RemoteException e) {
2073                throw new RuntimeException("Package manager has died", e);
2074            }
2075        }
2076
2077        @Override
2078        public ProviderInfo resolveContentProvider(String name,
2079                int flags) {
2080            try {
2081                return mPM.resolveContentProvider(name, flags);
2082            } catch (RemoteException e) {
2083                throw new RuntimeException("Package manager has died", e);
2084            }
2085        }
2086
2087        @Override
2088        public List<ProviderInfo> queryContentProviders(String processName,
2089                int uid, int flags) {
2090            try {
2091                return mPM.queryContentProviders(processName, uid, flags);
2092            } catch (RemoteException e) {
2093                throw new RuntimeException("Package manager has died", e);
2094            }
2095        }
2096
2097        @Override
2098        public InstrumentationInfo getInstrumentationInfo(
2099                ComponentName className, int flags)
2100                throws NameNotFoundException {
2101            try {
2102                InstrumentationInfo ii = mPM.getInstrumentationInfo(
2103                        className, flags);
2104                if (ii != null) {
2105                    return ii;
2106                }
2107            } catch (RemoteException e) {
2108                throw new RuntimeException("Package manager has died", e);
2109            }
2110
2111            throw new NameNotFoundException(className.toString());
2112        }
2113
2114        @Override
2115        public List<InstrumentationInfo> queryInstrumentation(
2116                String targetPackage, int flags) {
2117            try {
2118                return mPM.queryInstrumentation(targetPackage, flags);
2119            } catch (RemoteException e) {
2120                throw new RuntimeException("Package manager has died", e);
2121            }
2122        }
2123
2124        @Override public Drawable getDrawable(String packageName, int resid,
2125                ApplicationInfo appInfo) {
2126            ResourceName name = new ResourceName(packageName, resid);
2127            Drawable dr = getCachedIcon(name);
2128            if (dr != null) {
2129                return dr;
2130            }
2131            if (appInfo == null) {
2132                try {
2133                    appInfo = getApplicationInfo(packageName, 0);
2134                } catch (NameNotFoundException e) {
2135                    return null;
2136                }
2137            }
2138            try {
2139                Resources r = getResourcesForApplication(appInfo);
2140                dr = r.getDrawable(resid);
2141                if (false) {
2142                    RuntimeException e = new RuntimeException("here");
2143                    e.fillInStackTrace();
2144                    Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
2145                            + " from package " + packageName
2146                            + ": app scale=" + r.getCompatibilityInfo().applicationScale
2147                            + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
2148                            e);
2149                }
2150                if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
2151                        + Integer.toHexString(resid) + " from " + r
2152                        + ": " + dr);
2153                putCachedIcon(name, dr);
2154                return dr;
2155            } catch (NameNotFoundException e) {
2156                Log.w("PackageManager", "Failure retrieving resources for"
2157                        + appInfo.packageName);
2158            } catch (RuntimeException e) {
2159                // If an exception was thrown, fall through to return
2160                // default icon.
2161                Log.w("PackageManager", "Failure retrieving icon 0x"
2162                        + Integer.toHexString(resid) + " in package "
2163                        + packageName, e);
2164            }
2165            return null;
2166        }
2167
2168        @Override public Drawable getActivityIcon(ComponentName activityName)
2169                throws NameNotFoundException {
2170            return getActivityInfo(activityName, 0).loadIcon(this);
2171        }
2172
2173        @Override public Drawable getActivityIcon(Intent intent)
2174                throws NameNotFoundException {
2175            if (intent.getComponent() != null) {
2176                return getActivityIcon(intent.getComponent());
2177            }
2178
2179            ResolveInfo info = resolveActivity(
2180                intent, PackageManager.MATCH_DEFAULT_ONLY);
2181            if (info != null) {
2182                return info.activityInfo.loadIcon(this);
2183            }
2184
2185            throw new NameNotFoundException(intent.toURI());
2186        }
2187
2188        @Override public Drawable getDefaultActivityIcon() {
2189            return Resources.getSystem().getDrawable(
2190                com.android.internal.R.drawable.sym_def_app_icon);
2191        }
2192
2193        @Override public Drawable getApplicationIcon(ApplicationInfo info) {
2194            return info.loadIcon(this);
2195        }
2196
2197        @Override public Drawable getApplicationIcon(String packageName)
2198                throws NameNotFoundException {
2199            return getApplicationIcon(getApplicationInfo(packageName, 0));
2200        }
2201
2202        @Override
2203        public Drawable getActivityLogo(ComponentName activityName)
2204                throws NameNotFoundException {
2205            return getActivityInfo(activityName, 0).loadLogo(this);
2206        }
2207
2208        @Override
2209        public Drawable getActivityLogo(Intent intent)
2210                throws NameNotFoundException {
2211            if (intent.getComponent() != null) {
2212                return getActivityLogo(intent.getComponent());
2213            }
2214
2215            ResolveInfo info = resolveActivity(
2216                    intent, PackageManager.MATCH_DEFAULT_ONLY);
2217            if (info != null) {
2218                return info.activityInfo.loadLogo(this);
2219            }
2220
2221            throw new NameNotFoundException(intent.toUri(0));
2222        }
2223
2224        @Override
2225        public Drawable getApplicationLogo(ApplicationInfo info) {
2226            return info.loadLogo(this);
2227        }
2228
2229        @Override
2230        public Drawable getApplicationLogo(String packageName)
2231                throws NameNotFoundException {
2232            return getApplicationLogo(getApplicationInfo(packageName, 0));
2233        }
2234
2235        @Override public Resources getResourcesForActivity(
2236                ComponentName activityName) throws NameNotFoundException {
2237            return getResourcesForApplication(
2238                getActivityInfo(activityName, 0).applicationInfo);
2239        }
2240
2241        @Override public Resources getResourcesForApplication(
2242                ApplicationInfo app) throws NameNotFoundException {
2243            if (app.packageName.equals("system")) {
2244                return mContext.mMainThread.getSystemContext().getResources();
2245            }
2246            Resources r = mContext.mMainThread.getTopLevelResources(
2247                    app.uid == Process.myUid() ? app.sourceDir
2248                    : app.publicSourceDir, mContext.mPackageInfo);
2249            if (r != null) {
2250                return r;
2251            }
2252            throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2253        }
2254
2255        @Override public Resources getResourcesForApplication(
2256                String appPackageName) throws NameNotFoundException {
2257            return getResourcesForApplication(
2258                getApplicationInfo(appPackageName, 0));
2259        }
2260
2261        int mCachedSafeMode = -1;
2262        @Override public boolean isSafeMode() {
2263            try {
2264                if (mCachedSafeMode < 0) {
2265                    mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2266                }
2267                return mCachedSafeMode != 0;
2268            } catch (RemoteException e) {
2269                throw new RuntimeException("Package manager has died", e);
2270            }
2271        }
2272
2273        static void configurationChanged() {
2274            synchronized (sSync) {
2275                sIconCache.clear();
2276                sStringCache.clear();
2277            }
2278        }
2279
2280        ApplicationPackageManager(ContextImpl context,
2281                IPackageManager pm) {
2282            mContext = context;
2283            mPM = pm;
2284        }
2285
2286        private Drawable getCachedIcon(ResourceName name) {
2287            synchronized (sSync) {
2288                WeakReference<Drawable> wr = sIconCache.get(name);
2289                if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2290                        + name + ": " + wr);
2291                if (wr != null) {   // we have the activity
2292                    Drawable dr = wr.get();
2293                    if (dr != null) {
2294                        if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2295                                + name + ": " + dr);
2296                        return dr;
2297                    }
2298                    // our entry has been purged
2299                    sIconCache.remove(name);
2300                }
2301            }
2302            return null;
2303        }
2304
2305        private void putCachedIcon(ResourceName name, Drawable dr) {
2306            synchronized (sSync) {
2307                sIconCache.put(name, new WeakReference<Drawable>(dr));
2308                if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2309                        + name + ": " + dr);
2310            }
2311        }
2312
2313        static final void handlePackageBroadcast(int cmd, String[] pkgList,
2314                boolean hasPkgInfo) {
2315            boolean immediateGc = false;
2316            if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
2317                immediateGc = true;
2318            }
2319            if (pkgList != null && (pkgList.length > 0)) {
2320                boolean needCleanup = false;
2321                for (String ssp : pkgList) {
2322                    synchronized (sSync) {
2323                        if (sIconCache.size() > 0) {
2324                            Iterator<ResourceName> it = sIconCache.keySet().iterator();
2325                            while (it.hasNext()) {
2326                                ResourceName nm = it.next();
2327                                if (nm.packageName.equals(ssp)) {
2328                                    //Log.i(TAG, "Removing cached drawable for " + nm);
2329                                    it.remove();
2330                                    needCleanup = true;
2331                                }
2332                            }
2333                        }
2334                        if (sStringCache.size() > 0) {
2335                            Iterator<ResourceName> it = sStringCache.keySet().iterator();
2336                            while (it.hasNext()) {
2337                                ResourceName nm = it.next();
2338                                if (nm.packageName.equals(ssp)) {
2339                                    //Log.i(TAG, "Removing cached string for " + nm);
2340                                    it.remove();
2341                                    needCleanup = true;
2342                                }
2343                            }
2344                        }
2345                    }
2346                }
2347                if (needCleanup || hasPkgInfo) {
2348                    if (immediateGc) {
2349                        // Schedule an immediate gc.
2350                        Runtime.getRuntime().gc();
2351                    } else {
2352                        ActivityThread.currentActivityThread().scheduleGcIdler();
2353                    }
2354                }
2355            }
2356        }
2357
2358        private static final class ResourceName {
2359            final String packageName;
2360            final int iconId;
2361
2362            ResourceName(String _packageName, int _iconId) {
2363                packageName = _packageName;
2364                iconId = _iconId;
2365            }
2366
2367            ResourceName(ApplicationInfo aInfo, int _iconId) {
2368                this(aInfo.packageName, _iconId);
2369            }
2370
2371            ResourceName(ComponentInfo cInfo, int _iconId) {
2372                this(cInfo.applicationInfo.packageName, _iconId);
2373            }
2374
2375            ResourceName(ResolveInfo rInfo, int _iconId) {
2376                this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2377            }
2378
2379            @Override
2380            public boolean equals(Object o) {
2381                if (this == o) return true;
2382                if (o == null || getClass() != o.getClass()) return false;
2383
2384                ResourceName that = (ResourceName) o;
2385
2386                if (iconId != that.iconId) return false;
2387                return !(packageName != null ?
2388                        !packageName.equals(that.packageName) : that.packageName != null);
2389
2390            }
2391
2392            @Override
2393            public int hashCode() {
2394                int result;
2395                result = packageName.hashCode();
2396                result = 31 * result + iconId;
2397                return result;
2398            }
2399
2400            @Override
2401            public String toString() {
2402                return "{ResourceName " + packageName + " / " + iconId + "}";
2403            }
2404        }
2405
2406        private CharSequence getCachedString(ResourceName name) {
2407            synchronized (sSync) {
2408                WeakReference<CharSequence> wr = sStringCache.get(name);
2409                if (wr != null) {   // we have the activity
2410                    CharSequence cs = wr.get();
2411                    if (cs != null) {
2412                        return cs;
2413                    }
2414                    // our entry has been purged
2415                    sStringCache.remove(name);
2416                }
2417            }
2418            return null;
2419        }
2420
2421        private void putCachedString(ResourceName name, CharSequence cs) {
2422            synchronized (sSync) {
2423                sStringCache.put(name, new WeakReference<CharSequence>(cs));
2424            }
2425        }
2426
2427        @Override
2428        public CharSequence getText(String packageName, int resid,
2429                ApplicationInfo appInfo) {
2430            ResourceName name = new ResourceName(packageName, resid);
2431            CharSequence text = getCachedString(name);
2432            if (text != null) {
2433                return text;
2434            }
2435            if (appInfo == null) {
2436                try {
2437                    appInfo = getApplicationInfo(packageName, 0);
2438                } catch (NameNotFoundException e) {
2439                    return null;
2440                }
2441            }
2442            try {
2443                Resources r = getResourcesForApplication(appInfo);
2444                text = r.getText(resid);
2445                putCachedString(name, text);
2446                return text;
2447            } catch (NameNotFoundException e) {
2448                Log.w("PackageManager", "Failure retrieving resources for"
2449                        + appInfo.packageName);
2450            } catch (RuntimeException e) {
2451                // If an exception was thrown, fall through to return
2452                // default icon.
2453                Log.w("PackageManager", "Failure retrieving text 0x"
2454                        + Integer.toHexString(resid) + " in package "
2455                        + packageName, e);
2456            }
2457            return null;
2458        }
2459
2460        @Override
2461        public XmlResourceParser getXml(String packageName, int resid,
2462                ApplicationInfo appInfo) {
2463            if (appInfo == null) {
2464                try {
2465                    appInfo = getApplicationInfo(packageName, 0);
2466                } catch (NameNotFoundException e) {
2467                    return null;
2468                }
2469            }
2470            try {
2471                Resources r = getResourcesForApplication(appInfo);
2472                return r.getXml(resid);
2473            } catch (RuntimeException e) {
2474                // If an exception was thrown, fall through to return
2475                // default icon.
2476                Log.w("PackageManager", "Failure retrieving xml 0x"
2477                        + Integer.toHexString(resid) + " in package "
2478                        + packageName, e);
2479            } catch (NameNotFoundException e) {
2480                Log.w("PackageManager", "Failure retrieving resources for"
2481                        + appInfo.packageName);
2482            }
2483            return null;
2484        }
2485
2486        @Override
2487        public CharSequence getApplicationLabel(ApplicationInfo info) {
2488            return info.loadLabel(this);
2489        }
2490
2491        @Override
2492        public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2493                String installerPackageName) {
2494            try {
2495                mPM.installPackage(packageURI, observer, flags, installerPackageName);
2496            } catch (RemoteException e) {
2497                // Should never happen!
2498            }
2499        }
2500
2501        @Override
2502        public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
2503            try {
2504                mPM.movePackage(packageName, observer, flags);
2505            } catch (RemoteException e) {
2506                // Should never happen!
2507            }
2508        }
2509
2510        @Override
2511        public String getInstallerPackageName(String packageName) {
2512            try {
2513                return mPM.getInstallerPackageName(packageName);
2514            } catch (RemoteException e) {
2515                // Should never happen!
2516            }
2517            return null;
2518        }
2519
2520        @Override
2521        public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2522            try {
2523                mPM.deletePackage(packageName, observer, flags);
2524            } catch (RemoteException e) {
2525                // Should never happen!
2526            }
2527        }
2528        @Override
2529        public void clearApplicationUserData(String packageName,
2530                IPackageDataObserver observer) {
2531            try {
2532                mPM.clearApplicationUserData(packageName, observer);
2533            } catch (RemoteException e) {
2534                // Should never happen!
2535            }
2536        }
2537        @Override
2538        public void deleteApplicationCacheFiles(String packageName,
2539                IPackageDataObserver observer) {
2540            try {
2541                mPM.deleteApplicationCacheFiles(packageName, observer);
2542            } catch (RemoteException e) {
2543                // Should never happen!
2544            }
2545        }
2546        @Override
2547        public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2548            try {
2549                mPM.freeStorageAndNotify(idealStorageSize, observer);
2550            } catch (RemoteException e) {
2551                // Should never happen!
2552            }
2553        }
2554
2555        @Override
2556        public void freeStorage(long freeStorageSize, IntentSender pi) {
2557            try {
2558                mPM.freeStorage(freeStorageSize, pi);
2559            } catch (RemoteException e) {
2560                // Should never happen!
2561            }
2562        }
2563
2564        @Override
2565        public void getPackageSizeInfo(String packageName,
2566                IPackageStatsObserver observer) {
2567            try {
2568                mPM.getPackageSizeInfo(packageName, observer);
2569            } catch (RemoteException e) {
2570                // Should never happen!
2571            }
2572        }
2573        @Override
2574        public void addPackageToPreferred(String packageName) {
2575            try {
2576                mPM.addPackageToPreferred(packageName);
2577            } catch (RemoteException e) {
2578                // Should never happen!
2579            }
2580        }
2581
2582        @Override
2583        public void removePackageFromPreferred(String packageName) {
2584            try {
2585                mPM.removePackageFromPreferred(packageName);
2586            } catch (RemoteException e) {
2587                // Should never happen!
2588            }
2589        }
2590
2591        @Override
2592        public List<PackageInfo> getPreferredPackages(int flags) {
2593            try {
2594                return mPM.getPreferredPackages(flags);
2595            } catch (RemoteException e) {
2596                // Should never happen!
2597            }
2598            return new ArrayList<PackageInfo>();
2599        }
2600
2601        @Override
2602        public void addPreferredActivity(IntentFilter filter,
2603                int match, ComponentName[] set, ComponentName activity) {
2604            try {
2605                mPM.addPreferredActivity(filter, match, set, activity);
2606            } catch (RemoteException e) {
2607                // Should never happen!
2608            }
2609        }
2610
2611        @Override
2612        public void replacePreferredActivity(IntentFilter filter,
2613                int match, ComponentName[] set, ComponentName activity) {
2614            try {
2615                mPM.replacePreferredActivity(filter, match, set, activity);
2616            } catch (RemoteException e) {
2617                // Should never happen!
2618            }
2619        }
2620
2621        @Override
2622        public void clearPackagePreferredActivities(String packageName) {
2623            try {
2624                mPM.clearPackagePreferredActivities(packageName);
2625            } catch (RemoteException e) {
2626                // Should never happen!
2627            }
2628        }
2629
2630        @Override
2631        public int getPreferredActivities(List<IntentFilter> outFilters,
2632                List<ComponentName> outActivities, String packageName) {
2633            try {
2634                return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2635            } catch (RemoteException e) {
2636                // Should never happen!
2637            }
2638            return 0;
2639        }
2640
2641        @Override
2642        public void setComponentEnabledSetting(ComponentName componentName,
2643                int newState, int flags) {
2644            try {
2645                mPM.setComponentEnabledSetting(componentName, newState, flags);
2646            } catch (RemoteException e) {
2647                // Should never happen!
2648            }
2649        }
2650
2651        @Override
2652        public int getComponentEnabledSetting(ComponentName componentName) {
2653            try {
2654                return mPM.getComponentEnabledSetting(componentName);
2655            } catch (RemoteException e) {
2656                // Should never happen!
2657            }
2658            return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2659        }
2660
2661        @Override
2662        public void setApplicationEnabledSetting(String packageName,
2663                int newState, int flags) {
2664            try {
2665                mPM.setApplicationEnabledSetting(packageName, newState, flags);
2666            } catch (RemoteException e) {
2667                // Should never happen!
2668            }
2669        }
2670
2671        @Override
2672        public int getApplicationEnabledSetting(String packageName) {
2673            try {
2674                return mPM.getApplicationEnabledSetting(packageName);
2675            } catch (RemoteException e) {
2676                // Should never happen!
2677            }
2678            return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2679        }
2680
2681        @Override
2682        public void setPackageObbPath(String packageName, String path) {
2683            try {
2684                mPM.setPackageObbPath(packageName, path);
2685            } catch (RemoteException e) {
2686                // Should never happen!
2687            }
2688        }
2689
2690        private final ContextImpl mContext;
2691        private final IPackageManager mPM;
2692
2693        private static final Object sSync = new Object();
2694        private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2695                = new HashMap<ResourceName, WeakReference<Drawable> >();
2696        private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2697                = new HashMap<ResourceName, WeakReference<CharSequence> >();
2698    }
2699
2700    // ----------------------------------------------------------------------
2701    // ----------------------------------------------------------------------
2702    // ----------------------------------------------------------------------
2703
2704    private static final class SharedPreferencesImpl implements SharedPreferences {
2705
2706        private final File mFile;
2707        private final File mBackupFile;
2708        private final int mMode;
2709        private Map mMap;
2710        private final FileStatus mFileStatus = new FileStatus();
2711        private long mTimestamp;
2712
2713        private static final Object mContent = new Object();
2714        private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
2715
2716        SharedPreferencesImpl(
2717            File file, int mode, Map initialContents) {
2718            mFile = file;
2719            mBackupFile = makeBackupFile(file);
2720            mMode = mode;
2721            mMap = initialContents != null ? initialContents : new HashMap();
2722            if (FileUtils.getFileStatus(file.getPath(), mFileStatus)) {
2723                mTimestamp = mFileStatus.mtime;
2724            }
2725            mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
2726        }
2727
2728        public boolean hasFileChanged() {
2729            synchronized (this) {
2730                if (!FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2731                    return true;
2732                }
2733                return mTimestamp != mFileStatus.mtime;
2734            }
2735        }
2736
2737        public void replace(Map newContents) {
2738            if (newContents != null) {
2739                synchronized (this) {
2740                    mMap = newContents;
2741                }
2742            }
2743        }
2744
2745        public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2746            synchronized(this) {
2747                mListeners.put(listener, mContent);
2748            }
2749        }
2750
2751        public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2752            synchronized(this) {
2753                mListeners.remove(listener);
2754            }
2755        }
2756
2757        public Map<String, ?> getAll() {
2758            synchronized(this) {
2759                //noinspection unchecked
2760                return new HashMap(mMap);
2761            }
2762        }
2763
2764        public String getString(String key, String defValue) {
2765            synchronized (this) {
2766                String v = (String)mMap.get(key);
2767                return v != null ? v : defValue;
2768            }
2769        }
2770
2771        public Set<String> getStringSet(String key, Set<String> defValues) {
2772            synchronized (this) {
2773                Set<String> v = (Set<String>) mMap.get(key);
2774                return v != null ? v : defValues;
2775            }
2776        }
2777
2778        public int getInt(String key, int defValue) {
2779            synchronized (this) {
2780                Integer v = (Integer)mMap.get(key);
2781                return v != null ? v : defValue;
2782            }
2783        }
2784        public long getLong(String key, long defValue) {
2785            synchronized (this) {
2786                Long v = (Long) mMap.get(key);
2787                return v != null ? v : defValue;
2788            }
2789        }
2790        public float getFloat(String key, float defValue) {
2791            synchronized (this) {
2792                Float v = (Float)mMap.get(key);
2793                return v != null ? v : defValue;
2794            }
2795        }
2796        public boolean getBoolean(String key, boolean defValue) {
2797            synchronized (this) {
2798                Boolean v = (Boolean)mMap.get(key);
2799                return v != null ? v : defValue;
2800            }
2801        }
2802
2803        public boolean contains(String key) {
2804            synchronized (this) {
2805                return mMap.containsKey(key);
2806            }
2807        }
2808
2809        public final class EditorImpl implements Editor {
2810            private final Map<String, Object> mModified = Maps.newHashMap();
2811            private boolean mClear = false;
2812
2813            public Editor putString(String key, String value) {
2814                synchronized (this) {
2815                    mModified.put(key, value);
2816                    return this;
2817                }
2818            }
2819            public Editor putStringSet(String key, Set<String> values) {
2820                synchronized (this) {
2821                    mModified.put(key, values);
2822                    return this;
2823                }
2824            }
2825            public Editor putInt(String key, int value) {
2826                synchronized (this) {
2827                    mModified.put(key, value);
2828                    return this;
2829                }
2830            }
2831            public Editor putLong(String key, long value) {
2832                synchronized (this) {
2833                    mModified.put(key, value);
2834                    return this;
2835                }
2836            }
2837            public Editor putFloat(String key, float value) {
2838                synchronized (this) {
2839                    mModified.put(key, value);
2840                    return this;
2841                }
2842            }
2843            public Editor putBoolean(String key, boolean value) {
2844                synchronized (this) {
2845                    mModified.put(key, value);
2846                    return this;
2847                }
2848            }
2849
2850            public Editor remove(String key) {
2851                synchronized (this) {
2852                    mModified.put(key, this);
2853                    return this;
2854                }
2855            }
2856
2857            public Editor clear() {
2858                synchronized (this) {
2859                    mClear = true;
2860                    return this;
2861                }
2862            }
2863
2864            public boolean commit() {
2865                boolean returnValue;
2866
2867                boolean hasListeners;
2868                List<String> keysModified = null;
2869                Set<OnSharedPreferenceChangeListener> listeners = null;
2870
2871                synchronized (SharedPreferencesImpl.this) {
2872                    hasListeners = mListeners.size() > 0;
2873                    if (hasListeners) {
2874                        keysModified = new ArrayList<String>();
2875                        listeners =
2876                                new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
2877                    }
2878
2879                    synchronized (this) {
2880                        if (mClear) {
2881                            mMap.clear();
2882                            mClear = false;
2883                        }
2884
2885                        for (Entry<String, Object> e : mModified.entrySet()) {
2886                            String k = e.getKey();
2887                            Object v = e.getValue();
2888                            if (v == this) {
2889                                mMap.remove(k);
2890                            } else {
2891                                mMap.put(k, v);
2892                            }
2893
2894                            if (hasListeners) {
2895                                keysModified.add(k);
2896                            }
2897                        }
2898
2899                        mModified.clear();
2900                    }
2901
2902                    returnValue = writeFileLocked();
2903                }
2904
2905                if (hasListeners) {
2906                    for (int i = keysModified.size() - 1; i >= 0; i--) {
2907                        final String key = keysModified.get(i);
2908                        for (OnSharedPreferenceChangeListener listener : listeners) {
2909                            if (listener != null) {
2910                                listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
2911                            }
2912                        }
2913                    }
2914                }
2915
2916                return returnValue;
2917            }
2918        }
2919
2920        public Editor edit() {
2921            return new EditorImpl();
2922        }
2923
2924        private FileOutputStream createFileOutputStream(File file) {
2925            FileOutputStream str = null;
2926            try {
2927                str = new FileOutputStream(file);
2928            } catch (FileNotFoundException e) {
2929                File parent = file.getParentFile();
2930                if (!parent.mkdir()) {
2931                    Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
2932                    return null;
2933                }
2934                FileUtils.setPermissions(
2935                    parent.getPath(),
2936                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2937                    -1, -1);
2938                try {
2939                    str = new FileOutputStream(file);
2940                } catch (FileNotFoundException e2) {
2941                    Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
2942                }
2943            }
2944            return str;
2945        }
2946
2947        private boolean writeFileLocked() {
2948            // Rename the current file so it may be used as a backup during the next read
2949            if (mFile.exists()) {
2950                if (!mBackupFile.exists()) {
2951                    if (!mFile.renameTo(mBackupFile)) {
2952                        Log.e(TAG, "Couldn't rename file " + mFile
2953                                + " to backup file " + mBackupFile);
2954                        return false;
2955                    }
2956                } else {
2957                    mFile.delete();
2958                }
2959            }
2960
2961            // Attempt to write the file, delete the backup and return true as atomically as
2962            // possible.  If any exception occurs, delete the new file; next time we will restore
2963            // from the backup.
2964            try {
2965                FileOutputStream str = createFileOutputStream(mFile);
2966                if (str == null) {
2967                    return false;
2968                }
2969                XmlUtils.writeMapXml(mMap, str);
2970                str.close();
2971                setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
2972                if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2973                    mTimestamp = mFileStatus.mtime;
2974                }
2975
2976                // Writing was successful, delete the backup file if there is one.
2977                mBackupFile.delete();
2978                return true;
2979            } catch (XmlPullParserException e) {
2980                Log.w(TAG, "writeFileLocked: Got exception:", e);
2981            } catch (IOException e) {
2982                Log.w(TAG, "writeFileLocked: Got exception:", e);
2983            }
2984            // Clean up an unsuccessfully written file
2985            if (mFile.exists()) {
2986                if (!mFile.delete()) {
2987                    Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
2988                }
2989            }
2990            return false;
2991        }
2992    }
2993}
2994