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.annotation.DrawableRes;
     20 import android.annotation.NonNull;
     21 import android.annotation.Nullable;
     22 import android.annotation.StringRes;
     23 import android.annotation.XmlRes;
     24 import android.app.admin.DevicePolicyManager;
     25 import android.content.ComponentName;
     26 import android.content.ContentResolver;
     27 import android.content.Intent;
     28 import android.content.IntentFilter;
     29 import android.content.IntentSender;
     30 import android.content.pm.ActivityInfo;
     31 import android.content.pm.ApplicationInfo;
     32 import android.content.pm.ComponentInfo;
     33 import android.content.pm.EphemeralApplicationInfo;
     34 import android.content.pm.FeatureInfo;
     35 import android.content.pm.IOnPermissionsChangeListener;
     36 import android.content.pm.IPackageDataObserver;
     37 import android.content.pm.IPackageDeleteObserver;
     38 import android.content.pm.IPackageInstallObserver;
     39 import android.content.pm.IPackageManager;
     40 import android.content.pm.IPackageMoveObserver;
     41 import android.content.pm.IPackageStatsObserver;
     42 import android.content.pm.InstrumentationInfo;
     43 import android.content.pm.IntentFilterVerificationInfo;
     44 import android.content.pm.KeySet;
     45 import android.content.pm.PackageInfo;
     46 import android.content.pm.PackageInstaller;
     47 import android.content.pm.PackageItemInfo;
     48 import android.content.pm.PackageManager;
     49 import android.content.pm.ParceledListSlice;
     50 import android.content.pm.PermissionGroupInfo;
     51 import android.content.pm.PermissionInfo;
     52 import android.content.pm.ProviderInfo;
     53 import android.content.pm.ResolveInfo;
     54 import android.content.pm.ServiceInfo;
     55 import android.content.pm.UserInfo;
     56 import android.content.pm.VerifierDeviceIdentity;
     57 import android.content.res.Resources;
     58 import android.content.res.XmlResourceParser;
     59 import android.graphics.Bitmap;
     60 import android.graphics.Canvas;
     61 import android.graphics.Rect;
     62 import android.graphics.drawable.BitmapDrawable;
     63 import android.graphics.drawable.Drawable;
     64 import android.net.Uri;
     65 import android.os.Bundle;
     66 import android.os.Handler;
     67 import android.os.Looper;
     68 import android.os.Message;
     69 import android.os.Process;
     70 import android.os.RemoteException;
     71 import android.os.SystemProperties;
     72 import android.os.UserHandle;
     73 import android.os.UserManager;
     74 import android.os.storage.StorageManager;
     75 import android.os.storage.VolumeInfo;
     76 import android.provider.Settings;
     77 import android.util.ArrayMap;
     78 import android.util.Log;
     79 import android.view.Display;
     80 
     81 import dalvik.system.VMRuntime;
     82 
     83 import com.android.internal.annotations.GuardedBy;
     84 import com.android.internal.os.SomeArgs;
     85 import com.android.internal.util.Preconditions;
     86 import com.android.internal.util.UserIcons;
     87 import libcore.util.EmptyArray;
     88 
     89 import java.lang.ref.WeakReference;
     90 import java.util.ArrayList;
     91 import java.util.Collections;
     92 import java.util.Iterator;
     93 import java.util.List;
     94 import java.util.Map;
     95 import java.util.Objects;
     96 
     97 /** @hide */
     98 public class ApplicationPackageManager extends PackageManager {
     99     private static final String TAG = "ApplicationPackageManager";
    100     private final static boolean DEBUG_ICONS = false;
    101 
    102     private static final int DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES = 16384; // 16KB
    103 
    104     // Default flags to use with PackageManager when no flags are given.
    105     private final static int sDefaultFlags = PackageManager.GET_SHARED_LIBRARY_FILES;
    106 
    107     private final Object mLock = new Object();
    108 
    109     @GuardedBy("mLock")
    110     private UserManager mUserManager;
    111     @GuardedBy("mLock")
    112     private PackageInstaller mInstaller;
    113 
    114     @GuardedBy("mDelegates")
    115     private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>();
    116 
    117     @GuardedBy("mLock")
    118     private String mPermissionsControllerPackageName;
    119 
    120     UserManager getUserManager() {
    121         synchronized (mLock) {
    122             if (mUserManager == null) {
    123                 mUserManager = UserManager.get(mContext);
    124             }
    125             return mUserManager;
    126         }
    127     }
    128 
    129     @Override
    130     public PackageInfo getPackageInfo(String packageName, int flags)
    131             throws NameNotFoundException {
    132         return getPackageInfoAsUser(packageName, flags, mContext.getUserId());
    133     }
    134 
    135     @Override
    136     public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
    137             throws NameNotFoundException {
    138         try {
    139             PackageInfo pi = mPM.getPackageInfo(packageName, flags, userId);
    140             if (pi != null) {
    141                 return pi;
    142             }
    143         } catch (RemoteException e) {
    144             throw e.rethrowFromSystemServer();
    145         }
    146 
    147         throw new NameNotFoundException(packageName);
    148     }
    149 
    150     @Override
    151     public String[] currentToCanonicalPackageNames(String[] names) {
    152         try {
    153             return mPM.currentToCanonicalPackageNames(names);
    154         } catch (RemoteException e) {
    155             throw e.rethrowFromSystemServer();
    156         }
    157     }
    158 
    159     @Override
    160     public String[] canonicalToCurrentPackageNames(String[] names) {
    161         try {
    162             return mPM.canonicalToCurrentPackageNames(names);
    163         } catch (RemoteException e) {
    164             throw e.rethrowFromSystemServer();
    165         }
    166     }
    167 
    168     @Override
    169     public Intent getLaunchIntentForPackage(String packageName) {
    170         // First see if the package has an INFO activity; the existence of
    171         // such an activity is implied to be the desired front-door for the
    172         // overall package (such as if it has multiple launcher entries).
    173         Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
    174         intentToResolve.addCategory(Intent.CATEGORY_INFO);
    175         intentToResolve.setPackage(packageName);
    176         List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
    177 
    178         // Otherwise, try to find a main launcher activity.
    179         if (ris == null || ris.size() <= 0) {
    180             // reuse the intent instance
    181             intentToResolve.removeCategory(Intent.CATEGORY_INFO);
    182             intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
    183             intentToResolve.setPackage(packageName);
    184             ris = queryIntentActivities(intentToResolve, 0);
    185         }
    186         if (ris == null || ris.size() <= 0) {
    187             return null;
    188         }
    189         Intent intent = new Intent(intentToResolve);
    190         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    191         intent.setClassName(ris.get(0).activityInfo.packageName,
    192                 ris.get(0).activityInfo.name);
    193         return intent;
    194     }
    195 
    196     @Override
    197     public Intent getLeanbackLaunchIntentForPackage(String packageName) {
    198         // Try to find a main leanback_launcher activity.
    199         Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
    200         intentToResolve.addCategory(Intent.CATEGORY_LEANBACK_LAUNCHER);
    201         intentToResolve.setPackage(packageName);
    202         List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
    203 
    204         if (ris == null || ris.size() <= 0) {
    205             return null;
    206         }
    207         Intent intent = new Intent(intentToResolve);
    208         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    209         intent.setClassName(ris.get(0).activityInfo.packageName,
    210                 ris.get(0).activityInfo.name);
    211         return intent;
    212     }
    213 
    214     @Override
    215     public int[] getPackageGids(String packageName) throws NameNotFoundException {
    216         return getPackageGids(packageName, 0);
    217     }
    218 
    219     @Override
    220     public int[] getPackageGids(String packageName, int flags)
    221             throws NameNotFoundException {
    222         try {
    223             int[] gids = mPM.getPackageGids(packageName, flags, mContext.getUserId());
    224             if (gids != null) {
    225                 return gids;
    226             }
    227         } catch (RemoteException e) {
    228             throw e.rethrowFromSystemServer();
    229         }
    230 
    231         throw new NameNotFoundException(packageName);
    232     }
    233 
    234     @Override
    235     public int getPackageUid(String packageName, int flags) throws NameNotFoundException {
    236         return getPackageUidAsUser(packageName, flags, mContext.getUserId());
    237     }
    238 
    239     @Override
    240     public int getPackageUidAsUser(String packageName, int userId) throws NameNotFoundException {
    241         return getPackageUidAsUser(packageName, 0, userId);
    242     }
    243 
    244     @Override
    245     public int getPackageUidAsUser(String packageName, int flags, int userId)
    246             throws NameNotFoundException {
    247         try {
    248             int uid = mPM.getPackageUid(packageName, flags, userId);
    249             if (uid >= 0) {
    250                 return uid;
    251             }
    252         } catch (RemoteException e) {
    253             throw e.rethrowFromSystemServer();
    254         }
    255 
    256         throw new NameNotFoundException(packageName);
    257     }
    258 
    259     @Override
    260     public PermissionInfo getPermissionInfo(String name, int flags)
    261             throws NameNotFoundException {
    262         try {
    263             PermissionInfo pi = mPM.getPermissionInfo(name, flags);
    264             if (pi != null) {
    265                 return pi;
    266             }
    267         } catch (RemoteException e) {
    268             throw e.rethrowFromSystemServer();
    269         }
    270 
    271         throw new NameNotFoundException(name);
    272     }
    273 
    274     @Override
    275     @SuppressWarnings("unchecked")
    276     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
    277             throws NameNotFoundException {
    278         try {
    279             ParceledListSlice<PermissionInfo> parceledList =
    280                     mPM.queryPermissionsByGroup(group, flags);
    281             if (parceledList != null) {
    282                 List<PermissionInfo> pi = parceledList.getList();
    283                 if (pi != null) {
    284                     return pi;
    285                 }
    286             }
    287         } catch (RemoteException e) {
    288             throw e.rethrowFromSystemServer();
    289         }
    290 
    291         throw new NameNotFoundException(group);
    292     }
    293 
    294     @Override
    295     public PermissionGroupInfo getPermissionGroupInfo(String name,
    296             int flags) throws NameNotFoundException {
    297         try {
    298             PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
    299             if (pgi != null) {
    300                 return pgi;
    301             }
    302         } catch (RemoteException e) {
    303             throw e.rethrowFromSystemServer();
    304         }
    305 
    306         throw new NameNotFoundException(name);
    307     }
    308 
    309     @Override
    310     @SuppressWarnings("unchecked")
    311     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
    312         try {
    313             ParceledListSlice<PermissionGroupInfo> parceledList =
    314                     mPM.getAllPermissionGroups(flags);
    315             if (parceledList == null) {
    316                 return Collections.emptyList();
    317             }
    318             return parceledList.getList();
    319         } catch (RemoteException e) {
    320             throw e.rethrowFromSystemServer();
    321         }
    322     }
    323 
    324     @Override
    325     public ApplicationInfo getApplicationInfo(String packageName, int flags)
    326             throws NameNotFoundException {
    327         return getApplicationInfoAsUser(packageName, flags, mContext.getUserId());
    328     }
    329 
    330     @Override
    331     public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
    332             throws NameNotFoundException {
    333         try {
    334             ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, userId);
    335             if (ai != null) {
    336                 // This is a temporary hack. Callers must use
    337                 // createPackageContext(packageName).getApplicationInfo() to
    338                 // get the right paths.
    339                 return maybeAdjustApplicationInfo(ai);
    340             }
    341         } catch (RemoteException e) {
    342             throw e.rethrowFromSystemServer();
    343         }
    344 
    345         throw new NameNotFoundException(packageName);
    346     }
    347 
    348     private static ApplicationInfo maybeAdjustApplicationInfo(ApplicationInfo info) {
    349         // If we're dealing with a multi-arch application that has both
    350         // 32 and 64 bit shared libraries, we might need to choose the secondary
    351         // depending on what the current runtime's instruction set is.
    352         if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
    353             final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
    354 
    355             // Get the instruction set that the libraries of secondary Abi is supported.
    356             // In presence of a native bridge this might be different than the one secondary Abi used.
    357             String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
    358             final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
    359             secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
    360 
    361             // If the runtimeIsa is the same as the primary isa, then we do nothing.
    362             // Everything will be set up correctly because info.nativeLibraryDir will
    363             // correspond to the right ISA.
    364             if (runtimeIsa.equals(secondaryIsa)) {
    365                 ApplicationInfo modified = new ApplicationInfo(info);
    366                 modified.nativeLibraryDir = info.secondaryNativeLibraryDir;
    367                 return modified;
    368             }
    369         }
    370         return info;
    371     }
    372 
    373     @Override
    374     public ActivityInfo getActivityInfo(ComponentName className, int flags)
    375             throws NameNotFoundException {
    376         try {
    377             ActivityInfo ai = mPM.getActivityInfo(className, flags, mContext.getUserId());
    378             if (ai != null) {
    379                 return ai;
    380             }
    381         } catch (RemoteException e) {
    382             throw e.rethrowFromSystemServer();
    383         }
    384 
    385         throw new NameNotFoundException(className.toString());
    386     }
    387 
    388     @Override
    389     public ActivityInfo getReceiverInfo(ComponentName className, int flags)
    390             throws NameNotFoundException {
    391         try {
    392             ActivityInfo ai = mPM.getReceiverInfo(className, flags, mContext.getUserId());
    393             if (ai != null) {
    394                 return ai;
    395             }
    396         } catch (RemoteException e) {
    397             throw e.rethrowFromSystemServer();
    398         }
    399 
    400         throw new NameNotFoundException(className.toString());
    401     }
    402 
    403     @Override
    404     public ServiceInfo getServiceInfo(ComponentName className, int flags)
    405             throws NameNotFoundException {
    406         try {
    407             ServiceInfo si = mPM.getServiceInfo(className, flags, mContext.getUserId());
    408             if (si != null) {
    409                 return si;
    410             }
    411         } catch (RemoteException e) {
    412             throw e.rethrowFromSystemServer();
    413         }
    414 
    415         throw new NameNotFoundException(className.toString());
    416     }
    417 
    418     @Override
    419     public ProviderInfo getProviderInfo(ComponentName className, int flags)
    420             throws NameNotFoundException {
    421         try {
    422             ProviderInfo pi = mPM.getProviderInfo(className, flags, mContext.getUserId());
    423             if (pi != null) {
    424                 return pi;
    425             }
    426         } catch (RemoteException e) {
    427             throw e.rethrowFromSystemServer();
    428         }
    429 
    430         throw new NameNotFoundException(className.toString());
    431     }
    432 
    433     @Override
    434     public String[] getSystemSharedLibraryNames() {
    435         try {
    436             return mPM.getSystemSharedLibraryNames();
    437         } catch (RemoteException e) {
    438             throw e.rethrowFromSystemServer();
    439         }
    440     }
    441 
    442     /** @hide */
    443     @Override
    444     public @NonNull String getServicesSystemSharedLibraryPackageName() {
    445         try {
    446             return mPM.getServicesSystemSharedLibraryPackageName();
    447         } catch (RemoteException e) {
    448             throw e.rethrowFromSystemServer();
    449         }
    450     }
    451 
    452     /**
    453      * @hide
    454      */
    455     public @NonNull String getSharedSystemSharedLibraryPackageName() {
    456         try {
    457             return mPM.getSharedSystemSharedLibraryPackageName();
    458         } catch (RemoteException e) {
    459             throw e.rethrowFromSystemServer();
    460         }
    461     }
    462 
    463     @Override
    464     @SuppressWarnings("unchecked")
    465     public FeatureInfo[] getSystemAvailableFeatures() {
    466         try {
    467             ParceledListSlice<FeatureInfo> parceledList =
    468                     mPM.getSystemAvailableFeatures();
    469             if (parceledList == null) {
    470                 return new FeatureInfo[0];
    471             }
    472             final List<FeatureInfo> list = parceledList.getList();
    473             final FeatureInfo[] res = new FeatureInfo[list.size()];
    474             for (int i = 0; i < res.length; i++) {
    475                 res[i] = list.get(i);
    476             }
    477             return res;
    478         } catch (RemoteException e) {
    479             throw e.rethrowFromSystemServer();
    480         }
    481     }
    482 
    483     @Override
    484     public boolean hasSystemFeature(String name) {
    485         return hasSystemFeature(name, 0);
    486     }
    487 
    488     @Override
    489     public boolean hasSystemFeature(String name, int version) {
    490         try {
    491             return mPM.hasSystemFeature(name, version);
    492         } catch (RemoteException e) {
    493             throw e.rethrowFromSystemServer();
    494         }
    495     }
    496 
    497     @Override
    498     public int checkPermission(String permName, String pkgName) {
    499         try {
    500             return mPM.checkPermission(permName, pkgName, mContext.getUserId());
    501         } catch (RemoteException e) {
    502             throw e.rethrowFromSystemServer();
    503         }
    504     }
    505 
    506     @Override
    507     public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
    508         try {
    509             return mPM.isPermissionRevokedByPolicy(permName, pkgName, mContext.getUserId());
    510         } catch (RemoteException e) {
    511             throw e.rethrowFromSystemServer();
    512         }
    513     }
    514 
    515     /**
    516      * @hide
    517      */
    518     @Override
    519     public String getPermissionControllerPackageName() {
    520         synchronized (mLock) {
    521             if (mPermissionsControllerPackageName == null) {
    522                 try {
    523                     mPermissionsControllerPackageName = mPM.getPermissionControllerPackageName();
    524                 } catch (RemoteException e) {
    525                     throw e.rethrowFromSystemServer();
    526                 }
    527             }
    528             return mPermissionsControllerPackageName;
    529         }
    530     }
    531 
    532     @Override
    533     public boolean addPermission(PermissionInfo info) {
    534         try {
    535             return mPM.addPermission(info);
    536         } catch (RemoteException e) {
    537             throw e.rethrowFromSystemServer();
    538         }
    539     }
    540 
    541     @Override
    542     public boolean addPermissionAsync(PermissionInfo info) {
    543         try {
    544             return mPM.addPermissionAsync(info);
    545         } catch (RemoteException e) {
    546             throw e.rethrowFromSystemServer();
    547         }
    548     }
    549 
    550     @Override
    551     public void removePermission(String name) {
    552         try {
    553             mPM.removePermission(name);
    554         } catch (RemoteException e) {
    555             throw e.rethrowFromSystemServer();
    556         }
    557     }
    558 
    559     @Override
    560     public void grantRuntimePermission(String packageName, String permissionName,
    561             UserHandle user) {
    562         try {
    563             mPM.grantRuntimePermission(packageName, permissionName, user.getIdentifier());
    564         } catch (RemoteException e) {
    565             throw e.rethrowFromSystemServer();
    566         }
    567     }
    568 
    569     @Override
    570     public void revokeRuntimePermission(String packageName, String permissionName,
    571             UserHandle user) {
    572         try {
    573             mPM.revokeRuntimePermission(packageName, permissionName, user.getIdentifier());
    574         } catch (RemoteException e) {
    575             throw e.rethrowFromSystemServer();
    576         }
    577     }
    578 
    579     @Override
    580     public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
    581         try {
    582             return mPM.getPermissionFlags(permissionName, packageName, user.getIdentifier());
    583         } catch (RemoteException e) {
    584             throw e.rethrowFromSystemServer();
    585         }
    586     }
    587 
    588     @Override
    589     public void updatePermissionFlags(String permissionName, String packageName,
    590             int flagMask, int flagValues, UserHandle user) {
    591         try {
    592             mPM.updatePermissionFlags(permissionName, packageName, flagMask,
    593                     flagValues, user.getIdentifier());
    594         } catch (RemoteException e) {
    595             throw e.rethrowFromSystemServer();
    596         }
    597     }
    598 
    599     @Override
    600     public boolean shouldShowRequestPermissionRationale(String permission) {
    601         try {
    602             return mPM.shouldShowRequestPermissionRationale(permission,
    603                     mContext.getPackageName(), mContext.getUserId());
    604         } catch (RemoteException e) {
    605             throw e.rethrowFromSystemServer();
    606         }
    607     }
    608 
    609     @Override
    610     public int checkSignatures(String pkg1, String pkg2) {
    611         try {
    612             return mPM.checkSignatures(pkg1, pkg2);
    613         } catch (RemoteException e) {
    614             throw e.rethrowFromSystemServer();
    615         }
    616     }
    617 
    618     @Override
    619     public int checkSignatures(int uid1, int uid2) {
    620         try {
    621             return mPM.checkUidSignatures(uid1, uid2);
    622         } catch (RemoteException e) {
    623             throw e.rethrowFromSystemServer();
    624         }
    625     }
    626 
    627     @Override
    628     public String[] getPackagesForUid(int uid) {
    629         try {
    630             return mPM.getPackagesForUid(uid);
    631         } catch (RemoteException e) {
    632             throw e.rethrowFromSystemServer();
    633         }
    634     }
    635 
    636     @Override
    637     public String getNameForUid(int uid) {
    638         try {
    639             return mPM.getNameForUid(uid);
    640         } catch (RemoteException e) {
    641             throw e.rethrowFromSystemServer();
    642         }
    643     }
    644 
    645     @Override
    646     public int getUidForSharedUser(String sharedUserName)
    647             throws NameNotFoundException {
    648         try {
    649             int uid = mPM.getUidForSharedUser(sharedUserName);
    650             if(uid != -1) {
    651                 return uid;
    652             }
    653         } catch (RemoteException e) {
    654             throw e.rethrowFromSystemServer();
    655         }
    656         throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
    657     }
    658 
    659     @SuppressWarnings("unchecked")
    660     @Override
    661     public List<PackageInfo> getInstalledPackages(int flags) {
    662         return getInstalledPackagesAsUser(flags, mContext.getUserId());
    663     }
    664 
    665     /** @hide */
    666     @Override
    667     @SuppressWarnings("unchecked")
    668     public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
    669         try {
    670             ParceledListSlice<PackageInfo> parceledList =
    671                     mPM.getInstalledPackages(flags, userId);
    672             if (parceledList == null) {
    673                 return Collections.emptyList();
    674             }
    675             return parceledList.getList();
    676         } catch (RemoteException e) {
    677             throw e.rethrowFromSystemServer();
    678         }
    679     }
    680 
    681     @SuppressWarnings("unchecked")
    682     @Override
    683     public List<PackageInfo> getPackagesHoldingPermissions(
    684             String[] permissions, int flags) {
    685         final int userId = mContext.getUserId();
    686         try {
    687             ParceledListSlice<PackageInfo> parceledList =
    688                     mPM.getPackagesHoldingPermissions(permissions, flags, userId);
    689             if (parceledList == null) {
    690                 return Collections.emptyList();
    691             }
    692             return parceledList.getList();
    693         } catch (RemoteException e) {
    694             throw e.rethrowFromSystemServer();
    695         }
    696     }
    697 
    698     @SuppressWarnings("unchecked")
    699     @Override
    700     public List<ApplicationInfo> getInstalledApplications(int flags) {
    701         final int userId = mContext.getUserId();
    702         try {
    703             ParceledListSlice<ApplicationInfo> parceledList =
    704                     mPM.getInstalledApplications(flags, userId);
    705             if (parceledList == null) {
    706                 return Collections.emptyList();
    707             }
    708             return parceledList.getList();
    709         } catch (RemoteException e) {
    710             throw e.rethrowFromSystemServer();
    711         }
    712     }
    713 
    714     /** @hide */
    715     @SuppressWarnings("unchecked")
    716     @Override
    717     public List<EphemeralApplicationInfo> getEphemeralApplications() {
    718         try {
    719             ParceledListSlice<EphemeralApplicationInfo> slice =
    720                     mPM.getEphemeralApplications(mContext.getUserId());
    721             if (slice != null) {
    722                 return slice.getList();
    723             }
    724             return Collections.emptyList();
    725         } catch (RemoteException e) {
    726             throw e.rethrowFromSystemServer();
    727         }
    728     }
    729 
    730     /** @hide */
    731     @Override
    732     public Drawable getEphemeralApplicationIcon(String packageName) {
    733         try {
    734             Bitmap bitmap = mPM.getEphemeralApplicationIcon(
    735                     packageName, mContext.getUserId());
    736             if (bitmap != null) {
    737                 return new BitmapDrawable(null, bitmap);
    738             }
    739             return null;
    740         } catch (RemoteException e) {
    741             throw e.rethrowFromSystemServer();
    742         }
    743     }
    744 
    745     @Override
    746     public boolean isEphemeralApplication() {
    747         try {
    748             return mPM.isEphemeralApplication(
    749                     mContext.getPackageName(), mContext.getUserId());
    750         } catch (RemoteException e) {
    751             throw e.rethrowFromSystemServer();
    752         }
    753     }
    754 
    755     @Override
    756     public int getEphemeralCookieMaxSizeBytes() {
    757         return Settings.Global.getInt(mContext.getContentResolver(),
    758                 Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
    759                 DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES);
    760     }
    761 
    762     @Override
    763     public @NonNull byte[] getEphemeralCookie() {
    764         try {
    765             final byte[] cookie = mPM.getEphemeralApplicationCookie(
    766                     mContext.getPackageName(), mContext.getUserId());
    767             if (cookie != null) {
    768                 return cookie;
    769             } else {
    770                 return EmptyArray.BYTE;
    771             }
    772         } catch (RemoteException e) {
    773             throw e.rethrowFromSystemServer();
    774         }
    775     }
    776 
    777     @Override
    778     public boolean setEphemeralCookie(@NonNull  byte[] cookie) {
    779         try {
    780             return mPM.setEphemeralApplicationCookie(
    781                     mContext.getPackageName(), cookie, mContext.getUserId());
    782         } catch (RemoteException e) {
    783             throw e.rethrowFromSystemServer();
    784         }
    785     }
    786 
    787     @Override
    788     public ResolveInfo resolveActivity(Intent intent, int flags) {
    789         return resolveActivityAsUser(intent, flags, mContext.getUserId());
    790     }
    791 
    792     @Override
    793     public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
    794         try {
    795             return mPM.resolveIntent(
    796                 intent,
    797                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    798                 flags,
    799                 userId);
    800         } catch (RemoteException e) {
    801             throw e.rethrowFromSystemServer();
    802         }
    803     }
    804 
    805     @Override
    806     public List<ResolveInfo> queryIntentActivities(Intent intent,
    807                                                    int flags) {
    808         return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId());
    809     }
    810 
    811     /** @hide Same as above but for a specific user */
    812     @Override
    813     @SuppressWarnings("unchecked")
    814     public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
    815             int flags, int userId) {
    816         try {
    817             ParceledListSlice<ResolveInfo> parceledList =
    818                     mPM.queryIntentActivities(intent,
    819                             intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    820                             flags, userId);
    821             if (parceledList == null) {
    822                 return Collections.emptyList();
    823             }
    824             return parceledList.getList();
    825         } catch (RemoteException e) {
    826             throw e.rethrowFromSystemServer();
    827         }
    828     }
    829 
    830     @Override
    831     @SuppressWarnings("unchecked")
    832     public List<ResolveInfo> queryIntentActivityOptions(
    833         ComponentName caller, Intent[] specifics, Intent intent,
    834         int flags) {
    835         final ContentResolver resolver = mContext.getContentResolver();
    836 
    837         String[] specificTypes = null;
    838         if (specifics != null) {
    839             final int N = specifics.length;
    840             for (int i=0; i<N; i++) {
    841                 Intent sp = specifics[i];
    842                 if (sp != null) {
    843                     String t = sp.resolveTypeIfNeeded(resolver);
    844                     if (t != null) {
    845                         if (specificTypes == null) {
    846                             specificTypes = new String[N];
    847                         }
    848                         specificTypes[i] = t;
    849                     }
    850                 }
    851             }
    852         }
    853 
    854         try {
    855             ParceledListSlice<ResolveInfo> parceledList =
    856                     mPM.queryIntentActivityOptions(caller, specifics, specificTypes, intent,
    857                     intent.resolveTypeIfNeeded(resolver), flags, mContext.getUserId());
    858             if (parceledList == null) {
    859                 return Collections.emptyList();
    860             }
    861             return parceledList.getList();
    862         } catch (RemoteException e) {
    863             throw e.rethrowFromSystemServer();
    864         }
    865     }
    866 
    867     /**
    868      * @hide
    869      */
    870     @Override
    871     @SuppressWarnings("unchecked")
    872     public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
    873         try {
    874             ParceledListSlice<ResolveInfo> parceledList =
    875                     mPM.queryIntentReceivers(intent,
    876                             intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    877                             flags,  userId);
    878             if (parceledList == null) {
    879                 return Collections.emptyList();
    880             }
    881             return parceledList.getList();
    882         } catch (RemoteException e) {
    883             throw e.rethrowFromSystemServer();
    884         }
    885     }
    886 
    887     @Override
    888     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
    889         return queryBroadcastReceiversAsUser(intent, flags, mContext.getUserId());
    890     }
    891 
    892     @Override
    893     public ResolveInfo resolveService(Intent intent, int flags) {
    894         try {
    895             return mPM.resolveService(
    896                 intent,
    897                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    898                 flags,
    899                 mContext.getUserId());
    900         } catch (RemoteException e) {
    901             throw e.rethrowFromSystemServer();
    902         }
    903     }
    904 
    905     @Override
    906     @SuppressWarnings("unchecked")
    907     public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
    908         try {
    909             ParceledListSlice<ResolveInfo> parceledList =
    910                     mPM.queryIntentServices(intent,
    911                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    912                     flags, userId);
    913             if (parceledList == null) {
    914                 return Collections.emptyList();
    915             }
    916             return parceledList.getList();
    917         } catch (RemoteException e) {
    918             throw e.rethrowFromSystemServer();
    919         }
    920     }
    921 
    922     @Override
    923     public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
    924         return queryIntentServicesAsUser(intent, flags, mContext.getUserId());
    925     }
    926 
    927     @Override
    928     @SuppressWarnings("unchecked")
    929     public List<ResolveInfo> queryIntentContentProvidersAsUser(
    930             Intent intent, int flags, int userId) {
    931         try {
    932             ParceledListSlice<ResolveInfo> parceledList =
    933                     mPM.queryIntentContentProviders(intent,
    934                             intent.resolveTypeIfNeeded(mContext.getContentResolver()),
    935                             flags, userId);
    936             if (parceledList == null) {
    937                 return Collections.emptyList();
    938             }
    939             return parceledList.getList();
    940         } catch (RemoteException e) {
    941             throw e.rethrowFromSystemServer();
    942         }
    943     }
    944 
    945     @Override
    946     public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
    947         return queryIntentContentProvidersAsUser(intent, flags, mContext.getUserId());
    948     }
    949 
    950     @Override
    951     public ProviderInfo resolveContentProvider(String name, int flags) {
    952         return resolveContentProviderAsUser(name, flags, mContext.getUserId());
    953     }
    954 
    955     /** @hide **/
    956     @Override
    957     public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
    958         try {
    959             return mPM.resolveContentProvider(name, flags, userId);
    960         } catch (RemoteException e) {
    961             throw e.rethrowFromSystemServer();
    962         }
    963     }
    964 
    965     @Override
    966     @SuppressWarnings("unchecked")
    967     public List<ProviderInfo> queryContentProviders(String processName,
    968             int uid, int flags) {
    969         try {
    970             ParceledListSlice<ProviderInfo> slice =
    971                     mPM.queryContentProviders(processName, uid, flags);
    972             return slice != null ? slice.getList() : Collections.<ProviderInfo>emptyList();
    973         } catch (RemoteException e) {
    974             throw e.rethrowFromSystemServer();
    975         }
    976     }
    977 
    978     @Override
    979     public InstrumentationInfo getInstrumentationInfo(
    980         ComponentName className, int flags)
    981             throws NameNotFoundException {
    982         try {
    983             InstrumentationInfo ii = mPM.getInstrumentationInfo(
    984                 className, flags);
    985             if (ii != null) {
    986                 return ii;
    987             }
    988         } catch (RemoteException e) {
    989             throw e.rethrowFromSystemServer();
    990         }
    991 
    992         throw new NameNotFoundException(className.toString());
    993     }
    994 
    995     @Override
    996     @SuppressWarnings("unchecked")
    997     public List<InstrumentationInfo> queryInstrumentation(
    998         String targetPackage, int flags) {
    999         try {
   1000             ParceledListSlice<InstrumentationInfo> parceledList =
   1001                     mPM.queryInstrumentation(targetPackage, flags);
   1002             if (parceledList == null) {
   1003                 return Collections.emptyList();
   1004             }
   1005             return parceledList.getList();
   1006         } catch (RemoteException e) {
   1007             throw e.rethrowFromSystemServer();
   1008         }
   1009     }
   1010 
   1011     @Nullable
   1012     @Override
   1013     public Drawable getDrawable(String packageName, @DrawableRes int resId,
   1014             @Nullable ApplicationInfo appInfo) {
   1015         final ResourceName name = new ResourceName(packageName, resId);
   1016         final Drawable cachedIcon = getCachedIcon(name);
   1017         if (cachedIcon != null) {
   1018             return cachedIcon;
   1019         }
   1020 
   1021         if (appInfo == null) {
   1022             try {
   1023                 appInfo = getApplicationInfo(packageName, sDefaultFlags);
   1024             } catch (NameNotFoundException e) {
   1025                 return null;
   1026             }
   1027         }
   1028 
   1029         if (resId != 0) {
   1030             try {
   1031                 final Resources r = getResourcesForApplication(appInfo);
   1032                 final Drawable dr = r.getDrawable(resId, null);
   1033                 if (dr != null) {
   1034                     putCachedIcon(name, dr);
   1035                 }
   1036 
   1037                 if (false) {
   1038                     RuntimeException e = new RuntimeException("here");
   1039                     e.fillInStackTrace();
   1040                     Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resId)
   1041                                     + " from package " + packageName
   1042                                     + ": app scale=" + r.getCompatibilityInfo().applicationScale
   1043                                     + ", caller scale=" + mContext.getResources()
   1044                                     .getCompatibilityInfo().applicationScale,
   1045                             e);
   1046                 }
   1047                 if (DEBUG_ICONS) {
   1048                     Log.v(TAG, "Getting drawable 0x"
   1049                             + Integer.toHexString(resId) + " from " + r
   1050                             + ": " + dr);
   1051                 }
   1052                 return dr;
   1053             } catch (NameNotFoundException e) {
   1054                 Log.w("PackageManager", "Failure retrieving resources for "
   1055                         + appInfo.packageName);
   1056             } catch (Resources.NotFoundException e) {
   1057                 Log.w("PackageManager", "Failure retrieving resources for "
   1058                         + appInfo.packageName + ": " + e.getMessage());
   1059             } catch (Exception e) {
   1060                 // If an exception was thrown, fall through to return
   1061                 // default icon.
   1062                 Log.w("PackageManager", "Failure retrieving icon 0x"
   1063                         + Integer.toHexString(resId) + " in package "
   1064                         + packageName, e);
   1065             }
   1066         }
   1067 
   1068         return null;
   1069     }
   1070 
   1071     @Override public Drawable getActivityIcon(ComponentName activityName)
   1072             throws NameNotFoundException {
   1073         return getActivityInfo(activityName, sDefaultFlags).loadIcon(this);
   1074     }
   1075 
   1076     @Override public Drawable getActivityIcon(Intent intent)
   1077             throws NameNotFoundException {
   1078         if (intent.getComponent() != null) {
   1079             return getActivityIcon(intent.getComponent());
   1080         }
   1081 
   1082         ResolveInfo info = resolveActivity(
   1083             intent, PackageManager.MATCH_DEFAULT_ONLY);
   1084         if (info != null) {
   1085             return info.activityInfo.loadIcon(this);
   1086         }
   1087 
   1088         throw new NameNotFoundException(intent.toUri(0));
   1089     }
   1090 
   1091     @Override public Drawable getDefaultActivityIcon() {
   1092         return Resources.getSystem().getDrawable(
   1093             com.android.internal.R.drawable.sym_def_app_icon);
   1094     }
   1095 
   1096     @Override public Drawable getApplicationIcon(ApplicationInfo info) {
   1097         return info.loadIcon(this);
   1098     }
   1099 
   1100     @Override public Drawable getApplicationIcon(String packageName)
   1101             throws NameNotFoundException {
   1102         return getApplicationIcon(getApplicationInfo(packageName, sDefaultFlags));
   1103     }
   1104 
   1105     @Override
   1106     public Drawable getActivityBanner(ComponentName activityName)
   1107             throws NameNotFoundException {
   1108         return getActivityInfo(activityName, sDefaultFlags).loadBanner(this);
   1109     }
   1110 
   1111     @Override
   1112     public Drawable getActivityBanner(Intent intent)
   1113             throws NameNotFoundException {
   1114         if (intent.getComponent() != null) {
   1115             return getActivityBanner(intent.getComponent());
   1116         }
   1117 
   1118         ResolveInfo info = resolveActivity(
   1119                 intent, PackageManager.MATCH_DEFAULT_ONLY);
   1120         if (info != null) {
   1121             return info.activityInfo.loadBanner(this);
   1122         }
   1123 
   1124         throw new NameNotFoundException(intent.toUri(0));
   1125     }
   1126 
   1127     @Override
   1128     public Drawable getApplicationBanner(ApplicationInfo info) {
   1129         return info.loadBanner(this);
   1130     }
   1131 
   1132     @Override
   1133     public Drawable getApplicationBanner(String packageName)
   1134             throws NameNotFoundException {
   1135         return getApplicationBanner(getApplicationInfo(packageName, sDefaultFlags));
   1136     }
   1137 
   1138     @Override
   1139     public Drawable getActivityLogo(ComponentName activityName)
   1140             throws NameNotFoundException {
   1141         return getActivityInfo(activityName, sDefaultFlags).loadLogo(this);
   1142     }
   1143 
   1144     @Override
   1145     public Drawable getActivityLogo(Intent intent)
   1146             throws NameNotFoundException {
   1147         if (intent.getComponent() != null) {
   1148             return getActivityLogo(intent.getComponent());
   1149         }
   1150 
   1151         ResolveInfo info = resolveActivity(
   1152             intent, PackageManager.MATCH_DEFAULT_ONLY);
   1153         if (info != null) {
   1154             return info.activityInfo.loadLogo(this);
   1155         }
   1156 
   1157         throw new NameNotFoundException(intent.toUri(0));
   1158     }
   1159 
   1160     @Override
   1161     public Drawable getApplicationLogo(ApplicationInfo info) {
   1162         return info.loadLogo(this);
   1163     }
   1164 
   1165     @Override
   1166     public Drawable getApplicationLogo(String packageName)
   1167             throws NameNotFoundException {
   1168         return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags));
   1169     }
   1170 
   1171     @Override
   1172     public Drawable getManagedUserBadgedDrawable(Drawable drawable, Rect badgeLocation,
   1173             int badgeDensity) {
   1174         Drawable badgeDrawable = getDrawableForDensity(
   1175             com.android.internal.R.drawable.ic_corp_badge, badgeDensity);
   1176         return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
   1177     }
   1178 
   1179     @Override
   1180     public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
   1181         final int badgeResId = getBadgeResIdForUser(user.getIdentifier());
   1182         if (badgeResId == 0) {
   1183             return icon;
   1184         }
   1185         Drawable badgeIcon = getDrawable("system", badgeResId, null);
   1186         return getBadgedDrawable(icon, badgeIcon, null, true);
   1187     }
   1188 
   1189     @Override
   1190     public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
   1191             Rect badgeLocation, int badgeDensity) {
   1192         Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity);
   1193         if (badgeDrawable == null) {
   1194             return drawable;
   1195         }
   1196         return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
   1197     }
   1198 
   1199     @Override
   1200     public Drawable getUserBadgeForDensity(UserHandle user, int density) {
   1201         return getManagedProfileIconForDensity(user, com.android.internal.R.drawable.ic_corp_badge,
   1202                 density);
   1203     }
   1204 
   1205     @Override
   1206     public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
   1207         return getManagedProfileIconForDensity(user,
   1208                 com.android.internal.R.drawable.ic_corp_badge_no_background, density);
   1209     }
   1210 
   1211     private Drawable getDrawableForDensity(int drawableId, int density) {
   1212         if (density <= 0) {
   1213             density = mContext.getResources().getDisplayMetrics().densityDpi;
   1214         }
   1215         return Resources.getSystem().getDrawableForDensity(drawableId, density);
   1216     }
   1217 
   1218     private Drawable getManagedProfileIconForDensity(UserHandle user, int drawableId, int density) {
   1219         if (isManagedProfile(user.getIdentifier())) {
   1220             return getDrawableForDensity(drawableId, density);
   1221         }
   1222         return null;
   1223     }
   1224 
   1225     @Override
   1226     public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
   1227         if (isManagedProfile(user.getIdentifier())) {
   1228             return Resources.getSystem().getString(
   1229                     com.android.internal.R.string.managed_profile_label_badge, label);
   1230         }
   1231         return label;
   1232     }
   1233 
   1234     @Override
   1235     public Resources getResourcesForActivity(ComponentName activityName)
   1236             throws NameNotFoundException {
   1237         return getResourcesForApplication(
   1238             getActivityInfo(activityName, sDefaultFlags).applicationInfo);
   1239     }
   1240 
   1241     @Override
   1242     public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
   1243             throws NameNotFoundException {
   1244         if (app.packageName.equals("system")) {
   1245             return mContext.mMainThread.getSystemContext().getResources();
   1246         }
   1247         final boolean sameUid = (app.uid == Process.myUid());
   1248         try {
   1249             return mContext.mMainThread.getTopLevelResources(
   1250                     sameUid ? app.sourceDir : app.publicSourceDir,
   1251                     sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
   1252                     app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
   1253                     mContext.mPackageInfo);
   1254         } catch (Resources.NotFoundException cause) {
   1255             final NameNotFoundException ex =
   1256                     new NameNotFoundException("Unable to open " + app.publicSourceDir);
   1257             ex.initCause(cause);
   1258             throw ex;
   1259         }
   1260     }
   1261 
   1262     @Override
   1263     public Resources getResourcesForApplication(String appPackageName)
   1264             throws NameNotFoundException {
   1265         return getResourcesForApplication(
   1266             getApplicationInfo(appPackageName, sDefaultFlags));
   1267     }
   1268 
   1269     /** @hide */
   1270     @Override
   1271     public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
   1272             throws NameNotFoundException {
   1273         if (userId < 0) {
   1274             throw new IllegalArgumentException(
   1275                     "Call does not support special user #" + userId);
   1276         }
   1277         if ("system".equals(appPackageName)) {
   1278             return mContext.mMainThread.getSystemContext().getResources();
   1279         }
   1280         try {
   1281             ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
   1282             if (ai != null) {
   1283                 return getResourcesForApplication(ai);
   1284             }
   1285         } catch (RemoteException e) {
   1286             throw e.rethrowFromSystemServer();
   1287         }
   1288         throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
   1289     }
   1290 
   1291     volatile int mCachedSafeMode = -1;
   1292 
   1293     @Override
   1294     public boolean isSafeMode() {
   1295         try {
   1296             if (mCachedSafeMode < 0) {
   1297                 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
   1298             }
   1299             return mCachedSafeMode != 0;
   1300         } catch (RemoteException e) {
   1301             throw e.rethrowFromSystemServer();
   1302         }
   1303     }
   1304 
   1305     @Override
   1306     public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
   1307         synchronized (mPermissionListeners) {
   1308             if (mPermissionListeners.get(listener) != null) {
   1309                 return;
   1310             }
   1311             OnPermissionsChangeListenerDelegate delegate =
   1312                     new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper());
   1313             try {
   1314                 mPM.addOnPermissionsChangeListener(delegate);
   1315                 mPermissionListeners.put(listener, delegate);
   1316             } catch (RemoteException e) {
   1317                 throw e.rethrowFromSystemServer();
   1318             }
   1319         }
   1320     }
   1321 
   1322     @Override
   1323     public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
   1324         synchronized (mPermissionListeners) {
   1325             IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener);
   1326             if (delegate != null) {
   1327                 try {
   1328                     mPM.removeOnPermissionsChangeListener(delegate);
   1329                     mPermissionListeners.remove(listener);
   1330                 } catch (RemoteException e) {
   1331                     throw e.rethrowFromSystemServer();
   1332                 }
   1333             }
   1334         }
   1335     }
   1336 
   1337     static void configurationChanged() {
   1338         synchronized (sSync) {
   1339             sIconCache.clear();
   1340             sStringCache.clear();
   1341         }
   1342     }
   1343 
   1344     ApplicationPackageManager(ContextImpl context,
   1345                               IPackageManager pm) {
   1346         mContext = context;
   1347         mPM = pm;
   1348     }
   1349 
   1350     @Nullable
   1351     private Drawable getCachedIcon(@NonNull ResourceName name) {
   1352         synchronized (sSync) {
   1353             final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
   1354             if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
   1355                                    + name + ": " + wr);
   1356             if (wr != null) {   // we have the activity
   1357                 final Drawable.ConstantState state = wr.get();
   1358                 if (state != null) {
   1359                     if (DEBUG_ICONS) {
   1360                         Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
   1361                     }
   1362                     // Note: It's okay here to not use the newDrawable(Resources) variant
   1363                     //       of the API. The ConstantState comes from a drawable that was
   1364                     //       originally created by passing the proper app Resources instance
   1365                     //       which means the state should already contain the proper
   1366                     //       resources specific information (like density.) See
   1367                     //       BitmapDrawable.BitmapState for instance.
   1368                     return state.newDrawable();
   1369                 }
   1370                 // our entry has been purged
   1371                 sIconCache.remove(name);
   1372             }
   1373         }
   1374         return null;
   1375     }
   1376 
   1377     private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) {
   1378         synchronized (sSync) {
   1379             sIconCache.put(name, new WeakReference<>(dr.getConstantState()));
   1380             if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
   1381         }
   1382     }
   1383 
   1384     static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
   1385         boolean immediateGc = false;
   1386         if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
   1387             immediateGc = true;
   1388         }
   1389         if (pkgList != null && (pkgList.length > 0)) {
   1390             boolean needCleanup = false;
   1391             for (String ssp : pkgList) {
   1392                 synchronized (sSync) {
   1393                     for (int i=sIconCache.size()-1; i>=0; i--) {
   1394                         ResourceName nm = sIconCache.keyAt(i);
   1395                         if (nm.packageName.equals(ssp)) {
   1396                             //Log.i(TAG, "Removing cached drawable for " + nm);
   1397                             sIconCache.removeAt(i);
   1398                             needCleanup = true;
   1399                         }
   1400                     }
   1401                     for (int i=sStringCache.size()-1; i>=0; i--) {
   1402                         ResourceName nm = sStringCache.keyAt(i);
   1403                         if (nm.packageName.equals(ssp)) {
   1404                             //Log.i(TAG, "Removing cached string for " + nm);
   1405                             sStringCache.removeAt(i);
   1406                             needCleanup = true;
   1407                         }
   1408                     }
   1409                 }
   1410             }
   1411             if (needCleanup || hasPkgInfo) {
   1412                 if (immediateGc) {
   1413                     // Schedule an immediate gc.
   1414                     Runtime.getRuntime().gc();
   1415                 } else {
   1416                     ActivityThread.currentActivityThread().scheduleGcIdler();
   1417                 }
   1418             }
   1419         }
   1420     }
   1421 
   1422     private static final class ResourceName {
   1423         final String packageName;
   1424         final int iconId;
   1425 
   1426         ResourceName(String _packageName, int _iconId) {
   1427             packageName = _packageName;
   1428             iconId = _iconId;
   1429         }
   1430 
   1431         ResourceName(ApplicationInfo aInfo, int _iconId) {
   1432             this(aInfo.packageName, _iconId);
   1433         }
   1434 
   1435         ResourceName(ComponentInfo cInfo, int _iconId) {
   1436             this(cInfo.applicationInfo.packageName, _iconId);
   1437         }
   1438 
   1439         ResourceName(ResolveInfo rInfo, int _iconId) {
   1440             this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
   1441         }
   1442 
   1443         @Override
   1444         public boolean equals(Object o) {
   1445             if (this == o) return true;
   1446             if (o == null || getClass() != o.getClass()) return false;
   1447 
   1448             ResourceName that = (ResourceName) o;
   1449 
   1450             if (iconId != that.iconId) return false;
   1451             return !(packageName != null ?
   1452                      !packageName.equals(that.packageName) : that.packageName != null);
   1453 
   1454         }
   1455 
   1456         @Override
   1457         public int hashCode() {
   1458             int result;
   1459             result = packageName.hashCode();
   1460             result = 31 * result + iconId;
   1461             return result;
   1462         }
   1463 
   1464         @Override
   1465         public String toString() {
   1466             return "{ResourceName " + packageName + " / " + iconId + "}";
   1467         }
   1468     }
   1469 
   1470     private CharSequence getCachedString(ResourceName name) {
   1471         synchronized (sSync) {
   1472             WeakReference<CharSequence> wr = sStringCache.get(name);
   1473             if (wr != null) {   // we have the activity
   1474                 CharSequence cs = wr.get();
   1475                 if (cs != null) {
   1476                     return cs;
   1477                 }
   1478                 // our entry has been purged
   1479                 sStringCache.remove(name);
   1480             }
   1481         }
   1482         return null;
   1483     }
   1484 
   1485     private void putCachedString(ResourceName name, CharSequence cs) {
   1486         synchronized (sSync) {
   1487             sStringCache.put(name, new WeakReference<CharSequence>(cs));
   1488         }
   1489     }
   1490 
   1491     @Override
   1492     public CharSequence getText(String packageName, @StringRes int resid,
   1493                                 ApplicationInfo appInfo) {
   1494         ResourceName name = new ResourceName(packageName, resid);
   1495         CharSequence text = getCachedString(name);
   1496         if (text != null) {
   1497             return text;
   1498         }
   1499         if (appInfo == null) {
   1500             try {
   1501                 appInfo = getApplicationInfo(packageName, sDefaultFlags);
   1502             } catch (NameNotFoundException e) {
   1503                 return null;
   1504             }
   1505         }
   1506         try {
   1507             Resources r = getResourcesForApplication(appInfo);
   1508             text = r.getText(resid);
   1509             putCachedString(name, text);
   1510             return text;
   1511         } catch (NameNotFoundException e) {
   1512             Log.w("PackageManager", "Failure retrieving resources for "
   1513                   + appInfo.packageName);
   1514         } catch (RuntimeException e) {
   1515             // If an exception was thrown, fall through to return
   1516             // default icon.
   1517             Log.w("PackageManager", "Failure retrieving text 0x"
   1518                   + Integer.toHexString(resid) + " in package "
   1519                   + packageName, e);
   1520         }
   1521         return null;
   1522     }
   1523 
   1524     @Override
   1525     public XmlResourceParser getXml(String packageName, @XmlRes int resid,
   1526                                     ApplicationInfo appInfo) {
   1527         if (appInfo == null) {
   1528             try {
   1529                 appInfo = getApplicationInfo(packageName, sDefaultFlags);
   1530             } catch (NameNotFoundException e) {
   1531                 return null;
   1532             }
   1533         }
   1534         try {
   1535             Resources r = getResourcesForApplication(appInfo);
   1536             return r.getXml(resid);
   1537         } catch (RuntimeException e) {
   1538             // If an exception was thrown, fall through to return
   1539             // default icon.
   1540             Log.w("PackageManager", "Failure retrieving xml 0x"
   1541                   + Integer.toHexString(resid) + " in package "
   1542                   + packageName, e);
   1543         } catch (NameNotFoundException e) {
   1544             Log.w("PackageManager", "Failure retrieving resources for "
   1545                   + appInfo.packageName);
   1546         }
   1547         return null;
   1548     }
   1549 
   1550     @Override
   1551     public CharSequence getApplicationLabel(ApplicationInfo info) {
   1552         return info.loadLabel(this);
   1553     }
   1554 
   1555     @Override
   1556     public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
   1557                                String installerPackageName) {
   1558         installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
   1559                 installerPackageName, mContext.getUserId());
   1560     }
   1561 
   1562     @Override
   1563     public void installPackage(Uri packageURI, PackageInstallObserver observer,
   1564             int flags, String installerPackageName) {
   1565         installCommon(packageURI, observer, flags, installerPackageName, mContext.getUserId());
   1566     }
   1567 
   1568     private void installCommon(Uri packageURI,
   1569             PackageInstallObserver observer, int flags, String installerPackageName,
   1570             int userId) {
   1571         if (!"file".equals(packageURI.getScheme())) {
   1572             throw new UnsupportedOperationException("Only file:// URIs are supported");
   1573         }
   1574 
   1575         final String originPath = packageURI.getPath();
   1576         try {
   1577             mPM.installPackageAsUser(originPath, observer.getBinder(), flags, installerPackageName,
   1578                     userId);
   1579         } catch (RemoteException e) {
   1580             throw e.rethrowFromSystemServer();
   1581         }
   1582     }
   1583 
   1584     @Override
   1585     public int installExistingPackage(String packageName) throws NameNotFoundException {
   1586         return installExistingPackageAsUser(packageName, mContext.getUserId());
   1587     }
   1588 
   1589     @Override
   1590     public int installExistingPackageAsUser(String packageName, int userId)
   1591             throws NameNotFoundException {
   1592         try {
   1593             int res = mPM.installExistingPackageAsUser(packageName, userId);
   1594             if (res == INSTALL_FAILED_INVALID_URI) {
   1595                 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
   1596             }
   1597             return res;
   1598         } catch (RemoteException e) {
   1599             throw e.rethrowFromSystemServer();
   1600         }
   1601     }
   1602 
   1603     @Override
   1604     public void verifyPendingInstall(int id, int response) {
   1605         try {
   1606             mPM.verifyPendingInstall(id, response);
   1607         } catch (RemoteException e) {
   1608             throw e.rethrowFromSystemServer();
   1609         }
   1610     }
   1611 
   1612     @Override
   1613     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
   1614             long millisecondsToDelay) {
   1615         try {
   1616             mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
   1617         } catch (RemoteException e) {
   1618             throw e.rethrowFromSystemServer();
   1619         }
   1620     }
   1621 
   1622     @Override
   1623     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
   1624         try {
   1625             mPM.verifyIntentFilter(id, verificationCode, failedDomains);
   1626         } catch (RemoteException e) {
   1627             throw e.rethrowFromSystemServer();
   1628         }
   1629     }
   1630 
   1631     @Override
   1632     public int getIntentVerificationStatusAsUser(String packageName, int userId) {
   1633         try {
   1634             return mPM.getIntentVerificationStatus(packageName, userId);
   1635         } catch (RemoteException e) {
   1636             throw e.rethrowFromSystemServer();
   1637         }
   1638     }
   1639 
   1640     @Override
   1641     public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) {
   1642         try {
   1643             return mPM.updateIntentVerificationStatus(packageName, status, userId);
   1644         } catch (RemoteException e) {
   1645             throw e.rethrowFromSystemServer();
   1646         }
   1647     }
   1648 
   1649     @Override
   1650     @SuppressWarnings("unchecked")
   1651     public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
   1652         try {
   1653             ParceledListSlice<IntentFilterVerificationInfo> parceledList =
   1654                     mPM.getIntentFilterVerifications(packageName);
   1655             if (parceledList == null) {
   1656                 return Collections.emptyList();
   1657             }
   1658             return parceledList.getList();
   1659         } catch (RemoteException e) {
   1660             throw e.rethrowFromSystemServer();
   1661         }
   1662     }
   1663 
   1664     @Override
   1665     @SuppressWarnings("unchecked")
   1666     public List<IntentFilter> getAllIntentFilters(String packageName) {
   1667         try {
   1668             ParceledListSlice<IntentFilter> parceledList =
   1669                     mPM.getAllIntentFilters(packageName);
   1670             if (parceledList == null) {
   1671                 return Collections.emptyList();
   1672             }
   1673             return parceledList.getList();
   1674         } catch (RemoteException e) {
   1675             throw e.rethrowFromSystemServer();
   1676         }
   1677     }
   1678 
   1679     @Override
   1680     public String getDefaultBrowserPackageNameAsUser(int userId) {
   1681         try {
   1682             return mPM.getDefaultBrowserPackageName(userId);
   1683         } catch (RemoteException e) {
   1684             throw e.rethrowFromSystemServer();
   1685         }
   1686     }
   1687 
   1688     @Override
   1689     public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
   1690         try {
   1691             return mPM.setDefaultBrowserPackageName(packageName, userId);
   1692         } catch (RemoteException e) {
   1693             throw e.rethrowFromSystemServer();
   1694         }
   1695     }
   1696 
   1697     @Override
   1698     public void setInstallerPackageName(String targetPackage,
   1699             String installerPackageName) {
   1700         try {
   1701             mPM.setInstallerPackageName(targetPackage, installerPackageName);
   1702         } catch (RemoteException e) {
   1703             throw e.rethrowFromSystemServer();
   1704         }
   1705     }
   1706 
   1707     @Override
   1708     public String getInstallerPackageName(String packageName) {
   1709         try {
   1710             return mPM.getInstallerPackageName(packageName);
   1711         } catch (RemoteException e) {
   1712             throw e.rethrowFromSystemServer();
   1713         }
   1714     }
   1715 
   1716     @Override
   1717     public int getMoveStatus(int moveId) {
   1718         try {
   1719             return mPM.getMoveStatus(moveId);
   1720         } catch (RemoteException e) {
   1721             throw e.rethrowFromSystemServer();
   1722         }
   1723     }
   1724 
   1725     @Override
   1726     public void registerMoveCallback(MoveCallback callback, Handler handler) {
   1727         synchronized (mDelegates) {
   1728             final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback,
   1729                     handler.getLooper());
   1730             try {
   1731                 mPM.registerMoveCallback(delegate);
   1732             } catch (RemoteException e) {
   1733                 throw e.rethrowFromSystemServer();
   1734             }
   1735             mDelegates.add(delegate);
   1736         }
   1737     }
   1738 
   1739     @Override
   1740     public void unregisterMoveCallback(MoveCallback callback) {
   1741         synchronized (mDelegates) {
   1742             for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
   1743                 final MoveCallbackDelegate delegate = i.next();
   1744                 if (delegate.mCallback == callback) {
   1745                     try {
   1746                         mPM.unregisterMoveCallback(delegate);
   1747                     } catch (RemoteException e) {
   1748                         throw e.rethrowFromSystemServer();
   1749                     }
   1750                     i.remove();
   1751                 }
   1752             }
   1753         }
   1754     }
   1755 
   1756     @Override
   1757     public int movePackage(String packageName, VolumeInfo vol) {
   1758         try {
   1759             final String volumeUuid;
   1760             if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
   1761                 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
   1762             } else if (vol.isPrimaryPhysical()) {
   1763                 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
   1764             } else {
   1765                 volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
   1766             }
   1767 
   1768             return mPM.movePackage(packageName, volumeUuid);
   1769         } catch (RemoteException e) {
   1770             throw e.rethrowFromSystemServer();
   1771         }
   1772     }
   1773 
   1774     @Override
   1775     public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
   1776         final StorageManager storage = mContext.getSystemService(StorageManager.class);
   1777         if (app.isInternal()) {
   1778             return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
   1779         } else if (app.isExternalAsec()) {
   1780             return storage.getPrimaryPhysicalVolume();
   1781         } else {
   1782             return storage.findVolumeByUuid(app.volumeUuid);
   1783         }
   1784     }
   1785 
   1786     @Override
   1787     public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
   1788         final StorageManager storage = mContext.getSystemService(StorageManager.class);
   1789         final VolumeInfo currentVol = getPackageCurrentVolume(app);
   1790         final List<VolumeInfo> vols = storage.getVolumes();
   1791         final List<VolumeInfo> candidates = new ArrayList<>();
   1792         for (VolumeInfo vol : vols) {
   1793             if (Objects.equals(vol, currentVol) || isPackageCandidateVolume(mContext, app, vol)) {
   1794                 candidates.add(vol);
   1795             }
   1796         }
   1797         return candidates;
   1798     }
   1799 
   1800     private boolean isPackageCandidateVolume(
   1801             ContextImpl context, ApplicationInfo app, VolumeInfo vol) {
   1802         final boolean forceAllowOnExternal = Settings.Global.getInt(
   1803                 context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0;
   1804         // Private internal is always an option
   1805         if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
   1806             return true;
   1807         }
   1808 
   1809         // System apps and apps demanding internal storage can't be moved
   1810         // anywhere else
   1811         if (app.isSystemApp()) {
   1812             return false;
   1813         }
   1814         if (!forceAllowOnExternal
   1815                 && (app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY
   1816                         || app.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED)) {
   1817             return false;
   1818         }
   1819 
   1820         // Gotta be able to write there
   1821         if (!vol.isMountedWritable()) {
   1822             return false;
   1823         }
   1824 
   1825         // Moving into an ASEC on public primary is only option internal
   1826         if (vol.isPrimaryPhysical()) {
   1827             return app.isInternal();
   1828         }
   1829 
   1830         // Some apps can't be moved. (e.g. device admins)
   1831         try {
   1832             if (mPM.isPackageDeviceAdminOnAnyUser(app.packageName)) {
   1833                 return false;
   1834             }
   1835         } catch (RemoteException e) {
   1836             throw e.rethrowFromSystemServer();
   1837         }
   1838 
   1839         // Otherwise we can move to any private volume
   1840         return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
   1841     }
   1842 
   1843     @Override
   1844     public int movePrimaryStorage(VolumeInfo vol) {
   1845         try {
   1846             final String volumeUuid;
   1847             if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
   1848                 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
   1849             } else if (vol.isPrimaryPhysical()) {
   1850                 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
   1851             } else {
   1852                 volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
   1853             }
   1854 
   1855             return mPM.movePrimaryStorage(volumeUuid);
   1856         } catch (RemoteException e) {
   1857             throw e.rethrowFromSystemServer();
   1858         }
   1859     }
   1860 
   1861     @Override
   1862     public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
   1863         final StorageManager storage = mContext.getSystemService(StorageManager.class);
   1864         final String volumeUuid = storage.getPrimaryStorageUuid();
   1865         return storage.findVolumeByQualifiedUuid(volumeUuid);
   1866     }
   1867 
   1868     @Override
   1869     public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
   1870         final StorageManager storage = mContext.getSystemService(StorageManager.class);
   1871         final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
   1872         final List<VolumeInfo> vols = storage.getVolumes();
   1873         final List<VolumeInfo> candidates = new ArrayList<>();
   1874         if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL,
   1875                 storage.getPrimaryStorageUuid()) && currentVol != null) {
   1876             // TODO: support moving primary physical to emulated volume
   1877             candidates.add(currentVol);
   1878         } else {
   1879             for (VolumeInfo vol : vols) {
   1880                 if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
   1881                     candidates.add(vol);
   1882                 }
   1883             }
   1884         }
   1885         return candidates;
   1886     }
   1887 
   1888     private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) {
   1889         // Private internal is always an option
   1890         if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
   1891             return true;
   1892         }
   1893 
   1894         // Gotta be able to write there
   1895         if (!vol.isMountedWritable()) {
   1896             return false;
   1897         }
   1898 
   1899         // We can move to any private volume
   1900         return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
   1901     }
   1902 
   1903     @Override
   1904     public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
   1905         deletePackageAsUser(packageName, observer, flags, mContext.getUserId());
   1906     }
   1907 
   1908     @Override
   1909     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
   1910             int userId) {
   1911         try {
   1912             mPM.deletePackageAsUser(packageName, observer, userId, flags);
   1913         } catch (RemoteException e) {
   1914             throw e.rethrowFromSystemServer();
   1915         }
   1916     }
   1917 
   1918     @Override
   1919     public void clearApplicationUserData(String packageName,
   1920                                          IPackageDataObserver observer) {
   1921         try {
   1922             mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
   1923         } catch (RemoteException e) {
   1924             throw e.rethrowFromSystemServer();
   1925         }
   1926     }
   1927     @Override
   1928     public void deleteApplicationCacheFiles(String packageName,
   1929                                             IPackageDataObserver observer) {
   1930         try {
   1931             mPM.deleteApplicationCacheFiles(packageName, observer);
   1932         } catch (RemoteException e) {
   1933             throw e.rethrowFromSystemServer();
   1934         }
   1935     }
   1936 
   1937     @Override
   1938     public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
   1939             IPackageDataObserver observer) {
   1940         try {
   1941             mPM.deleteApplicationCacheFilesAsUser(packageName, userId, observer);
   1942         } catch (RemoteException e) {
   1943             throw e.rethrowFromSystemServer();
   1944         }
   1945     }
   1946 
   1947     @Override
   1948     public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
   1949             IPackageDataObserver observer) {
   1950         try {
   1951             mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer);
   1952         } catch (RemoteException e) {
   1953             throw e.rethrowFromSystemServer();
   1954         }
   1955     }
   1956 
   1957     @Override
   1958     public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
   1959         try {
   1960             mPM.freeStorage(volumeUuid, freeStorageSize, pi);
   1961         } catch (RemoteException e) {
   1962             throw e.rethrowFromSystemServer();
   1963         }
   1964     }
   1965 
   1966     @Override
   1967     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
   1968             int userId) {
   1969         try {
   1970             return mPM.setPackagesSuspendedAsUser(packageNames, suspended, userId);
   1971         } catch (RemoteException e) {
   1972             throw e.rethrowFromSystemServer();
   1973         }
   1974     }
   1975 
   1976     @Override
   1977     public boolean isPackageSuspendedForUser(String packageName, int userId) {
   1978         try {
   1979             return mPM.isPackageSuspendedForUser(packageName, userId);
   1980         } catch (RemoteException e) {
   1981             throw e.rethrowFromSystemServer();
   1982         }
   1983     }
   1984 
   1985     @Override
   1986     public void getPackageSizeInfoAsUser(String packageName, int userHandle,
   1987             IPackageStatsObserver observer) {
   1988         try {
   1989             mPM.getPackageSizeInfo(packageName, userHandle, observer);
   1990         } catch (RemoteException e) {
   1991             throw e.rethrowFromSystemServer();
   1992         }
   1993     }
   1994 
   1995     @Override
   1996     public void addPackageToPreferred(String packageName) {
   1997         Log.w(TAG, "addPackageToPreferred() is a no-op");
   1998     }
   1999 
   2000     @Override
   2001     public void removePackageFromPreferred(String packageName) {
   2002         Log.w(TAG, "removePackageFromPreferred() is a no-op");
   2003     }
   2004 
   2005     @Override
   2006     public List<PackageInfo> getPreferredPackages(int flags) {
   2007         Log.w(TAG, "getPreferredPackages() is a no-op");
   2008         return Collections.emptyList();
   2009     }
   2010 
   2011     @Override
   2012     public void addPreferredActivity(IntentFilter filter,
   2013                                      int match, ComponentName[] set, ComponentName activity) {
   2014         try {
   2015             mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
   2016         } catch (RemoteException e) {
   2017             throw e.rethrowFromSystemServer();
   2018         }
   2019     }
   2020 
   2021     @Override
   2022     public void addPreferredActivityAsUser(IntentFilter filter, int match,
   2023             ComponentName[] set, ComponentName activity, int userId) {
   2024         try {
   2025             mPM.addPreferredActivity(filter, match, set, activity, userId);
   2026         } catch (RemoteException e) {
   2027             throw e.rethrowFromSystemServer();
   2028         }
   2029     }
   2030 
   2031     @Override
   2032     public void replacePreferredActivity(IntentFilter filter,
   2033                                          int match, ComponentName[] set, ComponentName activity) {
   2034         try {
   2035             mPM.replacePreferredActivity(filter, match, set, activity, mContext.getUserId());
   2036         } catch (RemoteException e) {
   2037             throw e.rethrowFromSystemServer();
   2038         }
   2039     }
   2040 
   2041     @Override
   2042     public void replacePreferredActivityAsUser(IntentFilter filter,
   2043                                          int match, ComponentName[] set, ComponentName activity,
   2044                                          int userId) {
   2045         try {
   2046             mPM.replacePreferredActivity(filter, match, set, activity, userId);
   2047         } catch (RemoteException e) {
   2048             throw e.rethrowFromSystemServer();
   2049         }
   2050     }
   2051 
   2052     @Override
   2053     public void clearPackagePreferredActivities(String packageName) {
   2054         try {
   2055             mPM.clearPackagePreferredActivities(packageName);
   2056         } catch (RemoteException e) {
   2057             throw e.rethrowFromSystemServer();
   2058         }
   2059     }
   2060 
   2061     @Override
   2062     public int getPreferredActivities(List<IntentFilter> outFilters,
   2063                                       List<ComponentName> outActivities, String packageName) {
   2064         try {
   2065             return mPM.getPreferredActivities(outFilters, outActivities, packageName);
   2066         } catch (RemoteException e) {
   2067             throw e.rethrowFromSystemServer();
   2068         }
   2069     }
   2070 
   2071     @Override
   2072     public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
   2073         try {
   2074             return mPM.getHomeActivities(outActivities);
   2075         } catch (RemoteException e) {
   2076             throw e.rethrowFromSystemServer();
   2077         }
   2078     }
   2079 
   2080     @Override
   2081     public void setComponentEnabledSetting(ComponentName componentName,
   2082                                            int newState, int flags) {
   2083         try {
   2084             mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
   2085         } catch (RemoteException e) {
   2086             throw e.rethrowFromSystemServer();
   2087         }
   2088     }
   2089 
   2090     @Override
   2091     public int getComponentEnabledSetting(ComponentName componentName) {
   2092         try {
   2093             return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
   2094         } catch (RemoteException e) {
   2095             throw e.rethrowFromSystemServer();
   2096         }
   2097     }
   2098 
   2099     @Override
   2100     public void setApplicationEnabledSetting(String packageName,
   2101                                              int newState, int flags) {
   2102         try {
   2103             mPM.setApplicationEnabledSetting(packageName, newState, flags,
   2104                     mContext.getUserId(), mContext.getOpPackageName());
   2105         } catch (RemoteException e) {
   2106             throw e.rethrowFromSystemServer();
   2107         }
   2108     }
   2109 
   2110     @Override
   2111     public int getApplicationEnabledSetting(String packageName) {
   2112         try {
   2113             return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
   2114         } catch (RemoteException e) {
   2115             throw e.rethrowFromSystemServer();
   2116         }
   2117     }
   2118 
   2119     @Override
   2120     public void flushPackageRestrictionsAsUser(int userId) {
   2121         try {
   2122             mPM.flushPackageRestrictionsAsUser(userId);
   2123         } catch (RemoteException e) {
   2124             throw e.rethrowFromSystemServer();
   2125         }
   2126     }
   2127 
   2128     @Override
   2129     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
   2130             UserHandle user) {
   2131         try {
   2132             return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
   2133                     user.getIdentifier());
   2134         } catch (RemoteException e) {
   2135             throw e.rethrowFromSystemServer();
   2136         }
   2137     }
   2138 
   2139     @Override
   2140     public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
   2141         try {
   2142             return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
   2143         } catch (RemoteException e) {
   2144             throw e.rethrowFromSystemServer();
   2145         }
   2146     }
   2147 
   2148     /** @hide */
   2149     @Override
   2150     public KeySet getKeySetByAlias(String packageName, String alias) {
   2151         Preconditions.checkNotNull(packageName);
   2152         Preconditions.checkNotNull(alias);
   2153         try {
   2154             return mPM.getKeySetByAlias(packageName, alias);
   2155         } catch (RemoteException e) {
   2156             throw e.rethrowFromSystemServer();
   2157         }
   2158     }
   2159 
   2160     /** @hide */
   2161     @Override
   2162     public KeySet getSigningKeySet(String packageName) {
   2163         Preconditions.checkNotNull(packageName);
   2164         try {
   2165             return mPM.getSigningKeySet(packageName);
   2166         } catch (RemoteException e) {
   2167             throw e.rethrowFromSystemServer();
   2168         }
   2169     }
   2170 
   2171     /** @hide */
   2172     @Override
   2173     public boolean isSignedBy(String packageName, KeySet ks) {
   2174         Preconditions.checkNotNull(packageName);
   2175         Preconditions.checkNotNull(ks);
   2176         try {
   2177             return mPM.isPackageSignedByKeySet(packageName, ks);
   2178         } catch (RemoteException e) {
   2179             throw e.rethrowFromSystemServer();
   2180         }
   2181     }
   2182 
   2183     /** @hide */
   2184     @Override
   2185     public boolean isSignedByExactly(String packageName, KeySet ks) {
   2186         Preconditions.checkNotNull(packageName);
   2187         Preconditions.checkNotNull(ks);
   2188         try {
   2189             return mPM.isPackageSignedByKeySetExactly(packageName, ks);
   2190         } catch (RemoteException e) {
   2191             throw e.rethrowFromSystemServer();
   2192         }
   2193     }
   2194 
   2195     /**
   2196      * @hide
   2197      */
   2198     @Override
   2199     public VerifierDeviceIdentity getVerifierDeviceIdentity() {
   2200         try {
   2201             return mPM.getVerifierDeviceIdentity();
   2202         } catch (RemoteException e) {
   2203             throw e.rethrowFromSystemServer();
   2204         }
   2205     }
   2206 
   2207     /**
   2208      * @hide
   2209      */
   2210     @Override
   2211     public boolean isUpgrade() {
   2212         try {
   2213             return mPM.isUpgrade();
   2214         } catch (RemoteException e) {
   2215             throw e.rethrowFromSystemServer();
   2216         }
   2217     }
   2218 
   2219     @Override
   2220     public PackageInstaller getPackageInstaller() {
   2221         synchronized (mLock) {
   2222             if (mInstaller == null) {
   2223                 try {
   2224                     mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(),
   2225                             mContext.getPackageName(), mContext.getUserId());
   2226                 } catch (RemoteException e) {
   2227                     throw e.rethrowFromSystemServer();
   2228                 }
   2229             }
   2230             return mInstaller;
   2231         }
   2232     }
   2233 
   2234     @Override
   2235     public boolean isPackageAvailable(String packageName) {
   2236         try {
   2237             return mPM.isPackageAvailable(packageName, mContext.getUserId());
   2238         } catch (RemoteException e) {
   2239             throw e.rethrowFromSystemServer();
   2240         }
   2241     }
   2242 
   2243     /**
   2244      * @hide
   2245      */
   2246     @Override
   2247     public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
   2248             int flags) {
   2249         try {
   2250             mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
   2251                     sourceUserId, targetUserId, flags);
   2252         } catch (RemoteException e) {
   2253             throw e.rethrowFromSystemServer();
   2254         }
   2255     }
   2256 
   2257     /**
   2258      * @hide
   2259      */
   2260     @Override
   2261     public void clearCrossProfileIntentFilters(int sourceUserId) {
   2262         try {
   2263             mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName());
   2264         } catch (RemoteException e) {
   2265             throw e.rethrowFromSystemServer();
   2266         }
   2267     }
   2268 
   2269     /**
   2270      * @hide
   2271      */
   2272     public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
   2273         Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
   2274         if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
   2275             return dr;
   2276         }
   2277         return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
   2278     }
   2279 
   2280     /**
   2281      * @hide
   2282      */
   2283     public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
   2284         if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
   2285             Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
   2286             if (bitmap == null) {
   2287                 return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false);
   2288             }
   2289             return new BitmapDrawable(bitmap);
   2290         }
   2291         Drawable dr = null;
   2292         if (itemInfo.packageName != null) {
   2293             dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
   2294         }
   2295         if (dr == null) {
   2296             dr = itemInfo.loadDefaultIcon(this);
   2297         }
   2298         return dr;
   2299     }
   2300 
   2301     private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
   2302             Rect badgeLocation, boolean tryBadgeInPlace) {
   2303         final int badgedWidth = drawable.getIntrinsicWidth();
   2304         final int badgedHeight = drawable.getIntrinsicHeight();
   2305         final boolean canBadgeInPlace = tryBadgeInPlace
   2306                 && (drawable instanceof BitmapDrawable)
   2307                 && ((BitmapDrawable) drawable).getBitmap().isMutable();
   2308 
   2309         final Bitmap bitmap;
   2310         if (canBadgeInPlace) {
   2311             bitmap = ((BitmapDrawable) drawable).getBitmap();
   2312         } else {
   2313             bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
   2314         }
   2315         Canvas canvas = new Canvas(bitmap);
   2316 
   2317         if (!canBadgeInPlace) {
   2318             drawable.setBounds(0, 0, badgedWidth, badgedHeight);
   2319             drawable.draw(canvas);
   2320         }
   2321 
   2322         if (badgeLocation != null) {
   2323             if (badgeLocation.left < 0 || badgeLocation.top < 0
   2324                     || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
   2325                 throw new IllegalArgumentException("Badge location " + badgeLocation
   2326                         + " not in badged drawable bounds "
   2327                         + new Rect(0, 0, badgedWidth, badgedHeight));
   2328             }
   2329             badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
   2330 
   2331             canvas.save();
   2332             canvas.translate(badgeLocation.left, badgeLocation.top);
   2333             badgeDrawable.draw(canvas);
   2334             canvas.restore();
   2335         } else {
   2336             badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
   2337             badgeDrawable.draw(canvas);
   2338         }
   2339 
   2340         if (!canBadgeInPlace) {
   2341             BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
   2342 
   2343             if (drawable instanceof BitmapDrawable) {
   2344                 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
   2345                 mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
   2346             }
   2347 
   2348             return mergedDrawable;
   2349         }
   2350 
   2351         return drawable;
   2352     }
   2353 
   2354     private int getBadgeResIdForUser(int userId) {
   2355         // Return the framework-provided badge.
   2356         if (isManagedProfile(userId)) {
   2357             return com.android.internal.R.drawable.ic_corp_icon_badge;
   2358         }
   2359         return 0;
   2360     }
   2361 
   2362     private boolean isManagedProfile(int userId) {
   2363         return getUserManager().isManagedProfile(userId);
   2364     }
   2365 
   2366     /** {@hide} */
   2367     private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
   2368             Handler.Callback {
   2369         private static final int MSG_CREATED = 1;
   2370         private static final int MSG_STATUS_CHANGED = 2;
   2371 
   2372         final MoveCallback mCallback;
   2373         final Handler mHandler;
   2374 
   2375         public MoveCallbackDelegate(MoveCallback callback, Looper looper) {
   2376             mCallback = callback;
   2377             mHandler = new Handler(looper, this);
   2378         }
   2379 
   2380         @Override
   2381         public boolean handleMessage(Message msg) {
   2382             switch (msg.what) {
   2383                 case MSG_CREATED: {
   2384                     final SomeArgs args = (SomeArgs) msg.obj;
   2385                     mCallback.onCreated(args.argi1, (Bundle) args.arg2);
   2386                     args.recycle();
   2387                     return true;
   2388                 }
   2389                 case MSG_STATUS_CHANGED: {
   2390                     final SomeArgs args = (SomeArgs) msg.obj;
   2391                     mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
   2392                     args.recycle();
   2393                     return true;
   2394                 }
   2395             }
   2396             return false;
   2397         }
   2398 
   2399         @Override
   2400         public void onCreated(int moveId, Bundle extras) {
   2401             final SomeArgs args = SomeArgs.obtain();
   2402             args.argi1 = moveId;
   2403             args.arg2 = extras;
   2404             mHandler.obtainMessage(MSG_CREATED, args).sendToTarget();
   2405         }
   2406 
   2407         @Override
   2408         public void onStatusChanged(int moveId, int status, long estMillis) {
   2409             final SomeArgs args = SomeArgs.obtain();
   2410             args.argi1 = moveId;
   2411             args.argi2 = status;
   2412             args.arg3 = estMillis;
   2413             mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
   2414         }
   2415     }
   2416 
   2417     private final ContextImpl mContext;
   2418     private final IPackageManager mPM;
   2419 
   2420     private static final Object sSync = new Object();
   2421     private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
   2422             = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
   2423     private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
   2424             = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
   2425 
   2426     private final Map<OnPermissionsChangedListener, IOnPermissionsChangeListener>
   2427             mPermissionListeners = new ArrayMap<>();
   2428 
   2429     public class OnPermissionsChangeListenerDelegate extends IOnPermissionsChangeListener.Stub
   2430             implements Handler.Callback{
   2431         private static final int MSG_PERMISSIONS_CHANGED = 1;
   2432 
   2433         private final OnPermissionsChangedListener mListener;
   2434         private final Handler mHandler;
   2435 
   2436 
   2437         public OnPermissionsChangeListenerDelegate(OnPermissionsChangedListener listener,
   2438                 Looper looper) {
   2439             mListener = listener;
   2440             mHandler = new Handler(looper, this);
   2441         }
   2442 
   2443         @Override
   2444         public void onPermissionsChanged(int uid) {
   2445             mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
   2446         }
   2447 
   2448         @Override
   2449         public boolean handleMessage(Message msg) {
   2450             switch (msg.what) {
   2451                 case MSG_PERMISSIONS_CHANGED: {
   2452                     final int uid = msg.arg1;
   2453                     mListener.onPermissionsChanged(uid);
   2454                     return true;
   2455                 }
   2456             }
   2457             return false;
   2458         }
   2459     }
   2460 }
   2461