Move ApplicationPackageManager out of ContextImpl.java

Change-Id: I706bce3fc4a5c7e6ee351d677899a01ac222960c
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 174b6da..70e11df 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3001,7 +3001,7 @@
 
         Resources.updateSystemConfiguration(config, dm);
 
-        ContextImpl.ApplicationPackageManager.configurationChanged();
+        ApplicationPackageManager.configurationChanged();
         //Slog.i(TAG, "Configuration changed in " + currentPackageName());
         
         Iterator<WeakReference<Resources>> it =
@@ -3138,7 +3138,7 @@
                 mResourcePackages.remove(packages[i]);
             }
         }
-        ContextImpl.ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
+        ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
                 hasPkgInfo);
     }
         
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
new file mode 100644
index 0000000..e90ddbf
--- /dev/null
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -0,0 +1,1113 @@
+/*
+ * Copyright (C) 2010 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 android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ComponentInfo;
+import android.content.pm.FeatureInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageInstallObserver;
+import android.content.pm.IPackageManager;
+import android.content.pm.IPackageMoveObserver;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+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.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/*package*/
+final class ApplicationPackageManager extends PackageManager {
+    private static final String TAG = "ApplicationPackageManager";
+    private final static boolean DEBUG = false;
+    private final static boolean DEBUG_ICONS = false;
+
+    @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);
+    }
+
+    @Override
+    public String[] currentToCanonicalPackageNames(String[] names) {
+        try {
+            return mPM.currentToCanonicalPackageNames(names);
+        } catch (RemoteException e) {
+            throw new RuntimeException("Package manager has died", e);
+        }
+    }
+
+    @Override
+    public String[] canonicalToCurrentPackageNames(String[] names) {
+        try {
+            return mPM.canonicalToCurrentPackageNames(names);
+        } catch (RemoteException e) {
+            throw new RuntimeException("Package manager has died", e);
+        }
+    }
+
+    @Override
+    public Intent getLaunchIntentForPackage(String packageName) {
+        // 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 intentToResolve = new Intent(Intent.ACTION_MAIN);
+        intentToResolve.addCategory(Intent.CATEGORY_INFO);
+        intentToResolve.setPackage(packageName);
+        ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
+
+        // Otherwise, try to find a main launcher activity.
+        if (resolveInfo == null) {
+            // reuse the intent instance
+            intentToResolve.removeCategory(Intent.CATEGORY_INFO);
+            intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
+            intentToResolve.setPackage(packageName);
+            resolveInfo = resolveActivity(intentToResolve, 0);
+        }
+        if (resolveInfo == null) {
+            return null;
+        }
+        Intent intent = new Intent(intentToResolve);
+        intent.setClassName(resolveInfo.activityInfo.applicationInfo.packageName,
+                            resolveInfo.activityInfo.name);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return intent;
+    }
+
+    @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 ProviderInfo getProviderInfo(ComponentName className, int flags)
+            throws NameNotFoundException {
+        try {
+            ProviderInfo pi = mPM.getProviderInfo(className, flags);
+            if (pi != null) {
+                return pi;
+            }
+        } 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 FeatureInfo[] getSystemAvailableFeatures() {
+        try {
+            return mPM.getSystemAvailableFeatures();
+        } catch (RemoteException e) {
+            throw new RuntimeException("Package manager has died", e);
+        }
+    }
+
+    @Override
+    public boolean hasSystemFeature(String name) {
+        try {
+            return mPM.hasSystemFeature(name);
+        } 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 boolean addPermissionAsync(PermissionInfo info) {
+        try {
+            return mPM.addPermissionAsync(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 int checkSignatures(int uid1, int uid2) {
+        try {
+            return mPM.checkUidSignatures(uid1, uid2);
+        } 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 (false) {
+                RuntimeException e = new RuntimeException("here");
+                e.fillInStackTrace();
+                Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
+                      + " from package " + packageName
+                      + ": app scale=" + r.getCompatibilityInfo().applicationScale
+                      + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
+                      e);
+            }
+            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) {
+        return info.loadIcon(this);
+    }
+
+    @Override public Drawable getApplicationIcon(String packageName)
+            throws NameNotFoundException {
+        return getApplicationIcon(getApplicationInfo(packageName, 0));
+    }
+
+    @Override
+    public Drawable getActivityLogo(ComponentName activityName)
+            throws NameNotFoundException {
+        return getActivityInfo(activityName, 0).loadLogo(this);
+    }
+
+    @Override
+    public Drawable getActivityLogo(Intent intent)
+            throws NameNotFoundException {
+        if (intent.getComponent() != null) {
+            return getActivityLogo(intent.getComponent());
+        }
+
+        ResolveInfo info = resolveActivity(
+            intent, PackageManager.MATCH_DEFAULT_ONLY);
+        if (info != null) {
+            return info.activityInfo.loadLogo(this);
+        }
+
+        throw new NameNotFoundException(intent.toUri(0));
+    }
+
+    @Override
+    public Drawable getApplicationLogo(ApplicationInfo info) {
+        return info.loadLogo(this);
+    }
+
+    @Override
+    public Drawable getApplicationLogo(String packageName)
+            throws NameNotFoundException {
+        return getApplicationLogo(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();
+        }
+        Resources r = mContext.mMainThread.getTopLevelResources(
+            app.uid == Process.myUid() ? app.sourceDir
+            : app.publicSourceDir, mContext.mPackageInfo);
+        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(ContextImpl 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 putCachedIcon(ResourceName name, Drawable dr) {
+        synchronized (sSync) {
+            sIconCache.put(name, new WeakReference<Drawable>(dr));
+            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
+                                   + name + ": " + dr);
+        }
+    }
+
+    static final void handlePackageBroadcast(int cmd, String[] pkgList,
+                                             boolean hasPkgInfo) {
+        boolean immediateGc = false;
+        if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
+            immediateGc = true;
+        }
+        if (pkgList != null && (pkgList.length > 0)) {
+            boolean needCleanup = false;
+            for (String ssp : pkgList) {
+                synchronized (sSync) {
+                    if (sIconCache.size() > 0) {
+                        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;
+                            }
+                        }
+                    }
+                    if (sStringCache.size() > 0) {
+                        Iterator<ResourceName> 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 || hasPkgInfo) {
+                if (immediateGc) {
+                    // Schedule an immediate gc.
+                    Runtime.getRuntime().gc();
+                } else {
+                    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) {
+        synchronized (sSync) {
+            sStringCache.put(name, new WeakReference<CharSequence>(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) {
+        return info.loadLabel(this);
+    }
+
+    @Override
+    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
+                               String installerPackageName) {
+        try {
+            mPM.installPackage(packageURI, observer, flags, installerPackageName);
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+    }
+
+    @Override
+    public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
+        try {
+            mPM.movePackage(packageName, observer, flags);
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+    }
+
+    @Override
+    public String getInstallerPackageName(String packageName) {
+        try {
+            return mPM.getInstallerPackageName(packageName);
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+        return null;
+    }
+
+    @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 freeStorageSize, IntentSender pi) {
+        try {
+            mPM.freeStorage(freeStorageSize, pi);
+        } 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 replacePreferredActivity(IntentFilter filter,
+                                         int match, ComponentName[] set, ComponentName activity) {
+        try {
+            mPM.replacePreferredActivity(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;
+    }
+
+    @Override
+    public void setPackageObbPath(String packageName, String path) {
+        try {
+            mPM.setPackageObbPath(packageName, path);
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+    }
+
+    private final ContextImpl mContext;
+    private final IPackageManager mPM;
+
+    private static final Object sSync = new Object();
+    private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
+            = new HashMap<ResourceName, WeakReference<Drawable> >();
+    private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
+            = new HashMap<ResourceName, WeakReference<CharSequence> >();
+}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 860c5de..129c29d 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -34,7 +34,6 @@
 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.FeatureInfo;
@@ -44,17 +43,9 @@
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.IPackageManager;
 import android.content.pm.IPackageStatsObserver;
-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.DatabaseErrorHandler;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
@@ -110,10 +101,8 @@
 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.Set;
@@ -159,7 +148,6 @@
 class ContextImpl extends Context {
     private final static String TAG = "ApplicationContext";
     private final static boolean DEBUG = false;
-    private final static boolean DEBUG_ICONS = false;
 
     private static final Object sSync = new Object();
     private static AlarmManager sAlarmManager;
@@ -1666,1062 +1654,4 @@
 
         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);
-        }
-
-        @Override
-        public String[] currentToCanonicalPackageNames(String[] names) {
-            try {
-                return mPM.currentToCanonicalPackageNames(names);
-            } catch (RemoteException e) {
-                throw new RuntimeException("Package manager has died", e);
-            }
-        }
-
-        @Override
-        public String[] canonicalToCurrentPackageNames(String[] names) {
-            try {
-                return mPM.canonicalToCurrentPackageNames(names);
-            } catch (RemoteException e) {
-                throw new RuntimeException("Package manager has died", e);
-            }
-        }
-
-        @Override
-        public Intent getLaunchIntentForPackage(String packageName) {
-            // 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 intentToResolve = new Intent(Intent.ACTION_MAIN);
-            intentToResolve.addCategory(Intent.CATEGORY_INFO);
-            intentToResolve.setPackage(packageName);
-            ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
-
-            // Otherwise, try to find a main launcher activity.
-            if (resolveInfo == null) {
-                // reuse the intent instance
-                intentToResolve.removeCategory(Intent.CATEGORY_INFO);
-                intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
-                intentToResolve.setPackage(packageName);
-                resolveInfo = resolveActivity(intentToResolve, 0);
-            }
-            if (resolveInfo == null) {
-                return null;
-            }
-            Intent intent = new Intent(intentToResolve);
-            intent.setClassName(resolveInfo.activityInfo.applicationInfo.packageName,
-                                resolveInfo.activityInfo.name);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            return intent;
-        }
-
-        @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 ProviderInfo getProviderInfo(ComponentName className, int flags)
-            throws NameNotFoundException {
-            try {
-                ProviderInfo pi = mPM.getProviderInfo(className, flags);
-                if (pi != null) {
-                    return pi;
-                }
-            } 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 FeatureInfo[] getSystemAvailableFeatures() {
-            try {
-                return mPM.getSystemAvailableFeatures();
-            } catch (RemoteException e) {
-                throw new RuntimeException("Package manager has died", e);
-            }
-        }
-
-        @Override
-        public boolean hasSystemFeature(String name) {
-            try {
-                return mPM.hasSystemFeature(name);
-            } 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 boolean addPermissionAsync(PermissionInfo info) {
-            try {
-                return mPM.addPermissionAsync(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 int checkSignatures(int uid1, int uid2) {
-            try {
-                return mPM.checkUidSignatures(uid1, uid2);
-            } 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 (false) {
-                    RuntimeException e = new RuntimeException("here");
-                    e.fillInStackTrace();
-                    Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
-                            + " from package " + packageName
-                            + ": app scale=" + r.getCompatibilityInfo().applicationScale
-                            + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
-                            e);
-                }
-                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) {
-            return info.loadIcon(this);
-        }
-
-        @Override public Drawable getApplicationIcon(String packageName)
-                throws NameNotFoundException {
-            return getApplicationIcon(getApplicationInfo(packageName, 0));
-        }
-        
-        @Override 
-        public Drawable getActivityLogo(ComponentName activityName)
-                throws NameNotFoundException {
-            return getActivityInfo(activityName, 0).loadLogo(this);
-        }
-
-        @Override
-        public Drawable getActivityLogo(Intent intent)
-                throws NameNotFoundException {
-            if (intent.getComponent() != null) {
-                return getActivityLogo(intent.getComponent());
-            }
-
-            ResolveInfo info = resolveActivity(
-                    intent, PackageManager.MATCH_DEFAULT_ONLY);
-            if (info != null) {
-                return info.activityInfo.loadLogo(this);
-            }
-
-            throw new NameNotFoundException(intent.toUri(0));
-        }
-
-        @Override
-        public Drawable getApplicationLogo(ApplicationInfo info) {
-            return info.loadLogo(this);
-        }
-
-        @Override
-        public Drawable getApplicationLogo(String packageName)
-                throws NameNotFoundException {
-            return getApplicationLogo(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();
-            }
-            Resources r = mContext.mMainThread.getTopLevelResources(
-                    app.uid == Process.myUid() ? app.sourceDir
-                    : app.publicSourceDir, mContext.mPackageInfo);
-            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(ContextImpl 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 putCachedIcon(ResourceName name, Drawable dr) {
-            synchronized (sSync) {
-                sIconCache.put(name, new WeakReference<Drawable>(dr));
-                if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
-                        + name + ": " + dr);
-            }
-        }
-
-        static final void handlePackageBroadcast(int cmd, String[] pkgList,
-                boolean hasPkgInfo) {
-            boolean immediateGc = false;
-            if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
-                immediateGc = true;
-            }
-            if (pkgList != null && (pkgList.length > 0)) {
-                boolean needCleanup = false;
-                for (String ssp : pkgList) {
-                    synchronized (sSync) {
-                        if (sIconCache.size() > 0) {
-                            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;
-                                }
-                            }
-                        }
-                        if (sStringCache.size() > 0) {
-                            Iterator<ResourceName> 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 || hasPkgInfo) {
-                    if (immediateGc) {
-                        // Schedule an immediate gc.
-                        Runtime.getRuntime().gc();
-                    } else {
-                        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) {
-            synchronized (sSync) {
-                sStringCache.put(name, new WeakReference<CharSequence>(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) {
-            return info.loadLabel(this);
-        }
-
-        @Override
-        public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
-                String installerPackageName) {
-            try {
-                mPM.installPackage(packageURI, observer, flags, installerPackageName);
-            } catch (RemoteException e) {
-                // Should never happen!
-            }
-        }
-
-        @Override
-        public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
-            try {
-                mPM.movePackage(packageName, observer, flags);
-            } catch (RemoteException e) {
-                // Should never happen!
-            }
-        }
-
-        @Override
-        public String getInstallerPackageName(String packageName) {
-            try {
-                return mPM.getInstallerPackageName(packageName);
-            } catch (RemoteException e) {
-                // Should never happen!
-            }
-            return null;
-        }
-
-        @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 freeStorageSize, IntentSender pi) {
-            try {
-                mPM.freeStorage(freeStorageSize, pi);
-            } 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 replacePreferredActivity(IntentFilter filter,
-                int match, ComponentName[] set, ComponentName activity) {
-            try {
-                mPM.replacePreferredActivity(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;
-        }
-
-        @Override
-        public void setPackageObbPath(String packageName, String path) {
-            try {
-                mPM.setPackageObbPath(packageName, path);
-            } catch (RemoteException e) {
-                // Should never happen!
-            }
-        }
-
-        private final ContextImpl mContext;
-        private final IPackageManager mPM;
-
-        private static final Object sSync = new Object();
-        private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
-                = new HashMap<ResourceName, WeakReference<Drawable> >();
-        private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
-                = new HashMap<ResourceName, WeakReference<CharSequence> >();
-    }
 }