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