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