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