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