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