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