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