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