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