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