ApplicationPackageManager.java revision 9f68f41a5866e1feb810b16c769705c10e850d5d
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 getManagedUserBadgedDrawableForDensity(Drawable drawable, Rect badgeLocation,
1097            int badgeDensity) {
1098        Drawable badgeDrawable = getDrawableForDensity(badgeDensity,
1099                com.android.internal.R.drawable.ic_corp_badge);
1100        return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
1101    }
1102
1103    @Override
1104    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
1105        final int badgeResId = getBadgeResIdForUser(user.getIdentifier());
1106        if (badgeResId == 0) {
1107            return icon;
1108        }
1109        Drawable badgeIcon = getDrawable("system", badgeResId, null);
1110        return getBadgedDrawable(icon, badgeIcon, null, true);
1111    }
1112
1113    @Override
1114    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
1115            Rect badgeLocation, int badgeDensity) {
1116        Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity);
1117        if (badgeDrawable == null) {
1118            return drawable;
1119        }
1120        return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
1121    }
1122
1123    @Override
1124    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
1125        return getManagedProfileIconForDensity(user, density,
1126                com.android.internal.R.drawable.ic_corp_badge);
1127    }
1128
1129    @Override
1130    public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
1131        return getManagedProfileIconForDensity(user, density,
1132                com.android.internal.R.drawable.ic_corp_badge_no_background);
1133    }
1134
1135    private Drawable getDrawableForDensity(int density, int drawableId) {
1136        if (density <= 0) {
1137            density = mContext.getResources().getDisplayMetrics().densityDpi;
1138        }
1139        return Resources.getSystem().getDrawableForDensity(drawableId, density);
1140    }
1141
1142    private Drawable getManagedProfileIconForDensity(UserHandle user, int density,
1143            int drawableId) {
1144        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
1145        if (userInfo != null && userInfo.isManagedProfile()) {
1146            return getDrawableForDensity(density, drawableId);
1147        }
1148        return null;
1149    }
1150
1151    @Override
1152    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
1153        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
1154        if (userInfo != null && userInfo.isManagedProfile()) {
1155            return Resources.getSystem().getString(
1156                    com.android.internal.R.string.managed_profile_label_badge, label);
1157        }
1158        return label;
1159    }
1160
1161    @Override
1162    public Resources getResourcesForActivity(ComponentName activityName)
1163            throws NameNotFoundException {
1164        return getResourcesForApplication(
1165            getActivityInfo(activityName, sDefaultFlags).applicationInfo);
1166    }
1167
1168    @Override
1169    public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
1170            throws NameNotFoundException {
1171        if (app.packageName.equals("system")) {
1172            return mContext.mMainThread.getSystemContext().getResources();
1173        }
1174        final boolean sameUid = (app.uid == Process.myUid());
1175        final Resources r = mContext.mMainThread.getTopLevelResources(
1176                sameUid ? app.sourceDir : app.publicSourceDir,
1177                sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
1178                app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
1179                null, mContext.mPackageInfo);
1180        if (r != null) {
1181            return r;
1182        }
1183        throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
1184    }
1185
1186    @Override
1187    public Resources getResourcesForApplication(String appPackageName)
1188            throws NameNotFoundException {
1189        return getResourcesForApplication(
1190            getApplicationInfo(appPackageName, sDefaultFlags));
1191    }
1192
1193    /** @hide */
1194    @Override
1195    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
1196            throws NameNotFoundException {
1197        if (userId < 0) {
1198            throw new IllegalArgumentException(
1199                    "Call does not support special user #" + userId);
1200        }
1201        if ("system".equals(appPackageName)) {
1202            return mContext.mMainThread.getSystemContext().getResources();
1203        }
1204        try {
1205            ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
1206            if (ai != null) {
1207                return getResourcesForApplication(ai);
1208            }
1209        } catch (RemoteException e) {
1210            throw e.rethrowFromSystemServer();
1211        }
1212        throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
1213    }
1214
1215    volatile int mCachedSafeMode = -1;
1216
1217    @Override
1218    public boolean isSafeMode() {
1219        try {
1220            if (mCachedSafeMode < 0) {
1221                mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
1222            }
1223            return mCachedSafeMode != 0;
1224        } catch (RemoteException e) {
1225            throw e.rethrowFromSystemServer();
1226        }
1227    }
1228
1229    @Override
1230    public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
1231        synchronized (mPermissionListeners) {
1232            if (mPermissionListeners.get(listener) != null) {
1233                return;
1234            }
1235            OnPermissionsChangeListenerDelegate delegate =
1236                    new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper());
1237            try {
1238                mPM.addOnPermissionsChangeListener(delegate);
1239                mPermissionListeners.put(listener, delegate);
1240            } catch (RemoteException e) {
1241                throw e.rethrowFromSystemServer();
1242            }
1243        }
1244    }
1245
1246    @Override
1247    public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
1248        synchronized (mPermissionListeners) {
1249            IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener);
1250            if (delegate != null) {
1251                try {
1252                    mPM.removeOnPermissionsChangeListener(delegate);
1253                    mPermissionListeners.remove(listener);
1254                } catch (RemoteException e) {
1255                    throw e.rethrowFromSystemServer();
1256                }
1257            }
1258        }
1259    }
1260
1261    static void configurationChanged() {
1262        synchronized (sSync) {
1263            sIconCache.clear();
1264            sStringCache.clear();
1265        }
1266    }
1267
1268    ApplicationPackageManager(ContextImpl context,
1269                              IPackageManager pm) {
1270        mContext = context;
1271        mPM = pm;
1272    }
1273
1274    @Nullable
1275    private Drawable getCachedIcon(@NonNull ResourceName name) {
1276        synchronized (sSync) {
1277            final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
1278            if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
1279                                   + name + ": " + wr);
1280            if (wr != null) {   // we have the activity
1281                final Drawable.ConstantState state = wr.get();
1282                if (state != null) {
1283                    if (DEBUG_ICONS) {
1284                        Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
1285                    }
1286                    // Note: It's okay here to not use the newDrawable(Resources) variant
1287                    //       of the API. The ConstantState comes from a drawable that was
1288                    //       originally created by passing the proper app Resources instance
1289                    //       which means the state should already contain the proper
1290                    //       resources specific information (like density.) See
1291                    //       BitmapDrawable.BitmapState for instance.
1292                    return state.newDrawable();
1293                }
1294                // our entry has been purged
1295                sIconCache.remove(name);
1296            }
1297        }
1298        return null;
1299    }
1300
1301    private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) {
1302        synchronized (sSync) {
1303            sIconCache.put(name, new WeakReference<>(dr.getConstantState()));
1304            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
1305        }
1306    }
1307
1308    static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
1309        boolean immediateGc = false;
1310        if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
1311            immediateGc = true;
1312        }
1313        if (pkgList != null && (pkgList.length > 0)) {
1314            boolean needCleanup = false;
1315            for (String ssp : pkgList) {
1316                synchronized (sSync) {
1317                    for (int i=sIconCache.size()-1; i>=0; i--) {
1318                        ResourceName nm = sIconCache.keyAt(i);
1319                        if (nm.packageName.equals(ssp)) {
1320                            //Log.i(TAG, "Removing cached drawable for " + nm);
1321                            sIconCache.removeAt(i);
1322                            needCleanup = true;
1323                        }
1324                    }
1325                    for (int i=sStringCache.size()-1; i>=0; i--) {
1326                        ResourceName nm = sStringCache.keyAt(i);
1327                        if (nm.packageName.equals(ssp)) {
1328                            //Log.i(TAG, "Removing cached string for " + nm);
1329                            sStringCache.removeAt(i);
1330                            needCleanup = true;
1331                        }
1332                    }
1333                }
1334            }
1335            if (needCleanup || hasPkgInfo) {
1336                if (immediateGc) {
1337                    // Schedule an immediate gc.
1338                    Runtime.getRuntime().gc();
1339                } else {
1340                    ActivityThread.currentActivityThread().scheduleGcIdler();
1341                }
1342            }
1343        }
1344    }
1345
1346    private static final class ResourceName {
1347        final String packageName;
1348        final int iconId;
1349
1350        ResourceName(String _packageName, int _iconId) {
1351            packageName = _packageName;
1352            iconId = _iconId;
1353        }
1354
1355        ResourceName(ApplicationInfo aInfo, int _iconId) {
1356            this(aInfo.packageName, _iconId);
1357        }
1358
1359        ResourceName(ComponentInfo cInfo, int _iconId) {
1360            this(cInfo.applicationInfo.packageName, _iconId);
1361        }
1362
1363        ResourceName(ResolveInfo rInfo, int _iconId) {
1364            this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
1365        }
1366
1367        @Override
1368        public boolean equals(Object o) {
1369            if (this == o) return true;
1370            if (o == null || getClass() != o.getClass()) return false;
1371
1372            ResourceName that = (ResourceName) o;
1373
1374            if (iconId != that.iconId) return false;
1375            return !(packageName != null ?
1376                     !packageName.equals(that.packageName) : that.packageName != null);
1377
1378        }
1379
1380        @Override
1381        public int hashCode() {
1382            int result;
1383            result = packageName.hashCode();
1384            result = 31 * result + iconId;
1385            return result;
1386        }
1387
1388        @Override
1389        public String toString() {
1390            return "{ResourceName " + packageName + " / " + iconId + "}";
1391        }
1392    }
1393
1394    private CharSequence getCachedString(ResourceName name) {
1395        synchronized (sSync) {
1396            WeakReference<CharSequence> wr = sStringCache.get(name);
1397            if (wr != null) {   // we have the activity
1398                CharSequence cs = wr.get();
1399                if (cs != null) {
1400                    return cs;
1401                }
1402                // our entry has been purged
1403                sStringCache.remove(name);
1404            }
1405        }
1406        return null;
1407    }
1408
1409    private void putCachedString(ResourceName name, CharSequence cs) {
1410        synchronized (sSync) {
1411            sStringCache.put(name, new WeakReference<CharSequence>(cs));
1412        }
1413    }
1414
1415    @Override
1416    public CharSequence getText(String packageName, @StringRes int resid,
1417                                ApplicationInfo appInfo) {
1418        ResourceName name = new ResourceName(packageName, resid);
1419        CharSequence text = getCachedString(name);
1420        if (text != null) {
1421            return text;
1422        }
1423        if (appInfo == null) {
1424            try {
1425                appInfo = getApplicationInfo(packageName, sDefaultFlags);
1426            } catch (NameNotFoundException e) {
1427                return null;
1428            }
1429        }
1430        try {
1431            Resources r = getResourcesForApplication(appInfo);
1432            text = r.getText(resid);
1433            putCachedString(name, text);
1434            return text;
1435        } catch (NameNotFoundException e) {
1436            Log.w("PackageManager", "Failure retrieving resources for "
1437                  + appInfo.packageName);
1438        } catch (RuntimeException e) {
1439            // If an exception was thrown, fall through to return
1440            // default icon.
1441            Log.w("PackageManager", "Failure retrieving text 0x"
1442                  + Integer.toHexString(resid) + " in package "
1443                  + packageName, e);
1444        }
1445        return null;
1446    }
1447
1448    @Override
1449    public XmlResourceParser getXml(String packageName, @XmlRes int resid,
1450                                    ApplicationInfo appInfo) {
1451        if (appInfo == null) {
1452            try {
1453                appInfo = getApplicationInfo(packageName, sDefaultFlags);
1454            } catch (NameNotFoundException e) {
1455                return null;
1456            }
1457        }
1458        try {
1459            Resources r = getResourcesForApplication(appInfo);
1460            return r.getXml(resid);
1461        } catch (RuntimeException e) {
1462            // If an exception was thrown, fall through to return
1463            // default icon.
1464            Log.w("PackageManager", "Failure retrieving xml 0x"
1465                  + Integer.toHexString(resid) + " in package "
1466                  + packageName, e);
1467        } catch (NameNotFoundException e) {
1468            Log.w("PackageManager", "Failure retrieving resources for "
1469                  + appInfo.packageName);
1470        }
1471        return null;
1472    }
1473
1474    @Override
1475    public CharSequence getApplicationLabel(ApplicationInfo info) {
1476        return info.loadLabel(this);
1477    }
1478
1479    @Override
1480    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
1481                               String installerPackageName) {
1482        installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1483                installerPackageName, mContext.getUserId());
1484    }
1485
1486    @Override
1487    public void installPackage(Uri packageURI, PackageInstallObserver observer,
1488            int flags, String installerPackageName) {
1489        installCommon(packageURI, observer, flags, installerPackageName, mContext.getUserId());
1490    }
1491
1492    private void installCommon(Uri packageURI,
1493            PackageInstallObserver observer, int flags, String installerPackageName,
1494            int userId) {
1495        if (!"file".equals(packageURI.getScheme())) {
1496            throw new UnsupportedOperationException("Only file:// URIs are supported");
1497        }
1498
1499        final String originPath = packageURI.getPath();
1500        try {
1501            mPM.installPackageAsUser(originPath, observer.getBinder(), flags, installerPackageName,
1502                    userId);
1503        } catch (RemoteException e) {
1504            throw e.rethrowFromSystemServer();
1505        }
1506    }
1507
1508    @Override
1509    public int installExistingPackage(String packageName) throws NameNotFoundException {
1510        return installExistingPackageAsUser(packageName, mContext.getUserId());
1511    }
1512
1513    @Override
1514    public int installExistingPackageAsUser(String packageName, int userId)
1515            throws NameNotFoundException {
1516        try {
1517            int res = mPM.installExistingPackageAsUser(packageName, userId);
1518            if (res == INSTALL_FAILED_INVALID_URI) {
1519                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1520            }
1521            return res;
1522        } catch (RemoteException e) {
1523            throw e.rethrowFromSystemServer();
1524        }
1525    }
1526
1527    @Override
1528    public void verifyPendingInstall(int id, int response) {
1529        try {
1530            mPM.verifyPendingInstall(id, response);
1531        } catch (RemoteException e) {
1532            throw e.rethrowFromSystemServer();
1533        }
1534    }
1535
1536    @Override
1537    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1538            long millisecondsToDelay) {
1539        try {
1540            mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1541        } catch (RemoteException e) {
1542            throw e.rethrowFromSystemServer();
1543        }
1544    }
1545
1546    @Override
1547    public void verifyIntentFilter(int id, int verificationCode, List<String> outFailedDomains) {
1548        try {
1549            mPM.verifyIntentFilter(id, verificationCode, outFailedDomains);
1550        } catch (RemoteException e) {
1551            throw e.rethrowFromSystemServer();
1552        }
1553    }
1554
1555    @Override
1556    public int getIntentVerificationStatusAsUser(String packageName, int userId) {
1557        try {
1558            return mPM.getIntentVerificationStatus(packageName, userId);
1559        } catch (RemoteException e) {
1560            throw e.rethrowFromSystemServer();
1561        }
1562    }
1563
1564    @Override
1565    public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) {
1566        try {
1567            return mPM.updateIntentVerificationStatus(packageName, status, userId);
1568        } catch (RemoteException e) {
1569            throw e.rethrowFromSystemServer();
1570        }
1571    }
1572
1573    @Override
1574    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
1575        try {
1576            return mPM.getIntentFilterVerifications(packageName);
1577        } catch (RemoteException e) {
1578            throw e.rethrowFromSystemServer();
1579        }
1580    }
1581
1582    @Override
1583    public List<IntentFilter> getAllIntentFilters(String packageName) {
1584        try {
1585            return mPM.getAllIntentFilters(packageName);
1586        } catch (RemoteException e) {
1587            throw e.rethrowFromSystemServer();
1588        }
1589    }
1590
1591    @Override
1592    public String getDefaultBrowserPackageNameAsUser(int userId) {
1593        try {
1594            return mPM.getDefaultBrowserPackageName(userId);
1595        } catch (RemoteException e) {
1596            throw e.rethrowFromSystemServer();
1597        }
1598    }
1599
1600    @Override
1601    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
1602        try {
1603            return mPM.setDefaultBrowserPackageName(packageName, userId);
1604        } catch (RemoteException e) {
1605            throw e.rethrowFromSystemServer();
1606        }
1607    }
1608
1609    @Override
1610    public void setInstallerPackageName(String targetPackage,
1611            String installerPackageName) {
1612        try {
1613            mPM.setInstallerPackageName(targetPackage, installerPackageName);
1614        } catch (RemoteException e) {
1615            throw e.rethrowFromSystemServer();
1616        }
1617    }
1618
1619    @Override
1620    public String getInstallerPackageName(String packageName) {
1621        try {
1622            return mPM.getInstallerPackageName(packageName);
1623        } catch (RemoteException e) {
1624            throw e.rethrowFromSystemServer();
1625        }
1626    }
1627
1628    @Override
1629    public int getMoveStatus(int moveId) {
1630        try {
1631            return mPM.getMoveStatus(moveId);
1632        } catch (RemoteException e) {
1633            throw e.rethrowFromSystemServer();
1634        }
1635    }
1636
1637    @Override
1638    public void registerMoveCallback(MoveCallback callback, Handler handler) {
1639        synchronized (mDelegates) {
1640            final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback,
1641                    handler.getLooper());
1642            try {
1643                mPM.registerMoveCallback(delegate);
1644            } catch (RemoteException e) {
1645                throw e.rethrowFromSystemServer();
1646            }
1647            mDelegates.add(delegate);
1648        }
1649    }
1650
1651    @Override
1652    public void unregisterMoveCallback(MoveCallback callback) {
1653        synchronized (mDelegates) {
1654            for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
1655                final MoveCallbackDelegate delegate = i.next();
1656                if (delegate.mCallback == callback) {
1657                    try {
1658                        mPM.unregisterMoveCallback(delegate);
1659                    } catch (RemoteException e) {
1660                        throw e.rethrowFromSystemServer();
1661                    }
1662                    i.remove();
1663                }
1664            }
1665        }
1666    }
1667
1668    @Override
1669    public int movePackage(String packageName, VolumeInfo vol) {
1670        try {
1671            final String volumeUuid;
1672            if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
1673                volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
1674            } else if (vol.isPrimaryPhysical()) {
1675                volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
1676            } else {
1677                volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
1678            }
1679
1680            return mPM.movePackage(packageName, volumeUuid);
1681        } catch (RemoteException e) {
1682            throw e.rethrowFromSystemServer();
1683        }
1684    }
1685
1686    @Override
1687    public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
1688        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1689        if (app.isInternal()) {
1690            return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
1691        } else if (app.isExternalAsec()) {
1692            return storage.getPrimaryPhysicalVolume();
1693        } else {
1694            return storage.findVolumeByUuid(app.volumeUuid);
1695        }
1696    }
1697
1698    @Override
1699    public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
1700        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1701        final VolumeInfo currentVol = getPackageCurrentVolume(app);
1702        final List<VolumeInfo> vols = storage.getVolumes();
1703        final List<VolumeInfo> candidates = new ArrayList<>();
1704        for (VolumeInfo vol : vols) {
1705            if (Objects.equals(vol, currentVol) || isPackageCandidateVolume(mContext, app, vol)) {
1706                candidates.add(vol);
1707            }
1708        }
1709        return candidates;
1710    }
1711
1712    private boolean isPackageCandidateVolume(
1713            ContextImpl context, ApplicationInfo app, VolumeInfo vol) {
1714        final boolean forceAllowOnExternal = Settings.Global.getInt(
1715                context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0;
1716        // Private internal is always an option
1717        if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
1718            return true;
1719        }
1720
1721        // System apps and apps demanding internal storage can't be moved
1722        // anywhere else
1723        if (app.isSystemApp()) {
1724            return false;
1725        }
1726        if (!forceAllowOnExternal
1727                && (app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY
1728                        || app.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED)) {
1729            return false;
1730        }
1731
1732        // Gotta be able to write there
1733        if (!vol.isMountedWritable()) {
1734            return false;
1735        }
1736
1737        // Moving into an ASEC on public primary is only option internal
1738        if (vol.isPrimaryPhysical()) {
1739            return app.isInternal();
1740        }
1741
1742        // Some apps can't be moved. (e.g. device admins)
1743        try {
1744            if (mPM.isPackageDeviceAdminOnAnyUser(app.packageName)) {
1745                return false;
1746            }
1747        } catch (RemoteException e) {
1748            throw e.rethrowFromSystemServer();
1749        }
1750
1751        // Otherwise we can move to any private volume
1752        return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
1753    }
1754
1755    @Override
1756    public int movePrimaryStorage(VolumeInfo vol) {
1757        try {
1758            final String volumeUuid;
1759            if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
1760                volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
1761            } else if (vol.isPrimaryPhysical()) {
1762                volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
1763            } else {
1764                volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
1765            }
1766
1767            return mPM.movePrimaryStorage(volumeUuid);
1768        } catch (RemoteException e) {
1769            throw e.rethrowFromSystemServer();
1770        }
1771    }
1772
1773    @Override
1774    public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
1775        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1776        final String volumeUuid = storage.getPrimaryStorageUuid();
1777        return storage.findVolumeByQualifiedUuid(volumeUuid);
1778    }
1779
1780    @Override
1781    public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
1782        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1783        final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
1784        final List<VolumeInfo> vols = storage.getVolumes();
1785        final List<VolumeInfo> candidates = new ArrayList<>();
1786        if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL,
1787                storage.getPrimaryStorageUuid()) && currentVol != null) {
1788            // TODO: support moving primary physical to emulated volume
1789            candidates.add(currentVol);
1790        } else {
1791            for (VolumeInfo vol : vols) {
1792                if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
1793                    candidates.add(vol);
1794                }
1795            }
1796        }
1797        return candidates;
1798    }
1799
1800    private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) {
1801        // Private internal is always an option
1802        if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
1803            return true;
1804        }
1805
1806        // Gotta be able to write there
1807        if (!vol.isMountedWritable()) {
1808            return false;
1809        }
1810
1811        // We can move to any private volume
1812        return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
1813    }
1814
1815    @Override
1816    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1817        deletePackageAsUser(packageName, observer, flags, mContext.getUserId());
1818    }
1819
1820    @Override
1821    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
1822            int userId) {
1823        try {
1824            mPM.deletePackageAsUser(packageName, observer, userId, flags);
1825        } catch (RemoteException e) {
1826            throw e.rethrowFromSystemServer();
1827        }
1828    }
1829
1830    @Override
1831    public void clearApplicationUserData(String packageName,
1832                                         IPackageDataObserver observer) {
1833        try {
1834            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
1835        } catch (RemoteException e) {
1836            throw e.rethrowFromSystemServer();
1837        }
1838    }
1839    @Override
1840    public void deleteApplicationCacheFiles(String packageName,
1841                                            IPackageDataObserver observer) {
1842        try {
1843            mPM.deleteApplicationCacheFiles(packageName, observer);
1844        } catch (RemoteException e) {
1845            throw e.rethrowFromSystemServer();
1846        }
1847    }
1848
1849    @Override
1850    public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
1851            IPackageDataObserver observer) {
1852        try {
1853            mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer);
1854        } catch (RemoteException e) {
1855            throw e.rethrowFromSystemServer();
1856        }
1857    }
1858
1859    @Override
1860    public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
1861        try {
1862            mPM.freeStorage(volumeUuid, freeStorageSize, pi);
1863        } catch (RemoteException e) {
1864            throw e.rethrowFromSystemServer();
1865        }
1866    }
1867
1868    @Override
1869    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
1870            int userId) {
1871        try {
1872            return mPM.setPackagesSuspendedAsUser(packageNames, suspended, userId);
1873        } catch (RemoteException e) {
1874            throw e.rethrowFromSystemServer();
1875        }
1876    }
1877
1878    @Override
1879    public boolean isPackageSuspendedForUser(String packageName, int userId) {
1880        try {
1881            return mPM.isPackageSuspendedForUser(packageName, userId);
1882        } catch (RemoteException e) {
1883            throw e.rethrowFromSystemServer();
1884        }
1885    }
1886
1887    @Override
1888    public void getPackageSizeInfoAsUser(String packageName, int userHandle,
1889            IPackageStatsObserver observer) {
1890        try {
1891            mPM.getPackageSizeInfo(packageName, userHandle, observer);
1892        } catch (RemoteException e) {
1893            throw e.rethrowFromSystemServer();
1894        }
1895    }
1896    @Override
1897    public void addPackageToPreferred(String packageName) {
1898        try {
1899            mPM.addPackageToPreferred(packageName);
1900        } catch (RemoteException e) {
1901            throw e.rethrowFromSystemServer();
1902        }
1903    }
1904
1905    @Override
1906    public void removePackageFromPreferred(String packageName) {
1907        try {
1908            mPM.removePackageFromPreferred(packageName);
1909        } catch (RemoteException e) {
1910            throw e.rethrowFromSystemServer();
1911        }
1912    }
1913
1914    @Override
1915    public List<PackageInfo> getPreferredPackages(int flags) {
1916        try {
1917            return mPM.getPreferredPackages(flags);
1918        } catch (RemoteException e) {
1919            throw e.rethrowFromSystemServer();
1920        }
1921    }
1922
1923    @Override
1924    public void addPreferredActivity(IntentFilter filter,
1925                                     int match, ComponentName[] set, ComponentName activity) {
1926        try {
1927            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
1928        } catch (RemoteException e) {
1929            throw e.rethrowFromSystemServer();
1930        }
1931    }
1932
1933    @Override
1934    public void addPreferredActivityAsUser(IntentFilter filter, int match,
1935            ComponentName[] set, ComponentName activity, int userId) {
1936        try {
1937            mPM.addPreferredActivity(filter, match, set, activity, userId);
1938        } catch (RemoteException e) {
1939            throw e.rethrowFromSystemServer();
1940        }
1941    }
1942
1943    @Override
1944    public void replacePreferredActivity(IntentFilter filter,
1945                                         int match, ComponentName[] set, ComponentName activity) {
1946        try {
1947            mPM.replacePreferredActivity(filter, match, set, activity, mContext.getUserId());
1948        } catch (RemoteException e) {
1949            throw e.rethrowFromSystemServer();
1950        }
1951    }
1952
1953    @Override
1954    public void replacePreferredActivityAsUser(IntentFilter filter,
1955                                         int match, ComponentName[] set, ComponentName activity,
1956                                         int userId) {
1957        try {
1958            mPM.replacePreferredActivity(filter, match, set, activity, userId);
1959        } catch (RemoteException e) {
1960            throw e.rethrowFromSystemServer();
1961        }
1962    }
1963
1964    @Override
1965    public void clearPackagePreferredActivities(String packageName) {
1966        try {
1967            mPM.clearPackagePreferredActivities(packageName);
1968        } catch (RemoteException e) {
1969            throw e.rethrowFromSystemServer();
1970        }
1971    }
1972
1973    @Override
1974    public int getPreferredActivities(List<IntentFilter> outFilters,
1975                                      List<ComponentName> outActivities, String packageName) {
1976        try {
1977            return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1978        } catch (RemoteException e) {
1979            throw e.rethrowFromSystemServer();
1980        }
1981    }
1982
1983    @Override
1984    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
1985        try {
1986            return mPM.getHomeActivities(outActivities);
1987        } catch (RemoteException e) {
1988            throw e.rethrowFromSystemServer();
1989        }
1990    }
1991
1992    @Override
1993    public void setComponentEnabledSetting(ComponentName componentName,
1994                                           int newState, int flags) {
1995        try {
1996            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
1997        } catch (RemoteException e) {
1998            throw e.rethrowFromSystemServer();
1999        }
2000    }
2001
2002    @Override
2003    public int getComponentEnabledSetting(ComponentName componentName) {
2004        try {
2005            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
2006        } catch (RemoteException e) {
2007            throw e.rethrowFromSystemServer();
2008        }
2009    }
2010
2011    @Override
2012    public void setApplicationEnabledSetting(String packageName,
2013                                             int newState, int flags) {
2014        try {
2015            mPM.setApplicationEnabledSetting(packageName, newState, flags,
2016                    mContext.getUserId(), mContext.getOpPackageName());
2017        } catch (RemoteException e) {
2018            throw e.rethrowFromSystemServer();
2019        }
2020    }
2021
2022    @Override
2023    public int getApplicationEnabledSetting(String packageName) {
2024        try {
2025            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
2026        } catch (RemoteException e) {
2027            throw e.rethrowFromSystemServer();
2028        }
2029    }
2030
2031    @Override
2032    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
2033            UserHandle user) {
2034        try {
2035            return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
2036                    user.getIdentifier());
2037        } catch (RemoteException e) {
2038            throw e.rethrowFromSystemServer();
2039        }
2040    }
2041
2042    @Override
2043    public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
2044        try {
2045            return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
2046        } catch (RemoteException e) {
2047            throw e.rethrowFromSystemServer();
2048        }
2049    }
2050
2051    /** @hide */
2052    @Override
2053    public KeySet getKeySetByAlias(String packageName, String alias) {
2054        Preconditions.checkNotNull(packageName);
2055        Preconditions.checkNotNull(alias);
2056        try {
2057            return mPM.getKeySetByAlias(packageName, alias);
2058        } catch (RemoteException e) {
2059            throw e.rethrowFromSystemServer();
2060        }
2061    }
2062
2063    /** @hide */
2064    @Override
2065    public KeySet getSigningKeySet(String packageName) {
2066        Preconditions.checkNotNull(packageName);
2067        try {
2068            return mPM.getSigningKeySet(packageName);
2069        } catch (RemoteException e) {
2070            throw e.rethrowFromSystemServer();
2071        }
2072    }
2073
2074    /** @hide */
2075    @Override
2076    public boolean isSignedBy(String packageName, KeySet ks) {
2077        Preconditions.checkNotNull(packageName);
2078        Preconditions.checkNotNull(ks);
2079        try {
2080            return mPM.isPackageSignedByKeySet(packageName, ks);
2081        } catch (RemoteException e) {
2082            throw e.rethrowFromSystemServer();
2083        }
2084    }
2085
2086    /** @hide */
2087    @Override
2088    public boolean isSignedByExactly(String packageName, KeySet ks) {
2089        Preconditions.checkNotNull(packageName);
2090        Preconditions.checkNotNull(ks);
2091        try {
2092            return mPM.isPackageSignedByKeySetExactly(packageName, ks);
2093        } catch (RemoteException e) {
2094            throw e.rethrowFromSystemServer();
2095        }
2096    }
2097
2098    /**
2099     * @hide
2100     */
2101    @Override
2102    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
2103        try {
2104            return mPM.getVerifierDeviceIdentity();
2105        } catch (RemoteException e) {
2106            throw e.rethrowFromSystemServer();
2107        }
2108    }
2109
2110    /**
2111     * @hide
2112     */
2113    @Override
2114    public boolean isUpgrade() {
2115        try {
2116            return mPM.isUpgrade();
2117        } catch (RemoteException e) {
2118            throw e.rethrowFromSystemServer();
2119        }
2120    }
2121
2122    @Override
2123    public PackageInstaller getPackageInstaller() {
2124        synchronized (mLock) {
2125            if (mInstaller == null) {
2126                try {
2127                    mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(),
2128                            mContext.getPackageName(), mContext.getUserId());
2129                } catch (RemoteException e) {
2130                    throw e.rethrowFromSystemServer();
2131                }
2132            }
2133            return mInstaller;
2134        }
2135    }
2136
2137    @Override
2138    public boolean isPackageAvailable(String packageName) {
2139        try {
2140            return mPM.isPackageAvailable(packageName, mContext.getUserId());
2141        } catch (RemoteException e) {
2142            throw e.rethrowFromSystemServer();
2143        }
2144    }
2145
2146    /**
2147     * @hide
2148     */
2149    @Override
2150    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
2151            int flags) {
2152        try {
2153            mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
2154                    sourceUserId, targetUserId, flags);
2155        } catch (RemoteException e) {
2156            throw e.rethrowFromSystemServer();
2157        }
2158    }
2159
2160    /**
2161     * @hide
2162     */
2163    @Override
2164    public void clearCrossProfileIntentFilters(int sourceUserId) {
2165        try {
2166            mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName());
2167        } catch (RemoteException e) {
2168            throw e.rethrowFromSystemServer();
2169        }
2170    }
2171
2172    /**
2173     * @hide
2174     */
2175    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
2176        Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
2177        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
2178            return dr;
2179        }
2180        return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
2181    }
2182
2183    /**
2184     * @hide
2185     */
2186    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
2187        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
2188            Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
2189            if (bitmap == null) {
2190                return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false);
2191            }
2192            return new BitmapDrawable(bitmap);
2193        }
2194        Drawable dr = null;
2195        if (itemInfo.packageName != null) {
2196            dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
2197        }
2198        if (dr == null) {
2199            dr = itemInfo.loadDefaultIcon(this);
2200        }
2201        return dr;
2202    }
2203
2204    private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
2205            Rect badgeLocation, boolean tryBadgeInPlace) {
2206        final int badgedWidth = drawable.getIntrinsicWidth();
2207        final int badgedHeight = drawable.getIntrinsicHeight();
2208        final boolean canBadgeInPlace = tryBadgeInPlace
2209                && (drawable instanceof BitmapDrawable)
2210                && ((BitmapDrawable) drawable).getBitmap().isMutable();
2211
2212        final Bitmap bitmap;
2213        if (canBadgeInPlace) {
2214            bitmap = ((BitmapDrawable) drawable).getBitmap();
2215        } else {
2216            bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
2217        }
2218        Canvas canvas = new Canvas(bitmap);
2219
2220        if (!canBadgeInPlace) {
2221            drawable.setBounds(0, 0, badgedWidth, badgedHeight);
2222            drawable.draw(canvas);
2223        }
2224
2225        if (badgeLocation != null) {
2226            if (badgeLocation.left < 0 || badgeLocation.top < 0
2227                    || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
2228                throw new IllegalArgumentException("Badge location " + badgeLocation
2229                        + " not in badged drawable bounds "
2230                        + new Rect(0, 0, badgedWidth, badgedHeight));
2231            }
2232            badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
2233
2234            canvas.save();
2235            canvas.translate(badgeLocation.left, badgeLocation.top);
2236            badgeDrawable.draw(canvas);
2237            canvas.restore();
2238        } else {
2239            badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
2240            badgeDrawable.draw(canvas);
2241        }
2242
2243        if (!canBadgeInPlace) {
2244            BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
2245
2246            if (drawable instanceof BitmapDrawable) {
2247                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
2248                mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
2249            }
2250
2251            return mergedDrawable;
2252        }
2253
2254        return drawable;
2255    }
2256
2257    private int getBadgeResIdForUser(int userHandle) {
2258        // Return the framework-provided badge.
2259        UserInfo userInfo = getUserIfProfile(userHandle);
2260        if (userInfo != null && userInfo.isManagedProfile()) {
2261            return com.android.internal.R.drawable.ic_corp_icon_badge;
2262        }
2263        return 0;
2264    }
2265
2266    private UserInfo getUserIfProfile(int userHandle) {
2267        List<UserInfo> userProfiles = getUserManager().getProfiles(mContext.getUserId());
2268        for (UserInfo user : userProfiles) {
2269            if (user.id == userHandle) {
2270                return user;
2271            }
2272        }
2273        return null;
2274    }
2275
2276    /** {@hide} */
2277    private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
2278            Handler.Callback {
2279        private static final int MSG_CREATED = 1;
2280        private static final int MSG_STATUS_CHANGED = 2;
2281
2282        final MoveCallback mCallback;
2283        final Handler mHandler;
2284
2285        public MoveCallbackDelegate(MoveCallback callback, Looper looper) {
2286            mCallback = callback;
2287            mHandler = new Handler(looper, this);
2288        }
2289
2290        @Override
2291        public boolean handleMessage(Message msg) {
2292            switch (msg.what) {
2293                case MSG_CREATED: {
2294                    final SomeArgs args = (SomeArgs) msg.obj;
2295                    mCallback.onCreated(args.argi1, (Bundle) args.arg2);
2296                    args.recycle();
2297                    return true;
2298                }
2299                case MSG_STATUS_CHANGED: {
2300                    final SomeArgs args = (SomeArgs) msg.obj;
2301                    mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
2302                    args.recycle();
2303                    return true;
2304                }
2305            }
2306            return false;
2307        }
2308
2309        @Override
2310        public void onCreated(int moveId, Bundle extras) {
2311            final SomeArgs args = SomeArgs.obtain();
2312            args.argi1 = moveId;
2313            args.arg2 = extras;
2314            mHandler.obtainMessage(MSG_CREATED, args).sendToTarget();
2315        }
2316
2317        @Override
2318        public void onStatusChanged(int moveId, int status, long estMillis) {
2319            final SomeArgs args = SomeArgs.obtain();
2320            args.argi1 = moveId;
2321            args.argi2 = status;
2322            args.arg3 = estMillis;
2323            mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
2324        }
2325    }
2326
2327    private final ContextImpl mContext;
2328    private final IPackageManager mPM;
2329
2330    private static final Object sSync = new Object();
2331    private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
2332            = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
2333    private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
2334            = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
2335
2336    private final Map<OnPermissionsChangedListener, IOnPermissionsChangeListener>
2337            mPermissionListeners = new ArrayMap<>();
2338
2339    public class OnPermissionsChangeListenerDelegate extends IOnPermissionsChangeListener.Stub
2340            implements Handler.Callback{
2341        private static final int MSG_PERMISSIONS_CHANGED = 1;
2342
2343        private final OnPermissionsChangedListener mListener;
2344        private final Handler mHandler;
2345
2346
2347        public OnPermissionsChangeListenerDelegate(OnPermissionsChangedListener listener,
2348                Looper looper) {
2349            mListener = listener;
2350            mHandler = new Handler(looper, this);
2351        }
2352
2353        @Override
2354        public void onPermissionsChanged(int uid) {
2355            mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
2356        }
2357
2358        @Override
2359        public boolean handleMessage(Message msg) {
2360            switch (msg.what) {
2361                case MSG_PERMISSIONS_CHANGED: {
2362                    final int uid = msg.arg1;
2363                    mListener.onPermissionsChanged(uid);
2364                    return true;
2365                }
2366            }
2367            return false;
2368        }
2369    }
2370}
2371