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