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