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