ApplicationPackageManager.java revision 275e3e43f2fba72fa99001cafa2a70e5478fc545
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    @Override
1560    public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
1561        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1562        final String volumeUuid = storage.getPrimaryStorageUuid();
1563        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
1564            return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
1565        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
1566            return storage.getPrimaryPhysicalVolume();
1567        } else {
1568            return storage.findVolumeByUuid(volumeUuid);
1569        }
1570    }
1571
1572    @Override
1573    public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
1574        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1575        final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
1576        final List<VolumeInfo> vols = storage.getVolumes();
1577        final List<VolumeInfo> candidates = new ArrayList<>();
1578        for (VolumeInfo vol : vols) {
1579            if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
1580                candidates.add(vol);
1581            }
1582        }
1583        return candidates;
1584    }
1585
1586    private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) {
1587        // Private internal is always an option
1588        if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
1589            return true;
1590        }
1591
1592        // Gotta be able to write there
1593        if (!vol.isMountedWritable()) {
1594            return false;
1595        }
1596
1597        // We can move to public volumes on legacy devices
1598        if ((vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.getDisk().isDefaultPrimary()) {
1599            return true;
1600        }
1601
1602        // Otherwise we can move to any private volume
1603        return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
1604    }
1605
1606    @Override
1607    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1608        try {
1609            mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
1610        } catch (RemoteException e) {
1611            // Should never happen!
1612        }
1613    }
1614
1615    @Override
1616    public void clearApplicationUserData(String packageName,
1617                                         IPackageDataObserver observer) {
1618        try {
1619            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
1620        } catch (RemoteException e) {
1621            // Should never happen!
1622        }
1623    }
1624    @Override
1625    public void deleteApplicationCacheFiles(String packageName,
1626                                            IPackageDataObserver observer) {
1627        try {
1628            mPM.deleteApplicationCacheFiles(packageName, observer);
1629        } catch (RemoteException e) {
1630            // Should never happen!
1631        }
1632    }
1633
1634    @Override
1635    public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
1636            IPackageDataObserver observer) {
1637        try {
1638            mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer);
1639        } catch (RemoteException e) {
1640            // Should never happen!
1641        }
1642    }
1643
1644    @Override
1645    public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
1646        try {
1647            mPM.freeStorage(volumeUuid, freeStorageSize, pi);
1648        } catch (RemoteException e) {
1649            // Should never happen!
1650        }
1651    }
1652
1653    @Override
1654    public void getPackageSizeInfo(String packageName, int userHandle,
1655            IPackageStatsObserver observer) {
1656        try {
1657            mPM.getPackageSizeInfo(packageName, userHandle, observer);
1658        } catch (RemoteException e) {
1659            // Should never happen!
1660        }
1661    }
1662    @Override
1663    public void addPackageToPreferred(String packageName) {
1664        try {
1665            mPM.addPackageToPreferred(packageName);
1666        } catch (RemoteException e) {
1667            // Should never happen!
1668        }
1669    }
1670
1671    @Override
1672    public void removePackageFromPreferred(String packageName) {
1673        try {
1674            mPM.removePackageFromPreferred(packageName);
1675        } catch (RemoteException e) {
1676            // Should never happen!
1677        }
1678    }
1679
1680    @Override
1681    public List<PackageInfo> getPreferredPackages(int flags) {
1682        try {
1683            return mPM.getPreferredPackages(flags);
1684        } catch (RemoteException e) {
1685            // Should never happen!
1686        }
1687        return new ArrayList<PackageInfo>();
1688    }
1689
1690    @Override
1691    public void addPreferredActivity(IntentFilter filter,
1692                                     int match, ComponentName[] set, ComponentName activity) {
1693        try {
1694            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
1695        } catch (RemoteException e) {
1696            // Should never happen!
1697        }
1698    }
1699
1700    @Override
1701    public void addPreferredActivity(IntentFilter filter, int match,
1702            ComponentName[] set, ComponentName activity, int userId) {
1703        try {
1704            mPM.addPreferredActivity(filter, match, set, activity, userId);
1705        } catch (RemoteException e) {
1706            // Should never happen!
1707        }
1708    }
1709
1710    @Override
1711    public void replacePreferredActivity(IntentFilter filter,
1712                                         int match, ComponentName[] set, ComponentName activity) {
1713        try {
1714            mPM.replacePreferredActivity(filter, match, set, activity, UserHandle.myUserId());
1715        } catch (RemoteException e) {
1716            // Should never happen!
1717        }
1718    }
1719
1720    @Override
1721    public void replacePreferredActivityAsUser(IntentFilter filter,
1722                                         int match, ComponentName[] set, ComponentName activity,
1723                                         int userId) {
1724        try {
1725            mPM.replacePreferredActivity(filter, match, set, activity, userId);
1726        } catch (RemoteException e) {
1727            // Should never happen!
1728        }
1729    }
1730
1731    @Override
1732    public void clearPackagePreferredActivities(String packageName) {
1733        try {
1734            mPM.clearPackagePreferredActivities(packageName);
1735        } catch (RemoteException e) {
1736            // Should never happen!
1737        }
1738    }
1739
1740    @Override
1741    public int getPreferredActivities(List<IntentFilter> outFilters,
1742                                      List<ComponentName> outActivities, String packageName) {
1743        try {
1744            return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1745        } catch (RemoteException e) {
1746            // Should never happen!
1747        }
1748        return 0;
1749    }
1750
1751    @Override
1752    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
1753        try {
1754            return mPM.getHomeActivities(outActivities);
1755        } catch (RemoteException e) {
1756            // Should never happen!
1757        }
1758        return null;
1759    }
1760
1761    @Override
1762    public void setComponentEnabledSetting(ComponentName componentName,
1763                                           int newState, int flags) {
1764        try {
1765            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
1766        } catch (RemoteException e) {
1767            // Should never happen!
1768        }
1769    }
1770
1771    @Override
1772    public int getComponentEnabledSetting(ComponentName componentName) {
1773        try {
1774            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
1775        } catch (RemoteException e) {
1776            // Should never happen!
1777        }
1778        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1779    }
1780
1781    @Override
1782    public void setApplicationEnabledSetting(String packageName,
1783                                             int newState, int flags) {
1784        try {
1785            mPM.setApplicationEnabledSetting(packageName, newState, flags,
1786                    mContext.getUserId(), mContext.getOpPackageName());
1787        } catch (RemoteException e) {
1788            // Should never happen!
1789        }
1790    }
1791
1792    @Override
1793    public int getApplicationEnabledSetting(String packageName) {
1794        try {
1795            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
1796        } catch (RemoteException e) {
1797            // Should never happen!
1798        }
1799        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1800    }
1801
1802    @Override
1803    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
1804            UserHandle user) {
1805        try {
1806            return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
1807                    user.getIdentifier());
1808        } catch (RemoteException re) {
1809            // Should never happen!
1810        }
1811        return false;
1812    }
1813
1814    @Override
1815    public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
1816        try {
1817            return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
1818        } catch (RemoteException re) {
1819            // Should never happen!
1820        }
1821        return false;
1822    }
1823
1824    /** @hide */
1825    @Override
1826    public KeySet getKeySetByAlias(String packageName, String alias) {
1827        Preconditions.checkNotNull(packageName);
1828        Preconditions.checkNotNull(alias);
1829        KeySet ks;
1830        try {
1831            ks = mPM.getKeySetByAlias(packageName, alias);
1832        } catch (RemoteException e) {
1833            return null;
1834        }
1835        return ks;
1836    }
1837
1838    /** @hide */
1839    @Override
1840    public KeySet getSigningKeySet(String packageName) {
1841        Preconditions.checkNotNull(packageName);
1842        KeySet ks;
1843        try {
1844            ks = mPM.getSigningKeySet(packageName);
1845        } catch (RemoteException e) {
1846            return null;
1847        }
1848        return ks;
1849    }
1850
1851    /** @hide */
1852    @Override
1853    public boolean isSignedBy(String packageName, KeySet ks) {
1854        Preconditions.checkNotNull(packageName);
1855        Preconditions.checkNotNull(ks);
1856        try {
1857            return mPM.isPackageSignedByKeySet(packageName, ks);
1858        } catch (RemoteException e) {
1859            return false;
1860        }
1861    }
1862
1863    /** @hide */
1864    @Override
1865    public boolean isSignedByExactly(String packageName, KeySet ks) {
1866        Preconditions.checkNotNull(packageName);
1867        Preconditions.checkNotNull(ks);
1868        try {
1869            return mPM.isPackageSignedByKeySetExactly(packageName, ks);
1870        } catch (RemoteException e) {
1871            return false;
1872        }
1873    }
1874
1875    /**
1876     * @hide
1877     */
1878    @Override
1879    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1880        try {
1881            return mPM.getVerifierDeviceIdentity();
1882        } catch (RemoteException e) {
1883            // Should never happen!
1884        }
1885        return null;
1886    }
1887
1888    /**
1889     * @hide
1890     */
1891    @Override
1892    public boolean isUpgrade() {
1893        try {
1894            return mPM.isUpgrade();
1895        } catch (RemoteException e) {
1896            return false;
1897        }
1898    }
1899
1900    @Override
1901    public PackageInstaller getPackageInstaller() {
1902        synchronized (mLock) {
1903            if (mInstaller == null) {
1904                try {
1905                    mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(),
1906                            mContext.getPackageName(), mContext.getUserId());
1907                } catch (RemoteException e) {
1908                    throw e.rethrowAsRuntimeException();
1909                }
1910            }
1911            return mInstaller;
1912        }
1913    }
1914
1915    @Override
1916    public boolean isPackageAvailable(String packageName) {
1917        try {
1918            return mPM.isPackageAvailable(packageName, mContext.getUserId());
1919        } catch (RemoteException e) {
1920            throw e.rethrowAsRuntimeException();
1921        }
1922    }
1923
1924    /**
1925     * @hide
1926     */
1927    @Override
1928    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
1929            int flags) {
1930        try {
1931            mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
1932                    sourceUserId, targetUserId, flags);
1933        } catch (RemoteException e) {
1934            // Should never happen!
1935        }
1936    }
1937
1938    /**
1939     * @hide
1940     */
1941    @Override
1942    public void clearCrossProfileIntentFilters(int sourceUserId) {
1943        try {
1944            mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName());
1945        } catch (RemoteException e) {
1946            // Should never happen!
1947        }
1948    }
1949
1950    /**
1951     * @hide
1952     */
1953    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
1954        Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
1955        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
1956            return dr;
1957        }
1958        return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
1959    }
1960
1961    /**
1962     * @hide
1963     */
1964    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
1965        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
1966            Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
1967            if (bitmap == null) {
1968                return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false);
1969            }
1970            return new BitmapDrawable(bitmap);
1971        }
1972        Drawable dr = null;
1973        if (itemInfo.packageName != null) {
1974            dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
1975        }
1976        if (dr == null) {
1977            dr = itemInfo.loadDefaultIcon(this);
1978        }
1979        return dr;
1980    }
1981
1982    private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
1983            Rect badgeLocation, boolean tryBadgeInPlace) {
1984        final int badgedWidth = drawable.getIntrinsicWidth();
1985        final int badgedHeight = drawable.getIntrinsicHeight();
1986        final boolean canBadgeInPlace = tryBadgeInPlace
1987                && (drawable instanceof BitmapDrawable)
1988                && ((BitmapDrawable) drawable).getBitmap().isMutable();
1989
1990        final Bitmap bitmap;
1991        if (canBadgeInPlace) {
1992            bitmap = ((BitmapDrawable) drawable).getBitmap();
1993        } else {
1994            bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
1995        }
1996        Canvas canvas = new Canvas(bitmap);
1997
1998        if (!canBadgeInPlace) {
1999            drawable.setBounds(0, 0, badgedWidth, badgedHeight);
2000            drawable.draw(canvas);
2001        }
2002
2003        if (badgeLocation != null) {
2004            if (badgeLocation.left < 0 || badgeLocation.top < 0
2005                    || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
2006                throw new IllegalArgumentException("Badge location " + badgeLocation
2007                        + " not in badged drawable bounds "
2008                        + new Rect(0, 0, badgedWidth, badgedHeight));
2009            }
2010            badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
2011
2012            canvas.save();
2013            canvas.translate(badgeLocation.left, badgeLocation.top);
2014            badgeDrawable.draw(canvas);
2015            canvas.restore();
2016        } else {
2017            badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
2018            badgeDrawable.draw(canvas);
2019        }
2020
2021        if (!canBadgeInPlace) {
2022            BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
2023
2024            if (drawable instanceof BitmapDrawable) {
2025                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
2026                mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
2027            }
2028
2029            return mergedDrawable;
2030        }
2031
2032        return drawable;
2033    }
2034
2035    private int getBadgeResIdForUser(int userHandle) {
2036        // Return the framework-provided badge.
2037        UserInfo userInfo = getUserIfProfile(userHandle);
2038        if (userInfo != null && userInfo.isManagedProfile()) {
2039            return com.android.internal.R.drawable.ic_corp_icon_badge;
2040        }
2041        return 0;
2042    }
2043
2044    private UserInfo getUserIfProfile(int userHandle) {
2045        List<UserInfo> userProfiles = getUserManager().getProfiles(UserHandle.myUserId());
2046        for (UserInfo user : userProfiles) {
2047            if (user.id == userHandle) {
2048                return user;
2049            }
2050        }
2051        return null;
2052    }
2053
2054    /** {@hide} */
2055    private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
2056            Handler.Callback {
2057        private static final int MSG_STARTED = 1;
2058        private static final int MSG_STATUS_CHANGED = 2;
2059
2060        final MoveCallback mCallback;
2061        final Handler mHandler;
2062
2063        public MoveCallbackDelegate(MoveCallback callback, Looper looper) {
2064            mCallback = callback;
2065            mHandler = new Handler(looper, this);
2066        }
2067
2068        @Override
2069        public boolean handleMessage(Message msg) {
2070            final int moveId = msg.arg1;
2071            switch (msg.what) {
2072                case MSG_STARTED:
2073                    mCallback.onStarted(moveId, (String) msg.obj);
2074                    return true;
2075                case MSG_STATUS_CHANGED:
2076                    mCallback.onStatusChanged(moveId, msg.arg2, (long) msg.obj);
2077                    return true;
2078            }
2079            return false;
2080        }
2081
2082        @Override
2083        public void onStarted(int moveId, String title) {
2084            mHandler.obtainMessage(MSG_STARTED, moveId, 0, title).sendToTarget();
2085        }
2086
2087        @Override
2088        public void onStatusChanged(int moveId, int status, long estMillis) {
2089            mHandler.obtainMessage(MSG_STATUS_CHANGED, moveId, status, estMillis).sendToTarget();
2090        }
2091    }
2092
2093    private final ContextImpl mContext;
2094    private final IPackageManager mPM;
2095
2096    private static final Object sSync = new Object();
2097    private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
2098            = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
2099    private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
2100            = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
2101}
2102