Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.app;
     18 
     19 import android.content.ComponentName;
     20 import android.content.ContentResolver;
     21 import android.content.Intent;
     22 import android.content.IntentFilter;
     23 import android.content.IntentSender;
     24 import android.content.pm.ActivityInfo;
     25 import android.content.pm.ApplicationInfo;
     26 import android.content.pm.ComponentInfo;
     27 import android.content.pm.ContainerEncryptionParams;
     28 import android.content.pm.FeatureInfo;
     29 import android.content.pm.IPackageDataObserver;
     30 import android.content.pm.IPackageDeleteObserver;
     31 import android.content.pm.IPackageInstallObserver;
     32 import android.content.pm.IPackageManager;
     33 import android.content.pm.IPackageMoveObserver;
     34 import android.content.pm.IPackageStatsObserver;
     35 import android.content.pm.InstrumentationInfo;
     36 import android.content.pm.PackageInfo;
     37 import android.content.pm.PackageManager;
     38 import android.content.pm.ParceledListSlice;
     39 import android.content.pm.PermissionGroupInfo;
     40 import android.content.pm.PermissionInfo;
     41 import android.content.pm.ProviderInfo;
     42 import android.content.pm.ResolveInfo;
     43 import android.content.pm.ServiceInfo;
     44 import android.content.pm.ManifestDigest;
     45 import android.content.pm.VerificationParams;
     46 import android.content.pm.VerifierDeviceIdentity;
     47 import android.content.res.Resources;
     48 import android.content.res.XmlResourceParser;
     49 import android.graphics.drawable.Drawable;
     50 import android.net.Uri;
     51 import android.os.Process;
     52 import android.os.RemoteException;
     53 import android.os.UserHandle;
     54 import android.util.Log;
     55 import android.view.Display;
     56 
     57 import java.lang.ref.WeakReference;
     58 import java.util.ArrayList;
     59 import java.util.HashMap;
     60 import java.util.Iterator;
     61 import java.util.List;
     62 
     63 /*package*/
     64 final class ApplicationPackageManager extends PackageManager {
     65     private static final String TAG = "ApplicationPackageManager";
     66     private final static boolean DEBUG = false;
     67     private final static boolean DEBUG_ICONS = false;
     68 
     69     @Override
     70     public PackageInfo getPackageInfo(String packageName, int flags)
     71             throws NameNotFoundException {
     72         try {
     73             PackageInfo pi = mPM.getPackageInfo(packageName, flags, mContext.getUserId());
     74             if (pi != null) {
     75                 return pi;
     76             }
     77         } catch (RemoteException e) {
     78             throw new RuntimeException("Package manager has died", e);
     79         }
     80 
     81         throw new NameNotFoundException(packageName);
     82     }
     83 
     84     @Override
     85     public String[] currentToCanonicalPackageNames(String[] names) {
     86         try {
     87             return mPM.currentToCanonicalPackageNames(names);
     88         } catch (RemoteException e) {
     89             throw new RuntimeException("Package manager has died", e);
     90         }
     91     }
     92 
     93     @Override
     94     public String[] canonicalToCurrentPackageNames(String[] names) {
     95         try {
     96             return mPM.canonicalToCurrentPackageNames(names);
     97         } catch (RemoteException e) {
     98             throw new RuntimeException("Package manager has died", e);
     99         }
    100     }
    101 
    102     @Override
    103     public Intent getLaunchIntentForPackage(String packageName) {
    104         // First see if the package has an INFO activity; the existence of
    105         // such an activity is implied to be the desired front-door for the
    106         // overall package (such as if it has multiple launcher entries).
    107         Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
    108         intentToResolve.addCategory(Intent.CATEGORY_INFO);
    109         intentToResolve.setPackage(packageName);
    110         List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
    111 
    112         // Otherwise, try to find a main launcher activity.
    113         if (ris == null || ris.size() <= 0) {
    114             // reuse the intent instance
    115             intentToResolve.removeCategory(Intent.CATEGORY_INFO);
    116             intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
    117             intentToResolve.setPackage(packageName);
    118             ris = queryIntentActivities(intentToResolve, 0);
    119         }
    120         if (ris == null || ris.size() <= 0) {
    121             return null;
    122         }
    123         Intent intent = new Intent(intentToResolve);
    124         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    125         intent.setClassName(ris.get(0).activityInfo.packageName,
    126                 ris.get(0).activityInfo.name);
    127         return intent;
    128     }
    129 
    130     @Override
    131     public int[] getPackageGids(String packageName)
    132             throws NameNotFoundException {
    133         try {
    134             int[] gids = mPM.getPackageGids(packageName);
    135             if (gids == null || gids.length > 0) {
    136                 return gids;
    137             }
    138         } catch (RemoteException e) {
    139             throw new RuntimeException("Package manager has died", e);
    140         }
    141 
    142         throw new NameNotFoundException(packageName);
    143     }
    144 
    145     @Override
    146     public int getPackageUid(String packageName, int userHandle)
    147             throws NameNotFoundException {
    148         try {
    149             int uid = mPM.getPackageUid(packageName, userHandle);
    150             if (uid >= 0) {
    151                 return uid;
    152             }
    153         } catch (RemoteException e) {
    154             throw new RuntimeException("Package manager has died", e);
    155         }
    156 
    157         throw new NameNotFoundException(packageName);
    158     }
    159 
    160     @Override
    161     public PermissionInfo getPermissionInfo(String name, int flags)
    162             throws NameNotFoundException {
    163         try {
    164             PermissionInfo pi = mPM.getPermissionInfo(name, flags);
    165             if (pi != null) {
    166                 return pi;
    167             }
    168         } catch (RemoteException e) {
    169             throw new RuntimeException("Package manager has died", e);
    170         }
    171 
    172         throw new NameNotFoundException(name);
    173     }
    174 
    175     @Override
    176     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
    177             throws NameNotFoundException {
    178         try {
    179             List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
    180             if (pi != null) {
    181                 return pi;
    182             }
    183         } catch (RemoteException e) {
    184             throw new RuntimeException("Package manager has died", e);
    185         }
    186 
    187         throw new NameNotFoundException(group);
    188     }
    189 
    190     @Override
    191     public PermissionGroupInfo getPermissionGroupInfo(String name,
    192                                                       int flags) throws NameNotFoundException {
    193         try {
    194             PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
    195             if (pgi != null) {
    196                 return pgi;
    197             }
    198         } catch (RemoteException e) {
    199             throw new RuntimeException("Package manager has died", e);
    200         }
    201 
    202         throw new NameNotFoundException(name);
    203     }
    204 
    205     @Override
    206     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
    207         try {
    208             return mPM.getAllPermissionGroups(flags);
    209         } catch (RemoteException e) {
    210             throw new RuntimeException("Package manager has died", e);
    211         }
    212     }
    213 
    214     @Override
    215     public ApplicationInfo getApplicationInfo(String packageName, int flags)
    216             throws NameNotFoundException {
    217         try {
    218             ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, mContext.getUserId());
    219             if (ai != null) {
    220                 return ai;
    221             }
    222         } catch (RemoteException e) {
    223             throw new RuntimeException("Package manager has died", e);
    224         }
    225 
    226         throw new NameNotFoundException(packageName);
    227     }
    228 
    229     @Override
    230     public ActivityInfo getActivityInfo(ComponentName className, int flags)
    231             throws NameNotFoundException {
    232         try {
    233             ActivityInfo ai = mPM.getActivityInfo(className, flags, mContext.getUserId());
    234             if (ai != null) {
    235                 return ai;
    236             }
    237         } catch (RemoteException e) {
    238             throw new RuntimeException("Package manager has died", e);
    239         }
    240 
    241         throw new NameNotFoundException(className.toString());
    242     }
    243 
    244     @Override
    245     public ActivityInfo getReceiverInfo(ComponentName className, int flags)
    246             throws NameNotFoundException {
    247         try {
    248             ActivityInfo ai = mPM.getReceiverInfo(className, flags, mContext.getUserId());
    249             if (ai != null) {
    250                 return ai;
    251             }
    252         } catch (RemoteException e) {
    253             throw new RuntimeException("Package manager has died", e);
    254         }
    255 
    256         throw new NameNotFoundException(className.toString());
    257     }
    258 
    259     @Override
    260     public ServiceInfo getServiceInfo(ComponentName className, int flags)
    261             throws NameNotFoundException {
    262         try {
    263             ServiceInfo si = mPM.getServiceInfo(className, flags, mContext.getUserId());
    264             if (si != null) {
    265                 return si;
    266             }
    267         } catch (RemoteException e) {
    268             throw new RuntimeException("Package manager has died", e);
    269         }
    270 
    271         throw new NameNotFoundException(className.toString());
    272     }
    273 
    274     @Override
    275     public ProviderInfo getProviderInfo(ComponentName className, int flags)
    276             throws NameNotFoundException {
    277         try {
    278             ProviderInfo pi = mPM.getProviderInfo(className, flags, mContext.getUserId());
    279             if (pi != null) {
    280                 return pi;
    281             }
    282         } catch (RemoteException e) {
    283             throw new RuntimeException("Package manager has died", e);
    284         }
    285 
    286         throw new NameNotFoundException(className.toString());
    287     }
    288 
    289     @Override
    290     public String[] getSystemSharedLibraryNames() {
    291         try {
    292             return mPM.getSystemSharedLibraryNames();
    293         } catch (RemoteException e) {
    294             throw new RuntimeException("Package manager has died", e);
    295         }
    296     }
    297 
    298     @Override
    299     public FeatureInfo[] getSystemAvailableFeatures() {
    300         try {
    301             return mPM.getSystemAvailableFeatures();
    302         } catch (RemoteException e) {
    303             throw new RuntimeException("Package manager has died", e);
    304         }
    305     }
    306 
    307     @Override
    308     public boolean hasSystemFeature(String name) {
    309         try {
    310             return mPM.hasSystemFeature(name);
    311         } catch (RemoteException e) {
    312             throw new RuntimeException("Package manager has died", e);
    313         }
    314     }
    315 
    316     @Override
    317     public int checkPermission(String permName, String pkgName) {
    318         try {
    319             return mPM.checkPermission(permName, pkgName);
    320         } catch (RemoteException e) {
    321             throw new RuntimeException("Package manager has died", e);
    322         }
    323     }
    324 
    325     @Override
    326     public boolean addPermission(PermissionInfo info) {
    327         try {
    328             return mPM.addPermission(info);
    329         } catch (RemoteException e) {
    330             throw new RuntimeException("Package manager has died", e);
    331         }
    332     }
    333 
    334     @Override
    335     public boolean addPermissionAsync(PermissionInfo info) {
    336         try {
    337             return mPM.addPermissionAsync(info);
    338         } catch (RemoteException e) {
    339             throw new RuntimeException("Package manager has died", e);
    340         }
    341     }
    342 
    343     @Override
    344     public void removePermission(String name) {
    345         try {
    346             mPM.removePermission(name);
    347         } catch (RemoteException e) {
    348             throw new RuntimeException("Package manager has died", e);
    349         }
    350     }
    351 
    352     @Override
    353     public void grantPermission(String packageName, String permissionName) {
    354         try {
    355             mPM.grantPermission(packageName, permissionName);
    356         } catch (RemoteException e) {
    357             throw new RuntimeException("Package manager has died", e);
    358         }
    359     }
    360 
    361     @Override
    362     public void revokePermission(String packageName, String permissionName) {
    363         try {
    364             mPM.revokePermission(packageName, permissionName);
    365         } catch (RemoteException e) {
    366             throw new RuntimeException("Package manager has died", e);
    367         }
    368     }
    369 
    370     @Override
    371     public int checkSignatures(String pkg1, String pkg2) {
    372         try {
    373             return mPM.checkSignatures(pkg1, pkg2);
    374         } catch (RemoteException e) {
    375             throw new RuntimeException("Package manager has died", e);
    376         }
    377     }
    378 
    379     @Override
    380     public int checkSignatures(int uid1, int uid2) {
    381         try {
    382             return mPM.checkUidSignatures(uid1, uid2);
    383         } catch (RemoteException e) {
    384             throw new RuntimeException("Package manager has died", e);
    385         }
    386     }
    387 
    388     @Override
    389     public String[] getPackagesForUid(int uid) {
    390         try {
    391             return mPM.getPackagesForUid(uid);
    392         } catch (RemoteException e) {
    393             throw new RuntimeException("Package manager has died", e);
    394         }
    395     }
    396 
    397     @Override
    398     public String getNameForUid(int uid) {
    399         try {
    400             return mPM.getNameForUid(uid);
    401         } catch (RemoteException e) {
    402             throw new RuntimeException("Package manager has died", e);
    403         }
    404     }
    405 
    406     @Override
    407     public int getUidForSharedUser(String sharedUserName)
    408             throws NameNotFoundException {
    409         try {
    410             int uid = mPM.getUidForSharedUser(sharedUserName);
    411             if(uid != -1) {
    412                 return uid;
    413             }
    414         } catch (RemoteException e) {
    415             throw new RuntimeException("Package manager has died", e);
    416         }
    417         throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
    418     }
    419 
    420     @SuppressWarnings("unchecked")
    421     @Override
    422     public List<PackageInfo> getInstalledPackages(int flags) {
    423         return getInstalledPackages(flags, mContext.getUserId());
    424     }
    425 
    426     /** @hide */
    427     @Override
    428     public List<PackageInfo> getInstalledPackages(int flags, int userId) {
    429         try {
    430             ParceledListSlice<PackageInfo> slice = mPM.getInstalledPackages(flags, userId);
    431             return slice.getList();
    432         } catch (RemoteException e) {
    433             throw new RuntimeException("Package manager has died", e);
    434         }
    435     }
    436 
    437     @SuppressWarnings("unchecked")
    438     @Override
    439     public List<PackageInfo> getPackagesHoldingPermissions(
    440             String[] permissions, int flags) {
    441         final int userId = mContext.getUserId();
    442         try {
    443             ParceledListSlice<PackageInfo> slice = mPM.getPackagesHoldingPermissions(
    444                     permissions, flags, userId);
    445             return slice.getList();
    446         } catch (RemoteException e) {
    447             throw new RuntimeException("Package manager has died", e);
    448         }
    449     }
    450 
    451     @SuppressWarnings("unchecked")
    452     @Override
    453     public List<ApplicationInfo> getInstalledApplications(int flags) {
    454         final int userId = mContext.getUserId();
    455         try {
    456             ParceledListSlice<ApplicationInfo> slice = mPM.getInstalledApplications(flags, userId);
    457             return slice.getList();
    458         } catch (RemoteException e) {
    459             throw new RuntimeException("Package manager has died", e);
    460         }
    461     }
    462 
    463     @Override
    464     public ResolveInfo resolveActivity(Intent intent, int flags) {
    465         return resolveActivityAsUser(intent, flags, mContext.getUserId());
    466     }
    467 
    468     @Override
    469     public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
    470         try {
    471             return mPM.resolveIntent(
    472                 intent,
    473                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    474                 flags,
    475                 userId);
    476         } catch (RemoteException e) {
    477             throw new RuntimeException("Package manager has died", e);
    478         }
    479     }
    480 
    481     @Override
    482     public List<ResolveInfo> queryIntentActivities(Intent intent,
    483                                                    int flags) {
    484         return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId());
    485     }
    486 
    487     /** @hide Same as above but for a specific user */
    488     @Override
    489     public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
    490                                                    int flags, int userId) {
    491         try {
    492             return mPM.queryIntentActivities(
    493                 intent,
    494                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    495                 flags,
    496                 userId);
    497         } catch (RemoteException e) {
    498             throw new RuntimeException("Package manager has died", e);
    499         }
    500     }
    501 
    502     @Override
    503     public List<ResolveInfo> queryIntentActivityOptions(
    504         ComponentName caller, Intent[] specifics, Intent intent,
    505         int flags) {
    506         final ContentResolver resolver = mContext.getContentResolver();
    507 
    508         String[] specificTypes = null;
    509         if (specifics != null) {
    510             final int N = specifics.length;
    511             for (int i=0; i<N; i++) {
    512                 Intent sp = specifics[i];
    513                 if (sp != null) {
    514                     String t = sp.resolveTypeIfNeeded(resolver);
    515                     if (t != null) {
    516                         if (specificTypes == null) {
    517                             specificTypes = new String[N];
    518                         }
    519                         specificTypes[i] = t;
    520                     }
    521                 }
    522             }
    523         }
    524 
    525         try {
    526             return mPM.queryIntentActivityOptions(caller, specifics,
    527                                                   specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
    528                                                   flags, mContext.getUserId());
    529         } catch (RemoteException e) {
    530             throw new RuntimeException("Package manager has died", e);
    531         }
    532     }
    533 
    534     /**
    535      * @hide
    536      */
    537     @Override
    538     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags, int userId) {
    539         try {
    540             return mPM.queryIntentReceivers(
    541                 intent,
    542                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    543                 flags,
    544                 userId);
    545         } catch (RemoteException e) {
    546             throw new RuntimeException("Package manager has died", e);
    547         }
    548     }
    549 
    550     @Override
    551     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
    552         return queryBroadcastReceivers(intent, flags, mContext.getUserId());
    553     }
    554 
    555     @Override
    556     public ResolveInfo resolveService(Intent intent, int flags) {
    557         try {
    558             return mPM.resolveService(
    559                 intent,
    560                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    561                 flags,
    562                 mContext.getUserId());
    563         } catch (RemoteException e) {
    564             throw new RuntimeException("Package manager has died", e);
    565         }
    566     }
    567 
    568     @Override
    569     public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
    570         try {
    571             return mPM.queryIntentServices(
    572                 intent,
    573                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    574                 flags,
    575                 userId);
    576         } catch (RemoteException e) {
    577             throw new RuntimeException("Package manager has died", e);
    578         }
    579     }
    580 
    581     @Override
    582     public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
    583         return queryIntentServicesAsUser(intent, flags, mContext.getUserId());
    584     }
    585 
    586     @Override
    587     public ProviderInfo resolveContentProvider(String name,
    588                                                int flags) {
    589         try {
    590             return mPM.resolveContentProvider(name, flags, mContext.getUserId());
    591         } catch (RemoteException e) {
    592             throw new RuntimeException("Package manager has died", e);
    593         }
    594     }
    595 
    596     @Override
    597     public List<ProviderInfo> queryContentProviders(String processName,
    598                                                     int uid, int flags) {
    599         try {
    600             return mPM.queryContentProviders(processName, uid, flags);
    601         } catch (RemoteException e) {
    602             throw new RuntimeException("Package manager has died", e);
    603         }
    604     }
    605 
    606     @Override
    607     public InstrumentationInfo getInstrumentationInfo(
    608         ComponentName className, int flags)
    609             throws NameNotFoundException {
    610         try {
    611             InstrumentationInfo ii = mPM.getInstrumentationInfo(
    612                 className, flags);
    613             if (ii != null) {
    614                 return ii;
    615             }
    616         } catch (RemoteException e) {
    617             throw new RuntimeException("Package manager has died", e);
    618         }
    619 
    620         throw new NameNotFoundException(className.toString());
    621     }
    622 
    623     @Override
    624     public List<InstrumentationInfo> queryInstrumentation(
    625         String targetPackage, int flags) {
    626         try {
    627             return mPM.queryInstrumentation(targetPackage, flags);
    628         } catch (RemoteException e) {
    629             throw new RuntimeException("Package manager has died", e);
    630         }
    631     }
    632 
    633     @Override public Drawable getDrawable(String packageName, int resid,
    634                                           ApplicationInfo appInfo) {
    635         ResourceName name = new ResourceName(packageName, resid);
    636         Drawable dr = getCachedIcon(name);
    637         if (dr != null) {
    638             return dr;
    639         }
    640         if (appInfo == null) {
    641             try {
    642                 appInfo = getApplicationInfo(packageName, 0);
    643             } catch (NameNotFoundException e) {
    644                 return null;
    645             }
    646         }
    647         try {
    648             Resources r = getResourcesForApplication(appInfo);
    649             dr = r.getDrawable(resid);
    650             if (false) {
    651                 RuntimeException e = new RuntimeException("here");
    652                 e.fillInStackTrace();
    653                 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
    654                       + " from package " + packageName
    655                       + ": app scale=" + r.getCompatibilityInfo().applicationScale
    656                       + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
    657                       e);
    658             }
    659             if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
    660                                    + Integer.toHexString(resid) + " from " + r
    661                                    + ": " + dr);
    662             putCachedIcon(name, dr);
    663             return dr;
    664         } catch (NameNotFoundException e) {
    665             Log.w("PackageManager", "Failure retrieving resources for"
    666                   + appInfo.packageName);
    667         } catch (Resources.NotFoundException e) {
    668             Log.w("PackageManager", "Failure retrieving resources for"
    669                   + appInfo.packageName + ": " + e.getMessage());
    670         } catch (RuntimeException e) {
    671             // If an exception was thrown, fall through to return
    672             // default icon.
    673             Log.w("PackageManager", "Failure retrieving icon 0x"
    674                   + Integer.toHexString(resid) + " in package "
    675                   + packageName, e);
    676         }
    677         return null;
    678     }
    679 
    680     @Override public Drawable getActivityIcon(ComponentName activityName)
    681             throws NameNotFoundException {
    682         return getActivityInfo(activityName, 0).loadIcon(this);
    683     }
    684 
    685     @Override public Drawable getActivityIcon(Intent intent)
    686             throws NameNotFoundException {
    687         if (intent.getComponent() != null) {
    688             return getActivityIcon(intent.getComponent());
    689         }
    690 
    691         ResolveInfo info = resolveActivity(
    692             intent, PackageManager.MATCH_DEFAULT_ONLY);
    693         if (info != null) {
    694             return info.activityInfo.loadIcon(this);
    695         }
    696 
    697         throw new NameNotFoundException(intent.toUri(0));
    698     }
    699 
    700     @Override public Drawable getDefaultActivityIcon() {
    701         return Resources.getSystem().getDrawable(
    702             com.android.internal.R.drawable.sym_def_app_icon);
    703     }
    704 
    705     @Override public Drawable getApplicationIcon(ApplicationInfo info) {
    706         return info.loadIcon(this);
    707     }
    708 
    709     @Override public Drawable getApplicationIcon(String packageName)
    710             throws NameNotFoundException {
    711         return getApplicationIcon(getApplicationInfo(packageName, 0));
    712     }
    713 
    714     @Override
    715     public Drawable getActivityLogo(ComponentName activityName)
    716             throws NameNotFoundException {
    717         return getActivityInfo(activityName, 0).loadLogo(this);
    718     }
    719 
    720     @Override
    721     public Drawable getActivityLogo(Intent intent)
    722             throws NameNotFoundException {
    723         if (intent.getComponent() != null) {
    724             return getActivityLogo(intent.getComponent());
    725         }
    726 
    727         ResolveInfo info = resolveActivity(
    728             intent, PackageManager.MATCH_DEFAULT_ONLY);
    729         if (info != null) {
    730             return info.activityInfo.loadLogo(this);
    731         }
    732 
    733         throw new NameNotFoundException(intent.toUri(0));
    734     }
    735 
    736     @Override
    737     public Drawable getApplicationLogo(ApplicationInfo info) {
    738         return info.loadLogo(this);
    739     }
    740 
    741     @Override
    742     public Drawable getApplicationLogo(String packageName)
    743             throws NameNotFoundException {
    744         return getApplicationLogo(getApplicationInfo(packageName, 0));
    745     }
    746 
    747     @Override public Resources getResourcesForActivity(
    748         ComponentName activityName) throws NameNotFoundException {
    749         return getResourcesForApplication(
    750             getActivityInfo(activityName, 0).applicationInfo);
    751     }
    752 
    753     @Override public Resources getResourcesForApplication(
    754         ApplicationInfo app) throws NameNotFoundException {
    755         if (app.packageName.equals("system")) {
    756             return mContext.mMainThread.getSystemContext().getResources();
    757         }
    758         Resources r = mContext.mMainThread.getTopLevelResources(
    759                 app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
    760                         Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
    761         if (r != null) {
    762             return r;
    763         }
    764         throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
    765     }
    766 
    767     @Override public Resources getResourcesForApplication(
    768         String appPackageName) throws NameNotFoundException {
    769         return getResourcesForApplication(
    770             getApplicationInfo(appPackageName, 0));
    771     }
    772 
    773     /** @hide */
    774     @Override
    775     public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
    776             throws NameNotFoundException {
    777         if (userId < 0) {
    778             throw new IllegalArgumentException(
    779                     "Call does not support special user #" + userId);
    780         }
    781         if ("system".equals(appPackageName)) {
    782             return mContext.mMainThread.getSystemContext().getResources();
    783         }
    784         try {
    785             ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, 0, userId);
    786             if (ai != null) {
    787                 return getResourcesForApplication(ai);
    788             }
    789         } catch (RemoteException e) {
    790             throw new RuntimeException("Package manager has died", e);
    791         }
    792         throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
    793     }
    794 
    795     int mCachedSafeMode = -1;
    796     @Override public boolean isSafeMode() {
    797         try {
    798             if (mCachedSafeMode < 0) {
    799                 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
    800             }
    801             return mCachedSafeMode != 0;
    802         } catch (RemoteException e) {
    803             throw new RuntimeException("Package manager has died", e);
    804         }
    805     }
    806 
    807     static void configurationChanged() {
    808         synchronized (sSync) {
    809             sIconCache.clear();
    810             sStringCache.clear();
    811         }
    812     }
    813 
    814     ApplicationPackageManager(ContextImpl context,
    815                               IPackageManager pm) {
    816         mContext = context;
    817         mPM = pm;
    818     }
    819 
    820     private Drawable getCachedIcon(ResourceName name) {
    821         synchronized (sSync) {
    822             WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
    823             if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
    824                                    + name + ": " + wr);
    825             if (wr != null) {   // we have the activity
    826                 Drawable.ConstantState state = wr.get();
    827                 if (state != null) {
    828                     if (DEBUG_ICONS) {
    829                         Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
    830                     }
    831                     // Note: It's okay here to not use the newDrawable(Resources) variant
    832                     //       of the API. The ConstantState comes from a drawable that was
    833                     //       originally created by passing the proper app Resources instance
    834                     //       which means the state should already contain the proper
    835                     //       resources specific information (like density.) See
    836                     //       BitmapDrawable.BitmapState for instance.
    837                     return state.newDrawable();
    838                 }
    839                 // our entry has been purged
    840                 sIconCache.remove(name);
    841             }
    842         }
    843         return null;
    844     }
    845 
    846     private void putCachedIcon(ResourceName name, Drawable dr) {
    847         synchronized (sSync) {
    848             sIconCache.put(name, new WeakReference<Drawable.ConstantState>(dr.getConstantState()));
    849             if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
    850         }
    851     }
    852 
    853     static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
    854         boolean immediateGc = false;
    855         if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
    856             immediateGc = true;
    857         }
    858         if (pkgList != null && (pkgList.length > 0)) {
    859             boolean needCleanup = false;
    860             for (String ssp : pkgList) {
    861                 synchronized (sSync) {
    862                     if (sIconCache.size() > 0) {
    863                         Iterator<ResourceName> it = sIconCache.keySet().iterator();
    864                         while (it.hasNext()) {
    865                             ResourceName nm = it.next();
    866                             if (nm.packageName.equals(ssp)) {
    867                                 //Log.i(TAG, "Removing cached drawable for " + nm);
    868                                 it.remove();
    869                                 needCleanup = true;
    870                             }
    871                         }
    872                     }
    873                     if (sStringCache.size() > 0) {
    874                         Iterator<ResourceName> it = sStringCache.keySet().iterator();
    875                         while (it.hasNext()) {
    876                             ResourceName nm = it.next();
    877                             if (nm.packageName.equals(ssp)) {
    878                                 //Log.i(TAG, "Removing cached string for " + nm);
    879                                 it.remove();
    880                                 needCleanup = true;
    881                             }
    882                         }
    883                     }
    884                 }
    885             }
    886             if (needCleanup || hasPkgInfo) {
    887                 if (immediateGc) {
    888                     // Schedule an immediate gc.
    889                     Runtime.getRuntime().gc();
    890                 } else {
    891                     ActivityThread.currentActivityThread().scheduleGcIdler();
    892                 }
    893             }
    894         }
    895     }
    896 
    897     private static final class ResourceName {
    898         final String packageName;
    899         final int iconId;
    900 
    901         ResourceName(String _packageName, int _iconId) {
    902             packageName = _packageName;
    903             iconId = _iconId;
    904         }
    905 
    906         ResourceName(ApplicationInfo aInfo, int _iconId) {
    907             this(aInfo.packageName, _iconId);
    908         }
    909 
    910         ResourceName(ComponentInfo cInfo, int _iconId) {
    911             this(cInfo.applicationInfo.packageName, _iconId);
    912         }
    913 
    914         ResourceName(ResolveInfo rInfo, int _iconId) {
    915             this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
    916         }
    917 
    918         @Override
    919         public boolean equals(Object o) {
    920             if (this == o) return true;
    921             if (o == null || getClass() != o.getClass()) return false;
    922 
    923             ResourceName that = (ResourceName) o;
    924 
    925             if (iconId != that.iconId) return false;
    926             return !(packageName != null ?
    927                      !packageName.equals(that.packageName) : that.packageName != null);
    928 
    929         }
    930 
    931         @Override
    932         public int hashCode() {
    933             int result;
    934             result = packageName.hashCode();
    935             result = 31 * result + iconId;
    936             return result;
    937         }
    938 
    939         @Override
    940         public String toString() {
    941             return "{ResourceName " + packageName + " / " + iconId + "}";
    942         }
    943     }
    944 
    945     private CharSequence getCachedString(ResourceName name) {
    946         synchronized (sSync) {
    947             WeakReference<CharSequence> wr = sStringCache.get(name);
    948             if (wr != null) {   // we have the activity
    949                 CharSequence cs = wr.get();
    950                 if (cs != null) {
    951                     return cs;
    952                 }
    953                 // our entry has been purged
    954                 sStringCache.remove(name);
    955             }
    956         }
    957         return null;
    958     }
    959 
    960     private void putCachedString(ResourceName name, CharSequence cs) {
    961         synchronized (sSync) {
    962             sStringCache.put(name, new WeakReference<CharSequence>(cs));
    963         }
    964     }
    965 
    966     @Override
    967     public CharSequence getText(String packageName, int resid,
    968                                 ApplicationInfo appInfo) {
    969         ResourceName name = new ResourceName(packageName, resid);
    970         CharSequence text = getCachedString(name);
    971         if (text != null) {
    972             return text;
    973         }
    974         if (appInfo == null) {
    975             try {
    976                 appInfo = getApplicationInfo(packageName, 0);
    977             } catch (NameNotFoundException e) {
    978                 return null;
    979             }
    980         }
    981         try {
    982             Resources r = getResourcesForApplication(appInfo);
    983             text = r.getText(resid);
    984             putCachedString(name, text);
    985             return text;
    986         } catch (NameNotFoundException e) {
    987             Log.w("PackageManager", "Failure retrieving resources for"
    988                   + appInfo.packageName);
    989         } catch (RuntimeException e) {
    990             // If an exception was thrown, fall through to return
    991             // default icon.
    992             Log.w("PackageManager", "Failure retrieving text 0x"
    993                   + Integer.toHexString(resid) + " in package "
    994                   + packageName, e);
    995         }
    996         return null;
    997     }
    998 
    999     @Override
   1000     public XmlResourceParser getXml(String packageName, int resid,
   1001                                     ApplicationInfo appInfo) {
   1002         if (appInfo == null) {
   1003             try {
   1004                 appInfo = getApplicationInfo(packageName, 0);
   1005             } catch (NameNotFoundException e) {
   1006                 return null;
   1007             }
   1008         }
   1009         try {
   1010             Resources r = getResourcesForApplication(appInfo);
   1011             return r.getXml(resid);
   1012         } catch (RuntimeException e) {
   1013             // If an exception was thrown, fall through to return
   1014             // default icon.
   1015             Log.w("PackageManager", "Failure retrieving xml 0x"
   1016                   + Integer.toHexString(resid) + " in package "
   1017                   + packageName, e);
   1018         } catch (NameNotFoundException e) {
   1019             Log.w("PackageManager", "Failure retrieving resources for "
   1020                   + appInfo.packageName);
   1021         }
   1022         return null;
   1023     }
   1024 
   1025     @Override
   1026     public CharSequence getApplicationLabel(ApplicationInfo info) {
   1027         return info.loadLabel(this);
   1028     }
   1029 
   1030     @Override
   1031     public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
   1032                                String installerPackageName) {
   1033         try {
   1034             mPM.installPackage(packageURI, observer, flags, installerPackageName);
   1035         } catch (RemoteException e) {
   1036             // Should never happen!
   1037         }
   1038     }
   1039 
   1040     @Override
   1041     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
   1042             int flags, String installerPackageName, Uri verificationURI,
   1043             ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
   1044         try {
   1045             mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
   1046                     verificationURI, manifestDigest, encryptionParams);
   1047         } catch (RemoteException e) {
   1048             // Should never happen!
   1049         }
   1050     }
   1051 
   1052     @Override
   1053 	  public void installPackageWithVerificationAndEncryption(Uri packageURI,
   1054             IPackageInstallObserver observer, int flags, String installerPackageName,
   1055             VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
   1056         try {
   1057             mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags,
   1058                     installerPackageName, verificationParams, encryptionParams);
   1059         } catch (RemoteException e) {
   1060             // Should never happen!
   1061         }
   1062     }
   1063 
   1064     @Override
   1065     public int installExistingPackage(String packageName)
   1066             throws NameNotFoundException {
   1067         try {
   1068             int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
   1069             if (res == INSTALL_FAILED_INVALID_URI) {
   1070                 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
   1071             }
   1072             return res;
   1073         } catch (RemoteException e) {
   1074             // Should never happen!
   1075             throw new NameNotFoundException("Package " + packageName + " doesn't exist");
   1076         }
   1077     }
   1078 
   1079     @Override
   1080     public void verifyPendingInstall(int id, int response) {
   1081         try {
   1082             mPM.verifyPendingInstall(id, response);
   1083         } catch (RemoteException e) {
   1084             // Should never happen!
   1085         }
   1086     }
   1087 
   1088     @Override
   1089     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
   1090             long millisecondsToDelay) {
   1091         try {
   1092             mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
   1093         } catch (RemoteException e) {
   1094             // Should never happen!
   1095         }
   1096     }
   1097 
   1098     @Override
   1099     public void setInstallerPackageName(String targetPackage,
   1100             String installerPackageName) {
   1101         try {
   1102             mPM.setInstallerPackageName(targetPackage, installerPackageName);
   1103         } catch (RemoteException e) {
   1104             // Should never happen!
   1105         }
   1106     }
   1107 
   1108     @Override
   1109     public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
   1110         try {
   1111             mPM.movePackage(packageName, observer, flags);
   1112         } catch (RemoteException e) {
   1113             // Should never happen!
   1114         }
   1115     }
   1116 
   1117     @Override
   1118     public String getInstallerPackageName(String packageName) {
   1119         try {
   1120             return mPM.getInstallerPackageName(packageName);
   1121         } catch (RemoteException e) {
   1122             // Should never happen!
   1123         }
   1124         return null;
   1125     }
   1126 
   1127     @Override
   1128     public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
   1129         try {
   1130             mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
   1131         } catch (RemoteException e) {
   1132             // Should never happen!
   1133         }
   1134     }
   1135     @Override
   1136     public void clearApplicationUserData(String packageName,
   1137                                          IPackageDataObserver observer) {
   1138         try {
   1139             mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
   1140         } catch (RemoteException e) {
   1141             // Should never happen!
   1142         }
   1143     }
   1144     @Override
   1145     public void deleteApplicationCacheFiles(String packageName,
   1146                                             IPackageDataObserver observer) {
   1147         try {
   1148             mPM.deleteApplicationCacheFiles(packageName, observer);
   1149         } catch (RemoteException e) {
   1150             // Should never happen!
   1151         }
   1152     }
   1153     @Override
   1154     public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
   1155         try {
   1156             mPM.freeStorageAndNotify(idealStorageSize, observer);
   1157         } catch (RemoteException e) {
   1158             // Should never happen!
   1159         }
   1160     }
   1161 
   1162     @Override
   1163     public void freeStorage(long freeStorageSize, IntentSender pi) {
   1164         try {
   1165             mPM.freeStorage(freeStorageSize, pi);
   1166         } catch (RemoteException e) {
   1167             // Should never happen!
   1168         }
   1169     }
   1170 
   1171     @Override
   1172     public void getPackageSizeInfo(String packageName, int userHandle,
   1173             IPackageStatsObserver observer) {
   1174         try {
   1175             mPM.getPackageSizeInfo(packageName, userHandle, observer);
   1176         } catch (RemoteException e) {
   1177             // Should never happen!
   1178         }
   1179     }
   1180     @Override
   1181     public void addPackageToPreferred(String packageName) {
   1182         try {
   1183             mPM.addPackageToPreferred(packageName);
   1184         } catch (RemoteException e) {
   1185             // Should never happen!
   1186         }
   1187     }
   1188 
   1189     @Override
   1190     public void removePackageFromPreferred(String packageName) {
   1191         try {
   1192             mPM.removePackageFromPreferred(packageName);
   1193         } catch (RemoteException e) {
   1194             // Should never happen!
   1195         }
   1196     }
   1197 
   1198     @Override
   1199     public List<PackageInfo> getPreferredPackages(int flags) {
   1200         try {
   1201             return mPM.getPreferredPackages(flags);
   1202         } catch (RemoteException e) {
   1203             // Should never happen!
   1204         }
   1205         return new ArrayList<PackageInfo>();
   1206     }
   1207 
   1208     @Override
   1209     public void addPreferredActivity(IntentFilter filter,
   1210                                      int match, ComponentName[] set, ComponentName activity) {
   1211         try {
   1212             mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
   1213         } catch (RemoteException e) {
   1214             // Should never happen!
   1215         }
   1216     }
   1217 
   1218     @Override
   1219     public void addPreferredActivity(IntentFilter filter, int match,
   1220             ComponentName[] set, ComponentName activity, int userId) {
   1221         try {
   1222             mPM.addPreferredActivity(filter, match, set, activity, userId);
   1223         } catch (RemoteException e) {
   1224             // Should never happen!
   1225         }
   1226     }
   1227 
   1228     @Override
   1229     public void replacePreferredActivity(IntentFilter filter,
   1230                                          int match, ComponentName[] set, ComponentName activity) {
   1231         try {
   1232             mPM.replacePreferredActivity(filter, match, set, activity);
   1233         } catch (RemoteException e) {
   1234             // Should never happen!
   1235         }
   1236     }
   1237 
   1238     @Override
   1239     public void clearPackagePreferredActivities(String packageName) {
   1240         try {
   1241             mPM.clearPackagePreferredActivities(packageName);
   1242         } catch (RemoteException e) {
   1243             // Should never happen!
   1244         }
   1245     }
   1246 
   1247     @Override
   1248     public int getPreferredActivities(List<IntentFilter> outFilters,
   1249                                       List<ComponentName> outActivities, String packageName) {
   1250         try {
   1251             return mPM.getPreferredActivities(outFilters, outActivities, packageName);
   1252         } catch (RemoteException e) {
   1253             // Should never happen!
   1254         }
   1255         return 0;
   1256     }
   1257 
   1258     @Override
   1259     public void setComponentEnabledSetting(ComponentName componentName,
   1260                                            int newState, int flags) {
   1261         try {
   1262             mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
   1263         } catch (RemoteException e) {
   1264             // Should never happen!
   1265         }
   1266     }
   1267 
   1268     @Override
   1269     public int getComponentEnabledSetting(ComponentName componentName) {
   1270         try {
   1271             return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
   1272         } catch (RemoteException e) {
   1273             // Should never happen!
   1274         }
   1275         return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   1276     }
   1277 
   1278     @Override
   1279     public void setApplicationEnabledSetting(String packageName,
   1280                                              int newState, int flags) {
   1281         try {
   1282             mPM.setApplicationEnabledSetting(packageName, newState, flags,
   1283                     mContext.getUserId(), mContext.getBasePackageName());
   1284         } catch (RemoteException e) {
   1285             // Should never happen!
   1286         }
   1287     }
   1288 
   1289     @Override
   1290     public int getApplicationEnabledSetting(String packageName) {
   1291         try {
   1292             return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
   1293         } catch (RemoteException e) {
   1294             // Should never happen!
   1295         }
   1296         return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   1297     }
   1298 
   1299     /**
   1300      * @hide
   1301      */
   1302     @Override
   1303     public VerifierDeviceIdentity getVerifierDeviceIdentity() {
   1304         try {
   1305             return mPM.getVerifierDeviceIdentity();
   1306         } catch (RemoteException e) {
   1307             // Should never happen!
   1308         }
   1309         return null;
   1310     }
   1311 
   1312     private final ContextImpl mContext;
   1313     private final IPackageManager mPM;
   1314 
   1315     private static final Object sSync = new Object();
   1316     private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
   1317             = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>();
   1318     private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache
   1319             = new HashMap<ResourceName, WeakReference<CharSequence>>();
   1320 }
   1321