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