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