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