ApplicationPackageManager.java revision 31a16551910492321a6f7c291eb33e1458f39f0a
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        return isInstantApp(mContext.getPackageName());
809    }
810
811    @Override
812    public boolean isInstantApp(String packageName) {
813        try {
814            return mPM.isInstantApp(packageName, mContext.getUserId());
815        } catch (RemoteException e) {
816            throw e.rethrowFromSystemServer();
817        }
818    }
819
820    @Override
821    public int getInstantAppCookieMaxSize() {
822        return Settings.Global.getInt(mContext.getContentResolver(),
823                Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
824                DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES);
825    }
826
827    @Override
828    public @NonNull byte[] getInstantAppCookie() {
829        try {
830            final byte[] cookie = mPM.getInstantAppCookie(
831                    mContext.getPackageName(), mContext.getUserId());
832            if (cookie != null) {
833                return cookie;
834            } else {
835                return EmptyArray.BYTE;
836            }
837        } catch (RemoteException e) {
838            throw e.rethrowFromSystemServer();
839        }
840    }
841
842    @Override
843    public boolean setInstantAppCookie(@NonNull byte[] cookie) {
844        try {
845            return mPM.setInstantAppCookie(mContext.getPackageName(),
846                    cookie, mContext.getUserId());
847        } catch (RemoteException e) {
848            throw e.rethrowFromSystemServer();
849        }
850    }
851
852    @Override
853    public ResolveInfo resolveActivity(Intent intent, int flags) {
854        return resolveActivityAsUser(intent, flags, mContext.getUserId());
855    }
856
857    @Override
858    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
859        try {
860            return mPM.resolveIntent(
861                intent,
862                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
863                flags,
864                userId);
865        } catch (RemoteException e) {
866            throw e.rethrowFromSystemServer();
867        }
868    }
869
870    @Override
871    public List<ResolveInfo> queryIntentActivities(Intent intent,
872                                                   int flags) {
873        return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId());
874    }
875
876    /** @hide Same as above but for a specific user */
877    @Override
878    @SuppressWarnings("unchecked")
879    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
880            int flags, int userId) {
881        try {
882            ParceledListSlice<ResolveInfo> parceledList =
883                    mPM.queryIntentActivities(intent,
884                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
885                            flags, userId);
886            if (parceledList == null) {
887                return Collections.emptyList();
888            }
889            return parceledList.getList();
890        } catch (RemoteException e) {
891            throw e.rethrowFromSystemServer();
892        }
893    }
894
895    @Override
896    @SuppressWarnings("unchecked")
897    public List<ResolveInfo> queryIntentActivityOptions(
898        ComponentName caller, Intent[] specifics, Intent intent,
899        int flags) {
900        final ContentResolver resolver = mContext.getContentResolver();
901
902        String[] specificTypes = null;
903        if (specifics != null) {
904            final int N = specifics.length;
905            for (int i=0; i<N; i++) {
906                Intent sp = specifics[i];
907                if (sp != null) {
908                    String t = sp.resolveTypeIfNeeded(resolver);
909                    if (t != null) {
910                        if (specificTypes == null) {
911                            specificTypes = new String[N];
912                        }
913                        specificTypes[i] = t;
914                    }
915                }
916            }
917        }
918
919        try {
920            ParceledListSlice<ResolveInfo> parceledList =
921                    mPM.queryIntentActivityOptions(caller, specifics, specificTypes, intent,
922                    intent.resolveTypeIfNeeded(resolver), flags, mContext.getUserId());
923            if (parceledList == null) {
924                return Collections.emptyList();
925            }
926            return parceledList.getList();
927        } catch (RemoteException e) {
928            throw e.rethrowFromSystemServer();
929        }
930    }
931
932    /**
933     * @hide
934     */
935    @Override
936    @SuppressWarnings("unchecked")
937    public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
938        try {
939            ParceledListSlice<ResolveInfo> parceledList =
940                    mPM.queryIntentReceivers(intent,
941                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
942                            flags,  userId);
943            if (parceledList == null) {
944                return Collections.emptyList();
945            }
946            return parceledList.getList();
947        } catch (RemoteException e) {
948            throw e.rethrowFromSystemServer();
949        }
950    }
951
952    @Override
953    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
954        return queryBroadcastReceiversAsUser(intent, flags, mContext.getUserId());
955    }
956
957    @Override
958    public ResolveInfo resolveService(Intent intent, int flags) {
959        try {
960            return mPM.resolveService(
961                intent,
962                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
963                flags,
964                mContext.getUserId());
965        } catch (RemoteException e) {
966            throw e.rethrowFromSystemServer();
967        }
968    }
969
970    @Override
971    @SuppressWarnings("unchecked")
972    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
973        try {
974            ParceledListSlice<ResolveInfo> parceledList =
975                    mPM.queryIntentServices(intent,
976                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
977                    flags, userId);
978            if (parceledList == null) {
979                return Collections.emptyList();
980            }
981            return parceledList.getList();
982        } catch (RemoteException e) {
983            throw e.rethrowFromSystemServer();
984        }
985    }
986
987    @Override
988    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
989        return queryIntentServicesAsUser(intent, flags, mContext.getUserId());
990    }
991
992    @Override
993    @SuppressWarnings("unchecked")
994    public List<ResolveInfo> queryIntentContentProvidersAsUser(
995            Intent intent, int flags, int userId) {
996        try {
997            ParceledListSlice<ResolveInfo> parceledList =
998                    mPM.queryIntentContentProviders(intent,
999                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1000                            flags, userId);
1001            if (parceledList == null) {
1002                return Collections.emptyList();
1003            }
1004            return parceledList.getList();
1005        } catch (RemoteException e) {
1006            throw e.rethrowFromSystemServer();
1007        }
1008    }
1009
1010    @Override
1011    public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
1012        return queryIntentContentProvidersAsUser(intent, flags, mContext.getUserId());
1013    }
1014
1015    @Override
1016    public ProviderInfo resolveContentProvider(String name, int flags) {
1017        return resolveContentProviderAsUser(name, flags, mContext.getUserId());
1018    }
1019
1020    /** @hide **/
1021    @Override
1022    public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
1023        try {
1024            return mPM.resolveContentProvider(name, flags, userId);
1025        } catch (RemoteException e) {
1026            throw e.rethrowFromSystemServer();
1027        }
1028    }
1029
1030    @Override
1031    public List<ProviderInfo> queryContentProviders(String processName,
1032            int uid, int flags) {
1033        return queryContentProviders(processName, uid, flags, null);
1034    }
1035
1036    @Override
1037    @SuppressWarnings("unchecked")
1038    public List<ProviderInfo> queryContentProviders(String processName,
1039            int uid, int flags, String metaDataKey) {
1040        try {
1041            ParceledListSlice<ProviderInfo> slice =
1042                    mPM.queryContentProviders(processName, uid, flags, metaDataKey);
1043            return slice != null ? slice.getList() : Collections.<ProviderInfo>emptyList();
1044        } catch (RemoteException e) {
1045            throw e.rethrowFromSystemServer();
1046        }
1047    }
1048
1049    @Override
1050    public InstrumentationInfo getInstrumentationInfo(
1051        ComponentName className, int flags)
1052            throws NameNotFoundException {
1053        try {
1054            InstrumentationInfo ii = mPM.getInstrumentationInfo(
1055                className, flags);
1056            if (ii != null) {
1057                return ii;
1058            }
1059        } catch (RemoteException e) {
1060            throw e.rethrowFromSystemServer();
1061        }
1062
1063        throw new NameNotFoundException(className.toString());
1064    }
1065
1066    @Override
1067    @SuppressWarnings("unchecked")
1068    public List<InstrumentationInfo> queryInstrumentation(
1069        String targetPackage, int flags) {
1070        try {
1071            ParceledListSlice<InstrumentationInfo> parceledList =
1072                    mPM.queryInstrumentation(targetPackage, flags);
1073            if (parceledList == null) {
1074                return Collections.emptyList();
1075            }
1076            return parceledList.getList();
1077        } catch (RemoteException e) {
1078            throw e.rethrowFromSystemServer();
1079        }
1080    }
1081
1082    @Nullable
1083    @Override
1084    public Drawable getDrawable(String packageName, @DrawableRes int resId,
1085            @Nullable ApplicationInfo appInfo) {
1086        final ResourceName name = new ResourceName(packageName, resId);
1087        final Drawable cachedIcon = getCachedIcon(name);
1088        if (cachedIcon != null) {
1089            return cachedIcon;
1090        }
1091
1092        if (appInfo == null) {
1093            try {
1094                appInfo = getApplicationInfo(packageName, sDefaultFlags);
1095            } catch (NameNotFoundException e) {
1096                return null;
1097            }
1098        }
1099
1100        if (resId != 0) {
1101            try {
1102                final Resources r = getResourcesForApplication(appInfo);
1103                final Drawable dr = r.getDrawable(resId, null);
1104                if (dr != null) {
1105                    putCachedIcon(name, dr);
1106                }
1107
1108                if (false) {
1109                    RuntimeException e = new RuntimeException("here");
1110                    e.fillInStackTrace();
1111                    Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resId)
1112                                    + " from package " + packageName
1113                                    + ": app scale=" + r.getCompatibilityInfo().applicationScale
1114                                    + ", caller scale=" + mContext.getResources()
1115                                    .getCompatibilityInfo().applicationScale,
1116                            e);
1117                }
1118                if (DEBUG_ICONS) {
1119                    Log.v(TAG, "Getting drawable 0x"
1120                            + Integer.toHexString(resId) + " from " + r
1121                            + ": " + dr);
1122                }
1123                return dr;
1124            } catch (NameNotFoundException e) {
1125                Log.w("PackageManager", "Failure retrieving resources for "
1126                        + appInfo.packageName);
1127            } catch (Resources.NotFoundException e) {
1128                Log.w("PackageManager", "Failure retrieving resources for "
1129                        + appInfo.packageName + ": " + e.getMessage());
1130            } catch (Exception e) {
1131                // If an exception was thrown, fall through to return
1132                // default icon.
1133                Log.w("PackageManager", "Failure retrieving icon 0x"
1134                        + Integer.toHexString(resId) + " in package "
1135                        + packageName, e);
1136            }
1137        }
1138
1139        return null;
1140    }
1141
1142    @Override public Drawable getActivityIcon(ComponentName activityName)
1143            throws NameNotFoundException {
1144        return getActivityInfo(activityName, sDefaultFlags).loadIcon(this);
1145    }
1146
1147    @Override public Drawable getActivityIcon(Intent intent)
1148            throws NameNotFoundException {
1149        if (intent.getComponent() != null) {
1150            return getActivityIcon(intent.getComponent());
1151        }
1152
1153        ResolveInfo info = resolveActivity(
1154            intent, PackageManager.MATCH_DEFAULT_ONLY);
1155        if (info != null) {
1156            return info.activityInfo.loadIcon(this);
1157        }
1158
1159        throw new NameNotFoundException(intent.toUri(0));
1160    }
1161
1162    @Override public Drawable getDefaultActivityIcon() {
1163        return Resources.getSystem().getDrawable(
1164            com.android.internal.R.drawable.sym_def_app_icon);
1165    }
1166
1167    @Override public Drawable getApplicationIcon(ApplicationInfo info) {
1168        return info.loadIcon(this);
1169    }
1170
1171    @Override public Drawable getApplicationIcon(String packageName)
1172            throws NameNotFoundException {
1173        return getApplicationIcon(getApplicationInfo(packageName, sDefaultFlags));
1174    }
1175
1176    @Override
1177    public Drawable getActivityBanner(ComponentName activityName)
1178            throws NameNotFoundException {
1179        return getActivityInfo(activityName, sDefaultFlags).loadBanner(this);
1180    }
1181
1182    @Override
1183    public Drawable getActivityBanner(Intent intent)
1184            throws NameNotFoundException {
1185        if (intent.getComponent() != null) {
1186            return getActivityBanner(intent.getComponent());
1187        }
1188
1189        ResolveInfo info = resolveActivity(
1190                intent, PackageManager.MATCH_DEFAULT_ONLY);
1191        if (info != null) {
1192            return info.activityInfo.loadBanner(this);
1193        }
1194
1195        throw new NameNotFoundException(intent.toUri(0));
1196    }
1197
1198    @Override
1199    public Drawable getApplicationBanner(ApplicationInfo info) {
1200        return info.loadBanner(this);
1201    }
1202
1203    @Override
1204    public Drawable getApplicationBanner(String packageName)
1205            throws NameNotFoundException {
1206        return getApplicationBanner(getApplicationInfo(packageName, sDefaultFlags));
1207    }
1208
1209    @Override
1210    public Drawable getActivityLogo(ComponentName activityName)
1211            throws NameNotFoundException {
1212        return getActivityInfo(activityName, sDefaultFlags).loadLogo(this);
1213    }
1214
1215    @Override
1216    public Drawable getActivityLogo(Intent intent)
1217            throws NameNotFoundException {
1218        if (intent.getComponent() != null) {
1219            return getActivityLogo(intent.getComponent());
1220        }
1221
1222        ResolveInfo info = resolveActivity(
1223            intent, PackageManager.MATCH_DEFAULT_ONLY);
1224        if (info != null) {
1225            return info.activityInfo.loadLogo(this);
1226        }
1227
1228        throw new NameNotFoundException(intent.toUri(0));
1229    }
1230
1231    @Override
1232    public Drawable getApplicationLogo(ApplicationInfo info) {
1233        return info.loadLogo(this);
1234    }
1235
1236    @Override
1237    public Drawable getApplicationLogo(String packageName)
1238            throws NameNotFoundException {
1239        return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags));
1240    }
1241
1242    @Override
1243    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
1244        if (!isManagedProfile(user.getIdentifier())) {
1245            return icon;
1246        }
1247        Drawable badgeShadow = getDrawable("system",
1248                com.android.internal.R.drawable.ic_corp_icon_badge_shadow, null);
1249        Drawable badgeColor = getDrawable("system",
1250                com.android.internal.R.drawable.ic_corp_icon_badge_color, null);
1251        badgeColor.setTint(getUserBadgeColor(user));
1252        Drawable badgeForeground = getDrawable("system",
1253                com.android.internal.R.drawable.ic_corp_icon_badge_case, null);
1254
1255        Drawable badge = new LayerDrawable(
1256                new Drawable[] {badgeShadow, badgeColor, badgeForeground });
1257        return getBadgedDrawable(icon, badge, null, true);
1258    }
1259
1260    @Override
1261    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
1262            Rect badgeLocation, int badgeDensity) {
1263        Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity);
1264        if (badgeDrawable == null) {
1265            return drawable;
1266        }
1267        return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
1268    }
1269
1270    // Should have enough colors to cope with UserManagerService.getMaxManagedProfiles()
1271    @VisibleForTesting
1272    public static final int[] CORP_BADGE_COLORS = new int[] {
1273        com.android.internal.R.color.profile_badge_1,
1274        com.android.internal.R.color.profile_badge_2,
1275        com.android.internal.R.color.profile_badge_3
1276    };
1277
1278    @VisibleForTesting
1279    public static final int[] CORP_BADGE_LABEL_RES_ID = new int[] {
1280        com.android.internal.R.string.managed_profile_label_badge,
1281        com.android.internal.R.string.managed_profile_label_badge_2,
1282        com.android.internal.R.string.managed_profile_label_badge_3
1283    };
1284
1285    private int getUserBadgeColor(UserHandle user) {
1286        int badge = getUserManager().getManagedProfileBadge(user.getIdentifier());
1287        if (badge < 0) {
1288            badge = 0;
1289        }
1290        int resourceId = CORP_BADGE_COLORS[badge % CORP_BADGE_COLORS.length];
1291        return Resources.getSystem().getColor(resourceId, null);
1292    }
1293
1294    @Override
1295    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
1296        Drawable badgeColor = getManagedProfileIconForDensity(user,
1297                com.android.internal.R.drawable.ic_corp_badge_color, density);
1298        if (badgeColor == null) {
1299            return null;
1300        }
1301        badgeColor.setTint(getUserBadgeColor(user));
1302        Drawable badgeForeground = getDrawableForDensity(
1303                com.android.internal.R.drawable.ic_corp_badge_case, density);
1304        Drawable badge = new LayerDrawable(
1305                new Drawable[] {badgeColor, badgeForeground });
1306        return badge;
1307    }
1308
1309    @Override
1310    public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
1311        Drawable badge = getManagedProfileIconForDensity(user,
1312                com.android.internal.R.drawable.ic_corp_badge_no_background, density);
1313        if (badge != null) {
1314            badge.setTint(getUserBadgeColor(user));
1315        }
1316        return badge;
1317    }
1318
1319    private Drawable getDrawableForDensity(int drawableId, int density) {
1320        if (density <= 0) {
1321            density = mContext.getResources().getDisplayMetrics().densityDpi;
1322        }
1323        return Resources.getSystem().getDrawableForDensity(drawableId, density);
1324    }
1325
1326    private Drawable getManagedProfileIconForDensity(UserHandle user, int drawableId, int density) {
1327        if (isManagedProfile(user.getIdentifier())) {
1328            return getDrawableForDensity(drawableId, density);
1329        }
1330        return null;
1331    }
1332
1333    @Override
1334    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
1335        if (isManagedProfile(user.getIdentifier())) {
1336            int badge = getUserManager().getManagedProfileBadge(user.getIdentifier());
1337            int resourceId = CORP_BADGE_LABEL_RES_ID[badge % CORP_BADGE_LABEL_RES_ID.length];
1338            return Resources.getSystem().getString(resourceId, label);
1339        }
1340        return label;
1341    }
1342
1343    @Override
1344    public Resources getResourcesForActivity(ComponentName activityName)
1345            throws NameNotFoundException {
1346        return getResourcesForApplication(
1347            getActivityInfo(activityName, sDefaultFlags).applicationInfo);
1348    }
1349
1350    @Override
1351    public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
1352            throws NameNotFoundException {
1353        if (app.packageName.equals("system")) {
1354            return mContext.mMainThread.getSystemContext().getResources();
1355        }
1356        final boolean sameUid = (app.uid == Process.myUid());
1357        final Resources r = mContext.mMainThread.getTopLevelResources(
1358                    sameUid ? app.sourceDir : app.publicSourceDir,
1359                    sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
1360                    app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
1361                    mContext.mPackageInfo);
1362        if (r != null) {
1363            return r;
1364        }
1365        throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
1366
1367    }
1368
1369    @Override
1370    public Resources getResourcesForApplication(String appPackageName)
1371            throws NameNotFoundException {
1372        return getResourcesForApplication(
1373            getApplicationInfo(appPackageName, sDefaultFlags));
1374    }
1375
1376    /** @hide */
1377    @Override
1378    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
1379            throws NameNotFoundException {
1380        if (userId < 0) {
1381            throw new IllegalArgumentException(
1382                    "Call does not support special user #" + userId);
1383        }
1384        if ("system".equals(appPackageName)) {
1385            return mContext.mMainThread.getSystemContext().getResources();
1386        }
1387        try {
1388            ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
1389            if (ai != null) {
1390                return getResourcesForApplication(ai);
1391            }
1392        } catch (RemoteException e) {
1393            throw e.rethrowFromSystemServer();
1394        }
1395        throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
1396    }
1397
1398    volatile int mCachedSafeMode = -1;
1399
1400    @Override
1401    public boolean isSafeMode() {
1402        try {
1403            if (mCachedSafeMode < 0) {
1404                mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
1405            }
1406            return mCachedSafeMode != 0;
1407        } catch (RemoteException e) {
1408            throw e.rethrowFromSystemServer();
1409        }
1410    }
1411
1412    @Override
1413    public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
1414        synchronized (mPermissionListeners) {
1415            if (mPermissionListeners.get(listener) != null) {
1416                return;
1417            }
1418            OnPermissionsChangeListenerDelegate delegate =
1419                    new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper());
1420            try {
1421                mPM.addOnPermissionsChangeListener(delegate);
1422                mPermissionListeners.put(listener, delegate);
1423            } catch (RemoteException e) {
1424                throw e.rethrowFromSystemServer();
1425            }
1426        }
1427    }
1428
1429    @Override
1430    public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
1431        synchronized (mPermissionListeners) {
1432            IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener);
1433            if (delegate != null) {
1434                try {
1435                    mPM.removeOnPermissionsChangeListener(delegate);
1436                    mPermissionListeners.remove(listener);
1437                } catch (RemoteException e) {
1438                    throw e.rethrowFromSystemServer();
1439                }
1440            }
1441        }
1442    }
1443
1444    static void configurationChanged() {
1445        synchronized (sSync) {
1446            sIconCache.clear();
1447            sStringCache.clear();
1448        }
1449    }
1450
1451    protected ApplicationPackageManager(ContextImpl context,
1452                              IPackageManager pm) {
1453        mContext = context;
1454        mPM = pm;
1455    }
1456
1457    @Nullable
1458    private Drawable getCachedIcon(@NonNull ResourceName name) {
1459        synchronized (sSync) {
1460            final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
1461            if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
1462                                   + name + ": " + wr);
1463            if (wr != null) {   // we have the activity
1464                final Drawable.ConstantState state = wr.get();
1465                if (state != null) {
1466                    if (DEBUG_ICONS) {
1467                        Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
1468                    }
1469                    // Note: It's okay here to not use the newDrawable(Resources) variant
1470                    //       of the API. The ConstantState comes from a drawable that was
1471                    //       originally created by passing the proper app Resources instance
1472                    //       which means the state should already contain the proper
1473                    //       resources specific information (like density.) See
1474                    //       BitmapDrawable.BitmapState for instance.
1475                    return state.newDrawable();
1476                }
1477                // our entry has been purged
1478                sIconCache.remove(name);
1479            }
1480        }
1481        return null;
1482    }
1483
1484    private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) {
1485        synchronized (sSync) {
1486            sIconCache.put(name, new WeakReference<>(dr.getConstantState()));
1487            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
1488        }
1489    }
1490
1491    static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
1492        boolean immediateGc = false;
1493        if (cmd == ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE) {
1494            immediateGc = true;
1495        }
1496        if (pkgList != null && (pkgList.length > 0)) {
1497            boolean needCleanup = false;
1498            for (String ssp : pkgList) {
1499                synchronized (sSync) {
1500                    for (int i=sIconCache.size()-1; i>=0; i--) {
1501                        ResourceName nm = sIconCache.keyAt(i);
1502                        if (nm.packageName.equals(ssp)) {
1503                            //Log.i(TAG, "Removing cached drawable for " + nm);
1504                            sIconCache.removeAt(i);
1505                            needCleanup = true;
1506                        }
1507                    }
1508                    for (int i=sStringCache.size()-1; i>=0; i--) {
1509                        ResourceName nm = sStringCache.keyAt(i);
1510                        if (nm.packageName.equals(ssp)) {
1511                            //Log.i(TAG, "Removing cached string for " + nm);
1512                            sStringCache.removeAt(i);
1513                            needCleanup = true;
1514                        }
1515                    }
1516                }
1517            }
1518            if (needCleanup || hasPkgInfo) {
1519                if (immediateGc) {
1520                    // Schedule an immediate gc.
1521                    Runtime.getRuntime().gc();
1522                } else {
1523                    ActivityThread.currentActivityThread().scheduleGcIdler();
1524                }
1525            }
1526        }
1527    }
1528
1529    private static final class ResourceName {
1530        final String packageName;
1531        final int iconId;
1532
1533        ResourceName(String _packageName, int _iconId) {
1534            packageName = _packageName;
1535            iconId = _iconId;
1536        }
1537
1538        ResourceName(ApplicationInfo aInfo, int _iconId) {
1539            this(aInfo.packageName, _iconId);
1540        }
1541
1542        ResourceName(ComponentInfo cInfo, int _iconId) {
1543            this(cInfo.applicationInfo.packageName, _iconId);
1544        }
1545
1546        ResourceName(ResolveInfo rInfo, int _iconId) {
1547            this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
1548        }
1549
1550        @Override
1551        public boolean equals(Object o) {
1552            if (this == o) return true;
1553            if (o == null || getClass() != o.getClass()) return false;
1554
1555            ResourceName that = (ResourceName) o;
1556
1557            if (iconId != that.iconId) return false;
1558            return !(packageName != null ?
1559                     !packageName.equals(that.packageName) : that.packageName != null);
1560
1561        }
1562
1563        @Override
1564        public int hashCode() {
1565            int result;
1566            result = packageName.hashCode();
1567            result = 31 * result + iconId;
1568            return result;
1569        }
1570
1571        @Override
1572        public String toString() {
1573            return "{ResourceName " + packageName + " / " + iconId + "}";
1574        }
1575    }
1576
1577    private CharSequence getCachedString(ResourceName name) {
1578        synchronized (sSync) {
1579            WeakReference<CharSequence> wr = sStringCache.get(name);
1580            if (wr != null) {   // we have the activity
1581                CharSequence cs = wr.get();
1582                if (cs != null) {
1583                    return cs;
1584                }
1585                // our entry has been purged
1586                sStringCache.remove(name);
1587            }
1588        }
1589        return null;
1590    }
1591
1592    private void putCachedString(ResourceName name, CharSequence cs) {
1593        synchronized (sSync) {
1594            sStringCache.put(name, new WeakReference<CharSequence>(cs));
1595        }
1596    }
1597
1598    @Override
1599    public CharSequence getText(String packageName, @StringRes int resid,
1600                                ApplicationInfo appInfo) {
1601        ResourceName name = new ResourceName(packageName, resid);
1602        CharSequence text = getCachedString(name);
1603        if (text != null) {
1604            return text;
1605        }
1606        if (appInfo == null) {
1607            try {
1608                appInfo = getApplicationInfo(packageName, sDefaultFlags);
1609            } catch (NameNotFoundException e) {
1610                return null;
1611            }
1612        }
1613        try {
1614            Resources r = getResourcesForApplication(appInfo);
1615            text = r.getText(resid);
1616            putCachedString(name, text);
1617            return text;
1618        } catch (NameNotFoundException e) {
1619            Log.w("PackageManager", "Failure retrieving resources for "
1620                  + appInfo.packageName);
1621        } catch (RuntimeException e) {
1622            // If an exception was thrown, fall through to return
1623            // default icon.
1624            Log.w("PackageManager", "Failure retrieving text 0x"
1625                  + Integer.toHexString(resid) + " in package "
1626                  + packageName, e);
1627        }
1628        return null;
1629    }
1630
1631    @Override
1632    public XmlResourceParser getXml(String packageName, @XmlRes int resid,
1633                                    ApplicationInfo appInfo) {
1634        if (appInfo == null) {
1635            try {
1636                appInfo = getApplicationInfo(packageName, sDefaultFlags);
1637            } catch (NameNotFoundException e) {
1638                return null;
1639            }
1640        }
1641        try {
1642            Resources r = getResourcesForApplication(appInfo);
1643            return r.getXml(resid);
1644        } catch (RuntimeException e) {
1645            // If an exception was thrown, fall through to return
1646            // default icon.
1647            Log.w("PackageManager", "Failure retrieving xml 0x"
1648                  + Integer.toHexString(resid) + " in package "
1649                  + packageName, e);
1650        } catch (NameNotFoundException e) {
1651            Log.w("PackageManager", "Failure retrieving resources for "
1652                  + appInfo.packageName);
1653        }
1654        return null;
1655    }
1656
1657    @Override
1658    public CharSequence getApplicationLabel(ApplicationInfo info) {
1659        return info.loadLabel(this);
1660    }
1661
1662    @Override
1663    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
1664                               String installerPackageName) {
1665        installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1666                installerPackageName, mContext.getUserId());
1667    }
1668
1669    @Override
1670    public void installPackage(Uri packageURI, PackageInstallObserver observer,
1671            int flags, String installerPackageName) {
1672        installCommon(packageURI, observer, flags, installerPackageName, mContext.getUserId());
1673    }
1674
1675    private void installCommon(Uri packageURI,
1676            PackageInstallObserver observer, int flags, String installerPackageName,
1677            int userId) {
1678        if (!"file".equals(packageURI.getScheme())) {
1679            throw new UnsupportedOperationException("Only file:// URIs are supported");
1680        }
1681
1682        final String originPath = packageURI.getPath();
1683        try {
1684            mPM.installPackageAsUser(originPath, observer.getBinder(), flags, installerPackageName,
1685                    userId);
1686        } catch (RemoteException e) {
1687            throw e.rethrowFromSystemServer();
1688        }
1689    }
1690
1691    @Override
1692    public int installExistingPackage(String packageName) throws NameNotFoundException {
1693        return installExistingPackageAsUser(packageName, mContext.getUserId());
1694    }
1695
1696    @Override
1697    public int installExistingPackageAsUser(String packageName, int userId)
1698            throws NameNotFoundException {
1699        try {
1700            int res = mPM.installExistingPackageAsUser(packageName, userId, 0 /*installFlags*/,
1701                    PackageManager.INSTALL_REASON_UNKNOWN);
1702            if (res == INSTALL_FAILED_INVALID_URI) {
1703                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1704            }
1705            return res;
1706        } catch (RemoteException e) {
1707            throw e.rethrowFromSystemServer();
1708        }
1709    }
1710
1711    @Override
1712    public void verifyPendingInstall(int id, int response) {
1713        try {
1714            mPM.verifyPendingInstall(id, response);
1715        } catch (RemoteException e) {
1716            throw e.rethrowFromSystemServer();
1717        }
1718    }
1719
1720    @Override
1721    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1722            long millisecondsToDelay) {
1723        try {
1724            mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1725        } catch (RemoteException e) {
1726            throw e.rethrowFromSystemServer();
1727        }
1728    }
1729
1730    @Override
1731    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
1732        try {
1733            mPM.verifyIntentFilter(id, verificationCode, failedDomains);
1734        } catch (RemoteException e) {
1735            throw e.rethrowFromSystemServer();
1736        }
1737    }
1738
1739    @Override
1740    public int getIntentVerificationStatusAsUser(String packageName, int userId) {
1741        try {
1742            return mPM.getIntentVerificationStatus(packageName, userId);
1743        } catch (RemoteException e) {
1744            throw e.rethrowFromSystemServer();
1745        }
1746    }
1747
1748    @Override
1749    public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) {
1750        try {
1751            return mPM.updateIntentVerificationStatus(packageName, status, userId);
1752        } catch (RemoteException e) {
1753            throw e.rethrowFromSystemServer();
1754        }
1755    }
1756
1757    @Override
1758    @SuppressWarnings("unchecked")
1759    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
1760        try {
1761            ParceledListSlice<IntentFilterVerificationInfo> parceledList =
1762                    mPM.getIntentFilterVerifications(packageName);
1763            if (parceledList == null) {
1764                return Collections.emptyList();
1765            }
1766            return parceledList.getList();
1767        } catch (RemoteException e) {
1768            throw e.rethrowFromSystemServer();
1769        }
1770    }
1771
1772    @Override
1773    @SuppressWarnings("unchecked")
1774    public List<IntentFilter> getAllIntentFilters(String packageName) {
1775        try {
1776            ParceledListSlice<IntentFilter> parceledList =
1777                    mPM.getAllIntentFilters(packageName);
1778            if (parceledList == null) {
1779                return Collections.emptyList();
1780            }
1781            return parceledList.getList();
1782        } catch (RemoteException e) {
1783            throw e.rethrowFromSystemServer();
1784        }
1785    }
1786
1787    @Override
1788    public String getDefaultBrowserPackageNameAsUser(int userId) {
1789        try {
1790            return mPM.getDefaultBrowserPackageName(userId);
1791        } catch (RemoteException e) {
1792            throw e.rethrowFromSystemServer();
1793        }
1794    }
1795
1796    @Override
1797    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
1798        try {
1799            return mPM.setDefaultBrowserPackageName(packageName, userId);
1800        } catch (RemoteException e) {
1801            throw e.rethrowFromSystemServer();
1802        }
1803    }
1804
1805    @Override
1806    public void setInstallerPackageName(String targetPackage,
1807            String installerPackageName) {
1808        try {
1809            mPM.setInstallerPackageName(targetPackage, installerPackageName);
1810        } catch (RemoteException e) {
1811            throw e.rethrowFromSystemServer();
1812        }
1813    }
1814
1815    @Override
1816    public String getInstallerPackageName(String packageName) {
1817        try {
1818            return mPM.getInstallerPackageName(packageName);
1819        } catch (RemoteException e) {
1820            throw e.rethrowFromSystemServer();
1821        }
1822    }
1823
1824    @Override
1825    public int getMoveStatus(int moveId) {
1826        try {
1827            return mPM.getMoveStatus(moveId);
1828        } catch (RemoteException e) {
1829            throw e.rethrowFromSystemServer();
1830        }
1831    }
1832
1833    @Override
1834    public void registerMoveCallback(MoveCallback callback, Handler handler) {
1835        synchronized (mDelegates) {
1836            final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback,
1837                    handler.getLooper());
1838            try {
1839                mPM.registerMoveCallback(delegate);
1840            } catch (RemoteException e) {
1841                throw e.rethrowFromSystemServer();
1842            }
1843            mDelegates.add(delegate);
1844        }
1845    }
1846
1847    @Override
1848    public void unregisterMoveCallback(MoveCallback callback) {
1849        synchronized (mDelegates) {
1850            for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
1851                final MoveCallbackDelegate delegate = i.next();
1852                if (delegate.mCallback == callback) {
1853                    try {
1854                        mPM.unregisterMoveCallback(delegate);
1855                    } catch (RemoteException e) {
1856                        throw e.rethrowFromSystemServer();
1857                    }
1858                    i.remove();
1859                }
1860            }
1861        }
1862    }
1863
1864    @Override
1865    public int movePackage(String packageName, VolumeInfo vol) {
1866        try {
1867            final String volumeUuid;
1868            if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
1869                volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
1870            } else if (vol.isPrimaryPhysical()) {
1871                volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
1872            } else {
1873                volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
1874            }
1875
1876            return mPM.movePackage(packageName, volumeUuid);
1877        } catch (RemoteException e) {
1878            throw e.rethrowFromSystemServer();
1879        }
1880    }
1881
1882    @Override
1883    public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
1884        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1885        return getPackageCurrentVolume(app, storage);
1886    }
1887
1888    @VisibleForTesting
1889    protected @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app,
1890            StorageManager storage) {
1891        if (app.isInternal()) {
1892            return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
1893        } else if (app.isExternalAsec()) {
1894            return storage.getPrimaryPhysicalVolume();
1895        } else {
1896            return storage.findVolumeByUuid(app.volumeUuid);
1897        }
1898    }
1899
1900    @Override
1901    public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
1902        final StorageManager storageManager = mContext.getSystemService(StorageManager.class);
1903        return getPackageCandidateVolumes(app, storageManager, mPM);
1904    }
1905
1906    @VisibleForTesting
1907    protected @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app,
1908            StorageManager storageManager, IPackageManager pm) {
1909        final VolumeInfo currentVol = getPackageCurrentVolume(app, storageManager);
1910        final List<VolumeInfo> vols = storageManager.getVolumes();
1911        final List<VolumeInfo> candidates = new ArrayList<>();
1912        for (VolumeInfo vol : vols) {
1913            if (Objects.equals(vol, currentVol)
1914                    || isPackageCandidateVolume(mContext, app, vol, pm)) {
1915                candidates.add(vol);
1916            }
1917        }
1918        return candidates;
1919    }
1920
1921    @VisibleForTesting
1922    protected boolean isForceAllowOnExternal(Context context) {
1923        return Settings.Global.getInt(
1924                context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0;
1925    }
1926
1927    @VisibleForTesting
1928    protected boolean isAllow3rdPartyOnInternal(Context context) {
1929        return context.getResources().getBoolean(
1930                com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
1931    }
1932
1933    private boolean isPackageCandidateVolume(
1934            ContextImpl context, ApplicationInfo app, VolumeInfo vol, IPackageManager pm) {
1935        final boolean forceAllowOnExternal = isForceAllowOnExternal(context);
1936
1937        if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
1938            return app.isSystemApp() || isAllow3rdPartyOnInternal(context);
1939        }
1940
1941        // System apps and apps demanding internal storage can't be moved
1942        // anywhere else
1943        if (app.isSystemApp()) {
1944            return false;
1945        }
1946        if (!forceAllowOnExternal
1947                && (app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY
1948                        || app.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED)) {
1949            return false;
1950        }
1951
1952        // Gotta be able to write there
1953        if (!vol.isMountedWritable()) {
1954            return false;
1955        }
1956
1957        // Moving into an ASEC on public primary is only option internal
1958        if (vol.isPrimaryPhysical()) {
1959            return app.isInternal();
1960        }
1961
1962        // Some apps can't be moved. (e.g. device admins)
1963        try {
1964            if (pm.isPackageDeviceAdminOnAnyUser(app.packageName)) {
1965                return false;
1966            }
1967        } catch (RemoteException e) {
1968            throw e.rethrowFromSystemServer();
1969        }
1970
1971        // Otherwise we can move to any private volume
1972        return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
1973    }
1974
1975    @Override
1976    public int movePrimaryStorage(VolumeInfo vol) {
1977        try {
1978            final String volumeUuid;
1979            if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
1980                volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
1981            } else if (vol.isPrimaryPhysical()) {
1982                volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
1983            } else {
1984                volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
1985            }
1986
1987            return mPM.movePrimaryStorage(volumeUuid);
1988        } catch (RemoteException e) {
1989            throw e.rethrowFromSystemServer();
1990        }
1991    }
1992
1993    @Override
1994    public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
1995        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1996        final String volumeUuid = storage.getPrimaryStorageUuid();
1997        return storage.findVolumeByQualifiedUuid(volumeUuid);
1998    }
1999
2000    @Override
2001    public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
2002        final StorageManager storage = mContext.getSystemService(StorageManager.class);
2003        final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
2004        final List<VolumeInfo> vols = storage.getVolumes();
2005        final List<VolumeInfo> candidates = new ArrayList<>();
2006        if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL,
2007                storage.getPrimaryStorageUuid()) && currentVol != null) {
2008            // TODO: support moving primary physical to emulated volume
2009            candidates.add(currentVol);
2010        } else {
2011            for (VolumeInfo vol : vols) {
2012                if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
2013                    candidates.add(vol);
2014                }
2015            }
2016        }
2017        return candidates;
2018    }
2019
2020    private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) {
2021        // Private internal is always an option
2022        if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
2023            return true;
2024        }
2025
2026        // Gotta be able to write there
2027        if (!vol.isMountedWritable()) {
2028            return false;
2029        }
2030
2031        // We can move to any private volume
2032        return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
2033    }
2034
2035    @Override
2036    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2037        deletePackageAsUser(packageName, observer, flags, mContext.getUserId());
2038    }
2039
2040    @Override
2041    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer,
2042            int flags, int userId) {
2043        try {
2044            mPM.deletePackageAsUser(packageName, PackageManager.VERSION_CODE_HIGHEST,
2045                    observer, userId, flags);
2046        } catch (RemoteException e) {
2047            throw e.rethrowFromSystemServer();
2048        }
2049    }
2050
2051    @Override
2052    public void clearApplicationUserData(String packageName,
2053                                         IPackageDataObserver observer) {
2054        try {
2055            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
2056        } catch (RemoteException e) {
2057            throw e.rethrowFromSystemServer();
2058        }
2059    }
2060    @Override
2061    public void deleteApplicationCacheFiles(String packageName,
2062                                            IPackageDataObserver observer) {
2063        try {
2064            mPM.deleteApplicationCacheFiles(packageName, observer);
2065        } catch (RemoteException e) {
2066            throw e.rethrowFromSystemServer();
2067        }
2068    }
2069
2070    @Override
2071    public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
2072            IPackageDataObserver observer) {
2073        try {
2074            mPM.deleteApplicationCacheFilesAsUser(packageName, userId, observer);
2075        } catch (RemoteException e) {
2076            throw e.rethrowFromSystemServer();
2077        }
2078    }
2079
2080    @Override
2081    public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
2082            IPackageDataObserver observer) {
2083        try {
2084            mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer);
2085        } catch (RemoteException e) {
2086            throw e.rethrowFromSystemServer();
2087        }
2088    }
2089
2090    @Override
2091    public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
2092        try {
2093            mPM.freeStorage(volumeUuid, freeStorageSize, pi);
2094        } catch (RemoteException e) {
2095            throw e.rethrowFromSystemServer();
2096        }
2097    }
2098
2099    @Override
2100    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
2101            int userId) {
2102        try {
2103            return mPM.setPackagesSuspendedAsUser(packageNames, suspended, userId);
2104        } catch (RemoteException e) {
2105            throw e.rethrowFromSystemServer();
2106        }
2107    }
2108
2109    @Override
2110    public boolean isPackageSuspendedForUser(String packageName, int userId) {
2111        try {
2112            return mPM.isPackageSuspendedForUser(packageName, userId);
2113        } catch (RemoteException e) {
2114            throw e.rethrowFromSystemServer();
2115        }
2116    }
2117
2118    /** @hide */
2119    @Override
2120    public void setApplicationCategoryHint(String packageName, int categoryHint) {
2121        try {
2122            mPM.setApplicationCategoryHint(packageName, categoryHint,
2123                    mContext.getOpPackageName());
2124        } catch (RemoteException e) {
2125            throw e.rethrowFromSystemServer();
2126        }
2127    }
2128
2129    @Override
2130    public void getPackageSizeInfoAsUser(String packageName, int userHandle,
2131            IPackageStatsObserver observer) {
2132        try {
2133            mPM.getPackageSizeInfo(packageName, userHandle, observer);
2134        } catch (RemoteException e) {
2135            throw e.rethrowFromSystemServer();
2136        }
2137    }
2138
2139    @Override
2140    public void addPackageToPreferred(String packageName) {
2141        Log.w(TAG, "addPackageToPreferred() is a no-op");
2142    }
2143
2144    @Override
2145    public void removePackageFromPreferred(String packageName) {
2146        Log.w(TAG, "removePackageFromPreferred() is a no-op");
2147    }
2148
2149    @Override
2150    public List<PackageInfo> getPreferredPackages(int flags) {
2151        Log.w(TAG, "getPreferredPackages() is a no-op");
2152        return Collections.emptyList();
2153    }
2154
2155    @Override
2156    public void addPreferredActivity(IntentFilter filter,
2157                                     int match, ComponentName[] set, ComponentName activity) {
2158        try {
2159            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
2160        } catch (RemoteException e) {
2161            throw e.rethrowFromSystemServer();
2162        }
2163    }
2164
2165    @Override
2166    public void addPreferredActivityAsUser(IntentFilter filter, int match,
2167            ComponentName[] set, ComponentName activity, int userId) {
2168        try {
2169            mPM.addPreferredActivity(filter, match, set, activity, userId);
2170        } catch (RemoteException e) {
2171            throw e.rethrowFromSystemServer();
2172        }
2173    }
2174
2175    @Override
2176    public void replacePreferredActivity(IntentFilter filter,
2177                                         int match, ComponentName[] set, ComponentName activity) {
2178        try {
2179            mPM.replacePreferredActivity(filter, match, set, activity, mContext.getUserId());
2180        } catch (RemoteException e) {
2181            throw e.rethrowFromSystemServer();
2182        }
2183    }
2184
2185    @Override
2186    public void replacePreferredActivityAsUser(IntentFilter filter,
2187                                         int match, ComponentName[] set, ComponentName activity,
2188                                         int userId) {
2189        try {
2190            mPM.replacePreferredActivity(filter, match, set, activity, userId);
2191        } catch (RemoteException e) {
2192            throw e.rethrowFromSystemServer();
2193        }
2194    }
2195
2196    @Override
2197    public void clearPackagePreferredActivities(String packageName) {
2198        try {
2199            mPM.clearPackagePreferredActivities(packageName);
2200        } catch (RemoteException e) {
2201            throw e.rethrowFromSystemServer();
2202        }
2203    }
2204
2205    @Override
2206    public int getPreferredActivities(List<IntentFilter> outFilters,
2207                                      List<ComponentName> outActivities, String packageName) {
2208        try {
2209            return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2210        } catch (RemoteException e) {
2211            throw e.rethrowFromSystemServer();
2212        }
2213    }
2214
2215    @Override
2216    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
2217        try {
2218            return mPM.getHomeActivities(outActivities);
2219        } catch (RemoteException e) {
2220            throw e.rethrowFromSystemServer();
2221        }
2222    }
2223
2224    @Override
2225    public void setComponentEnabledSetting(ComponentName componentName,
2226                                           int newState, int flags) {
2227        try {
2228            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
2229        } catch (RemoteException e) {
2230            throw e.rethrowFromSystemServer();
2231        }
2232    }
2233
2234    @Override
2235    public int getComponentEnabledSetting(ComponentName componentName) {
2236        try {
2237            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
2238        } catch (RemoteException e) {
2239            throw e.rethrowFromSystemServer();
2240        }
2241    }
2242
2243    @Override
2244    public void setApplicationEnabledSetting(String packageName,
2245                                             int newState, int flags) {
2246        try {
2247            mPM.setApplicationEnabledSetting(packageName, newState, flags,
2248                    mContext.getUserId(), mContext.getOpPackageName());
2249        } catch (RemoteException e) {
2250            throw e.rethrowFromSystemServer();
2251        }
2252    }
2253
2254    @Override
2255    public int getApplicationEnabledSetting(String packageName) {
2256        try {
2257            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
2258        } catch (RemoteException e) {
2259            throw e.rethrowFromSystemServer();
2260        }
2261    }
2262
2263    @Override
2264    public void flushPackageRestrictionsAsUser(int userId) {
2265        try {
2266            mPM.flushPackageRestrictionsAsUser(userId);
2267        } catch (RemoteException e) {
2268            throw e.rethrowFromSystemServer();
2269        }
2270    }
2271
2272    @Override
2273    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
2274            UserHandle user) {
2275        try {
2276            return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
2277                    user.getIdentifier());
2278        } catch (RemoteException e) {
2279            throw e.rethrowFromSystemServer();
2280        }
2281    }
2282
2283    @Override
2284    public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
2285        try {
2286            return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
2287        } catch (RemoteException e) {
2288            throw e.rethrowFromSystemServer();
2289        }
2290    }
2291
2292    /** @hide */
2293    @Override
2294    public KeySet getKeySetByAlias(String packageName, String alias) {
2295        Preconditions.checkNotNull(packageName);
2296        Preconditions.checkNotNull(alias);
2297        try {
2298            return mPM.getKeySetByAlias(packageName, alias);
2299        } catch (RemoteException e) {
2300            throw e.rethrowFromSystemServer();
2301        }
2302    }
2303
2304    /** @hide */
2305    @Override
2306    public KeySet getSigningKeySet(String packageName) {
2307        Preconditions.checkNotNull(packageName);
2308        try {
2309            return mPM.getSigningKeySet(packageName);
2310        } catch (RemoteException e) {
2311            throw e.rethrowFromSystemServer();
2312        }
2313    }
2314
2315    /** @hide */
2316    @Override
2317    public boolean isSignedBy(String packageName, KeySet ks) {
2318        Preconditions.checkNotNull(packageName);
2319        Preconditions.checkNotNull(ks);
2320        try {
2321            return mPM.isPackageSignedByKeySet(packageName, ks);
2322        } catch (RemoteException e) {
2323            throw e.rethrowFromSystemServer();
2324        }
2325    }
2326
2327    /** @hide */
2328    @Override
2329    public boolean isSignedByExactly(String packageName, KeySet ks) {
2330        Preconditions.checkNotNull(packageName);
2331        Preconditions.checkNotNull(ks);
2332        try {
2333            return mPM.isPackageSignedByKeySetExactly(packageName, ks);
2334        } catch (RemoteException e) {
2335            throw e.rethrowFromSystemServer();
2336        }
2337    }
2338
2339    /**
2340     * @hide
2341     */
2342    @Override
2343    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
2344        try {
2345            return mPM.getVerifierDeviceIdentity();
2346        } catch (RemoteException e) {
2347            throw e.rethrowFromSystemServer();
2348        }
2349    }
2350
2351    /**
2352     * @hide
2353     */
2354    @Override
2355    public boolean isUpgrade() {
2356        try {
2357            return mPM.isUpgrade();
2358        } catch (RemoteException e) {
2359            throw e.rethrowFromSystemServer();
2360        }
2361    }
2362
2363    @Override
2364    public PackageInstaller getPackageInstaller() {
2365        synchronized (mLock) {
2366            if (mInstaller == null) {
2367                try {
2368                    mInstaller = new PackageInstaller(mPM.getPackageInstaller(),
2369                            mContext.getPackageName(), mContext.getUserId());
2370                } catch (RemoteException e) {
2371                    throw e.rethrowFromSystemServer();
2372                }
2373            }
2374            return mInstaller;
2375        }
2376    }
2377
2378    @Override
2379    public boolean isPackageAvailable(String packageName) {
2380        try {
2381            return mPM.isPackageAvailable(packageName, mContext.getUserId());
2382        } catch (RemoteException e) {
2383            throw e.rethrowFromSystemServer();
2384        }
2385    }
2386
2387    /**
2388     * @hide
2389     */
2390    @Override
2391    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
2392            int flags) {
2393        try {
2394            mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
2395                    sourceUserId, targetUserId, flags);
2396        } catch (RemoteException e) {
2397            throw e.rethrowFromSystemServer();
2398        }
2399    }
2400
2401    /**
2402     * @hide
2403     */
2404    @Override
2405    public void clearCrossProfileIntentFilters(int sourceUserId) {
2406        try {
2407            mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName());
2408        } catch (RemoteException e) {
2409            throw e.rethrowFromSystemServer();
2410        }
2411    }
2412
2413    /**
2414     * @hide
2415     */
2416    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
2417        Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
2418        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
2419            return dr;
2420        }
2421        return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
2422    }
2423
2424    /**
2425     * @hide
2426     */
2427    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
2428        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
2429            Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
2430            if (bitmap == null) {
2431                return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false);
2432            }
2433            return new BitmapDrawable(bitmap);
2434        }
2435        Drawable dr = null;
2436        if (itemInfo.packageName != null) {
2437            dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
2438        }
2439        if (dr == null) {
2440            dr = itemInfo.loadDefaultIcon(this);
2441        }
2442        return dr;
2443    }
2444
2445    private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
2446            Rect badgeLocation, boolean tryBadgeInPlace) {
2447        final int badgedWidth = drawable.getIntrinsicWidth();
2448        final int badgedHeight = drawable.getIntrinsicHeight();
2449        final boolean canBadgeInPlace = tryBadgeInPlace
2450                && (drawable instanceof BitmapDrawable)
2451                && ((BitmapDrawable) drawable).getBitmap().isMutable();
2452
2453        final Bitmap bitmap;
2454        if (canBadgeInPlace) {
2455            bitmap = ((BitmapDrawable) drawable).getBitmap();
2456        } else {
2457            bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
2458        }
2459        Canvas canvas = new Canvas(bitmap);
2460
2461        if (!canBadgeInPlace) {
2462            drawable.setBounds(0, 0, badgedWidth, badgedHeight);
2463            drawable.draw(canvas);
2464        }
2465
2466        if (badgeLocation != null) {
2467            if (badgeLocation.left < 0 || badgeLocation.top < 0
2468                    || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
2469                throw new IllegalArgumentException("Badge location " + badgeLocation
2470                        + " not in badged drawable bounds "
2471                        + new Rect(0, 0, badgedWidth, badgedHeight));
2472            }
2473            badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
2474
2475            canvas.save();
2476            canvas.translate(badgeLocation.left, badgeLocation.top);
2477            badgeDrawable.draw(canvas);
2478            canvas.restore();
2479        } else {
2480            badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
2481            badgeDrawable.draw(canvas);
2482        }
2483
2484        if (!canBadgeInPlace) {
2485            BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
2486
2487            if (drawable instanceof BitmapDrawable) {
2488                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
2489                mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
2490            }
2491
2492            return mergedDrawable;
2493        }
2494
2495        return drawable;
2496    }
2497
2498    private boolean isManagedProfile(int userId) {
2499        return getUserManager().isManagedProfile(userId);
2500    }
2501
2502    /**
2503     * @hide
2504     */
2505    @Override
2506    public int getInstallReason(String packageName, UserHandle user) {
2507        try {
2508            return mPM.getInstallReason(packageName, user.getIdentifier());
2509        } catch (RemoteException e) {
2510            throw e.rethrowFromSystemServer();
2511        }
2512    }
2513
2514    /** {@hide} */
2515    private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
2516            Handler.Callback {
2517        private static final int MSG_CREATED = 1;
2518        private static final int MSG_STATUS_CHANGED = 2;
2519
2520        final MoveCallback mCallback;
2521        final Handler mHandler;
2522
2523        public MoveCallbackDelegate(MoveCallback callback, Looper looper) {
2524            mCallback = callback;
2525            mHandler = new Handler(looper, this);
2526        }
2527
2528        @Override
2529        public boolean handleMessage(Message msg) {
2530            switch (msg.what) {
2531                case MSG_CREATED: {
2532                    final SomeArgs args = (SomeArgs) msg.obj;
2533                    mCallback.onCreated(args.argi1, (Bundle) args.arg2);
2534                    args.recycle();
2535                    return true;
2536                }
2537                case MSG_STATUS_CHANGED: {
2538                    final SomeArgs args = (SomeArgs) msg.obj;
2539                    mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
2540                    args.recycle();
2541                    return true;
2542                }
2543            }
2544            return false;
2545        }
2546
2547        @Override
2548        public void onCreated(int moveId, Bundle extras) {
2549            final SomeArgs args = SomeArgs.obtain();
2550            args.argi1 = moveId;
2551            args.arg2 = extras;
2552            mHandler.obtainMessage(MSG_CREATED, args).sendToTarget();
2553        }
2554
2555        @Override
2556        public void onStatusChanged(int moveId, int status, long estMillis) {
2557            final SomeArgs args = SomeArgs.obtain();
2558            args.argi1 = moveId;
2559            args.argi2 = status;
2560            args.arg3 = estMillis;
2561            mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
2562        }
2563    }
2564
2565    private final ContextImpl mContext;
2566    private final IPackageManager mPM;
2567
2568    private static final Object sSync = new Object();
2569    private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
2570            = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
2571    private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
2572            = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
2573
2574    private final Map<OnPermissionsChangedListener, IOnPermissionsChangeListener>
2575            mPermissionListeners = new ArrayMap<>();
2576
2577    public class OnPermissionsChangeListenerDelegate extends IOnPermissionsChangeListener.Stub
2578            implements Handler.Callback{
2579        private static final int MSG_PERMISSIONS_CHANGED = 1;
2580
2581        private final OnPermissionsChangedListener mListener;
2582        private final Handler mHandler;
2583
2584
2585        public OnPermissionsChangeListenerDelegate(OnPermissionsChangedListener listener,
2586                Looper looper) {
2587            mListener = listener;
2588            mHandler = new Handler(looper, this);
2589        }
2590
2591        @Override
2592        public void onPermissionsChanged(int uid) {
2593            mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
2594        }
2595
2596        @Override
2597        public boolean handleMessage(Message msg) {
2598            switch (msg.what) {
2599                case MSG_PERMISSIONS_CHANGED: {
2600                    final int uid = msg.arg1;
2601                    mListener.onPermissionsChanged(uid);
2602                    return true;
2603                }
2604            }
2605            return false;
2606        }
2607    }
2608
2609    @Override
2610    public boolean canRequestPackageInstalls() {
2611        try {
2612            return mPM.canRequestPackageInstalls(mContext.getPackageName(), mContext.getUserId());
2613        } catch (RemoteException e) {
2614            throw e.rethrowAsRuntimeException();
2615        }
2616    }
2617}
2618