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