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