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