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