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