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