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