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