/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app;

import com.google.android.collect.Maps;
import com.android.internal.util.XmlUtils;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.IBluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ReceiverCallNotAllowedException;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ComponentInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.IPackageManager;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.SensorManager;
import android.location.ILocationManager;
import android.location.LocationManager;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
import android.net.Uri;
import android.net.wifi.IWifiManager;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Looper;
import android.os.RemoteException;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
import android.os.IPowerManager;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.Process;
import android.os.ServiceManager;
import android.os.Vibrator;
import android.os.FileUtils.FileStatus;
import android.telephony.TelephonyManager;
import android.text.ClipboardManager;
import android.util.AndroidRuntimeException;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.WindowManagerImpl;
import android.view.inputmethod.InputMethodManager;
import android.accounts.AccountManager;
import android.accounts.IAccountManager;

import com.android.internal.policy.PolicyManager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.Map.Entry;

import org.xmlpull.v1.XmlPullParserException;

class ReceiverRestrictedContext extends ContextWrapper {
    ReceiverRestrictedContext(Context base) {
        super(base);
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return registerReceiver(receiver, filter, null, null);
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler) {
        throw new ReceiverCallNotAllowedException(
                "IntentReceiver components are not allowed to register to receive intents");
        //ex.fillInStackTrace();
        //Log.e("IntentReceiver", ex.getMessage(), ex);
        //return mContext.registerReceiver(receiver, filter, broadcastPermission,
        //        scheduler);
    }

    @Override
    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
        throw new ReceiverCallNotAllowedException(
                "IntentReceiver components are not allowed to bind to services");
        //ex.fillInStackTrace();
        //Log.e("IntentReceiver", ex.getMessage(), ex);
        //return mContext.bindService(service, interfaceName, conn, flags);
    }
}

/**
 * Common implementation of Context API, which Activity and other application
 * classes inherit.
 */
class ApplicationContext extends Context {
    private final static String TAG = "ApplicationContext";
    private final static boolean DEBUG_ICONS = false;

    private static final Object sSync = new Object();
    private static AccountManager sAccountManager;
    private static AlarmManager sAlarmManager;
    private static PowerManager sPowerManager;
    private static ConnectivityManager sConnectivityManager;
    private static WifiManager sWifiManager;
    private static LocationManager sLocationManager;
    private static boolean sIsBluetoothDeviceCached = false;
    private static BluetoothDevice sBluetoothDevice;
    private static IWallpaperService sWallpaperService;
    private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
            new HashMap<File, SharedPreferencesImpl>();

    private AudioManager mAudioManager;
    /*package*/ ActivityThread.PackageInfo mPackageInfo;
    private Resources mResources;
    /*package*/ ActivityThread mMainThread;
    private Context mOuterContext;
    private IBinder mActivityToken = null;
    private ApplicationContentResolver mContentResolver;
    private int mThemeResource = 0;
    private Resources.Theme mTheme = null;
    private PackageManager mPackageManager;
    private NotificationManager mNotificationManager = null;
    private ActivityManager mActivityManager = null;
    private Context mReceiverRestrictedContext = null;
    private SearchManager mSearchManager = null;
    private SensorManager mSensorManager = null;
    private Vibrator mVibrator = null;
    private LayoutInflater mLayoutInflater = null;
    private StatusBarManager mStatusBarManager = null;
    private TelephonyManager mTelephonyManager = null;
    private ClipboardManager mClipboardManager = null;

    private final Object mSync = new Object();

    private File mDatabasesDir;
    private File mPreferencesDir;
    private File mFilesDir;
    

    private File mCacheDir;
    
    private Drawable mWallpaper;
    private IWallpaperServiceCallback mWallpaperCallback = null;
        
    private static long sInstanceCount = 0;

    private static final String[] EMPTY_FILE_LIST = {};

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        --sInstanceCount;
    }

    public static long getInstanceCount() {
        return sInstanceCount;
    }

    @Override
    public AssetManager getAssets() {
        return mResources.getAssets();
    }

    @Override
    public Resources getResources() {
        return mResources;
    }

    @Override
    public PackageManager getPackageManager() {
        if (mPackageManager != null) {
            return mPackageManager;
        }

        IPackageManager pm = ActivityThread.getPackageManager();
        if (pm != null) {
            // Doesn't matter if we make more than one instance.
            return (mPackageManager = new ApplicationPackageManager(this, pm));
        }

        return null;
    }

    @Override
    public ContentResolver getContentResolver() {
        return mContentResolver;
    }

    @Override
    public Looper getMainLooper() {
        return mMainThread.getLooper();
    }
    
    @Override
    public Context getApplicationContext() {
        return mMainThread.getApplication();
    }
    
    @Override
    public void setTheme(int resid) {
        mThemeResource = resid;
    }
    
    @Override
    public Resources.Theme getTheme() {
        if (mTheme == null) {
            if (mThemeResource == 0) {
                mThemeResource = com.android.internal.R.style.Theme;
            }
            mTheme = mResources.newTheme();
            mTheme.applyStyle(mThemeResource, true);
        }
        return mTheme;
    }

    @Override
    public ClassLoader getClassLoader() {
        return mPackageInfo != null ?
                mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
    }

    @Override
    public String getPackageName() {
        if (mPackageInfo != null) {
            return mPackageInfo.getPackageName();
        }
        throw new RuntimeException("Not supported in system context");
    }

    @Override
    public String getPackageResourcePath() {
        if (mPackageInfo != null) {
            return mPackageInfo.getResDir();
        }
        throw new RuntimeException("Not supported in system context");
    }

    @Override
    public String getPackageCodePath() {
        if (mPackageInfo != null) {
            return mPackageInfo.getAppDir();
        }
        throw new RuntimeException("Not supported in system context");
    }
    
    private static File makeBackupFile(File prefsFile) {
        return new File(prefsFile.getPath() + ".bak");
    }

    @Override
    public SharedPreferences getSharedPreferences(String name, int mode) {
        SharedPreferencesImpl sp;
        File f = makeFilename(getPreferencesDir(), name + ".xml");
        synchronized (sSharedPrefs) {
            sp = sSharedPrefs.get(f);
            if (sp != null && !sp.hasFileChanged()) {
                //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
                return sp;
            }
        }
        
        FileInputStream str = null;
        File backup = makeBackupFile(f);
        if (backup.exists()) {
            f.delete();
            backup.renameTo(f);
        }

        // Debugging
        if (f.exists() && !f.canRead()) {
            Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
        }
        
        Map map = null;
        if (f.exists() && f.canRead()) {
            try {
                str = new FileInputStream(f);
                map = XmlUtils.readMapXml(str);
                str.close();
            } catch (org.xmlpull.v1.XmlPullParserException e) {
                Log.w(TAG, "getSharedPreferences", e);
            } catch (FileNotFoundException e) {
                Log.w(TAG, "getSharedPreferences", e);
            } catch (IOException e) {
                Log.w(TAG, "getSharedPreferences", e);
            }
        }

        synchronized (sSharedPrefs) {
            if (sp != null) {
                //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
                sp.replace(map);
            } else {
                sp = sSharedPrefs.get(f);
                if (sp == null) {
                    sp = new SharedPreferencesImpl(f, mode, map);
                    sSharedPrefs.put(f, sp);
                }
            }
            return sp;
        }
    }

    private File getPreferencesDir() {
        synchronized (mSync) {
            if (mPreferencesDir == null) {
                mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
            }
            return mPreferencesDir;
        }
    }

    @Override
    public FileInputStream openFileInput(String name)
        throws FileNotFoundException {
        File f = makeFilename(getFilesDir(), name);
        return new FileInputStream(f);
    }

    @Override
    public FileOutputStream openFileOutput(String name, int mode)
        throws FileNotFoundException {
        final boolean append = (mode&MODE_APPEND) != 0;
        File f = makeFilename(getFilesDir(), name);
        try {
            FileOutputStream fos = new FileOutputStream(f, append);
            setFilePermissionsFromMode(f.getPath(), mode, 0);
            return fos;
        } catch (FileNotFoundException e) {
        }

        File parent = f.getParentFile();
        parent.mkdir();
        FileUtils.setPermissions(
            parent.getPath(),
            FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
            -1, -1);
        FileOutputStream fos = new FileOutputStream(f, append);
        setFilePermissionsFromMode(f.getPath(), mode, 0);
        return fos;
    }

    @Override
    public boolean deleteFile(String name) {
        File f = makeFilename(getFilesDir(), name);
        return f.delete();
    }

    @Override
    public File getFilesDir() {
        synchronized (mSync) {
            if (mFilesDir == null) {
                mFilesDir = new File(getDataDirFile(), "files");
            }
            if (!mFilesDir.exists()) {
                if(!mFilesDir.mkdirs()) {
                    Log.w(TAG, "Unable to create files directory");
                    return null;
                }
                FileUtils.setPermissions(
                        mFilesDir.getPath(),
                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                        -1, -1);
            }
            return mFilesDir;
        }
    }
    
    @Override
    public File getCacheDir() {
        synchronized (mSync) {
            if (mCacheDir == null) {
                mCacheDir = new File(getDataDirFile(), "cache");
            }
            if (!mCacheDir.exists()) {
                if(!mCacheDir.mkdirs()) {
                    Log.w(TAG, "Unable to create cache directory");
                    return null;
                }
                FileUtils.setPermissions(
                        mCacheDir.getPath(),
                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                        -1, -1);
            }
        }
        return mCacheDir;
    }
    

    @Override
    public File getFileStreamPath(String name) {
        return makeFilename(getFilesDir(), name);
    }

    @Override
    public String[] fileList() {
        final String[] list = getFilesDir().list();
        return (list != null) ? list : EMPTY_FILE_LIST;
    }

    @Override
    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
        File dir = getDatabasesDir();
        if (!dir.isDirectory() && dir.mkdir()) {
            FileUtils.setPermissions(dir.getPath(),
                FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                -1, -1);
        }

        File f = makeFilename(dir, name);
        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
        setFilePermissionsFromMode(f.getPath(), mode, 0);
        return db;
    }

    @Override
    public boolean deleteDatabase(String name) {
        try {
            File f = makeFilename(getDatabasesDir(), name);
            return f.delete();
        } catch (Exception e) {
        }
        return false;
    }

    @Override
    public File getDatabasePath(String name) {
        return makeFilename(getDatabasesDir(), name);
    }

    @Override
    public String[] databaseList() {
        final String[] list = getDatabasesDir().list();
        return (list != null) ? list : EMPTY_FILE_LIST;
    }

    
    private File getDatabasesDir() {
        synchronized (mSync) {
            if (mDatabasesDir == null) {
                mDatabasesDir = new File(getDataDirFile(), "databases");
            }
            if (mDatabasesDir.getPath().equals("databases")) {
                mDatabasesDir = new File("/data/system");
            }
            return mDatabasesDir;
        }
    }
    
    @Override
    public Drawable getWallpaper() {
        Drawable dr = peekWallpaper();
        return dr != null ? dr : getResources().getDrawable(
                com.android.internal.R.drawable.default_wallpaper);
    }

    @Override
    public synchronized Drawable peekWallpaper() {
        if (mWallpaper != null) {
            return mWallpaper;
        }
        mWallpaperCallback = new WallpaperCallback(this);
        mWallpaper = getCurrentWallpaperLocked();
        return mWallpaper;
    }

    private Drawable getCurrentWallpaperLocked() {
        try {
            ParcelFileDescriptor fd = getWallpaperService().getWallpaper(mWallpaperCallback);
            if (fd != null) {
                Bitmap bm = BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor());
                if (bm != null) {
                    return new BitmapDrawable(bm);
                }
            }
        } catch (RemoteException e) {
        }
        return null;
    }

    @Override
    public int getWallpaperDesiredMinimumWidth() {
        try {
            return getWallpaperService().getWidthHint();
        } catch (RemoteException e) {
            // Shouldn't happen!
            return 0;
        }
    }

    @Override
    public int getWallpaperDesiredMinimumHeight() {
        try {
            return getWallpaperService().getHeightHint();
        } catch (RemoteException e) {
            // Shouldn't happen!
            return 0;
        }
    }

    /**
     * @hide
     */
    @Override
    public float getApplicationScale() {
        if (mPackageInfo != null) {
            return mPackageInfo.getApplicationScale();
        } else {
            // same as system density
            return 1.0f;
        }
    }

    @Override
    public void setWallpaper(Bitmap bitmap) throws IOException  {
        try {
            ParcelFileDescriptor fd = getWallpaperService().setWallpaper();
            if (fd == null) {
                return;
            }
            FileOutputStream fos = null;
            try {
                fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
                bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
            } finally {
                if (fos != null) {
                    fos.close();
                }
            }
        } catch (RemoteException e) {
        }
    }

    @Override
    public void setWallpaper(InputStream data) throws IOException {
        try {
            ParcelFileDescriptor fd = getWallpaperService().setWallpaper();
            if (fd == null) {
                return;
            }
            FileOutputStream fos = null;
            try {
                fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
                setWallpaper(data, fos);
            } finally {
                if (fos != null) {
                    fos.close();
                }
            }
        } catch (RemoteException e) {
        }
    }

    private void setWallpaper(InputStream data, FileOutputStream fos)
            throws IOException {
        byte[] buffer = new byte[32768];
        int amt;
        while ((amt=data.read(buffer)) > 0) {
            fos.write(buffer, 0, amt);
        }
    }

    @Override
    public void clearWallpaper() throws IOException {
        try {
            /* Set the wallpaper to the default values */
            ParcelFileDescriptor fd = getWallpaperService().setWallpaper();
            if (fd != null) {
                FileOutputStream fos = null;
                try {
                    fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
                    setWallpaper(getResources().openRawResource(
                            com.android.internal.R.drawable.default_wallpaper),
                            fos);
                } finally {
                    if (fos != null) {
                        fos.close();
                    }
                }
            }
        } catch (RemoteException e) {
        }
    }

    @Override
    public void startActivity(Intent intent) {
        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
            throw new AndroidRuntimeException(
                    "Calling startActivity() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                    + " Is this really what you want?");
        }
        mMainThread.getInstrumentation().execStartActivity(
            getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
    }

    @Override
    public void sendBroadcast(Intent intent) {
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            ActivityManagerNative.getDefault().broadcastIntent(
                mMainThread.getApplicationThread(), intent, resolvedType, null,
                Activity.RESULT_OK, null, null, null, false, false);
        } catch (RemoteException e) {
        }
    }

    @Override
    public void sendBroadcast(Intent intent, String receiverPermission) {
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            ActivityManagerNative.getDefault().broadcastIntent(
                mMainThread.getApplicationThread(), intent, resolvedType, null,
                Activity.RESULT_OK, null, null, receiverPermission, false, false);
        } catch (RemoteException e) {
        }
    }

    @Override
    public void sendOrderedBroadcast(Intent intent,
            String receiverPermission) {
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            ActivityManagerNative.getDefault().broadcastIntent(
                mMainThread.getApplicationThread(), intent, resolvedType, null,
                Activity.RESULT_OK, null, null, receiverPermission, true, false);
        } catch (RemoteException e) {
        }
    }

    @Override
    public void sendOrderedBroadcast(Intent intent,
            String receiverPermission, BroadcastReceiver resultReceiver,
            Handler scheduler, int initialCode, String initialData,
            Bundle initialExtras) {
        IIntentReceiver rd = null;
        if (resultReceiver != null) {
            if (mPackageInfo != null) {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = mPackageInfo.getReceiverDispatcher(
                    resultReceiver, getOuterContext(), scheduler,
                    mMainThread.getInstrumentation(), false);
            } else {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
            }
        }
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            ActivityManagerNative.getDefault().broadcastIntent(
                mMainThread.getApplicationThread(), intent, resolvedType, rd,
                initialCode, initialData, initialExtras, receiverPermission,
                true, false);
        } catch (RemoteException e) {
        }
    }

    @Override
    public void sendStickyBroadcast(Intent intent) {
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            ActivityManagerNative.getDefault().broadcastIntent(
                mMainThread.getApplicationThread(), intent, resolvedType, null,
                Activity.RESULT_OK, null, null, null, false, true);
        } catch (RemoteException e) {
        }
    }

    @Override
    public void removeStickyBroadcast(Intent intent) {
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        if (resolvedType != null) {
            intent = new Intent(intent);
            intent.setDataAndType(intent.getData(), resolvedType);
        }
        try {
            ActivityManagerNative.getDefault().unbroadcastIntent(
                mMainThread.getApplicationThread(), intent);
        } catch (RemoteException e) {
        }
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return registerReceiver(receiver, filter, null, null);
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler) {
        return registerReceiverInternal(receiver, filter, broadcastPermission,
                scheduler, getOuterContext());
    }

    private Intent registerReceiverInternal(BroadcastReceiver receiver,
            IntentFilter filter, String broadcastPermission,
            Handler scheduler, Context context) {
        IIntentReceiver rd = null;
        if (receiver != null) {
            if (mPackageInfo != null && context != null) {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = mPackageInfo.getReceiverDispatcher(
                    receiver, context, scheduler,
                    mMainThread.getInstrumentation(), true);
            } else {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
                        receiver, context, scheduler, null, false).getIIntentReceiver();
            }
        }
        try {
            return ActivityManagerNative.getDefault().registerReceiver(
                    mMainThread.getApplicationThread(),
                    rd, filter, broadcastPermission);
        } catch (RemoteException e) {
            return null;
        }
    }

    @Override
    public void unregisterReceiver(BroadcastReceiver receiver) {
        if (mPackageInfo != null) {
            IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
                    getOuterContext(), receiver);
            try {
                ActivityManagerNative.getDefault().unregisterReceiver(rd);
            } catch (RemoteException e) {
            }
        } else {
            throw new RuntimeException("Not supported in system context");
        }
    }

    @Override
    public ComponentName startService(Intent service) {
        try {
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()));
            if (cn != null && cn.getPackageName().equals("!")) {
                throw new SecurityException(
                        "Not allowed to start service " + service
                        + " without permission " + cn.getClassName());
            }
            return cn;
        } catch (RemoteException e) {
            return null;
        }
    }

    @Override
    public boolean stopService(Intent service) {
        try {
            int res = ActivityManagerNative.getDefault().stopService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()));
            if (res < 0) {
                throw new SecurityException(
                        "Not allowed to stop service " + service);
            }
            return res != 0;
        } catch (RemoteException e) {
            return false;
        }
    }

    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        IServiceConnection sd;
        if (mPackageInfo != null) {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
                    mMainThread.getHandler(), flags);
        } else {
            throw new RuntimeException("Not supported in system context");
        }
        try {
            int res = ActivityManagerNative.getDefault().bindService(
                mMainThread.getApplicationThread(), getActivityToken(),
                service, service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags);
            if (res < 0) {
                throw new SecurityException(
                        "Not allowed to bind to service " + service);
            }
            return res != 0;
        } catch (RemoteException e) {
            return false;
        }
    }

    @Override
    public void unbindService(ServiceConnection conn) {
        if (mPackageInfo != null) {
            IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
                    getOuterContext(), conn);
            try {
                ActivityManagerNative.getDefault().unbindService(sd);
            } catch (RemoteException e) {
            }
        } else {
            throw new RuntimeException("Not supported in system context");
        }
    }

    @Override
    public boolean startInstrumentation(ComponentName className,
            String profileFile, Bundle arguments) {
        try {
            return ActivityManagerNative.getDefault().startInstrumentation(
                    className, profileFile, 0, arguments, null);
        } catch (RemoteException e) {
            // System has crashed, nothing we can do.
        }
        return false;
    }

    @Override
    public Object getSystemService(String name) {
        if (WINDOW_SERVICE.equals(name)) {
            return WindowManagerImpl.getDefault();
        } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
            synchronized (mSync) {
                LayoutInflater inflater = mLayoutInflater;
                if (inflater != null) {
                    return inflater;
                }
                mLayoutInflater = inflater =
                    PolicyManager.makeNewLayoutInflater(getOuterContext());
                return inflater;
            }
        } else if (ACTIVITY_SERVICE.equals(name)) {
            return getActivityManager();
        } else if (ALARM_SERVICE.equals(name)) {
            return getAlarmManager();
        } else if (ACCOUNT_SERVICE.equals(name)) {
            return getAccountManager();
        } else if (POWER_SERVICE.equals(name)) {
            return getPowerManager();
        } else if (CONNECTIVITY_SERVICE.equals(name)) {
            return getConnectivityManager();
        } else if (WIFI_SERVICE.equals(name)) {
            return getWifiManager();
        } else if (NOTIFICATION_SERVICE.equals(name)) {
            return getNotificationManager();
        } else if (KEYGUARD_SERVICE.equals(name)) {
            return new KeyguardManager();
        } else if (LOCATION_SERVICE.equals(name)) {
            return getLocationManager();
        } else if (SEARCH_SERVICE.equals(name)) {
            return getSearchManager();
        } else if ( SENSOR_SERVICE.equals(name)) {
            return getSensorManager();
        } else if (BLUETOOTH_SERVICE.equals(name)) {
            return getBluetoothDevice();
        } else if (VIBRATOR_SERVICE.equals(name)) {
            return getVibrator();
        } else if (STATUS_BAR_SERVICE.equals(name)) {
            synchronized (mSync) {
                if (mStatusBarManager == null) {
                    mStatusBarManager = new StatusBarManager(getOuterContext());
                }
                return mStatusBarManager;
            }
        } else if (AUDIO_SERVICE.equals(name)) {
            return getAudioManager();
        } else if (TELEPHONY_SERVICE.equals(name)) {
            return getTelephonyManager();
        } else if (CLIPBOARD_SERVICE.equals(name)) {
            return getClipboardManager();
        } else if (INPUT_METHOD_SERVICE.equals(name)) {
            return InputMethodManager.getInstance(this);
        }

        return null;
    }

    private AccountManager getAccountManager() {
        synchronized (sSync) {
            if (sAccountManager == null) {
                IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
                IAccountManager service = IAccountManager.Stub.asInterface(b);
                sAccountManager = new AccountManager(this, service);
            }
        }
        return sAccountManager;
    }

    private ActivityManager getActivityManager() {
        synchronized (mSync) {
            if (mActivityManager == null) {
                mActivityManager = new ActivityManager(getOuterContext(),
                        mMainThread.getHandler());
            }
        }
        return mActivityManager;
    }

    private AlarmManager getAlarmManager() {
        synchronized (sSync) {
            if (sAlarmManager == null) {
                IBinder b = ServiceManager.getService(ALARM_SERVICE);
                IAlarmManager service = IAlarmManager.Stub.asInterface(b);
                sAlarmManager = new AlarmManager(service);
            }
        }
        return sAlarmManager;
    }

    private PowerManager getPowerManager() {
        synchronized (sSync) {
            if (sPowerManager == null) {
                IBinder b = ServiceManager.getService(POWER_SERVICE);
                IPowerManager service = IPowerManager.Stub.asInterface(b);
                sPowerManager = new PowerManager(service, mMainThread.getHandler());
            }
        }
        return sPowerManager;
    }

    private ConnectivityManager getConnectivityManager()
    {
        synchronized (sSync) {
            if (sConnectivityManager == null) {
                IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
                IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
                sConnectivityManager = new ConnectivityManager(service);
            }
        }
        return sConnectivityManager;
    }

    private WifiManager getWifiManager()
    {
        synchronized (sSync) {
            if (sWifiManager == null) {
                IBinder b = ServiceManager.getService(WIFI_SERVICE);
                IWifiManager service = IWifiManager.Stub.asInterface(b);
                sWifiManager = new WifiManager(service, mMainThread.getHandler());
            }
        }
        return sWifiManager;
    }

    private NotificationManager getNotificationManager()
    {
        synchronized (mSync) {
            if (mNotificationManager == null) {
                mNotificationManager = new NotificationManager(
                        new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
                        mMainThread.getHandler());
            }
        }
        return mNotificationManager;
    }

    private TelephonyManager getTelephonyManager() {
        synchronized (mSync) {
            if (mTelephonyManager == null) {
                mTelephonyManager = new TelephonyManager(getOuterContext());
            }
        }
        return mTelephonyManager;
    }

    private ClipboardManager getClipboardManager() {
        synchronized (mSync) {
            if (mClipboardManager == null) {
                mClipboardManager = new ClipboardManager(getOuterContext(),
                        mMainThread.getHandler());
            }
        }
        return mClipboardManager;
    }

    private LocationManager getLocationManager() {
        synchronized (sSync) {
            if (sLocationManager == null) {
                IBinder b = ServiceManager.getService(LOCATION_SERVICE);
                ILocationManager service = ILocationManager.Stub.asInterface(b);
                sLocationManager = new LocationManager(service);
            }
        }
        return sLocationManager;
    }

    private SearchManager getSearchManager() {
        // This is only useable in Activity Contexts
        if (getActivityToken() == null) {
            throw new AndroidRuntimeException(
                "Acquiring SearchManager objects only valid in Activity Contexts.");
        }
        synchronized (mSync) {
            if (mSearchManager == null) {
                mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
            }
        }
        return mSearchManager;
    }

    private BluetoothDevice getBluetoothDevice() {
        if (sIsBluetoothDeviceCached) {
            return sBluetoothDevice;
        }
        synchronized (sSync) {
            IBinder b = ServiceManager.getService(BLUETOOTH_SERVICE);
            if (b == null) {
                sBluetoothDevice = null;
            } else {
                IBluetoothDevice service = IBluetoothDevice.Stub.asInterface(b);
                sBluetoothDevice = new BluetoothDevice(service);
            }
            sIsBluetoothDeviceCached = true;
        }
        return sBluetoothDevice;
    }

    private SensorManager getSensorManager() {
        synchronized (mSync) {
            if (mSensorManager == null) {
                mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
            }
        }
        return mSensorManager;
    }

    private Vibrator getVibrator() {
        synchronized (mSync) {
            if (mVibrator == null) {
                mVibrator = new Vibrator();
            }
        }
        return mVibrator;
    }
  
    private IWallpaperService getWallpaperService() {
        synchronized (sSync) {
            if (sWallpaperService == null) {
                IBinder b = ServiceManager.getService(WALLPAPER_SERVICE);
                sWallpaperService = IWallpaperService.Stub.asInterface(b);
            }
        }
        return sWallpaperService;
    }

    private AudioManager getAudioManager()
    {
        if (mAudioManager == null) {
            mAudioManager = new AudioManager(this);
        }
        return mAudioManager;
    }

    @Override
    public int checkPermission(String permission, int pid, int uid) {
        if (permission == null) {
            throw new IllegalArgumentException("permission is null");
        }

        if (!Process.supportsProcesses()) {
            return PackageManager.PERMISSION_GRANTED;
        }
        try {
            return ActivityManagerNative.getDefault().checkPermission(
                    permission, pid, uid);
        } catch (RemoteException e) {
            return PackageManager.PERMISSION_DENIED;
        }
    }

    @Override
    public int checkCallingPermission(String permission) {
        if (permission == null) {
            throw new IllegalArgumentException("permission is null");
        }

        if (!Process.supportsProcesses()) {
            return PackageManager.PERMISSION_GRANTED;
        }
        int pid = Binder.getCallingPid();
        if (pid != Process.myPid()) {
            return checkPermission(permission, pid,
                    Binder.getCallingUid());
        }
        return PackageManager.PERMISSION_DENIED;
    }

    @Override
    public int checkCallingOrSelfPermission(String permission) {
        if (permission == null) {
            throw new IllegalArgumentException("permission is null");
        }

        return checkPermission(permission, Binder.getCallingPid(),
                Binder.getCallingUid());
    }

    private void enforce(
            String permission, int resultOfCheck,
            boolean selfToo, int uid, String message) {
        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException(
                    (message != null ? (message + ": ") : "") +
                    (selfToo
                     ? "Neither user " + uid + " nor current process has "
                     : "User " + uid + " does not have ") +
                    permission +
                    ".");
        }
    }

    public void enforcePermission(
            String permission, int pid, int uid, String message) {
        enforce(permission,
                checkPermission(permission, pid, uid),
                false,
                uid,
                message);
    }

    public void enforceCallingPermission(String permission, String message) {
        enforce(permission,
                checkCallingPermission(permission),
                false,
                Binder.getCallingUid(),
                message);
    }

    public void enforceCallingOrSelfPermission(
            String permission, String message) {
        enforce(permission,
                checkCallingOrSelfPermission(permission),
                true,
                Binder.getCallingUid(),
                message);
    }

    @Override
    public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
         try {
            ActivityManagerNative.getDefault().grantUriPermission(
                    mMainThread.getApplicationThread(), toPackage, uri,
                    modeFlags);
        } catch (RemoteException e) {
        }
    }

    @Override
    public void revokeUriPermission(Uri uri, int modeFlags) {
         try {
            ActivityManagerNative.getDefault().revokeUriPermission(
                    mMainThread.getApplicationThread(), uri,
                    modeFlags);
        } catch (RemoteException e) {
        }
    }

    @Override
    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
        if (!Process.supportsProcesses()) {
            return PackageManager.PERMISSION_GRANTED;
        }
        try {
            return ActivityManagerNative.getDefault().checkUriPermission(
                    uri, pid, uid, modeFlags);
        } catch (RemoteException e) {
            return PackageManager.PERMISSION_DENIED;
        }
    }

    @Override
    public int checkCallingUriPermission(Uri uri, int modeFlags) {
        if (!Process.supportsProcesses()) {
            return PackageManager.PERMISSION_GRANTED;
        }
        int pid = Binder.getCallingPid();
        if (pid != Process.myPid()) {
            return checkUriPermission(uri, pid,
                    Binder.getCallingUid(), modeFlags);
        }
        return PackageManager.PERMISSION_DENIED;
    }

    @Override
    public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
        return checkUriPermission(uri, Binder.getCallingPid(),
                Binder.getCallingUid(), modeFlags);
    }

    @Override
    public int checkUriPermission(Uri uri, String readPermission,
            String writePermission, int pid, int uid, int modeFlags) {
        if (false) {
            Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
                    + readPermission + " writePermission=" + writePermission
                    + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
        }
        if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
            if (readPermission == null
                    || checkPermission(readPermission, pid, uid)
                    == PackageManager.PERMISSION_GRANTED) {
                return PackageManager.PERMISSION_GRANTED;
            }
        }
        if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
            if (writePermission == null
                    || checkPermission(writePermission, pid, uid)
                    == PackageManager.PERMISSION_GRANTED) {
                return PackageManager.PERMISSION_GRANTED;
            }
        }
        return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
                : PackageManager.PERMISSION_DENIED;
    }

    private String uriModeFlagToString(int uriModeFlags) {
        switch (uriModeFlags) {
            case Intent.FLAG_GRANT_READ_URI_PERMISSION |
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
                return "read and write";
            case Intent.FLAG_GRANT_READ_URI_PERMISSION:
                return "read";
            case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
                return "write";
        }
        throw new IllegalArgumentException(
                "Unknown permission mode flags: " + uriModeFlags);
    }

    private void enforceForUri(
            int modeFlags, int resultOfCheck, boolean selfToo,
            int uid, Uri uri, String message) {
        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException(
                    (message != null ? (message + ": ") : "") +
                    (selfToo
                     ? "Neither user " + uid + " nor current process has "
                     : "User " + uid + " does not have ") +
                    uriModeFlagToString(modeFlags) +
                    " permission on " +
                    uri +
                    ".");
        }
    }

    public void enforceUriPermission(
            Uri uri, int pid, int uid, int modeFlags, String message) {
        enforceForUri(
                modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
                false, uid, uri, message);
    }

    public void enforceCallingUriPermission(
            Uri uri, int modeFlags, String message) {
        enforceForUri(
                modeFlags, checkCallingUriPermission(uri, modeFlags),
                false, Binder.getCallingUid(), uri, message);
    }

    public void enforceCallingOrSelfUriPermission(
            Uri uri, int modeFlags, String message) {
        enforceForUri(
                modeFlags,
                checkCallingOrSelfUriPermission(uri, modeFlags), true,
                Binder.getCallingUid(), uri, message);
    }

    public void enforceUriPermission(
            Uri uri, String readPermission, String writePermission,
            int pid, int uid, int modeFlags, String message) {
        enforceForUri(modeFlags,
                      checkUriPermission(
                              uri, readPermission, writePermission, pid, uid,
                              modeFlags),
                      false,
                      uid,
                      uri,
                      message);
    }

    @Override
    public Context createPackageContext(String packageName, int flags)
        throws PackageManager.NameNotFoundException {
        if (packageName.equals("system") || packageName.equals("android")) {
            return new ApplicationContext(mMainThread.getSystemContext());
        }

        ActivityThread.PackageInfo pi =
            mMainThread.getPackageInfo(packageName, flags);
        if (pi != null) {
            ApplicationContext c = new ApplicationContext();
            c.init(pi, null, mMainThread);
            if (c.mResources != null) {
                return c;
            }
        }

        // Should be a better exception.
        throw new PackageManager.NameNotFoundException(
            "Application package " + packageName + " not found");
    }

    private File getDataDirFile() {
        if (mPackageInfo != null) {
            return mPackageInfo.getDataDirFile();
        }
        throw new RuntimeException("Not supported in system context");
    }

    @Override
    public File getDir(String name, int mode) {
        name = "app_" + name;
        File file = makeFilename(getDataDirFile(), name);
        if (!file.exists()) {
            file.mkdir();
            setFilePermissionsFromMode(file.getPath(), mode,
                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
        }
        return file;
    }

    static ApplicationContext createSystemContext(ActivityThread mainThread) {
        ApplicationContext context = new ApplicationContext();
        context.init(Resources.getSystem(), mainThread);
        return context;
    }

    ApplicationContext() {
        ++sInstanceCount;
        mOuterContext = this;
    }

    /**
     * Create a new ApplicationContext from an existing one.  The new one
     * works and operates the same as the one it is copying.
     *
     * @param context Existing application context.
     */
    public ApplicationContext(ApplicationContext context) {
        ++sInstanceCount;
        mPackageInfo = context.mPackageInfo;
        mResources = context.mResources;
        mMainThread = context.mMainThread;
        mContentResolver = context.mContentResolver;
        mOuterContext = this;
    }

    final void init(ActivityThread.PackageInfo packageInfo,
            IBinder activityToken, ActivityThread mainThread) {
        mPackageInfo = packageInfo;
        mResources = mPackageInfo.getResources(mainThread);
        mMainThread = mainThread;
        mContentResolver = new ApplicationContentResolver(this, mainThread);

        setActivityToken(activityToken);
    }

    final void init(Resources resources, ActivityThread mainThread) {
        mPackageInfo = null;
        mResources = resources;
        mMainThread = mainThread;
        mContentResolver = new ApplicationContentResolver(this, mainThread);
    }

    final void scheduleFinalCleanup(String who, String what) {
        mMainThread.scheduleContextCleanup(this, who, what);
    }

    final void performFinalCleanup(String who, String what) {
        //Log.i(TAG, "Cleanup up context: " + this);
        mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
    }

    final Context getReceiverRestrictedContext() {
        if (mReceiverRestrictedContext != null) {
            return mReceiverRestrictedContext;
        }
        return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
    }

    final void setActivityToken(IBinder token) {
        mActivityToken = token;
    }
    
    final void setOuterContext(Context context) {
        mOuterContext = context;
    }
    
    final Context getOuterContext() {
        return mOuterContext;
    }
    
    final IBinder getActivityToken() {
        return mActivityToken;
    }

    private static void setFilePermissionsFromMode(String name, int mode,
            int extraPermissions) {
        int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
            |FileUtils.S_IRGRP|FileUtils.S_IWGRP
            |extraPermissions;
        if ((mode&MODE_WORLD_READABLE) != 0) {
            perms |= FileUtils.S_IROTH;
        }
        if ((mode&MODE_WORLD_WRITEABLE) != 0) {
            perms |= FileUtils.S_IWOTH;
        }
        if (false) {
            Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
                  + ", perms=0x" + Integer.toHexString(perms));
        }
        FileUtils.setPermissions(name, perms, -1, -1);
    }

    private File makeFilename(File base, String name) {
        if (name.indexOf(File.separatorChar) < 0) {
            return new File(base, name);
        }
        throw new IllegalArgumentException(
            "File " + name + " contains a path separator");
    }

    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------

    private static final class ApplicationContentResolver extends ContentResolver {
        public ApplicationContentResolver(Context context,
                                          ActivityThread mainThread)
        {
            super(context);
            mMainThread = mainThread;
        }

        @Override
        protected IContentProvider acquireProvider(Context context, String name)
        {
            return mMainThread.acquireProvider(context, name);
        }

        @Override
        public boolean releaseProvider(IContentProvider provider)
        {
            return mMainThread.releaseProvider(provider);
        }
        
        private final ActivityThread mMainThread;
    }

    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------

    /*package*/
    static final class ApplicationPackageManager extends PackageManager {
        @Override
        public PackageInfo getPackageInfo(String packageName, int flags)
                throws NameNotFoundException {
            try {
                PackageInfo pi = mPM.getPackageInfo(packageName, flags);
                if (pi != null) {
                    return pi;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }

            throw new NameNotFoundException(packageName);
        }

        public Intent getLaunchIntentForPackage(String packageName)
                throws NameNotFoundException {
            // First see if the package has an INFO activity; the existence of
            // such an activity is implied to be the desired front-door for the
            // overall package (such as if it has multiple launcher entries).
            Intent intent = getLaunchIntentForPackageCategory(this, packageName,
                    Intent.CATEGORY_INFO);
            if (intent != null) {
                return intent;
            }
            
            // Otherwise, try to find a main launcher activity.
            return getLaunchIntentForPackageCategory(this, packageName,
                    Intent.CATEGORY_LAUNCHER);
        }
        
        // XXX This should be implemented as a call to the package manager,
        // to reduce the work needed.
        static Intent getLaunchIntentForPackageCategory(PackageManager pm,
                String packageName, String category) {
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            Intent intentToResolve = new Intent(Intent.ACTION_MAIN, null);
            intentToResolve.addCategory(category);
            final List<ResolveInfo> apps =
                    pm.queryIntentActivities(intentToResolve, 0);
            // I wish there were a way to directly get the "main" activity of a
            // package but ...
            for (ResolveInfo app : apps) {
                if (app.activityInfo.packageName.equals(packageName)) {
                    intent.setClassName(packageName, app.activityInfo.name);
                    return intent;
                }
            }
            return null;
        }
        
        @Override
        public int[] getPackageGids(String packageName)
            throws NameNotFoundException {
            try {
                int[] gids = mPM.getPackageGids(packageName);
                if (gids == null || gids.length > 0) {
                    return gids;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }

            throw new NameNotFoundException(packageName);
        }

        @Override
        public PermissionInfo getPermissionInfo(String name, int flags)
            throws NameNotFoundException {
            try {
                PermissionInfo pi = mPM.getPermissionInfo(name, flags);
                if (pi != null) {
                    return pi;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }

            throw new NameNotFoundException(name);
        }

        @Override
        public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
                throws NameNotFoundException {
            try {
                List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
                if (pi != null) {
                    return pi;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }

            throw new NameNotFoundException(group);
        }

        @Override
        public PermissionGroupInfo getPermissionGroupInfo(String name,
                int flags) throws NameNotFoundException {
            try {
                PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
                if (pgi != null) {
                    return pgi;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }

            throw new NameNotFoundException(name);
        }

        @Override
        public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
            try {
                return mPM.getAllPermissionGroups(flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public ApplicationInfo getApplicationInfo(String packageName, int flags)
            throws NameNotFoundException {
            try {
                ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
                if (ai != null) {
                    return ai;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }

            throw new NameNotFoundException(packageName);
        }

        @Override
        public ActivityInfo getActivityInfo(ComponentName className, int flags)
            throws NameNotFoundException {
            try {
                ActivityInfo ai = mPM.getActivityInfo(className, flags);
                if (ai != null) {
                    return ai;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }

            throw new NameNotFoundException(className.toString());
        }

        @Override
        public ActivityInfo getReceiverInfo(ComponentName className, int flags)
            throws NameNotFoundException {
            try {
                ActivityInfo ai = mPM.getReceiverInfo(className, flags);
                if (ai != null) {
                    return ai;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }

            throw new NameNotFoundException(className.toString());
        }

        @Override
        public ServiceInfo getServiceInfo(ComponentName className, int flags)
            throws NameNotFoundException {
            try {
                ServiceInfo si = mPM.getServiceInfo(className, flags);
                if (si != null) {
                    return si;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }

            throw new NameNotFoundException(className.toString());
        }

        @Override
        public String[] getSystemSharedLibraryNames() {
             try {
                 return mPM.getSystemSharedLibraryNames();
             } catch (RemoteException e) {
                 throw new RuntimeException("Package manager has died", e);
             }
        }

        @Override
        public int checkPermission(String permName, String pkgName) {
            try {
                return mPM.checkPermission(permName, pkgName);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public boolean addPermission(PermissionInfo info) {
            try {
                return mPM.addPermission(info);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public void removePermission(String name) {
            try {
                mPM.removePermission(name);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public int checkSignatures(String pkg1, String pkg2) {
            try {
                return mPM.checkSignatures(pkg1, pkg2);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public String[] getPackagesForUid(int uid) {
            try {
                return mPM.getPackagesForUid(uid);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public String getNameForUid(int uid) {
            try {
                return mPM.getNameForUid(uid);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }
        
        @Override
        public int getUidForSharedUser(String sharedUserName) 
                throws NameNotFoundException {
            try {
                int uid = mPM.getUidForSharedUser(sharedUserName);
                if(uid != -1) {
                    return uid;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
            throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
        }

        @Override
        public List<PackageInfo> getInstalledPackages(int flags) {
            try {
                return mPM.getInstalledPackages(flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public List<ApplicationInfo> getInstalledApplications(int flags) {
            try {
                return mPM.getInstalledApplications(flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public ResolveInfo resolveActivity(Intent intent, int flags) {
            try {
                return mPM.resolveIntent(
                    intent,
                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                    flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public List<ResolveInfo> queryIntentActivities(Intent intent,
                int flags) {
            try {
                return mPM.queryIntentActivities(
                    intent,
                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                    flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public List<ResolveInfo> queryIntentActivityOptions(
                ComponentName caller, Intent[] specifics, Intent intent,
                int flags) {
            final ContentResolver resolver = mContext.getContentResolver();

            String[] specificTypes = null;
            if (specifics != null) {
                final int N = specifics.length;
                for (int i=0; i<N; i++) {
                    Intent sp = specifics[i];
                    if (sp != null) {
                        String t = sp.resolveTypeIfNeeded(resolver);
                        if (t != null) {
                            if (specificTypes == null) {
                                specificTypes = new String[N];
                            }
                            specificTypes[i] = t;
                        }
                    }
                }
            }

            try {
                return mPM.queryIntentActivityOptions(caller, specifics,
                    specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
                    flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
            try {
                return mPM.queryIntentReceivers(
                    intent,
                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                    flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public ResolveInfo resolveService(Intent intent, int flags) {
            try {
                return mPM.resolveService(
                    intent,
                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                    flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
            try {
                return mPM.queryIntentServices(
                    intent,
                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                    flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public ProviderInfo resolveContentProvider(String name,
                int flags) {
            try {
                return mPM.resolveContentProvider(name, flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public List<ProviderInfo> queryContentProviders(String processName,
                int uid, int flags) {
            try {
                return mPM.queryContentProviders(processName, uid, flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public InstrumentationInfo getInstrumentationInfo(
                ComponentName className, int flags)
                throws NameNotFoundException {
            try {
                InstrumentationInfo ii = mPM.getInstrumentationInfo(
                        className, flags);
                if (ii != null) {
                    return ii;
                }
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }

            throw new NameNotFoundException(className.toString());
        }

        @Override
        public List<InstrumentationInfo> queryInstrumentation(
                String targetPackage, int flags) {
            try {
                return mPM.queryInstrumentation(targetPackage, flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override public Drawable getDrawable(String packageName, int resid,
                ApplicationInfo appInfo) {
            ResourceName name = new ResourceName(packageName, resid);
            Drawable dr = getCachedIcon(name);
            if (dr != null) {
                return dr;
            }
            if (appInfo == null) {
                try {
                    appInfo = getApplicationInfo(packageName, 0);
                } catch (NameNotFoundException e) {
                    return null;
                }
            }
            try {
                Resources r = getResourcesForApplication(appInfo);
                dr = r.getDrawable(resid);
                if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
                        + Integer.toHexString(resid) + " from " + r
                        + ": " + dr);
                putCachedIcon(name, dr);
                return dr;
            } catch (NameNotFoundException e) {
                Log.w("PackageManager", "Failure retrieving resources for"
                        + appInfo.packageName);
            } catch (RuntimeException e) {
                // If an exception was thrown, fall through to return
                // default icon.
                Log.w("PackageManager", "Failure retrieving icon 0x"
                        + Integer.toHexString(resid) + " in package "
                        + packageName, e);
            }
            return null;
        }

        @Override public Drawable getActivityIcon(ComponentName activityName)
                throws NameNotFoundException {
            return getActivityInfo(activityName, 0).loadIcon(this);
        }

        @Override public Drawable getActivityIcon(Intent intent)
                throws NameNotFoundException {
            if (intent.getComponent() != null) {
                return getActivityIcon(intent.getComponent());
            }

            ResolveInfo info = resolveActivity(
                intent, PackageManager.MATCH_DEFAULT_ONLY);
            if (info != null) {
                return info.activityInfo.loadIcon(this);
            }

            throw new NameNotFoundException(intent.toURI());
        }

        @Override public Drawable getDefaultActivityIcon() {
            return Resources.getSystem().getDrawable(
                com.android.internal.R.drawable.sym_def_app_icon);
        }

        @Override public Drawable getApplicationIcon(ApplicationInfo info) {
            final int icon = info.icon;
            if (icon != 0) {
                ResourceName name = new ResourceName(info, icon);
                Drawable dr = getCachedIcon(name);
                if (dr != null) {
                    return dr;
                }
                try {
                    Resources r = getResourcesForApplication(info);
                    dr = r.getDrawable(icon);
                    if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
                            + Integer.toHexString(icon) + " from " + r
                            + ": " + dr);
                    putCachedIcon(name, dr);
                    return dr;
                } catch (NameNotFoundException e) {
                    Log.w("PackageManager", "Failure retrieving resources for"
                            + info.packageName);
                } catch (RuntimeException e) {
                    // If an exception was thrown, fall through to return
                    // default icon.
                    Log.w("PackageManager", "Failure retrieving app icon", e);
                }
            }
            return getDefaultActivityIcon();
        }

        @Override public Drawable getApplicationIcon(String packageName)
                throws NameNotFoundException {
            return getApplicationIcon(getApplicationInfo(packageName, 0));
        }

        @Override public Resources getResourcesForActivity(
                ComponentName activityName) throws NameNotFoundException {
            return getResourcesForApplication(
                getActivityInfo(activityName, 0).applicationInfo);
        }

        @Override public Resources getResourcesForApplication(
                ApplicationInfo app) throws NameNotFoundException {
            if (app.packageName.equals("system")) {
                return mContext.mMainThread.getSystemContext().getResources();
            }
            ActivityThread.PackageInfo pi = mContext.mMainThread.getPackageInfoNoCheck(app);
            Resources r = mContext.mMainThread.getTopLevelResources(
                    app.uid == Process.myUid() ? app.sourceDir
                    : app.publicSourceDir,
                    pi.getApplicationScale());
            if (r != null) {
                return r;
            }
            throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
        }

        @Override public Resources getResourcesForApplication(
                String appPackageName) throws NameNotFoundException {
            return getResourcesForApplication(
                getApplicationInfo(appPackageName, 0));
        }

        int mCachedSafeMode = -1;
        @Override public boolean isSafeMode() {
            try {
                if (mCachedSafeMode < 0) {
                    mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
                }
                return mCachedSafeMode != 0;
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        static void configurationChanged() {
            synchronized (sSync) {
                sIconCache.clear();
                sStringCache.clear();
            }
        }

        ApplicationPackageManager(ApplicationContext context,
                IPackageManager pm) {
            mContext = context;
            mPM = pm;
        }

        private Drawable getCachedIcon(ResourceName name) {
            synchronized (sSync) {
                WeakReference<Drawable> wr = sIconCache.get(name);
                if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
                        + name + ": " + wr);
                if (wr != null) {   // we have the activity
                    Drawable dr = wr.get();
                    if (dr != null) {
                        if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
                                + name + ": " + dr);
                        return dr;
                    }
                    // our entry has been purged
                    sIconCache.remove(name);
                }
            }
            return null;
        }

        private void establishPackageRemovedReceiver() {
            // mContext.registerReceiverInternal() winds up acquiring the
            // main ActivityManagerService.this lock.  If we hold our usual
            // sSync global lock at the same time, we impose a required ordering
            // on those two locks, which is not good for deadlock prevention.
            // Use a dedicated lock around initialization of
            // sPackageRemovedReceiver to avoid this.
            synchronized (sPackageRemovedSync) {
                if (sPackageRemovedReceiver == null) {
                    sPackageRemovedReceiver = new PackageRemovedReceiver();
                    IntentFilter filter = new IntentFilter(
                            Intent.ACTION_PACKAGE_REMOVED);
                    filter.addDataScheme("package");
                    mContext.registerReceiverInternal(sPackageRemovedReceiver,
                            filter, null, null, null);
                }
            }
        }
        
        private void putCachedIcon(ResourceName name, Drawable dr) {
            establishPackageRemovedReceiver();

            synchronized (sSync) {
                sIconCache.put(name, new WeakReference<Drawable>(dr));
                if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
                        + name + ": " + dr);
            }
        }

        private static final class PackageRemovedReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                Uri data = intent.getData();
                String ssp;
                if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
                    boolean needCleanup = false;
                    synchronized (sSync) {
                        Iterator<ResourceName> it = sIconCache.keySet().iterator();
                        while (it.hasNext()) {
                            ResourceName nm = it.next();
                            if (nm.packageName.equals(ssp)) {
                                //Log.i(TAG, "Removing cached drawable for " + nm);
                                it.remove();
                                needCleanup = true;
                            }
                        }
                        it = sStringCache.keySet().iterator();
                        while (it.hasNext()) {
                            ResourceName nm = it.next();
                            if (nm.packageName.equals(ssp)) {
                                //Log.i(TAG, "Removing cached string for " + nm);
                                it.remove();
                                needCleanup = true;
                            }
                        }
                    }
                    if (needCleanup || ActivityThread.currentActivityThread().hasPackageInfo(ssp)) {
                        ActivityThread.currentActivityThread().scheduleGcIdler();
                    }
                }
            }
        }

        private static final class ResourceName {
            final String packageName;
            final int iconId;

            ResourceName(String _packageName, int _iconId) {
                packageName = _packageName;
                iconId = _iconId;
            }

            ResourceName(ApplicationInfo aInfo, int _iconId) {
                this(aInfo.packageName, _iconId);
            }

            ResourceName(ComponentInfo cInfo, int _iconId) {
                this(cInfo.applicationInfo.packageName, _iconId);
            }

            ResourceName(ResolveInfo rInfo, int _iconId) {
                this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
            }

            @Override
            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;

                ResourceName that = (ResourceName) o;

                if (iconId != that.iconId) return false;
                return !(packageName != null ?
                        !packageName.equals(that.packageName) : that.packageName != null);

            }

            @Override
            public int hashCode() {
                int result;
                result = packageName.hashCode();
                result = 31 * result + iconId;
                return result;
            }

            @Override
            public String toString() {
                return "{ResourceName " + packageName + " / " + iconId + "}";
            }
        }

        private CharSequence getCachedString(ResourceName name) {
            synchronized (sSync) {
                WeakReference<CharSequence> wr = sStringCache.get(name);
                if (wr != null) {   // we have the activity
                    CharSequence cs = wr.get();
                    if (cs != null) {
                        return cs;
                    }
                    // our entry has been purged
                    sStringCache.remove(name);
                }
            }
            return null;
        }

        private void putCachedString(ResourceName name, CharSequence cs) {
            establishPackageRemovedReceiver();

            synchronized (sSync) {
                sStringCache.put(name, new WeakReference<CharSequence>(cs));
            }
        }

        private CharSequence getLabel(ResourceName name, ApplicationInfo app, int id) {
            CharSequence cs = getCachedString(name);
            if (cs != null) {
                return cs;
            }
            try {
                Resources r = getResourcesForApplication(app);
                cs = r.getText(id);
                putCachedString(name, cs);
            } catch (NameNotFoundException e) {
                Log.w("PackageManager", "Failure retrieving resources for"
                        + app.packageName);
            } catch (RuntimeException e) {
                // If an exception was thrown, fall through to return null
                Log.w("ApplicationInfo", "Failure retrieving activity name", e);
            }
            return cs;
        }

        @Override
        public CharSequence getText(String packageName, int resid,
                ApplicationInfo appInfo) {
            ResourceName name = new ResourceName(packageName, resid);
            CharSequence text = getCachedString(name);
            if (text != null) {
                return text;
            }
            if (appInfo == null) {
                try {
                    appInfo = getApplicationInfo(packageName, 0);
                } catch (NameNotFoundException e) {
                    return null;
                }
            }
            try {
                Resources r = getResourcesForApplication(appInfo);
                text = r.getText(resid);
                putCachedString(name, text);
                return text;
            } catch (NameNotFoundException e) {
                Log.w("PackageManager", "Failure retrieving resources for"
                        + appInfo.packageName);
            } catch (RuntimeException e) {
                // If an exception was thrown, fall through to return
                // default icon.
                Log.w("PackageManager", "Failure retrieving text 0x"
                        + Integer.toHexString(resid) + " in package "
                        + packageName, e);
            }
            return null;
        }

        @Override
        public XmlResourceParser getXml(String packageName, int resid,
                ApplicationInfo appInfo) {
            if (appInfo == null) {
                try {
                    appInfo = getApplicationInfo(packageName, 0);
                } catch (NameNotFoundException e) {
                    return null;
                }
            }
            try {
                Resources r = getResourcesForApplication(appInfo);
                return r.getXml(resid);
            } catch (RuntimeException e) {
                // If an exception was thrown, fall through to return
                // default icon.
                Log.w("PackageManager", "Failure retrieving xml 0x"
                        + Integer.toHexString(resid) + " in package "
                        + packageName, e);
            } catch (NameNotFoundException e) {
                Log.w("PackageManager", "Failure retrieving resources for"
                        + appInfo.packageName);
            }
            return null;
        }

        @Override
        public CharSequence getApplicationLabel(ApplicationInfo info) {
            if (info.nonLocalizedLabel != null) {
                return info.nonLocalizedLabel;
            }
            final int id = info.labelRes;
            if (id != 0) {
                CharSequence cs = getLabel(new ResourceName(info, id), info, id);
                if (cs != null) {
                    return cs;
                }
            }
            return info.packageName;
        }

        @Override
        public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags) {
            try {
                mPM.installPackage(packageURI, observer, flags);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }

        @Override
        public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
            try {
                mPM.deletePackage(packageName, observer, flags);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }
        @Override
        public void clearApplicationUserData(String packageName, 
                IPackageDataObserver observer) {
            try {
                mPM.clearApplicationUserData(packageName, observer);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }
        @Override
        public void deleteApplicationCacheFiles(String packageName, 
                IPackageDataObserver observer) {
            try {
                mPM.deleteApplicationCacheFiles(packageName, observer);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }
        @Override
        public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
            try {
                mPM.freeStorageAndNotify(idealStorageSize, observer);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }
        
        @Override
        public void freeStorage(long idealStorageSize, PendingIntent opFinishedIntent) {
            try {
                mPM.freeStorage(idealStorageSize, opFinishedIntent);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }
        
        @Override
        public void getPackageSizeInfo(String packageName, 
                IPackageStatsObserver observer) {
            try {
                mPM.getPackageSizeInfo(packageName, observer);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }
        @Override
        public void addPackageToPreferred(String packageName) {
            try {
                mPM.addPackageToPreferred(packageName);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }

        @Override
        public void removePackageFromPreferred(String packageName) {
            try {
                mPM.removePackageFromPreferred(packageName);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }

        @Override
        public List<PackageInfo> getPreferredPackages(int flags) {
            try {
                return mPM.getPreferredPackages(flags);
            } catch (RemoteException e) {
                // Should never happen!
            }
            return new ArrayList<PackageInfo>();
        }

        @Override
        public void addPreferredActivity(IntentFilter filter,
                int match, ComponentName[] set, ComponentName activity) {
            try {
                mPM.addPreferredActivity(filter, match, set, activity);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }
        
        @Override
        public void clearPackagePreferredActivities(String packageName) {
            try {
                mPM.clearPackagePreferredActivities(packageName);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }
        
        @Override
        public int getPreferredActivities(List<IntentFilter> outFilters,
                List<ComponentName> outActivities, String packageName) {
            try {
                return mPM.getPreferredActivities(outFilters, outActivities, packageName);
            } catch (RemoteException e) {
                // Should never happen!
            }
            return 0;
        }
        
        @Override
        public void setComponentEnabledSetting(ComponentName componentName,
                int newState, int flags) {
            try {
                mPM.setComponentEnabledSetting(componentName, newState, flags);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }

        @Override
        public int getComponentEnabledSetting(ComponentName componentName) {
            try {
                return mPM.getComponentEnabledSetting(componentName);
            } catch (RemoteException e) {
                // Should never happen!
            }
            return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
        }

        @Override
        public void setApplicationEnabledSetting(String packageName,
                int newState, int flags) {
            try {
                mPM.setApplicationEnabledSetting(packageName, newState, flags);
            } catch (RemoteException e) {
                // Should never happen!
            }
        }
        
        @Override
        public int getApplicationEnabledSetting(String packageName) {
            try {
                return mPM.getApplicationEnabledSetting(packageName);
            } catch (RemoteException e) {
                // Should never happen!
            }
            return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
        }

        private final ApplicationContext mContext;
        private final IPackageManager mPM;

        private static final Object sSync = new Object();
        private static final Object sPackageRemovedSync = new Object();
        private static BroadcastReceiver sPackageRemovedReceiver;
        private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
                = new HashMap<ResourceName, WeakReference<Drawable> >();
        private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
                = new HashMap<ResourceName, WeakReference<CharSequence> >();
    }

    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------

    private static final class SharedPreferencesImpl implements SharedPreferences {

        private final File mFile;
        private final File mBackupFile;
        private final int mMode;
        private Map mMap;
        private final FileStatus mFileStatus = new FileStatus();
        private long mTimestamp;

        private static final Object mContent = new Object();
        private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;

        SharedPreferencesImpl(
            File file, int mode, Map initialContents) {
            mFile = file;
            mBackupFile = makeBackupFile(file);
            mMode = mode;
            mMap = initialContents != null ? initialContents : new HashMap();
            if (FileUtils.getFileStatus(file.getPath(), mFileStatus)) {
                mTimestamp = mFileStatus.mtime;
            }
            mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
        }

        public boolean hasFileChanged() {
            synchronized (this) {
                if (!FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
                    return true;
                }
                return mTimestamp != mFileStatus.mtime;
            }
        }
        
        public void replace(Map newContents) {
            if (newContents != null) {
                synchronized (this) {
                    mMap = newContents;
                }
            }
        }
        
        public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
            synchronized(this) {
                mListeners.put(listener, mContent);
            }
        }

        public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
            synchronized(this) {
                mListeners.remove(listener);
            }
        }

        public Map<String, ?> getAll() {
            synchronized(this) {
                //noinspection unchecked
                return new HashMap(mMap);
            }
        }

        public String getString(String key, String defValue) {
            synchronized (this) {
                String v = (String)mMap.get(key);
                return v != null ? v : defValue;
            }
        }

        public int getInt(String key, int defValue) {
            synchronized (this) {
                Integer v = (Integer)mMap.get(key);
                return v != null ? v : defValue;
            }
        }
        public long getLong(String key, long defValue) {
            synchronized (this) {
                Long v = (Long) mMap.get(key);
                return v != null ? v : defValue;
            }
        }
        public float getFloat(String key, float defValue) {
            synchronized (this) {
                Float v = (Float)mMap.get(key);
                return v != null ? v : defValue;
            }
        }
        public boolean getBoolean(String key, boolean defValue) {
            synchronized (this) {
                Boolean v = (Boolean)mMap.get(key);
                return v != null ? v : defValue;
            }
        }

        public boolean contains(String key) {
            synchronized (this) {
                return mMap.containsKey(key);
            }
        }

        public final class EditorImpl implements Editor {
            private final Map<String, Object> mModified = Maps.newHashMap();
            private boolean mClear = false;

            public Editor putString(String key, String value) {
                synchronized (this) {
                    mModified.put(key, value);
                    return this;
                }
            }
            public Editor putInt(String key, int value) {
                synchronized (this) {
                    mModified.put(key, value);
                    return this;
                }
            }
            public Editor putLong(String key, long value) {
                synchronized (this) {
                    mModified.put(key, value);
                    return this;
                }
            }
            public Editor putFloat(String key, float value) {
                synchronized (this) {
                    mModified.put(key, value);
                    return this;
                }
            }
            public Editor putBoolean(String key, boolean value) {
                synchronized (this) {
                    mModified.put(key, value);
                    return this;
                }
            }

            public Editor remove(String key) {
                synchronized (this) {
                    mModified.put(key, this);
                    return this;
                }
            }

            public Editor clear() {
                synchronized (this) {
                    mClear = true;
                    return this;
                }
            }

            public boolean commit() {
                boolean returnValue;

                boolean hasListeners;
                List<String> keysModified = null;
                Set<OnSharedPreferenceChangeListener> listeners = null;

                synchronized (SharedPreferencesImpl.this) {
                    hasListeners = mListeners.size() > 0;
                    if (hasListeners) {
                        keysModified = new ArrayList<String>();
                        listeners =
                                new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
                    }

                    synchronized (this) {
                        if (mClear) {
                            mMap.clear();
                            mClear = false;
                        }

                        for (Entry<String, Object> e : mModified.entrySet()) {
                            String k = e.getKey();
                            Object v = e.getValue();
                            if (v == this) {
                                mMap.remove(k);
                            } else {
                                mMap.put(k, v);
                            }

                            if (hasListeners) {
                                keysModified.add(k);
                            }
                        }

                        mModified.clear();
                    }

                    returnValue = writeFileLocked();
                }

                if (hasListeners) {
                    for (int i = keysModified.size() - 1; i >= 0; i--) {
                        final String key = keysModified.get(i);
                        for (OnSharedPreferenceChangeListener listener : listeners) {
                            if (listener != null) {
                                listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
                            }
                        }
                    }
                }

                return returnValue;
            }
        }

        public Editor edit() {
            return new EditorImpl();
        }
        
        private FileOutputStream createFileOutputStream(File file) {
            FileOutputStream str = null;
            try {
                str = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                File parent = file.getParentFile();
                if (!parent.mkdir()) {
                    Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
                    return null;
                }
                FileUtils.setPermissions(
                    parent.getPath(),
                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                    -1, -1);
                try {
                    str = new FileOutputStream(file);
                } catch (FileNotFoundException e2) {
                    Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
                }
            }
            return str;
        }

        private boolean writeFileLocked() {
            // Rename the current file so it may be used as a backup during the next read
            if (mFile.exists()) {
                if (!mFile.renameTo(mBackupFile)) {
                    Log.e(TAG, "Couldn't rename file " + mFile + " to backup file " + mBackupFile);
                }
            }
            
            // Attempt to write the file, delete the backup and return true as atomically as
            // possible.  If any exception occurs, delete the new file; next time we will restore
            // from the backup.
            try {
                FileOutputStream str = createFileOutputStream(mFile);
                if (str == null) {
                    return false;
                }
                XmlUtils.writeMapXml(mMap, str);
                str.close();
                setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
                if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
                    mTimestamp = mFileStatus.mtime;
                }
                
                // Writing was successful, delete the backup file if there is one.
                mBackupFile.delete();
                return true;
            } catch (XmlPullParserException e) {
                Log.w(TAG, "writeFileLocked: Got exception:", e);
            } catch (IOException e) {
                Log.w(TAG, "writeFileLocked: Got exception:", e);
            }
            // Clean up an unsuccessfully written file
            if (mFile.exists()) {
                if (!mFile.delete()) {
                    Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
                }
            }
            return false;
        }
    }

    private static class WallpaperCallback extends IWallpaperServiceCallback.Stub {
        private WeakReference<ApplicationContext> mContext;

        public WallpaperCallback(ApplicationContext context) {
            mContext = new WeakReference<ApplicationContext>(context);
        }

        public synchronized void onWallpaperChanged() {

            /* The wallpaper has changed but we shouldn't eagerly load the
             * wallpaper as that would be inefficient. Reset the cached wallpaper
             * to null so if the user requests the wallpaper again then we'll
             * fetch it.
             */
            final ApplicationContext applicationContext = mContext.get();
            if (applicationContext != null) {
                applicationContext.mWallpaper = null;
            }
        }
    }
}
