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.UserInfo;
     45 import android.content.pm.ManifestDigest;
     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.UserId;
     54 import android.util.Log;
     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, UserId.myUserId());
     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, UserId.myUserId());
    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, UserId.myUserId());
    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, UserId.myUserId());
    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, UserId.myUserId());
    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, UserId.myUserId());
    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         try {
    408             final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
    409             PackageInfo lastItem = null;
    410             ParceledListSlice<PackageInfo> slice;
    411 
    412             do {
    413                 final String lastKey = lastItem != null ? lastItem.packageName : null;
    414                 slice = mPM.getInstalledPackages(flags, lastKey);
    415                 lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
    416             } while (!slice.isLastSlice());
    417 
    418             return packageInfos;
    419         } catch (RemoteException e) {
    420             throw new RuntimeException("Package manager has died", e);
    421         }
    422     }
    423 
    424     @SuppressWarnings("unchecked")
    425     @Override
    426     public List<ApplicationInfo> getInstalledApplications(int flags) {
    427         int userId = UserId.getUserId(Process.myUid());
    428         try {
    429             final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>();
    430             ApplicationInfo lastItem = null;
    431             ParceledListSlice<ApplicationInfo> slice;
    432 
    433             do {
    434                 final String lastKey = lastItem != null ? lastItem.packageName : null;
    435                 slice = mPM.getInstalledApplications(flags, lastKey, userId);
    436                 lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR);
    437             } while (!slice.isLastSlice());
    438 
    439             return applicationInfos;
    440         } catch (RemoteException e) {
    441             throw new RuntimeException("Package manager has died", e);
    442         }
    443     }
    444 
    445     @Override
    446     public ResolveInfo resolveActivity(Intent intent, int flags) {
    447         try {
    448             return mPM.resolveIntent(
    449                 intent,
    450                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    451                     flags, UserId.myUserId());
    452         } catch (RemoteException e) {
    453             throw new RuntimeException("Package manager has died", e);
    454         }
    455     }
    456 
    457     @Override
    458     public List<ResolveInfo> queryIntentActivities(Intent intent,
    459                                                    int flags) {
    460         try {
    461             return mPM.queryIntentActivities(
    462                 intent,
    463                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    464                 flags,
    465                 UserId.myUserId());
    466         } catch (RemoteException e) {
    467             throw new RuntimeException("Package manager has died", e);
    468         }
    469     }
    470 
    471     @Override
    472     public List<ResolveInfo> queryIntentActivityOptions(
    473         ComponentName caller, Intent[] specifics, Intent intent,
    474         int flags) {
    475         final ContentResolver resolver = mContext.getContentResolver();
    476 
    477         String[] specificTypes = null;
    478         if (specifics != null) {
    479             final int N = specifics.length;
    480             for (int i=0; i<N; i++) {
    481                 Intent sp = specifics[i];
    482                 if (sp != null) {
    483                     String t = sp.resolveTypeIfNeeded(resolver);
    484                     if (t != null) {
    485                         if (specificTypes == null) {
    486                             specificTypes = new String[N];
    487                         }
    488                         specificTypes[i] = t;
    489                     }
    490                 }
    491             }
    492         }
    493 
    494         try {
    495             return mPM.queryIntentActivityOptions(caller, specifics,
    496                                                   specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
    497                                                   flags, UserId.myUserId());
    498         } catch (RemoteException e) {
    499             throw new RuntimeException("Package manager has died", e);
    500         }
    501     }
    502 
    503     @Override
    504     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
    505         try {
    506             return mPM.queryIntentReceivers(
    507                 intent,
    508                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    509                 flags,
    510                 UserId.myUserId());
    511         } catch (RemoteException e) {
    512             throw new RuntimeException("Package manager has died", e);
    513         }
    514     }
    515 
    516     @Override
    517     public ResolveInfo resolveService(Intent intent, int flags) {
    518         try {
    519             return mPM.resolveService(
    520                 intent,
    521                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    522                 flags,
    523                 UserId.myUserId());
    524         } catch (RemoteException e) {
    525             throw new RuntimeException("Package manager has died", e);
    526         }
    527     }
    528 
    529     @Override
    530     public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
    531         try {
    532             return mPM.queryIntentServices(
    533                 intent,
    534                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    535                 flags,
    536                 UserId.myUserId());
    537         } catch (RemoteException e) {
    538             throw new RuntimeException("Package manager has died", e);
    539         }
    540     }
    541 
    542     @Override
    543     public ProviderInfo resolveContentProvider(String name,
    544                                                int flags) {
    545         try {
    546             return mPM.resolveContentProvider(name, flags, UserId.myUserId());
    547         } catch (RemoteException e) {
    548             throw new RuntimeException("Package manager has died", e);
    549         }
    550     }
    551 
    552     @Override
    553     public List<ProviderInfo> queryContentProviders(String processName,
    554                                                     int uid, int flags) {
    555         try {
    556             return mPM.queryContentProviders(processName, uid, flags);
    557         } catch (RemoteException e) {
    558             throw new RuntimeException("Package manager has died", e);
    559         }
    560     }
    561 
    562     @Override
    563     public InstrumentationInfo getInstrumentationInfo(
    564         ComponentName className, int flags)
    565             throws NameNotFoundException {
    566         try {
    567             InstrumentationInfo ii = mPM.getInstrumentationInfo(
    568                 className, flags);
    569             if (ii != null) {
    570                 return ii;
    571             }
    572         } catch (RemoteException e) {
    573             throw new RuntimeException("Package manager has died", e);
    574         }
    575 
    576         throw new NameNotFoundException(className.toString());
    577     }
    578 
    579     @Override
    580     public List<InstrumentationInfo> queryInstrumentation(
    581         String targetPackage, int flags) {
    582         try {
    583             return mPM.queryInstrumentation(targetPackage, flags);
    584         } catch (RemoteException e) {
    585             throw new RuntimeException("Package manager has died", e);
    586         }
    587     }
    588 
    589     @Override public Drawable getDrawable(String packageName, int resid,
    590                                           ApplicationInfo appInfo) {
    591         ResourceName name = new ResourceName(packageName, resid);
    592         Drawable dr = getCachedIcon(name);
    593         if (dr != null) {
    594             return dr;
    595         }
    596         if (appInfo == null) {
    597             try {
    598                 appInfo = getApplicationInfo(packageName, 0);
    599             } catch (NameNotFoundException e) {
    600                 return null;
    601             }
    602         }
    603         try {
    604             Resources r = getResourcesForApplication(appInfo);
    605             dr = r.getDrawable(resid);
    606             if (false) {
    607                 RuntimeException e = new RuntimeException("here");
    608                 e.fillInStackTrace();
    609                 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
    610                       + " from package " + packageName
    611                       + ": app scale=" + r.getCompatibilityInfo().applicationScale
    612                       + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
    613                       e);
    614             }
    615             if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
    616                                    + Integer.toHexString(resid) + " from " + r
    617                                    + ": " + dr);
    618             putCachedIcon(name, dr);
    619             return dr;
    620         } catch (NameNotFoundException e) {
    621             Log.w("PackageManager", "Failure retrieving resources for"
    622                   + appInfo.packageName);
    623         } catch (Resources.NotFoundException e) {
    624             Log.w("PackageManager", "Failure retrieving resources for"
    625                   + appInfo.packageName + ": " + e.getMessage());
    626         } catch (RuntimeException e) {
    627             // If an exception was thrown, fall through to return
    628             // default icon.
    629             Log.w("PackageManager", "Failure retrieving icon 0x"
    630                   + Integer.toHexString(resid) + " in package "
    631                   + packageName, e);
    632         }
    633         return null;
    634     }
    635 
    636     @Override public Drawable getActivityIcon(ComponentName activityName)
    637             throws NameNotFoundException {
    638         return getActivityInfo(activityName, 0).loadIcon(this);
    639     }
    640 
    641     @Override public Drawable getActivityIcon(Intent intent)
    642             throws NameNotFoundException {
    643         if (intent.getComponent() != null) {
    644             return getActivityIcon(intent.getComponent());
    645         }
    646 
    647         ResolveInfo info = resolveActivity(
    648             intent, PackageManager.MATCH_DEFAULT_ONLY);
    649         if (info != null) {
    650             return info.activityInfo.loadIcon(this);
    651         }
    652 
    653         throw new NameNotFoundException(intent.toUri(0));
    654     }
    655 
    656     @Override public Drawable getDefaultActivityIcon() {
    657         return Resources.getSystem().getDrawable(
    658             com.android.internal.R.drawable.sym_def_app_icon);
    659     }
    660 
    661     @Override public Drawable getApplicationIcon(ApplicationInfo info) {
    662         return info.loadIcon(this);
    663     }
    664 
    665     @Override public Drawable getApplicationIcon(String packageName)
    666             throws NameNotFoundException {
    667         return getApplicationIcon(getApplicationInfo(packageName, 0));
    668     }
    669 
    670     @Override
    671     public Drawable getActivityLogo(ComponentName activityName)
    672             throws NameNotFoundException {
    673         return getActivityInfo(activityName, 0).loadLogo(this);
    674     }
    675 
    676     @Override
    677     public Drawable getActivityLogo(Intent intent)
    678             throws NameNotFoundException {
    679         if (intent.getComponent() != null) {
    680             return getActivityLogo(intent.getComponent());
    681         }
    682 
    683         ResolveInfo info = resolveActivity(
    684             intent, PackageManager.MATCH_DEFAULT_ONLY);
    685         if (info != null) {
    686             return info.activityInfo.loadLogo(this);
    687         }
    688 
    689         throw new NameNotFoundException(intent.toUri(0));
    690     }
    691 
    692     @Override
    693     public Drawable getApplicationLogo(ApplicationInfo info) {
    694         return info.loadLogo(this);
    695     }
    696 
    697     @Override
    698     public Drawable getApplicationLogo(String packageName)
    699             throws NameNotFoundException {
    700         return getApplicationLogo(getApplicationInfo(packageName, 0));
    701     }
    702 
    703     @Override public Resources getResourcesForActivity(
    704         ComponentName activityName) throws NameNotFoundException {
    705         return getResourcesForApplication(
    706             getActivityInfo(activityName, 0).applicationInfo);
    707     }
    708 
    709     @Override public Resources getResourcesForApplication(
    710         ApplicationInfo app) throws NameNotFoundException {
    711         if (app.packageName.equals("system")) {
    712             return mContext.mMainThread.getSystemContext().getResources();
    713         }
    714         Resources r = mContext.mMainThread.getTopLevelResources(
    715             app.uid == Process.myUid() ? app.sourceDir
    716             : app.publicSourceDir, mContext.mPackageInfo);
    717         if (r != null) {
    718             return r;
    719         }
    720         throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
    721     }
    722 
    723     @Override public Resources getResourcesForApplication(
    724         String appPackageName) throws NameNotFoundException {
    725         return getResourcesForApplication(
    726             getApplicationInfo(appPackageName, 0));
    727     }
    728 
    729     int mCachedSafeMode = -1;
    730     @Override public boolean isSafeMode() {
    731         try {
    732             if (mCachedSafeMode < 0) {
    733                 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
    734             }
    735             return mCachedSafeMode != 0;
    736         } catch (RemoteException e) {
    737             throw new RuntimeException("Package manager has died", e);
    738         }
    739     }
    740 
    741     static void configurationChanged() {
    742         synchronized (sSync) {
    743             sIconCache.clear();
    744             sStringCache.clear();
    745         }
    746     }
    747 
    748     ApplicationPackageManager(ContextImpl context,
    749                               IPackageManager pm) {
    750         mContext = context;
    751         mPM = pm;
    752     }
    753 
    754     private Drawable getCachedIcon(ResourceName name) {
    755         synchronized (sSync) {
    756             WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
    757             if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
    758                                    + name + ": " + wr);
    759             if (wr != null) {   // we have the activity
    760                 Drawable.ConstantState state = wr.get();
    761                 if (state != null) {
    762                     if (DEBUG_ICONS) {
    763                         Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
    764                     }
    765                     // Note: It's okay here to not use the newDrawable(Resources) variant
    766                     //       of the API. The ConstantState comes from a drawable that was
    767                     //       originally created by passing the proper app Resources instance
    768                     //       which means the state should already contain the proper
    769                     //       resources specific information (like density.) See
    770                     //       BitmapDrawable.BitmapState for instance.
    771                     return state.newDrawable();
    772                 }
    773                 // our entry has been purged
    774                 sIconCache.remove(name);
    775             }
    776         }
    777         return null;
    778     }
    779 
    780     private void putCachedIcon(ResourceName name, Drawable dr) {
    781         synchronized (sSync) {
    782             sIconCache.put(name, new WeakReference<Drawable.ConstantState>(dr.getConstantState()));
    783             if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
    784         }
    785     }
    786 
    787     static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
    788         boolean immediateGc = false;
    789         if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
    790             immediateGc = true;
    791         }
    792         if (pkgList != null && (pkgList.length > 0)) {
    793             boolean needCleanup = false;
    794             for (String ssp : pkgList) {
    795                 synchronized (sSync) {
    796                     if (sIconCache.size() > 0) {
    797                         Iterator<ResourceName> it = sIconCache.keySet().iterator();
    798                         while (it.hasNext()) {
    799                             ResourceName nm = it.next();
    800                             if (nm.packageName.equals(ssp)) {
    801                                 //Log.i(TAG, "Removing cached drawable for " + nm);
    802                                 it.remove();
    803                                 needCleanup = true;
    804                             }
    805                         }
    806                     }
    807                     if (sStringCache.size() > 0) {
    808                         Iterator<ResourceName> it = sStringCache.keySet().iterator();
    809                         while (it.hasNext()) {
    810                             ResourceName nm = it.next();
    811                             if (nm.packageName.equals(ssp)) {
    812                                 //Log.i(TAG, "Removing cached string for " + nm);
    813                                 it.remove();
    814                                 needCleanup = true;
    815                             }
    816                         }
    817                     }
    818                 }
    819             }
    820             if (needCleanup || hasPkgInfo) {
    821                 if (immediateGc) {
    822                     // Schedule an immediate gc.
    823                     Runtime.getRuntime().gc();
    824                 } else {
    825                     ActivityThread.currentActivityThread().scheduleGcIdler();
    826                 }
    827             }
    828         }
    829     }
    830 
    831     private static final class ResourceName {
    832         final String packageName;
    833         final int iconId;
    834 
    835         ResourceName(String _packageName, int _iconId) {
    836             packageName = _packageName;
    837             iconId = _iconId;
    838         }
    839 
    840         ResourceName(ApplicationInfo aInfo, int _iconId) {
    841             this(aInfo.packageName, _iconId);
    842         }
    843 
    844         ResourceName(ComponentInfo cInfo, int _iconId) {
    845             this(cInfo.applicationInfo.packageName, _iconId);
    846         }
    847 
    848         ResourceName(ResolveInfo rInfo, int _iconId) {
    849             this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
    850         }
    851 
    852         @Override
    853         public boolean equals(Object o) {
    854             if (this == o) return true;
    855             if (o == null || getClass() != o.getClass()) return false;
    856 
    857             ResourceName that = (ResourceName) o;
    858 
    859             if (iconId != that.iconId) return false;
    860             return !(packageName != null ?
    861                      !packageName.equals(that.packageName) : that.packageName != null);
    862 
    863         }
    864 
    865         @Override
    866         public int hashCode() {
    867             int result;
    868             result = packageName.hashCode();
    869             result = 31 * result + iconId;
    870             return result;
    871         }
    872 
    873         @Override
    874         public String toString() {
    875             return "{ResourceName " + packageName + " / " + iconId + "}";
    876         }
    877     }
    878 
    879     private CharSequence getCachedString(ResourceName name) {
    880         synchronized (sSync) {
    881             WeakReference<CharSequence> wr = sStringCache.get(name);
    882             if (wr != null) {   // we have the activity
    883                 CharSequence cs = wr.get();
    884                 if (cs != null) {
    885                     return cs;
    886                 }
    887                 // our entry has been purged
    888                 sStringCache.remove(name);
    889             }
    890         }
    891         return null;
    892     }
    893 
    894     private void putCachedString(ResourceName name, CharSequence cs) {
    895         synchronized (sSync) {
    896             sStringCache.put(name, new WeakReference<CharSequence>(cs));
    897         }
    898     }
    899 
    900     @Override
    901     public CharSequence getText(String packageName, int resid,
    902                                 ApplicationInfo appInfo) {
    903         ResourceName name = new ResourceName(packageName, resid);
    904         CharSequence text = getCachedString(name);
    905         if (text != null) {
    906             return text;
    907         }
    908         if (appInfo == null) {
    909             try {
    910                 appInfo = getApplicationInfo(packageName, 0);
    911             } catch (NameNotFoundException e) {
    912                 return null;
    913             }
    914         }
    915         try {
    916             Resources r = getResourcesForApplication(appInfo);
    917             text = r.getText(resid);
    918             putCachedString(name, text);
    919             return text;
    920         } catch (NameNotFoundException e) {
    921             Log.w("PackageManager", "Failure retrieving resources for"
    922                   + appInfo.packageName);
    923         } catch (RuntimeException e) {
    924             // If an exception was thrown, fall through to return
    925             // default icon.
    926             Log.w("PackageManager", "Failure retrieving text 0x"
    927                   + Integer.toHexString(resid) + " in package "
    928                   + packageName, e);
    929         }
    930         return null;
    931     }
    932 
    933     @Override
    934     public XmlResourceParser getXml(String packageName, int resid,
    935                                     ApplicationInfo appInfo) {
    936         if (appInfo == null) {
    937             try {
    938                 appInfo = getApplicationInfo(packageName, 0);
    939             } catch (NameNotFoundException e) {
    940                 return null;
    941             }
    942         }
    943         try {
    944             Resources r = getResourcesForApplication(appInfo);
    945             return r.getXml(resid);
    946         } catch (RuntimeException e) {
    947             // If an exception was thrown, fall through to return
    948             // default icon.
    949             Log.w("PackageManager", "Failure retrieving xml 0x"
    950                   + Integer.toHexString(resid) + " in package "
    951                   + packageName, e);
    952         } catch (NameNotFoundException e) {
    953             Log.w("PackageManager", "Failure retrieving resources for "
    954                   + appInfo.packageName);
    955         }
    956         return null;
    957     }
    958 
    959     @Override
    960     public CharSequence getApplicationLabel(ApplicationInfo info) {
    961         return info.loadLabel(this);
    962     }
    963 
    964     @Override
    965     public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
    966                                String installerPackageName) {
    967         try {
    968             mPM.installPackage(packageURI, observer, flags, installerPackageName);
    969         } catch (RemoteException e) {
    970             // Should never happen!
    971         }
    972     }
    973 
    974     @Override
    975     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
    976             int flags, String installerPackageName, Uri verificationURI,
    977             ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
    978         try {
    979             mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
    980                     verificationURI, manifestDigest, encryptionParams);
    981         } catch (RemoteException e) {
    982             // Should never happen!
    983         }
    984     }
    985 
    986     @Override
    987     public void verifyPendingInstall(int id, int response) {
    988         try {
    989             mPM.verifyPendingInstall(id, response);
    990         } catch (RemoteException e) {
    991             // Should never happen!
    992         }
    993     }
    994 
    995     @Override
    996     public void setInstallerPackageName(String targetPackage,
    997             String installerPackageName) {
    998         try {
    999             mPM.setInstallerPackageName(targetPackage, installerPackageName);
   1000         } catch (RemoteException e) {
   1001             // Should never happen!
   1002         }
   1003     }
   1004 
   1005     @Override
   1006     public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
   1007         try {
   1008             mPM.movePackage(packageName, observer, flags);
   1009         } catch (RemoteException e) {
   1010             // Should never happen!
   1011         }
   1012     }
   1013 
   1014     @Override
   1015     public String getInstallerPackageName(String packageName) {
   1016         try {
   1017             return mPM.getInstallerPackageName(packageName);
   1018         } catch (RemoteException e) {
   1019             // Should never happen!
   1020         }
   1021         return null;
   1022     }
   1023 
   1024     @Override
   1025     public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
   1026         try {
   1027             mPM.deletePackage(packageName, observer, flags);
   1028         } catch (RemoteException e) {
   1029             // Should never happen!
   1030         }
   1031     }
   1032     @Override
   1033     public void clearApplicationUserData(String packageName,
   1034                                          IPackageDataObserver observer) {
   1035         try {
   1036             mPM.clearApplicationUserData(packageName, observer, UserId.myUserId());
   1037         } catch (RemoteException e) {
   1038             // Should never happen!
   1039         }
   1040     }
   1041     @Override
   1042     public void deleteApplicationCacheFiles(String packageName,
   1043                                             IPackageDataObserver observer) {
   1044         try {
   1045             mPM.deleteApplicationCacheFiles(packageName, observer);
   1046         } catch (RemoteException e) {
   1047             // Should never happen!
   1048         }
   1049     }
   1050     @Override
   1051     public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
   1052         try {
   1053             mPM.freeStorageAndNotify(idealStorageSize, observer);
   1054         } catch (RemoteException e) {
   1055             // Should never happen!
   1056         }
   1057     }
   1058 
   1059     @Override
   1060     public void freeStorage(long freeStorageSize, IntentSender pi) {
   1061         try {
   1062             mPM.freeStorage(freeStorageSize, pi);
   1063         } catch (RemoteException e) {
   1064             // Should never happen!
   1065         }
   1066     }
   1067 
   1068     @Override
   1069     public void getPackageSizeInfo(String packageName,
   1070                                    IPackageStatsObserver observer) {
   1071         try {
   1072             mPM.getPackageSizeInfo(packageName, observer);
   1073         } catch (RemoteException e) {
   1074             // Should never happen!
   1075         }
   1076     }
   1077     @Override
   1078     public void addPackageToPreferred(String packageName) {
   1079         try {
   1080             mPM.addPackageToPreferred(packageName);
   1081         } catch (RemoteException e) {
   1082             // Should never happen!
   1083         }
   1084     }
   1085 
   1086     @Override
   1087     public void removePackageFromPreferred(String packageName) {
   1088         try {
   1089             mPM.removePackageFromPreferred(packageName);
   1090         } catch (RemoteException e) {
   1091             // Should never happen!
   1092         }
   1093     }
   1094 
   1095     @Override
   1096     public List<PackageInfo> getPreferredPackages(int flags) {
   1097         try {
   1098             return mPM.getPreferredPackages(flags);
   1099         } catch (RemoteException e) {
   1100             // Should never happen!
   1101         }
   1102         return new ArrayList<PackageInfo>();
   1103     }
   1104 
   1105     @Override
   1106     public void addPreferredActivity(IntentFilter filter,
   1107                                      int match, ComponentName[] set, ComponentName activity) {
   1108         try {
   1109             mPM.addPreferredActivity(filter, match, set, activity);
   1110         } catch (RemoteException e) {
   1111             // Should never happen!
   1112         }
   1113     }
   1114 
   1115     @Override
   1116     public void replacePreferredActivity(IntentFilter filter,
   1117                                          int match, ComponentName[] set, ComponentName activity) {
   1118         try {
   1119             mPM.replacePreferredActivity(filter, match, set, activity);
   1120         } catch (RemoteException e) {
   1121             // Should never happen!
   1122         }
   1123     }
   1124 
   1125     @Override
   1126     public void clearPackagePreferredActivities(String packageName) {
   1127         try {
   1128             mPM.clearPackagePreferredActivities(packageName);
   1129         } catch (RemoteException e) {
   1130             // Should never happen!
   1131         }
   1132     }
   1133 
   1134     @Override
   1135     public int getPreferredActivities(List<IntentFilter> outFilters,
   1136                                       List<ComponentName> outActivities, String packageName) {
   1137         try {
   1138             return mPM.getPreferredActivities(outFilters, outActivities, packageName);
   1139         } catch (RemoteException e) {
   1140             // Should never happen!
   1141         }
   1142         return 0;
   1143     }
   1144 
   1145     @Override
   1146     public void setComponentEnabledSetting(ComponentName componentName,
   1147                                            int newState, int flags) {
   1148         try {
   1149             mPM.setComponentEnabledSetting(componentName, newState, flags, UserId.myUserId());
   1150         } catch (RemoteException e) {
   1151             // Should never happen!
   1152         }
   1153     }
   1154 
   1155     @Override
   1156     public int getComponentEnabledSetting(ComponentName componentName) {
   1157         try {
   1158             return mPM.getComponentEnabledSetting(componentName, UserId.myUserId());
   1159         } catch (RemoteException e) {
   1160             // Should never happen!
   1161         }
   1162         return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   1163     }
   1164 
   1165     @Override
   1166     public void setApplicationEnabledSetting(String packageName,
   1167                                              int newState, int flags) {
   1168         try {
   1169             mPM.setApplicationEnabledSetting(packageName, newState, flags, UserId.myUserId());
   1170         } catch (RemoteException e) {
   1171             // Should never happen!
   1172         }
   1173     }
   1174 
   1175     @Override
   1176     public int getApplicationEnabledSetting(String packageName) {
   1177         try {
   1178             return mPM.getApplicationEnabledSetting(packageName, UserId.myUserId());
   1179         } catch (RemoteException e) {
   1180             // Should never happen!
   1181         }
   1182         return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   1183     }
   1184 
   1185     // Multi-user support
   1186 
   1187     /**
   1188      * @hide
   1189      */
   1190     @Override
   1191     public UserInfo createUser(String name, int flags) {
   1192         try {
   1193             return mPM.createUser(name, flags);
   1194         } catch (RemoteException e) {
   1195             // Should never happen!
   1196         }
   1197         return null;
   1198     }
   1199 
   1200     /**
   1201      * @hide
   1202      */
   1203     @Override
   1204     public List<UserInfo> getUsers() {
   1205         try {
   1206             return mPM.getUsers();
   1207         } catch (RemoteException re) {
   1208             ArrayList<UserInfo> users = new ArrayList<UserInfo>();
   1209             UserInfo primary = new UserInfo(0, "Root!", UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
   1210             users.add(primary);
   1211             return users;
   1212         }
   1213     }
   1214 
   1215     /**
   1216      * @hide
   1217      */
   1218     @Override
   1219     public UserInfo getUser(int userId) {
   1220         try {
   1221             return mPM.getUser(userId);
   1222         } catch (RemoteException re) {
   1223             return null;
   1224         }
   1225     }
   1226 
   1227     /**
   1228      * @hide
   1229      */
   1230     @Override
   1231     public boolean removeUser(int id) {
   1232         try {
   1233             return mPM.removeUser(id);
   1234         } catch (RemoteException e) {
   1235             return false;
   1236         }
   1237     }
   1238 
   1239     /**
   1240      * @hide
   1241      */
   1242     @Override
   1243     public void updateUserName(int id, String name) {
   1244         try {
   1245             mPM.updateUserName(id, name);
   1246         } catch (RemoteException re) {
   1247         }
   1248     }
   1249 
   1250     /**
   1251      * @hide
   1252      */
   1253     @Override
   1254     public void updateUserFlags(int id, int flags) {
   1255         // TODO:
   1256     }
   1257 
   1258     /**
   1259      * @hide
   1260      */
   1261     @Override
   1262     public VerifierDeviceIdentity getVerifierDeviceIdentity() {
   1263         try {
   1264             return mPM.getVerifierDeviceIdentity();
   1265         } catch (RemoteException e) {
   1266             // Should never happen!
   1267         }
   1268         return null;
   1269     }
   1270 
   1271     private final ContextImpl mContext;
   1272     private final IPackageManager mPM;
   1273 
   1274     private static final Object sSync = new Object();
   1275     private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
   1276             = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>();
   1277     private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache
   1278             = new HashMap<ResourceName, WeakReference<CharSequence>>();
   1279 }
   1280