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