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