• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.app;
18 
19 import android.content.ComponentName;
20 import android.content.ContentResolver;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.content.IntentSender;
24 import android.content.pm.ActivityInfo;
25 import android.content.pm.ApplicationInfo;
26 import android.content.pm.ComponentInfo;
27 import android.content.pm.FeatureInfo;
28 import android.content.pm.IPackageDataObserver;
29 import android.content.pm.IPackageDeleteObserver;
30 import android.content.pm.IPackageInstallObserver;
31 import android.content.pm.IPackageManager;
32 import android.content.pm.IPackageMoveObserver;
33 import android.content.pm.IPackageStatsObserver;
34 import android.content.pm.InstrumentationInfo;
35 import android.content.pm.PackageInfo;
36 import android.content.pm.PackageManager;
37 import android.content.pm.ParceledListSlice;
38 import android.content.pm.PermissionGroupInfo;
39 import android.content.pm.PermissionInfo;
40 import android.content.pm.ProviderInfo;
41 import android.content.pm.ResolveInfo;
42 import android.content.pm.ServiceInfo;
43 import android.content.pm.UserInfo;
44 import android.content.pm.ManifestDigest;
45 import android.content.pm.VerifierDeviceIdentity;
46 import android.content.res.Resources;
47 import android.content.res.XmlResourceParser;
48 import android.graphics.drawable.Drawable;
49 import android.net.Uri;
50 import android.os.Process;
51 import android.os.RemoteException;
52 import android.util.Log;
53 
54 import java.lang.ref.WeakReference;
55 import java.util.ArrayList;
56 import java.util.HashMap;
57 import java.util.Iterator;
58 import java.util.List;
59 
60 /*package*/
61 final class ApplicationPackageManager extends PackageManager {
62     private static final String TAG = "ApplicationPackageManager";
63     private final static boolean DEBUG = false;
64     private final static boolean DEBUG_ICONS = false;
65 
66     @Override
getPackageInfo(String packageName, int flags)67     public PackageInfo getPackageInfo(String packageName, int flags)
68             throws NameNotFoundException {
69         try {
70             PackageInfo pi = mPM.getPackageInfo(packageName, flags);
71             if (pi != null) {
72                 return pi;
73             }
74         } catch (RemoteException e) {
75             throw new RuntimeException("Package manager has died", e);
76         }
77 
78         throw new NameNotFoundException(packageName);
79     }
80 
81     @Override
currentToCanonicalPackageNames(String[] names)82     public String[] currentToCanonicalPackageNames(String[] names) {
83         try {
84             return mPM.currentToCanonicalPackageNames(names);
85         } catch (RemoteException e) {
86             throw new RuntimeException("Package manager has died", e);
87         }
88     }
89 
90     @Override
canonicalToCurrentPackageNames(String[] names)91     public String[] canonicalToCurrentPackageNames(String[] names) {
92         try {
93             return mPM.canonicalToCurrentPackageNames(names);
94         } catch (RemoteException e) {
95             throw new RuntimeException("Package manager has died", e);
96         }
97     }
98 
99     @Override
getLaunchIntentForPackage(String packageName)100     public Intent getLaunchIntentForPackage(String packageName) {
101         // First see if the package has an INFO activity; the existence of
102         // such an activity is implied to be the desired front-door for the
103         // overall package (such as if it has multiple launcher entries).
104         Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
105         intentToResolve.addCategory(Intent.CATEGORY_INFO);
106         intentToResolve.setPackage(packageName);
107         List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
108 
109         // Otherwise, try to find a main launcher activity.
110         if (ris == null || ris.size() <= 0) {
111             // reuse the intent instance
112             intentToResolve.removeCategory(Intent.CATEGORY_INFO);
113             intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
114             intentToResolve.setPackage(packageName);
115             ris = queryIntentActivities(intentToResolve, 0);
116         }
117         if (ris == null || ris.size() <= 0) {
118             return null;
119         }
120         Intent intent = new Intent(intentToResolve);
121         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
122         intent.setClassName(ris.get(0).activityInfo.packageName,
123                 ris.get(0).activityInfo.name);
124         return intent;
125     }
126 
127     @Override
getPackageGids(String packageName)128     public int[] getPackageGids(String packageName)
129             throws NameNotFoundException {
130         try {
131             int[] gids = mPM.getPackageGids(packageName);
132             if (gids == null || gids.length > 0) {
133                 return gids;
134             }
135         } catch (RemoteException e) {
136             throw new RuntimeException("Package manager has died", e);
137         }
138 
139         throw new NameNotFoundException(packageName);
140     }
141 
142     @Override
getPermissionInfo(String name, int flags)143     public PermissionInfo getPermissionInfo(String name, int flags)
144             throws NameNotFoundException {
145         try {
146             PermissionInfo pi = mPM.getPermissionInfo(name, flags);
147             if (pi != null) {
148                 return pi;
149             }
150         } catch (RemoteException e) {
151             throw new RuntimeException("Package manager has died", e);
152         }
153 
154         throw new NameNotFoundException(name);
155     }
156 
157     @Override
queryPermissionsByGroup(String group, int flags)158     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
159             throws NameNotFoundException {
160         try {
161             List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
162             if (pi != null) {
163                 return pi;
164             }
165         } catch (RemoteException e) {
166             throw new RuntimeException("Package manager has died", e);
167         }
168 
169         throw new NameNotFoundException(group);
170     }
171 
172     @Override
getPermissionGroupInfo(String name, int flags)173     public PermissionGroupInfo getPermissionGroupInfo(String name,
174                                                       int flags) throws NameNotFoundException {
175         try {
176             PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
177             if (pgi != null) {
178                 return pgi;
179             }
180         } catch (RemoteException e) {
181             throw new RuntimeException("Package manager has died", e);
182         }
183 
184         throw new NameNotFoundException(name);
185     }
186 
187     @Override
getAllPermissionGroups(int flags)188     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
189         try {
190             return mPM.getAllPermissionGroups(flags);
191         } catch (RemoteException e) {
192             throw new RuntimeException("Package manager has died", e);
193         }
194     }
195 
196     @Override
getApplicationInfo(String packageName, int flags)197     public ApplicationInfo getApplicationInfo(String packageName, int flags)
198             throws NameNotFoundException {
199         try {
200             ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
201             if (ai != null) {
202                 return ai;
203             }
204         } catch (RemoteException e) {
205             throw new RuntimeException("Package manager has died", e);
206         }
207 
208         throw new NameNotFoundException(packageName);
209     }
210 
211     @Override
getActivityInfo(ComponentName className, int flags)212     public ActivityInfo getActivityInfo(ComponentName className, int flags)
213             throws NameNotFoundException {
214         try {
215             ActivityInfo ai = mPM.getActivityInfo(className, flags);
216             if (ai != null) {
217                 return ai;
218             }
219         } catch (RemoteException e) {
220             throw new RuntimeException("Package manager has died", e);
221         }
222 
223         throw new NameNotFoundException(className.toString());
224     }
225 
226     @Override
getReceiverInfo(ComponentName className, int flags)227     public ActivityInfo getReceiverInfo(ComponentName className, int flags)
228             throws NameNotFoundException {
229         try {
230             ActivityInfo ai = mPM.getReceiverInfo(className, flags);
231             if (ai != null) {
232                 return ai;
233             }
234         } catch (RemoteException e) {
235             throw new RuntimeException("Package manager has died", e);
236         }
237 
238         throw new NameNotFoundException(className.toString());
239     }
240 
241     @Override
getServiceInfo(ComponentName className, int flags)242     public ServiceInfo getServiceInfo(ComponentName className, int flags)
243             throws NameNotFoundException {
244         try {
245             ServiceInfo si = mPM.getServiceInfo(className, flags);
246             if (si != null) {
247                 return si;
248             }
249         } catch (RemoteException e) {
250             throw new RuntimeException("Package manager has died", e);
251         }
252 
253         throw new NameNotFoundException(className.toString());
254     }
255 
256     @Override
getProviderInfo(ComponentName className, int flags)257     public ProviderInfo getProviderInfo(ComponentName className, int flags)
258             throws NameNotFoundException {
259         try {
260             ProviderInfo pi = mPM.getProviderInfo(className, flags);
261             if (pi != null) {
262                 return pi;
263             }
264         } catch (RemoteException e) {
265             throw new RuntimeException("Package manager has died", e);
266         }
267 
268         throw new NameNotFoundException(className.toString());
269     }
270 
271     @Override
getSystemSharedLibraryNames()272     public String[] getSystemSharedLibraryNames() {
273         try {
274             return mPM.getSystemSharedLibraryNames();
275         } catch (RemoteException e) {
276             throw new RuntimeException("Package manager has died", e);
277         }
278     }
279 
280     @Override
getSystemAvailableFeatures()281     public FeatureInfo[] getSystemAvailableFeatures() {
282         try {
283             return mPM.getSystemAvailableFeatures();
284         } catch (RemoteException e) {
285             throw new RuntimeException("Package manager has died", e);
286         }
287     }
288 
289     @Override
hasSystemFeature(String name)290     public boolean hasSystemFeature(String name) {
291         try {
292             return mPM.hasSystemFeature(name);
293         } catch (RemoteException e) {
294             throw new RuntimeException("Package manager has died", e);
295         }
296     }
297 
298     @Override
checkPermission(String permName, String pkgName)299     public int checkPermission(String permName, String pkgName) {
300         try {
301             return mPM.checkPermission(permName, pkgName);
302         } catch (RemoteException e) {
303             throw new RuntimeException("Package manager has died", e);
304         }
305     }
306 
307     @Override
addPermission(PermissionInfo info)308     public boolean addPermission(PermissionInfo info) {
309         try {
310             return mPM.addPermission(info);
311         } catch (RemoteException e) {
312             throw new RuntimeException("Package manager has died", e);
313         }
314     }
315 
316     @Override
addPermissionAsync(PermissionInfo info)317     public boolean addPermissionAsync(PermissionInfo info) {
318         try {
319             return mPM.addPermissionAsync(info);
320         } catch (RemoteException e) {
321             throw new RuntimeException("Package manager has died", e);
322         }
323     }
324 
325     @Override
removePermission(String name)326     public void removePermission(String name) {
327         try {
328             mPM.removePermission(name);
329         } catch (RemoteException e) {
330             throw new RuntimeException("Package manager has died", e);
331         }
332     }
333 
334     @Override
checkSignatures(String pkg1, String pkg2)335     public int checkSignatures(String pkg1, String pkg2) {
336         try {
337             return mPM.checkSignatures(pkg1, pkg2);
338         } catch (RemoteException e) {
339             throw new RuntimeException("Package manager has died", e);
340         }
341     }
342 
343     @Override
checkSignatures(int uid1, int uid2)344     public int checkSignatures(int uid1, int uid2) {
345         try {
346             return mPM.checkUidSignatures(uid1, uid2);
347         } catch (RemoteException e) {
348             throw new RuntimeException("Package manager has died", e);
349         }
350     }
351 
352     @Override
getPackagesForUid(int uid)353     public String[] getPackagesForUid(int uid) {
354         try {
355             return mPM.getPackagesForUid(uid);
356         } catch (RemoteException e) {
357             throw new RuntimeException("Package manager has died", e);
358         }
359     }
360 
361     @Override
getNameForUid(int uid)362     public String getNameForUid(int uid) {
363         try {
364             return mPM.getNameForUid(uid);
365         } catch (RemoteException e) {
366             throw new RuntimeException("Package manager has died", e);
367         }
368     }
369 
370     @Override
getUidForSharedUser(String sharedUserName)371     public int getUidForSharedUser(String sharedUserName)
372             throws NameNotFoundException {
373         try {
374             int uid = mPM.getUidForSharedUser(sharedUserName);
375             if(uid != -1) {
376                 return uid;
377             }
378         } catch (RemoteException e) {
379             throw new RuntimeException("Package manager has died", e);
380         }
381         throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
382     }
383 
384     @SuppressWarnings("unchecked")
385     @Override
getInstalledPackages(int flags)386     public List<PackageInfo> getInstalledPackages(int flags) {
387         try {
388             final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
389             PackageInfo lastItem = null;
390             ParceledListSlice<PackageInfo> slice;
391 
392             do {
393                 final String lastKey = lastItem != null ? lastItem.packageName : null;
394                 slice = mPM.getInstalledPackages(flags, lastKey);
395                 lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
396             } while (!slice.isLastSlice());
397 
398             return packageInfos;
399         } catch (RemoteException e) {
400             throw new RuntimeException("Package manager has died", e);
401         }
402     }
403 
404     @SuppressWarnings("unchecked")
405     @Override
getInstalledApplications(int flags)406     public List<ApplicationInfo> getInstalledApplications(int flags) {
407         try {
408             final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>();
409             ApplicationInfo lastItem = null;
410             ParceledListSlice<ApplicationInfo> slice;
411 
412             do {
413                 final String lastKey = lastItem != null ? lastItem.packageName : null;
414                 slice = mPM.getInstalledApplications(flags, lastKey);
415                 lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR);
416             } while (!slice.isLastSlice());
417 
418             return applicationInfos;
419         } catch (RemoteException e) {
420             throw new RuntimeException("Package manager has died", e);
421         }
422     }
423 
424     @Override
resolveActivity(Intent intent, int flags)425     public ResolveInfo resolveActivity(Intent intent, int flags) {
426         try {
427             return mPM.resolveIntent(
428                 intent,
429                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
430                 flags);
431         } catch (RemoteException e) {
432             throw new RuntimeException("Package manager has died", e);
433         }
434     }
435 
436     @Override
queryIntentActivities(Intent intent, int flags)437     public List<ResolveInfo> queryIntentActivities(Intent intent,
438                                                    int flags) {
439         try {
440             return mPM.queryIntentActivities(
441                 intent,
442                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
443                 flags);
444         } catch (RemoteException e) {
445             throw new RuntimeException("Package manager has died", e);
446         }
447     }
448 
449     @Override
queryIntentActivityOptions( ComponentName caller, Intent[] specifics, Intent intent, int flags)450     public List<ResolveInfo> queryIntentActivityOptions(
451         ComponentName caller, Intent[] specifics, Intent intent,
452         int flags) {
453         final ContentResolver resolver = mContext.getContentResolver();
454 
455         String[] specificTypes = null;
456         if (specifics != null) {
457             final int N = specifics.length;
458             for (int i=0; i<N; i++) {
459                 Intent sp = specifics[i];
460                 if (sp != null) {
461                     String t = sp.resolveTypeIfNeeded(resolver);
462                     if (t != null) {
463                         if (specificTypes == null) {
464                             specificTypes = new String[N];
465                         }
466                         specificTypes[i] = t;
467                     }
468                 }
469             }
470         }
471 
472         try {
473             return mPM.queryIntentActivityOptions(caller, specifics,
474                                                   specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
475                                                   flags);
476         } catch (RemoteException e) {
477             throw new RuntimeException("Package manager has died", e);
478         }
479     }
480 
481     @Override
queryBroadcastReceivers(Intent intent, int flags)482     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
483         try {
484             return mPM.queryIntentReceivers(
485                 intent,
486                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
487                 flags);
488         } catch (RemoteException e) {
489             throw new RuntimeException("Package manager has died", e);
490         }
491     }
492 
493     @Override
resolveService(Intent intent, int flags)494     public ResolveInfo resolveService(Intent intent, int flags) {
495         try {
496             return mPM.resolveService(
497                 intent,
498                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
499                 flags);
500         } catch (RemoteException e) {
501             throw new RuntimeException("Package manager has died", e);
502         }
503     }
504 
505     @Override
queryIntentServices(Intent intent, int flags)506     public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
507         try {
508             return mPM.queryIntentServices(
509                 intent,
510                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
511                 flags);
512         } catch (RemoteException e) {
513             throw new RuntimeException("Package manager has died", e);
514         }
515     }
516 
517     @Override
resolveContentProvider(String name, int flags)518     public ProviderInfo resolveContentProvider(String name,
519                                                int flags) {
520         try {
521             return mPM.resolveContentProvider(name, flags);
522         } catch (RemoteException e) {
523             throw new RuntimeException("Package manager has died", e);
524         }
525     }
526 
527     @Override
queryContentProviders(String processName, int uid, int flags)528     public List<ProviderInfo> queryContentProviders(String processName,
529                                                     int uid, int flags) {
530         try {
531             return mPM.queryContentProviders(processName, uid, flags);
532         } catch (RemoteException e) {
533             throw new RuntimeException("Package manager has died", e);
534         }
535     }
536 
537     @Override
getInstrumentationInfo( ComponentName className, int flags)538     public InstrumentationInfo getInstrumentationInfo(
539         ComponentName className, int flags)
540             throws NameNotFoundException {
541         try {
542             InstrumentationInfo ii = mPM.getInstrumentationInfo(
543                 className, flags);
544             if (ii != null) {
545                 return ii;
546             }
547         } catch (RemoteException e) {
548             throw new RuntimeException("Package manager has died", e);
549         }
550 
551         throw new NameNotFoundException(className.toString());
552     }
553 
554     @Override
queryInstrumentation( String targetPackage, int flags)555     public List<InstrumentationInfo> queryInstrumentation(
556         String targetPackage, int flags) {
557         try {
558             return mPM.queryInstrumentation(targetPackage, flags);
559         } catch (RemoteException e) {
560             throw new RuntimeException("Package manager has died", e);
561         }
562     }
563 
getDrawable(String packageName, int resid, ApplicationInfo appInfo)564     @Override public Drawable getDrawable(String packageName, int resid,
565                                           ApplicationInfo appInfo) {
566         ResourceName name = new ResourceName(packageName, resid);
567         Drawable dr = getCachedIcon(name);
568         if (dr != null) {
569             return dr;
570         }
571         if (appInfo == null) {
572             try {
573                 appInfo = getApplicationInfo(packageName, 0);
574             } catch (NameNotFoundException e) {
575                 return null;
576             }
577         }
578         try {
579             Resources r = getResourcesForApplication(appInfo);
580             dr = r.getDrawable(resid);
581             if (false) {
582                 RuntimeException e = new RuntimeException("here");
583                 e.fillInStackTrace();
584                 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
585                       + " from package " + packageName
586                       + ": app scale=" + r.getCompatibilityInfo().applicationScale
587                       + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
588                       e);
589             }
590             if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
591                                    + Integer.toHexString(resid) + " from " + r
592                                    + ": " + dr);
593             putCachedIcon(name, dr);
594             return dr;
595         } catch (NameNotFoundException e) {
596             Log.w("PackageManager", "Failure retrieving resources for"
597                   + appInfo.packageName);
598         } catch (Resources.NotFoundException e) {
599             Log.w("PackageManager", "Failure retrieving resources for"
600                   + appInfo.packageName + ": " + e.getMessage());
601         } catch (RuntimeException e) {
602             // If an exception was thrown, fall through to return
603             // default icon.
604             Log.w("PackageManager", "Failure retrieving icon 0x"
605                   + Integer.toHexString(resid) + " in package "
606                   + packageName, e);
607         }
608         return null;
609     }
610 
getActivityIcon(ComponentName activityName)611     @Override public Drawable getActivityIcon(ComponentName activityName)
612             throws NameNotFoundException {
613         return getActivityInfo(activityName, 0).loadIcon(this);
614     }
615 
getActivityIcon(Intent intent)616     @Override public Drawable getActivityIcon(Intent intent)
617             throws NameNotFoundException {
618         if (intent.getComponent() != null) {
619             return getActivityIcon(intent.getComponent());
620         }
621 
622         ResolveInfo info = resolveActivity(
623             intent, PackageManager.MATCH_DEFAULT_ONLY);
624         if (info != null) {
625             return info.activityInfo.loadIcon(this);
626         }
627 
628         throw new NameNotFoundException(intent.toURI());
629     }
630 
getDefaultActivityIcon()631     @Override public Drawable getDefaultActivityIcon() {
632         return Resources.getSystem().getDrawable(
633             com.android.internal.R.drawable.sym_def_app_icon);
634     }
635 
getApplicationIcon(ApplicationInfo info)636     @Override public Drawable getApplicationIcon(ApplicationInfo info) {
637         return info.loadIcon(this);
638     }
639 
getApplicationIcon(String packageName)640     @Override public Drawable getApplicationIcon(String packageName)
641             throws NameNotFoundException {
642         return getApplicationIcon(getApplicationInfo(packageName, 0));
643     }
644 
645     @Override
getActivityLogo(ComponentName activityName)646     public Drawable getActivityLogo(ComponentName activityName)
647             throws NameNotFoundException {
648         return getActivityInfo(activityName, 0).loadLogo(this);
649     }
650 
651     @Override
getActivityLogo(Intent intent)652     public Drawable getActivityLogo(Intent intent)
653             throws NameNotFoundException {
654         if (intent.getComponent() != null) {
655             return getActivityLogo(intent.getComponent());
656         }
657 
658         ResolveInfo info = resolveActivity(
659             intent, PackageManager.MATCH_DEFAULT_ONLY);
660         if (info != null) {
661             return info.activityInfo.loadLogo(this);
662         }
663 
664         throw new NameNotFoundException(intent.toUri(0));
665     }
666 
667     @Override
getApplicationLogo(ApplicationInfo info)668     public Drawable getApplicationLogo(ApplicationInfo info) {
669         return info.loadLogo(this);
670     }
671 
672     @Override
getApplicationLogo(String packageName)673     public Drawable getApplicationLogo(String packageName)
674             throws NameNotFoundException {
675         return getApplicationLogo(getApplicationInfo(packageName, 0));
676     }
677 
getResourcesForActivity( ComponentName activityName)678     @Override public Resources getResourcesForActivity(
679         ComponentName activityName) throws NameNotFoundException {
680         return getResourcesForApplication(
681             getActivityInfo(activityName, 0).applicationInfo);
682     }
683 
getResourcesForApplication( ApplicationInfo app)684     @Override public Resources getResourcesForApplication(
685         ApplicationInfo app) throws NameNotFoundException {
686         if (app.packageName.equals("system")) {
687             return mContext.mMainThread.getSystemContext().getResources();
688         }
689         Resources r = mContext.mMainThread.getTopLevelResources(
690             app.uid == Process.myUid() ? app.sourceDir
691             : app.publicSourceDir, mContext.mPackageInfo);
692         if (r != null) {
693             return r;
694         }
695         throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
696     }
697 
getResourcesForApplication( String appPackageName)698     @Override public Resources getResourcesForApplication(
699         String appPackageName) throws NameNotFoundException {
700         return getResourcesForApplication(
701             getApplicationInfo(appPackageName, 0));
702     }
703 
704     int mCachedSafeMode = -1;
isSafeMode()705     @Override public boolean isSafeMode() {
706         try {
707             if (mCachedSafeMode < 0) {
708                 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
709             }
710             return mCachedSafeMode != 0;
711         } catch (RemoteException e) {
712             throw new RuntimeException("Package manager has died", e);
713         }
714     }
715 
configurationChanged()716     static void configurationChanged() {
717         synchronized (sSync) {
718             sIconCache.clear();
719             sStringCache.clear();
720         }
721     }
722 
ApplicationPackageManager(ContextImpl context, IPackageManager pm)723     ApplicationPackageManager(ContextImpl context,
724                               IPackageManager pm) {
725         mContext = context;
726         mPM = pm;
727     }
728 
getCachedIcon(ResourceName name)729     private Drawable getCachedIcon(ResourceName name) {
730         synchronized (sSync) {
731             WeakReference<Drawable> wr = sIconCache.get(name);
732             if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
733                                    + name + ": " + wr);
734             if (wr != null) {   // we have the activity
735                 Drawable dr = wr.get();
736                 if (dr != null) {
737                     if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
738                                            + name + ": " + dr);
739                     return dr;
740                 }
741                 // our entry has been purged
742                 sIconCache.remove(name);
743             }
744         }
745         return null;
746     }
747 
putCachedIcon(ResourceName name, Drawable dr)748     private void putCachedIcon(ResourceName name, Drawable dr) {
749         synchronized (sSync) {
750             sIconCache.put(name, new WeakReference<Drawable>(dr));
751             if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
752                                    + name + ": " + dr);
753         }
754     }
755 
handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo)756     static final void handlePackageBroadcast(int cmd, String[] pkgList,
757                                              boolean hasPkgInfo) {
758         boolean immediateGc = false;
759         if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
760             immediateGc = true;
761         }
762         if (pkgList != null && (pkgList.length > 0)) {
763             boolean needCleanup = false;
764             for (String ssp : pkgList) {
765                 synchronized (sSync) {
766                     if (sIconCache.size() > 0) {
767                         Iterator<ResourceName> it = sIconCache.keySet().iterator();
768                         while (it.hasNext()) {
769                             ResourceName nm = it.next();
770                             if (nm.packageName.equals(ssp)) {
771                                 //Log.i(TAG, "Removing cached drawable for " + nm);
772                                 it.remove();
773                                 needCleanup = true;
774                             }
775                         }
776                     }
777                     if (sStringCache.size() > 0) {
778                         Iterator<ResourceName> it = sStringCache.keySet().iterator();
779                         while (it.hasNext()) {
780                             ResourceName nm = it.next();
781                             if (nm.packageName.equals(ssp)) {
782                                 //Log.i(TAG, "Removing cached string for " + nm);
783                                 it.remove();
784                                 needCleanup = true;
785                             }
786                         }
787                     }
788                 }
789             }
790             if (needCleanup || hasPkgInfo) {
791                 if (immediateGc) {
792                     // Schedule an immediate gc.
793                     Runtime.getRuntime().gc();
794                 } else {
795                     ActivityThread.currentActivityThread().scheduleGcIdler();
796                 }
797             }
798         }
799     }
800 
801     private static final class ResourceName {
802         final String packageName;
803         final int iconId;
804 
ResourceName(String _packageName, int _iconId)805         ResourceName(String _packageName, int _iconId) {
806             packageName = _packageName;
807             iconId = _iconId;
808         }
809 
ResourceName(ApplicationInfo aInfo, int _iconId)810         ResourceName(ApplicationInfo aInfo, int _iconId) {
811             this(aInfo.packageName, _iconId);
812         }
813 
ResourceName(ComponentInfo cInfo, int _iconId)814         ResourceName(ComponentInfo cInfo, int _iconId) {
815             this(cInfo.applicationInfo.packageName, _iconId);
816         }
817 
ResourceName(ResolveInfo rInfo, int _iconId)818         ResourceName(ResolveInfo rInfo, int _iconId) {
819             this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
820         }
821 
822         @Override
equals(Object o)823         public boolean equals(Object o) {
824             if (this == o) return true;
825             if (o == null || getClass() != o.getClass()) return false;
826 
827             ResourceName that = (ResourceName) o;
828 
829             if (iconId != that.iconId) return false;
830             return !(packageName != null ?
831                      !packageName.equals(that.packageName) : that.packageName != null);
832 
833         }
834 
835         @Override
hashCode()836         public int hashCode() {
837             int result;
838             result = packageName.hashCode();
839             result = 31 * result + iconId;
840             return result;
841         }
842 
843         @Override
toString()844         public String toString() {
845             return "{ResourceName " + packageName + " / " + iconId + "}";
846         }
847     }
848 
getCachedString(ResourceName name)849     private CharSequence getCachedString(ResourceName name) {
850         synchronized (sSync) {
851             WeakReference<CharSequence> wr = sStringCache.get(name);
852             if (wr != null) {   // we have the activity
853                 CharSequence cs = wr.get();
854                 if (cs != null) {
855                     return cs;
856                 }
857                 // our entry has been purged
858                 sStringCache.remove(name);
859             }
860         }
861         return null;
862     }
863 
putCachedString(ResourceName name, CharSequence cs)864     private void putCachedString(ResourceName name, CharSequence cs) {
865         synchronized (sSync) {
866             sStringCache.put(name, new WeakReference<CharSequence>(cs));
867         }
868     }
869 
870     @Override
getText(String packageName, int resid, ApplicationInfo appInfo)871     public CharSequence getText(String packageName, int resid,
872                                 ApplicationInfo appInfo) {
873         ResourceName name = new ResourceName(packageName, resid);
874         CharSequence text = getCachedString(name);
875         if (text != null) {
876             return text;
877         }
878         if (appInfo == null) {
879             try {
880                 appInfo = getApplicationInfo(packageName, 0);
881             } catch (NameNotFoundException e) {
882                 return null;
883             }
884         }
885         try {
886             Resources r = getResourcesForApplication(appInfo);
887             text = r.getText(resid);
888             putCachedString(name, text);
889             return text;
890         } catch (NameNotFoundException e) {
891             Log.w("PackageManager", "Failure retrieving resources for"
892                   + appInfo.packageName);
893         } catch (RuntimeException e) {
894             // If an exception was thrown, fall through to return
895             // default icon.
896             Log.w("PackageManager", "Failure retrieving text 0x"
897                   + Integer.toHexString(resid) + " in package "
898                   + packageName, e);
899         }
900         return null;
901     }
902 
903     @Override
getXml(String packageName, int resid, ApplicationInfo appInfo)904     public XmlResourceParser getXml(String packageName, int resid,
905                                     ApplicationInfo appInfo) {
906         if (appInfo == null) {
907             try {
908                 appInfo = getApplicationInfo(packageName, 0);
909             } catch (NameNotFoundException e) {
910                 return null;
911             }
912         }
913         try {
914             Resources r = getResourcesForApplication(appInfo);
915             return r.getXml(resid);
916         } catch (RuntimeException e) {
917             // If an exception was thrown, fall through to return
918             // default icon.
919             Log.w("PackageManager", "Failure retrieving xml 0x"
920                   + Integer.toHexString(resid) + " in package "
921                   + packageName, e);
922         } catch (NameNotFoundException e) {
923             Log.w("PackageManager", "Failure retrieving resources for "
924                   + appInfo.packageName);
925         }
926         return null;
927     }
928 
929     @Override
getApplicationLabel(ApplicationInfo info)930     public CharSequence getApplicationLabel(ApplicationInfo info) {
931         return info.loadLabel(this);
932     }
933 
934     @Override
installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName)935     public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
936                                String installerPackageName) {
937         try {
938             mPM.installPackage(packageURI, observer, flags, installerPackageName);
939         } catch (RemoteException e) {
940             // Should never happen!
941         }
942     }
943 
944     @Override
installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest)945     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
946             int flags, String installerPackageName, Uri verificationURI,
947             ManifestDigest manifestDigest) {
948         try {
949             mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
950                     verificationURI, manifestDigest);
951         } catch (RemoteException e) {
952             // Should never happen!
953         }
954     }
955 
956     @Override
verifyPendingInstall(int id, int response)957     public void verifyPendingInstall(int id, int response) {
958         try {
959             mPM.verifyPendingInstall(id, response);
960         } catch (RemoteException e) {
961             // Should never happen!
962         }
963     }
964 
965     @Override
setInstallerPackageName(String targetPackage, String installerPackageName)966     public void setInstallerPackageName(String targetPackage,
967             String installerPackageName) {
968         try {
969             mPM.setInstallerPackageName(targetPackage, installerPackageName);
970         } catch (RemoteException e) {
971             // Should never happen!
972         }
973     }
974 
975     @Override
movePackage(String packageName, IPackageMoveObserver observer, int flags)976     public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
977         try {
978             mPM.movePackage(packageName, observer, flags);
979         } catch (RemoteException e) {
980             // Should never happen!
981         }
982     }
983 
984     @Override
getInstallerPackageName(String packageName)985     public String getInstallerPackageName(String packageName) {
986         try {
987             return mPM.getInstallerPackageName(packageName);
988         } catch (RemoteException e) {
989             // Should never happen!
990         }
991         return null;
992     }
993 
994     @Override
deletePackage(String packageName, IPackageDeleteObserver observer, int flags)995     public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
996         try {
997             mPM.deletePackage(packageName, observer, flags);
998         } catch (RemoteException e) {
999             // Should never happen!
1000         }
1001     }
1002     @Override
clearApplicationUserData(String packageName, IPackageDataObserver observer)1003     public void clearApplicationUserData(String packageName,
1004                                          IPackageDataObserver observer) {
1005         try {
1006             mPM.clearApplicationUserData(packageName, observer);
1007         } catch (RemoteException e) {
1008             // Should never happen!
1009         }
1010     }
1011     @Override
deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer)1012     public void deleteApplicationCacheFiles(String packageName,
1013                                             IPackageDataObserver observer) {
1014         try {
1015             mPM.deleteApplicationCacheFiles(packageName, observer);
1016         } catch (RemoteException e) {
1017             // Should never happen!
1018         }
1019     }
1020     @Override
freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer)1021     public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
1022         try {
1023             mPM.freeStorageAndNotify(idealStorageSize, observer);
1024         } catch (RemoteException e) {
1025             // Should never happen!
1026         }
1027     }
1028 
1029     @Override
freeStorage(long freeStorageSize, IntentSender pi)1030     public void freeStorage(long freeStorageSize, IntentSender pi) {
1031         try {
1032             mPM.freeStorage(freeStorageSize, pi);
1033         } catch (RemoteException e) {
1034             // Should never happen!
1035         }
1036     }
1037 
1038     @Override
getPackageSizeInfo(String packageName, IPackageStatsObserver observer)1039     public void getPackageSizeInfo(String packageName,
1040                                    IPackageStatsObserver observer) {
1041         try {
1042             mPM.getPackageSizeInfo(packageName, observer);
1043         } catch (RemoteException e) {
1044             // Should never happen!
1045         }
1046     }
1047     @Override
addPackageToPreferred(String packageName)1048     public void addPackageToPreferred(String packageName) {
1049         try {
1050             mPM.addPackageToPreferred(packageName);
1051         } catch (RemoteException e) {
1052             // Should never happen!
1053         }
1054     }
1055 
1056     @Override
removePackageFromPreferred(String packageName)1057     public void removePackageFromPreferred(String packageName) {
1058         try {
1059             mPM.removePackageFromPreferred(packageName);
1060         } catch (RemoteException e) {
1061             // Should never happen!
1062         }
1063     }
1064 
1065     @Override
getPreferredPackages(int flags)1066     public List<PackageInfo> getPreferredPackages(int flags) {
1067         try {
1068             return mPM.getPreferredPackages(flags);
1069         } catch (RemoteException e) {
1070             // Should never happen!
1071         }
1072         return new ArrayList<PackageInfo>();
1073     }
1074 
1075     @Override
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)1076     public void addPreferredActivity(IntentFilter filter,
1077                                      int match, ComponentName[] set, ComponentName activity) {
1078         try {
1079             mPM.addPreferredActivity(filter, match, set, activity);
1080         } catch (RemoteException e) {
1081             // Should never happen!
1082         }
1083     }
1084 
1085     @Override
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)1086     public void replacePreferredActivity(IntentFilter filter,
1087                                          int match, ComponentName[] set, ComponentName activity) {
1088         try {
1089             mPM.replacePreferredActivity(filter, match, set, activity);
1090         } catch (RemoteException e) {
1091             // Should never happen!
1092         }
1093     }
1094 
1095     @Override
clearPackagePreferredActivities(String packageName)1096     public void clearPackagePreferredActivities(String packageName) {
1097         try {
1098             mPM.clearPackagePreferredActivities(packageName);
1099         } catch (RemoteException e) {
1100             // Should never happen!
1101         }
1102     }
1103 
1104     @Override
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)1105     public int getPreferredActivities(List<IntentFilter> outFilters,
1106                                       List<ComponentName> outActivities, String packageName) {
1107         try {
1108             return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1109         } catch (RemoteException e) {
1110             // Should never happen!
1111         }
1112         return 0;
1113     }
1114 
1115     @Override
setComponentEnabledSetting(ComponentName componentName, int newState, int flags)1116     public void setComponentEnabledSetting(ComponentName componentName,
1117                                            int newState, int flags) {
1118         try {
1119             mPM.setComponentEnabledSetting(componentName, newState, flags);
1120         } catch (RemoteException e) {
1121             // Should never happen!
1122         }
1123     }
1124 
1125     @Override
getComponentEnabledSetting(ComponentName componentName)1126     public int getComponentEnabledSetting(ComponentName componentName) {
1127         try {
1128             return mPM.getComponentEnabledSetting(componentName);
1129         } catch (RemoteException e) {
1130             // Should never happen!
1131         }
1132         return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1133     }
1134 
1135     @Override
setApplicationEnabledSetting(String packageName, int newState, int flags)1136     public void setApplicationEnabledSetting(String packageName,
1137                                              int newState, int flags) {
1138         try {
1139             mPM.setApplicationEnabledSetting(packageName, newState, flags);
1140         } catch (RemoteException e) {
1141             // Should never happen!
1142         }
1143     }
1144 
1145     @Override
getApplicationEnabledSetting(String packageName)1146     public int getApplicationEnabledSetting(String packageName) {
1147         try {
1148             return mPM.getApplicationEnabledSetting(packageName);
1149         } catch (RemoteException e) {
1150             // Should never happen!
1151         }
1152         return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1153     }
1154 
1155     // Multi-user support
1156 
1157     /**
1158      * @hide
1159      */
1160     @Override
createUser(String name, int flags)1161     public UserInfo createUser(String name, int flags) {
1162         try {
1163             return mPM.createUser(name, flags);
1164         } catch (RemoteException e) {
1165             // Should never happen!
1166         }
1167         return null;
1168     }
1169 
1170     /**
1171      * @hide
1172      */
1173     @Override
getUsers()1174     public List<UserInfo> getUsers() {
1175         // TODO:
1176         // Dummy code, always returns just the primary user
1177         ArrayList<UserInfo> users = new ArrayList<UserInfo>();
1178         UserInfo primary = new UserInfo(0, "Root!",
1179                 UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
1180         users.add(primary);
1181         return users;
1182     }
1183 
1184     /**
1185      * @hide
1186      */
1187     @Override
removeUser(int id)1188     public boolean removeUser(int id) {
1189         try {
1190             return mPM.removeUser(id);
1191         } catch (RemoteException e) {
1192             return false;
1193         }
1194     }
1195 
1196     /**
1197      * @hide
1198      */
1199     @Override
updateUserName(int id, String name)1200     public void updateUserName(int id, String name) {
1201         // TODO:
1202     }
1203 
1204     /**
1205      * @hide
1206      */
1207     @Override
updateUserFlags(int id, int flags)1208     public void updateUserFlags(int id, int flags) {
1209         // TODO:
1210     }
1211 
1212     /**
1213      * @hide
1214      */
1215     @Override
getVerifierDeviceIdentity()1216     public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1217         try {
1218             return mPM.getVerifierDeviceIdentity();
1219         } catch (RemoteException e) {
1220             // Should never happen!
1221         }
1222         return null;
1223     }
1224 
1225     private final ContextImpl mContext;
1226     private final IPackageManager mPM;
1227 
1228     private static final Object sSync = new Object();
1229     private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
1230             = new HashMap<ResourceName, WeakReference<Drawable> >();
1231     private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
1232             = new HashMap<ResourceName, WeakReference<CharSequence> >();
1233 }
1234