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