ApplicationPackageManager.java revision 53fafdfbe76d3eeb0fe6782873a03869167a65b0
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        final Resources r = mContext.mMainThread.getTopLevelResources(
1249                    sameUid ? app.sourceDir : app.publicSourceDir,
1250                    sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
1251                    app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
1252                    mContext.mPackageInfo);
1253        if (r != null) {
1254            return r;
1255        }
1256        throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
1257
1258    }
1259
1260    @Override
1261    public Resources getResourcesForApplication(String appPackageName)
1262            throws NameNotFoundException {
1263        return getResourcesForApplication(
1264            getApplicationInfo(appPackageName, sDefaultFlags));
1265    }
1266
1267    /** @hide */
1268    @Override
1269    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
1270            throws NameNotFoundException {
1271        if (userId < 0) {
1272            throw new IllegalArgumentException(
1273                    "Call does not support special user #" + userId);
1274        }
1275        if ("system".equals(appPackageName)) {
1276            return mContext.mMainThread.getSystemContext().getResources();
1277        }
1278        try {
1279            ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
1280            if (ai != null) {
1281                return getResourcesForApplication(ai);
1282            }
1283        } catch (RemoteException e) {
1284            throw e.rethrowFromSystemServer();
1285        }
1286        throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
1287    }
1288
1289    volatile int mCachedSafeMode = -1;
1290
1291    @Override
1292    public boolean isSafeMode() {
1293        try {
1294            if (mCachedSafeMode < 0) {
1295                mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
1296            }
1297            return mCachedSafeMode != 0;
1298        } catch (RemoteException e) {
1299            throw e.rethrowFromSystemServer();
1300        }
1301    }
1302
1303    @Override
1304    public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
1305        synchronized (mPermissionListeners) {
1306            if (mPermissionListeners.get(listener) != null) {
1307                return;
1308            }
1309            OnPermissionsChangeListenerDelegate delegate =
1310                    new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper());
1311            try {
1312                mPM.addOnPermissionsChangeListener(delegate);
1313                mPermissionListeners.put(listener, delegate);
1314            } catch (RemoteException e) {
1315                throw e.rethrowFromSystemServer();
1316            }
1317        }
1318    }
1319
1320    @Override
1321    public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
1322        synchronized (mPermissionListeners) {
1323            IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener);
1324            if (delegate != null) {
1325                try {
1326                    mPM.removeOnPermissionsChangeListener(delegate);
1327                    mPermissionListeners.remove(listener);
1328                } catch (RemoteException e) {
1329                    throw e.rethrowFromSystemServer();
1330                }
1331            }
1332        }
1333    }
1334
1335    static void configurationChanged() {
1336        synchronized (sSync) {
1337            sIconCache.clear();
1338            sStringCache.clear();
1339        }
1340    }
1341
1342    ApplicationPackageManager(ContextImpl context,
1343                              IPackageManager pm) {
1344        mContext = context;
1345        mPM = pm;
1346    }
1347
1348    @Nullable
1349    private Drawable getCachedIcon(@NonNull ResourceName name) {
1350        synchronized (sSync) {
1351            final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
1352            if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
1353                                   + name + ": " + wr);
1354            if (wr != null) {   // we have the activity
1355                final Drawable.ConstantState state = wr.get();
1356                if (state != null) {
1357                    if (DEBUG_ICONS) {
1358                        Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
1359                    }
1360                    // Note: It's okay here to not use the newDrawable(Resources) variant
1361                    //       of the API. The ConstantState comes from a drawable that was
1362                    //       originally created by passing the proper app Resources instance
1363                    //       which means the state should already contain the proper
1364                    //       resources specific information (like density.) See
1365                    //       BitmapDrawable.BitmapState for instance.
1366                    return state.newDrawable();
1367                }
1368                // our entry has been purged
1369                sIconCache.remove(name);
1370            }
1371        }
1372        return null;
1373    }
1374
1375    private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) {
1376        synchronized (sSync) {
1377            sIconCache.put(name, new WeakReference<>(dr.getConstantState()));
1378            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
1379        }
1380    }
1381
1382    static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
1383        boolean immediateGc = false;
1384        if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
1385            immediateGc = true;
1386        }
1387        if (pkgList != null && (pkgList.length > 0)) {
1388            boolean needCleanup = false;
1389            for (String ssp : pkgList) {
1390                synchronized (sSync) {
1391                    for (int i=sIconCache.size()-1; i>=0; i--) {
1392                        ResourceName nm = sIconCache.keyAt(i);
1393                        if (nm.packageName.equals(ssp)) {
1394                            //Log.i(TAG, "Removing cached drawable for " + nm);
1395                            sIconCache.removeAt(i);
1396                            needCleanup = true;
1397                        }
1398                    }
1399                    for (int i=sStringCache.size()-1; i>=0; i--) {
1400                        ResourceName nm = sStringCache.keyAt(i);
1401                        if (nm.packageName.equals(ssp)) {
1402                            //Log.i(TAG, "Removing cached string for " + nm);
1403                            sStringCache.removeAt(i);
1404                            needCleanup = true;
1405                        }
1406                    }
1407                }
1408            }
1409            if (needCleanup || hasPkgInfo) {
1410                if (immediateGc) {
1411                    // Schedule an immediate gc.
1412                    Runtime.getRuntime().gc();
1413                } else {
1414                    ActivityThread.currentActivityThread().scheduleGcIdler();
1415                }
1416            }
1417        }
1418    }
1419
1420    private static final class ResourceName {
1421        final String packageName;
1422        final int iconId;
1423
1424        ResourceName(String _packageName, int _iconId) {
1425            packageName = _packageName;
1426            iconId = _iconId;
1427        }
1428
1429        ResourceName(ApplicationInfo aInfo, int _iconId) {
1430            this(aInfo.packageName, _iconId);
1431        }
1432
1433        ResourceName(ComponentInfo cInfo, int _iconId) {
1434            this(cInfo.applicationInfo.packageName, _iconId);
1435        }
1436
1437        ResourceName(ResolveInfo rInfo, int _iconId) {
1438            this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
1439        }
1440
1441        @Override
1442        public boolean equals(Object o) {
1443            if (this == o) return true;
1444            if (o == null || getClass() != o.getClass()) return false;
1445
1446            ResourceName that = (ResourceName) o;
1447
1448            if (iconId != that.iconId) return false;
1449            return !(packageName != null ?
1450                     !packageName.equals(that.packageName) : that.packageName != null);
1451
1452        }
1453
1454        @Override
1455        public int hashCode() {
1456            int result;
1457            result = packageName.hashCode();
1458            result = 31 * result + iconId;
1459            return result;
1460        }
1461
1462        @Override
1463        public String toString() {
1464            return "{ResourceName " + packageName + " / " + iconId + "}";
1465        }
1466    }
1467
1468    private CharSequence getCachedString(ResourceName name) {
1469        synchronized (sSync) {
1470            WeakReference<CharSequence> wr = sStringCache.get(name);
1471            if (wr != null) {   // we have the activity
1472                CharSequence cs = wr.get();
1473                if (cs != null) {
1474                    return cs;
1475                }
1476                // our entry has been purged
1477                sStringCache.remove(name);
1478            }
1479        }
1480        return null;
1481    }
1482
1483    private void putCachedString(ResourceName name, CharSequence cs) {
1484        synchronized (sSync) {
1485            sStringCache.put(name, new WeakReference<CharSequence>(cs));
1486        }
1487    }
1488
1489    @Override
1490    public CharSequence getText(String packageName, @StringRes int resid,
1491                                ApplicationInfo appInfo) {
1492        ResourceName name = new ResourceName(packageName, resid);
1493        CharSequence text = getCachedString(name);
1494        if (text != null) {
1495            return text;
1496        }
1497        if (appInfo == null) {
1498            try {
1499                appInfo = getApplicationInfo(packageName, sDefaultFlags);
1500            } catch (NameNotFoundException e) {
1501                return null;
1502            }
1503        }
1504        try {
1505            Resources r = getResourcesForApplication(appInfo);
1506            text = r.getText(resid);
1507            putCachedString(name, text);
1508            return text;
1509        } catch (NameNotFoundException e) {
1510            Log.w("PackageManager", "Failure retrieving resources for "
1511                  + appInfo.packageName);
1512        } catch (RuntimeException e) {
1513            // If an exception was thrown, fall through to return
1514            // default icon.
1515            Log.w("PackageManager", "Failure retrieving text 0x"
1516                  + Integer.toHexString(resid) + " in package "
1517                  + packageName, e);
1518        }
1519        return null;
1520    }
1521
1522    @Override
1523    public XmlResourceParser getXml(String packageName, @XmlRes int resid,
1524                                    ApplicationInfo appInfo) {
1525        if (appInfo == null) {
1526            try {
1527                appInfo = getApplicationInfo(packageName, sDefaultFlags);
1528            } catch (NameNotFoundException e) {
1529                return null;
1530            }
1531        }
1532        try {
1533            Resources r = getResourcesForApplication(appInfo);
1534            return r.getXml(resid);
1535        } catch (RuntimeException e) {
1536            // If an exception was thrown, fall through to return
1537            // default icon.
1538            Log.w("PackageManager", "Failure retrieving xml 0x"
1539                  + Integer.toHexString(resid) + " in package "
1540                  + packageName, e);
1541        } catch (NameNotFoundException e) {
1542            Log.w("PackageManager", "Failure retrieving resources for "
1543                  + appInfo.packageName);
1544        }
1545        return null;
1546    }
1547
1548    @Override
1549    public CharSequence getApplicationLabel(ApplicationInfo info) {
1550        return info.loadLabel(this);
1551    }
1552
1553    @Override
1554    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
1555                               String installerPackageName) {
1556        installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1557                installerPackageName, mContext.getUserId());
1558    }
1559
1560    @Override
1561    public void installPackage(Uri packageURI, PackageInstallObserver observer,
1562            int flags, String installerPackageName) {
1563        installCommon(packageURI, observer, flags, installerPackageName, mContext.getUserId());
1564    }
1565
1566    private void installCommon(Uri packageURI,
1567            PackageInstallObserver observer, int flags, String installerPackageName,
1568            int userId) {
1569        if (!"file".equals(packageURI.getScheme())) {
1570            throw new UnsupportedOperationException("Only file:// URIs are supported");
1571        }
1572
1573        final String originPath = packageURI.getPath();
1574        try {
1575            mPM.installPackageAsUser(originPath, observer.getBinder(), flags, installerPackageName,
1576                    userId);
1577        } catch (RemoteException e) {
1578            throw e.rethrowFromSystemServer();
1579        }
1580    }
1581
1582    @Override
1583    public int installExistingPackage(String packageName) throws NameNotFoundException {
1584        return installExistingPackageAsUser(packageName, mContext.getUserId());
1585    }
1586
1587    @Override
1588    public int installExistingPackageAsUser(String packageName, int userId)
1589            throws NameNotFoundException {
1590        try {
1591            int res = mPM.installExistingPackageAsUser(packageName, userId);
1592            if (res == INSTALL_FAILED_INVALID_URI) {
1593                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1594            }
1595            return res;
1596        } catch (RemoteException e) {
1597            throw e.rethrowFromSystemServer();
1598        }
1599    }
1600
1601    @Override
1602    public void verifyPendingInstall(int id, int response) {
1603        try {
1604            mPM.verifyPendingInstall(id, response);
1605        } catch (RemoteException e) {
1606            throw e.rethrowFromSystemServer();
1607        }
1608    }
1609
1610    @Override
1611    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1612            long millisecondsToDelay) {
1613        try {
1614            mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1615        } catch (RemoteException e) {
1616            throw e.rethrowFromSystemServer();
1617        }
1618    }
1619
1620    @Override
1621    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
1622        try {
1623            mPM.verifyIntentFilter(id, verificationCode, failedDomains);
1624        } catch (RemoteException e) {
1625            throw e.rethrowFromSystemServer();
1626        }
1627    }
1628
1629    @Override
1630    public int getIntentVerificationStatusAsUser(String packageName, int userId) {
1631        try {
1632            return mPM.getIntentVerificationStatus(packageName, userId);
1633        } catch (RemoteException e) {
1634            throw e.rethrowFromSystemServer();
1635        }
1636    }
1637
1638    @Override
1639    public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) {
1640        try {
1641            return mPM.updateIntentVerificationStatus(packageName, status, userId);
1642        } catch (RemoteException e) {
1643            throw e.rethrowFromSystemServer();
1644        }
1645    }
1646
1647    @Override
1648    @SuppressWarnings("unchecked")
1649    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
1650        try {
1651            ParceledListSlice<IntentFilterVerificationInfo> parceledList =
1652                    mPM.getIntentFilterVerifications(packageName);
1653            if (parceledList == null) {
1654                return Collections.emptyList();
1655            }
1656            return parceledList.getList();
1657        } catch (RemoteException e) {
1658            throw e.rethrowFromSystemServer();
1659        }
1660    }
1661
1662    @Override
1663    @SuppressWarnings("unchecked")
1664    public List<IntentFilter> getAllIntentFilters(String packageName) {
1665        try {
1666            ParceledListSlice<IntentFilter> parceledList =
1667                    mPM.getAllIntentFilters(packageName);
1668            if (parceledList == null) {
1669                return Collections.emptyList();
1670            }
1671            return parceledList.getList();
1672        } catch (RemoteException e) {
1673            throw e.rethrowFromSystemServer();
1674        }
1675    }
1676
1677    @Override
1678    public String getDefaultBrowserPackageNameAsUser(int userId) {
1679        try {
1680            return mPM.getDefaultBrowserPackageName(userId);
1681        } catch (RemoteException e) {
1682            throw e.rethrowFromSystemServer();
1683        }
1684    }
1685
1686    @Override
1687    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
1688        try {
1689            return mPM.setDefaultBrowserPackageName(packageName, userId);
1690        } catch (RemoteException e) {
1691            throw e.rethrowFromSystemServer();
1692        }
1693    }
1694
1695    @Override
1696    public void setInstallerPackageName(String targetPackage,
1697            String installerPackageName) {
1698        try {
1699            mPM.setInstallerPackageName(targetPackage, installerPackageName);
1700        } catch (RemoteException e) {
1701            throw e.rethrowFromSystemServer();
1702        }
1703    }
1704
1705    @Override
1706    public String getInstallerPackageName(String packageName) {
1707        try {
1708            return mPM.getInstallerPackageName(packageName);
1709        } catch (RemoteException e) {
1710            throw e.rethrowFromSystemServer();
1711        }
1712    }
1713
1714    @Override
1715    public int getMoveStatus(int moveId) {
1716        try {
1717            return mPM.getMoveStatus(moveId);
1718        } catch (RemoteException e) {
1719            throw e.rethrowFromSystemServer();
1720        }
1721    }
1722
1723    @Override
1724    public void registerMoveCallback(MoveCallback callback, Handler handler) {
1725        synchronized (mDelegates) {
1726            final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback,
1727                    handler.getLooper());
1728            try {
1729                mPM.registerMoveCallback(delegate);
1730            } catch (RemoteException e) {
1731                throw e.rethrowFromSystemServer();
1732            }
1733            mDelegates.add(delegate);
1734        }
1735    }
1736
1737    @Override
1738    public void unregisterMoveCallback(MoveCallback callback) {
1739        synchronized (mDelegates) {
1740            for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
1741                final MoveCallbackDelegate delegate = i.next();
1742                if (delegate.mCallback == callback) {
1743                    try {
1744                        mPM.unregisterMoveCallback(delegate);
1745                    } catch (RemoteException e) {
1746                        throw e.rethrowFromSystemServer();
1747                    }
1748                    i.remove();
1749                }
1750            }
1751        }
1752    }
1753
1754    @Override
1755    public int movePackage(String packageName, VolumeInfo vol) {
1756        try {
1757            final String volumeUuid;
1758            if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
1759                volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
1760            } else if (vol.isPrimaryPhysical()) {
1761                volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
1762            } else {
1763                volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
1764            }
1765
1766            return mPM.movePackage(packageName, volumeUuid);
1767        } catch (RemoteException e) {
1768            throw e.rethrowFromSystemServer();
1769        }
1770    }
1771
1772    @Override
1773    public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
1774        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1775        if (app.isInternal()) {
1776            return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
1777        } else if (app.isExternalAsec()) {
1778            return storage.getPrimaryPhysicalVolume();
1779        } else {
1780            return storage.findVolumeByUuid(app.volumeUuid);
1781        }
1782    }
1783
1784    @Override
1785    public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
1786        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1787        final VolumeInfo currentVol = getPackageCurrentVolume(app);
1788        final List<VolumeInfo> vols = storage.getVolumes();
1789        final List<VolumeInfo> candidates = new ArrayList<>();
1790        for (VolumeInfo vol : vols) {
1791            if (Objects.equals(vol, currentVol) || isPackageCandidateVolume(mContext, app, vol)) {
1792                candidates.add(vol);
1793            }
1794        }
1795        return candidates;
1796    }
1797
1798    private boolean isPackageCandidateVolume(
1799            ContextImpl context, ApplicationInfo app, VolumeInfo vol) {
1800        final boolean forceAllowOnExternal = Settings.Global.getInt(
1801                context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0;
1802        // Private internal is always an option
1803        if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
1804            return true;
1805        }
1806
1807        // System apps and apps demanding internal storage can't be moved
1808        // anywhere else
1809        if (app.isSystemApp()) {
1810            return false;
1811        }
1812        if (!forceAllowOnExternal
1813                && (app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY
1814                        || app.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED)) {
1815            return false;
1816        }
1817
1818        // Gotta be able to write there
1819        if (!vol.isMountedWritable()) {
1820            return false;
1821        }
1822
1823        // Moving into an ASEC on public primary is only option internal
1824        if (vol.isPrimaryPhysical()) {
1825            return app.isInternal();
1826        }
1827
1828        // Some apps can't be moved. (e.g. device admins)
1829        try {
1830            if (mPM.isPackageDeviceAdminOnAnyUser(app.packageName)) {
1831                return false;
1832            }
1833        } catch (RemoteException e) {
1834            throw e.rethrowFromSystemServer();
1835        }
1836
1837        // Otherwise we can move to any private volume
1838        return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
1839    }
1840
1841    @Override
1842    public int movePrimaryStorage(VolumeInfo vol) {
1843        try {
1844            final String volumeUuid;
1845            if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
1846                volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
1847            } else if (vol.isPrimaryPhysical()) {
1848                volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
1849            } else {
1850                volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
1851            }
1852
1853            return mPM.movePrimaryStorage(volumeUuid);
1854        } catch (RemoteException e) {
1855            throw e.rethrowFromSystemServer();
1856        }
1857    }
1858
1859    @Override
1860    public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
1861        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1862        final String volumeUuid = storage.getPrimaryStorageUuid();
1863        return storage.findVolumeByQualifiedUuid(volumeUuid);
1864    }
1865
1866    @Override
1867    public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
1868        final StorageManager storage = mContext.getSystemService(StorageManager.class);
1869        final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
1870        final List<VolumeInfo> vols = storage.getVolumes();
1871        final List<VolumeInfo> candidates = new ArrayList<>();
1872        if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL,
1873                storage.getPrimaryStorageUuid()) && currentVol != null) {
1874            // TODO: support moving primary physical to emulated volume
1875            candidates.add(currentVol);
1876        } else {
1877            for (VolumeInfo vol : vols) {
1878                if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
1879                    candidates.add(vol);
1880                }
1881            }
1882        }
1883        return candidates;
1884    }
1885
1886    private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) {
1887        // Private internal is always an option
1888        if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
1889            return true;
1890        }
1891
1892        // Gotta be able to write there
1893        if (!vol.isMountedWritable()) {
1894            return false;
1895        }
1896
1897        // We can move to any private volume
1898        return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
1899    }
1900
1901    @Override
1902    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1903        deletePackageAsUser(packageName, observer, flags, mContext.getUserId());
1904    }
1905
1906    @Override
1907    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
1908            int userId) {
1909        try {
1910            mPM.deletePackageAsUser(packageName, observer, userId, flags);
1911        } catch (RemoteException e) {
1912            throw e.rethrowFromSystemServer();
1913        }
1914    }
1915
1916    @Override
1917    public void clearApplicationUserData(String packageName,
1918                                         IPackageDataObserver observer) {
1919        try {
1920            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
1921        } catch (RemoteException e) {
1922            throw e.rethrowFromSystemServer();
1923        }
1924    }
1925    @Override
1926    public void deleteApplicationCacheFiles(String packageName,
1927                                            IPackageDataObserver observer) {
1928        try {
1929            mPM.deleteApplicationCacheFiles(packageName, observer);
1930        } catch (RemoteException e) {
1931            throw e.rethrowFromSystemServer();
1932        }
1933    }
1934
1935    @Override
1936    public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
1937            IPackageDataObserver observer) {
1938        try {
1939            mPM.deleteApplicationCacheFilesAsUser(packageName, userId, observer);
1940        } catch (RemoteException e) {
1941            throw e.rethrowFromSystemServer();
1942        }
1943    }
1944
1945    @Override
1946    public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
1947            IPackageDataObserver observer) {
1948        try {
1949            mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer);
1950        } catch (RemoteException e) {
1951            throw e.rethrowFromSystemServer();
1952        }
1953    }
1954
1955    @Override
1956    public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
1957        try {
1958            mPM.freeStorage(volumeUuid, freeStorageSize, pi);
1959        } catch (RemoteException e) {
1960            throw e.rethrowFromSystemServer();
1961        }
1962    }
1963
1964    @Override
1965    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
1966            int userId) {
1967        try {
1968            return mPM.setPackagesSuspendedAsUser(packageNames, suspended, userId);
1969        } catch (RemoteException e) {
1970            throw e.rethrowFromSystemServer();
1971        }
1972    }
1973
1974    @Override
1975    public boolean isPackageSuspendedForUser(String packageName, int userId) {
1976        try {
1977            return mPM.isPackageSuspendedForUser(packageName, userId);
1978        } catch (RemoteException e) {
1979            throw e.rethrowFromSystemServer();
1980        }
1981    }
1982
1983    @Override
1984    public void getPackageSizeInfoAsUser(String packageName, int userHandle,
1985            IPackageStatsObserver observer) {
1986        try {
1987            mPM.getPackageSizeInfo(packageName, userHandle, observer);
1988        } catch (RemoteException e) {
1989            throw e.rethrowFromSystemServer();
1990        }
1991    }
1992
1993    @Override
1994    public void addPackageToPreferred(String packageName) {
1995        Log.w(TAG, "addPackageToPreferred() is a no-op");
1996    }
1997
1998    @Override
1999    public void removePackageFromPreferred(String packageName) {
2000        Log.w(TAG, "removePackageFromPreferred() is a no-op");
2001    }
2002
2003    @Override
2004    public List<PackageInfo> getPreferredPackages(int flags) {
2005        Log.w(TAG, "getPreferredPackages() is a no-op");
2006        return Collections.emptyList();
2007    }
2008
2009    @Override
2010    public void addPreferredActivity(IntentFilter filter,
2011                                     int match, ComponentName[] set, ComponentName activity) {
2012        try {
2013            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
2014        } catch (RemoteException e) {
2015            throw e.rethrowFromSystemServer();
2016        }
2017    }
2018
2019    @Override
2020    public void addPreferredActivityAsUser(IntentFilter filter, int match,
2021            ComponentName[] set, ComponentName activity, int userId) {
2022        try {
2023            mPM.addPreferredActivity(filter, match, set, activity, userId);
2024        } catch (RemoteException e) {
2025            throw e.rethrowFromSystemServer();
2026        }
2027    }
2028
2029    @Override
2030    public void replacePreferredActivity(IntentFilter filter,
2031                                         int match, ComponentName[] set, ComponentName activity) {
2032        try {
2033            mPM.replacePreferredActivity(filter, match, set, activity, mContext.getUserId());
2034        } catch (RemoteException e) {
2035            throw e.rethrowFromSystemServer();
2036        }
2037    }
2038
2039    @Override
2040    public void replacePreferredActivityAsUser(IntentFilter filter,
2041                                         int match, ComponentName[] set, ComponentName activity,
2042                                         int userId) {
2043        try {
2044            mPM.replacePreferredActivity(filter, match, set, activity, userId);
2045        } catch (RemoteException e) {
2046            throw e.rethrowFromSystemServer();
2047        }
2048    }
2049
2050    @Override
2051    public void clearPackagePreferredActivities(String packageName) {
2052        try {
2053            mPM.clearPackagePreferredActivities(packageName);
2054        } catch (RemoteException e) {
2055            throw e.rethrowFromSystemServer();
2056        }
2057    }
2058
2059    @Override
2060    public int getPreferredActivities(List<IntentFilter> outFilters,
2061                                      List<ComponentName> outActivities, String packageName) {
2062        try {
2063            return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2064        } catch (RemoteException e) {
2065            throw e.rethrowFromSystemServer();
2066        }
2067    }
2068
2069    @Override
2070    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
2071        try {
2072            return mPM.getHomeActivities(outActivities);
2073        } catch (RemoteException e) {
2074            throw e.rethrowFromSystemServer();
2075        }
2076    }
2077
2078    @Override
2079    public void setComponentEnabledSetting(ComponentName componentName,
2080                                           int newState, int flags) {
2081        try {
2082            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
2083        } catch (RemoteException e) {
2084            throw e.rethrowFromSystemServer();
2085        }
2086    }
2087
2088    @Override
2089    public int getComponentEnabledSetting(ComponentName componentName) {
2090        try {
2091            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
2092        } catch (RemoteException e) {
2093            throw e.rethrowFromSystemServer();
2094        }
2095    }
2096
2097    @Override
2098    public void setApplicationEnabledSetting(String packageName,
2099                                             int newState, int flags) {
2100        try {
2101            mPM.setApplicationEnabledSetting(packageName, newState, flags,
2102                    mContext.getUserId(), mContext.getOpPackageName());
2103        } catch (RemoteException e) {
2104            throw e.rethrowFromSystemServer();
2105        }
2106    }
2107
2108    @Override
2109    public int getApplicationEnabledSetting(String packageName) {
2110        try {
2111            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
2112        } catch (RemoteException e) {
2113            throw e.rethrowFromSystemServer();
2114        }
2115    }
2116
2117    @Override
2118    public void flushPackageRestrictionsAsUser(int userId) {
2119        try {
2120            mPM.flushPackageRestrictionsAsUser(userId);
2121        } catch (RemoteException e) {
2122            throw e.rethrowFromSystemServer();
2123        }
2124    }
2125
2126    @Override
2127    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
2128            UserHandle user) {
2129        try {
2130            return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
2131                    user.getIdentifier());
2132        } catch (RemoteException e) {
2133            throw e.rethrowFromSystemServer();
2134        }
2135    }
2136
2137    @Override
2138    public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
2139        try {
2140            return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
2141        } catch (RemoteException e) {
2142            throw e.rethrowFromSystemServer();
2143        }
2144    }
2145
2146    /** @hide */
2147    @Override
2148    public KeySet getKeySetByAlias(String packageName, String alias) {
2149        Preconditions.checkNotNull(packageName);
2150        Preconditions.checkNotNull(alias);
2151        try {
2152            return mPM.getKeySetByAlias(packageName, alias);
2153        } catch (RemoteException e) {
2154            throw e.rethrowFromSystemServer();
2155        }
2156    }
2157
2158    /** @hide */
2159    @Override
2160    public KeySet getSigningKeySet(String packageName) {
2161        Preconditions.checkNotNull(packageName);
2162        try {
2163            return mPM.getSigningKeySet(packageName);
2164        } catch (RemoteException e) {
2165            throw e.rethrowFromSystemServer();
2166        }
2167    }
2168
2169    /** @hide */
2170    @Override
2171    public boolean isSignedBy(String packageName, KeySet ks) {
2172        Preconditions.checkNotNull(packageName);
2173        Preconditions.checkNotNull(ks);
2174        try {
2175            return mPM.isPackageSignedByKeySet(packageName, ks);
2176        } catch (RemoteException e) {
2177            throw e.rethrowFromSystemServer();
2178        }
2179    }
2180
2181    /** @hide */
2182    @Override
2183    public boolean isSignedByExactly(String packageName, KeySet ks) {
2184        Preconditions.checkNotNull(packageName);
2185        Preconditions.checkNotNull(ks);
2186        try {
2187            return mPM.isPackageSignedByKeySetExactly(packageName, ks);
2188        } catch (RemoteException e) {
2189            throw e.rethrowFromSystemServer();
2190        }
2191    }
2192
2193    /**
2194     * @hide
2195     */
2196    @Override
2197    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
2198        try {
2199            return mPM.getVerifierDeviceIdentity();
2200        } catch (RemoteException e) {
2201            throw e.rethrowFromSystemServer();
2202        }
2203    }
2204
2205    /**
2206     * @hide
2207     */
2208    @Override
2209    public boolean isUpgrade() {
2210        try {
2211            return mPM.isUpgrade();
2212        } catch (RemoteException e) {
2213            throw e.rethrowFromSystemServer();
2214        }
2215    }
2216
2217    @Override
2218    public PackageInstaller getPackageInstaller() {
2219        synchronized (mLock) {
2220            if (mInstaller == null) {
2221                try {
2222                    mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(),
2223                            mContext.getPackageName(), mContext.getUserId());
2224                } catch (RemoteException e) {
2225                    throw e.rethrowFromSystemServer();
2226                }
2227            }
2228            return mInstaller;
2229        }
2230    }
2231
2232    @Override
2233    public boolean isPackageAvailable(String packageName) {
2234        try {
2235            return mPM.isPackageAvailable(packageName, mContext.getUserId());
2236        } catch (RemoteException e) {
2237            throw e.rethrowFromSystemServer();
2238        }
2239    }
2240
2241    /**
2242     * @hide
2243     */
2244    @Override
2245    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
2246            int flags) {
2247        try {
2248            mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
2249                    sourceUserId, targetUserId, flags);
2250        } catch (RemoteException e) {
2251            throw e.rethrowFromSystemServer();
2252        }
2253    }
2254
2255    /**
2256     * @hide
2257     */
2258    @Override
2259    public void clearCrossProfileIntentFilters(int sourceUserId) {
2260        try {
2261            mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName());
2262        } catch (RemoteException e) {
2263            throw e.rethrowFromSystemServer();
2264        }
2265    }
2266
2267    /**
2268     * @hide
2269     */
2270    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
2271        Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
2272        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
2273            return dr;
2274        }
2275        return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
2276    }
2277
2278    /**
2279     * @hide
2280     */
2281    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
2282        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
2283            Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
2284            if (bitmap == null) {
2285                return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false);
2286            }
2287            return new BitmapDrawable(bitmap);
2288        }
2289        Drawable dr = null;
2290        if (itemInfo.packageName != null) {
2291            dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
2292        }
2293        if (dr == null) {
2294            dr = itemInfo.loadDefaultIcon(this);
2295        }
2296        return dr;
2297    }
2298
2299    private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
2300            Rect badgeLocation, boolean tryBadgeInPlace) {
2301        final int badgedWidth = drawable.getIntrinsicWidth();
2302        final int badgedHeight = drawable.getIntrinsicHeight();
2303        final boolean canBadgeInPlace = tryBadgeInPlace
2304                && (drawable instanceof BitmapDrawable)
2305                && ((BitmapDrawable) drawable).getBitmap().isMutable();
2306
2307        final Bitmap bitmap;
2308        if (canBadgeInPlace) {
2309            bitmap = ((BitmapDrawable) drawable).getBitmap();
2310        } else {
2311            bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
2312        }
2313        Canvas canvas = new Canvas(bitmap);
2314
2315        if (!canBadgeInPlace) {
2316            drawable.setBounds(0, 0, badgedWidth, badgedHeight);
2317            drawable.draw(canvas);
2318        }
2319
2320        if (badgeLocation != null) {
2321            if (badgeLocation.left < 0 || badgeLocation.top < 0
2322                    || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
2323                throw new IllegalArgumentException("Badge location " + badgeLocation
2324                        + " not in badged drawable bounds "
2325                        + new Rect(0, 0, badgedWidth, badgedHeight));
2326            }
2327            badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
2328
2329            canvas.save();
2330            canvas.translate(badgeLocation.left, badgeLocation.top);
2331            badgeDrawable.draw(canvas);
2332            canvas.restore();
2333        } else {
2334            badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
2335            badgeDrawable.draw(canvas);
2336        }
2337
2338        if (!canBadgeInPlace) {
2339            BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
2340
2341            if (drawable instanceof BitmapDrawable) {
2342                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
2343                mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
2344            }
2345
2346            return mergedDrawable;
2347        }
2348
2349        return drawable;
2350    }
2351
2352    private int getBadgeResIdForUser(int userId) {
2353        // Return the framework-provided badge.
2354        if (isManagedProfile(userId)) {
2355            return com.android.internal.R.drawable.ic_corp_icon_badge;
2356        }
2357        return 0;
2358    }
2359
2360    private boolean isManagedProfile(int userId) {
2361        return getUserManager().isManagedProfile(userId);
2362    }
2363
2364    /** {@hide} */
2365    private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
2366            Handler.Callback {
2367        private static final int MSG_CREATED = 1;
2368        private static final int MSG_STATUS_CHANGED = 2;
2369
2370        final MoveCallback mCallback;
2371        final Handler mHandler;
2372
2373        public MoveCallbackDelegate(MoveCallback callback, Looper looper) {
2374            mCallback = callback;
2375            mHandler = new Handler(looper, this);
2376        }
2377
2378        @Override
2379        public boolean handleMessage(Message msg) {
2380            switch (msg.what) {
2381                case MSG_CREATED: {
2382                    final SomeArgs args = (SomeArgs) msg.obj;
2383                    mCallback.onCreated(args.argi1, (Bundle) args.arg2);
2384                    args.recycle();
2385                    return true;
2386                }
2387                case MSG_STATUS_CHANGED: {
2388                    final SomeArgs args = (SomeArgs) msg.obj;
2389                    mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
2390                    args.recycle();
2391                    return true;
2392                }
2393            }
2394            return false;
2395        }
2396
2397        @Override
2398        public void onCreated(int moveId, Bundle extras) {
2399            final SomeArgs args = SomeArgs.obtain();
2400            args.argi1 = moveId;
2401            args.arg2 = extras;
2402            mHandler.obtainMessage(MSG_CREATED, args).sendToTarget();
2403        }
2404
2405        @Override
2406        public void onStatusChanged(int moveId, int status, long estMillis) {
2407            final SomeArgs args = SomeArgs.obtain();
2408            args.argi1 = moveId;
2409            args.argi2 = status;
2410            args.arg3 = estMillis;
2411            mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
2412        }
2413    }
2414
2415    private final ContextImpl mContext;
2416    private final IPackageManager mPM;
2417
2418    private static final Object sSync = new Object();
2419    private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
2420            = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
2421    private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
2422            = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
2423
2424    private final Map<OnPermissionsChangedListener, IOnPermissionsChangeListener>
2425            mPermissionListeners = new ArrayMap<>();
2426
2427    public class OnPermissionsChangeListenerDelegate extends IOnPermissionsChangeListener.Stub
2428            implements Handler.Callback{
2429        private static final int MSG_PERMISSIONS_CHANGED = 1;
2430
2431        private final OnPermissionsChangedListener mListener;
2432        private final Handler mHandler;
2433
2434
2435        public OnPermissionsChangeListenerDelegate(OnPermissionsChangedListener listener,
2436                Looper looper) {
2437            mListener = listener;
2438            mHandler = new Handler(looper, this);
2439        }
2440
2441        @Override
2442        public void onPermissionsChanged(int uid) {
2443            mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
2444        }
2445
2446        @Override
2447        public boolean handleMessage(Message msg) {
2448            switch (msg.what) {
2449                case MSG_PERMISSIONS_CHANGED: {
2450                    final int uid = msg.arg1;
2451                    mListener.onPermissionsChanged(uid);
2452                    return true;
2453                }
2454            }
2455            return false;
2456        }
2457    }
2458}
2459