blob: 50e56c7926f3cee3105f39d66321ef374a0883ae [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);
Joe Onorato08f16542011-01-20 11:49:56 -0800573 } catch (Resources.NotFoundException e) {
574 Log.w("PackageManager", "Failure retrieving resources for"
575 + appInfo.packageName + ": " + e.getMessage());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800576 } catch (RuntimeException e) {
577 // If an exception was thrown, fall through to return
578 // default icon.
579 Log.w("PackageManager", "Failure retrieving icon 0x"
580 + Integer.toHexString(resid) + " in package "
581 + packageName, e);
582 }
583 return null;
584 }
585
586 @Override public Drawable getActivityIcon(ComponentName activityName)
587 throws NameNotFoundException {
588 return getActivityInfo(activityName, 0).loadIcon(this);
589 }
590
591 @Override public Drawable getActivityIcon(Intent intent)
592 throws NameNotFoundException {
593 if (intent.getComponent() != null) {
594 return getActivityIcon(intent.getComponent());
595 }
596
597 ResolveInfo info = resolveActivity(
598 intent, PackageManager.MATCH_DEFAULT_ONLY);
599 if (info != null) {
600 return info.activityInfo.loadIcon(this);
601 }
602
603 throw new NameNotFoundException(intent.toURI());
604 }
605
606 @Override public Drawable getDefaultActivityIcon() {
607 return Resources.getSystem().getDrawable(
608 com.android.internal.R.drawable.sym_def_app_icon);
609 }
610
611 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
612 return info.loadIcon(this);
613 }
614
615 @Override public Drawable getApplicationIcon(String packageName)
616 throws NameNotFoundException {
617 return getApplicationIcon(getApplicationInfo(packageName, 0));
618 }
619
620 @Override
621 public Drawable getActivityLogo(ComponentName activityName)
622 throws NameNotFoundException {
623 return getActivityInfo(activityName, 0).loadLogo(this);
624 }
625
626 @Override
627 public Drawable getActivityLogo(Intent intent)
628 throws NameNotFoundException {
629 if (intent.getComponent() != null) {
630 return getActivityLogo(intent.getComponent());
631 }
632
633 ResolveInfo info = resolveActivity(
634 intent, PackageManager.MATCH_DEFAULT_ONLY);
635 if (info != null) {
636 return info.activityInfo.loadLogo(this);
637 }
638
639 throw new NameNotFoundException(intent.toUri(0));
640 }
641
642 @Override
643 public Drawable getApplicationLogo(ApplicationInfo info) {
644 return info.loadLogo(this);
645 }
646
647 @Override
648 public Drawable getApplicationLogo(String packageName)
649 throws NameNotFoundException {
650 return getApplicationLogo(getApplicationInfo(packageName, 0));
651 }
652
653 @Override public Resources getResourcesForActivity(
654 ComponentName activityName) throws NameNotFoundException {
655 return getResourcesForApplication(
656 getActivityInfo(activityName, 0).applicationInfo);
657 }
658
659 @Override public Resources getResourcesForApplication(
660 ApplicationInfo app) throws NameNotFoundException {
661 if (app.packageName.equals("system")) {
662 return mContext.mMainThread.getSystemContext().getResources();
663 }
664 Resources r = mContext.mMainThread.getTopLevelResources(
665 app.uid == Process.myUid() ? app.sourceDir
666 : app.publicSourceDir, mContext.mPackageInfo);
667 if (r != null) {
668 return r;
669 }
670 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
671 }
672
673 @Override public Resources getResourcesForApplication(
674 String appPackageName) throws NameNotFoundException {
675 return getResourcesForApplication(
676 getApplicationInfo(appPackageName, 0));
677 }
678
679 int mCachedSafeMode = -1;
680 @Override public boolean isSafeMode() {
681 try {
682 if (mCachedSafeMode < 0) {
683 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
684 }
685 return mCachedSafeMode != 0;
686 } catch (RemoteException e) {
687 throw new RuntimeException("Package manager has died", e);
688 }
689 }
690
691 static void configurationChanged() {
692 synchronized (sSync) {
693 sIconCache.clear();
694 sStringCache.clear();
695 }
696 }
697
698 ApplicationPackageManager(ContextImpl context,
699 IPackageManager pm) {
700 mContext = context;
701 mPM = pm;
702 }
703
704 private Drawable getCachedIcon(ResourceName name) {
705 synchronized (sSync) {
706 WeakReference<Drawable> wr = sIconCache.get(name);
707 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
708 + name + ": " + wr);
709 if (wr != null) { // we have the activity
710 Drawable dr = wr.get();
711 if (dr != null) {
712 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
713 + name + ": " + dr);
714 return dr;
715 }
716 // our entry has been purged
717 sIconCache.remove(name);
718 }
719 }
720 return null;
721 }
722
723 private void putCachedIcon(ResourceName name, Drawable dr) {
724 synchronized (sSync) {
725 sIconCache.put(name, new WeakReference<Drawable>(dr));
726 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
727 + name + ": " + dr);
728 }
729 }
730
731 static final void handlePackageBroadcast(int cmd, String[] pkgList,
732 boolean hasPkgInfo) {
733 boolean immediateGc = false;
734 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
735 immediateGc = true;
736 }
737 if (pkgList != null && (pkgList.length > 0)) {
738 boolean needCleanup = false;
739 for (String ssp : pkgList) {
740 synchronized (sSync) {
741 if (sIconCache.size() > 0) {
742 Iterator<ResourceName> it = sIconCache.keySet().iterator();
743 while (it.hasNext()) {
744 ResourceName nm = it.next();
745 if (nm.packageName.equals(ssp)) {
746 //Log.i(TAG, "Removing cached drawable for " + nm);
747 it.remove();
748 needCleanup = true;
749 }
750 }
751 }
752 if (sStringCache.size() > 0) {
753 Iterator<ResourceName> it = sStringCache.keySet().iterator();
754 while (it.hasNext()) {
755 ResourceName nm = it.next();
756 if (nm.packageName.equals(ssp)) {
757 //Log.i(TAG, "Removing cached string for " + nm);
758 it.remove();
759 needCleanup = true;
760 }
761 }
762 }
763 }
764 }
765 if (needCleanup || hasPkgInfo) {
766 if (immediateGc) {
767 // Schedule an immediate gc.
768 Runtime.getRuntime().gc();
769 } else {
770 ActivityThread.currentActivityThread().scheduleGcIdler();
771 }
772 }
773 }
774 }
775
776 private static final class ResourceName {
777 final String packageName;
778 final int iconId;
779
780 ResourceName(String _packageName, int _iconId) {
781 packageName = _packageName;
782 iconId = _iconId;
783 }
784
785 ResourceName(ApplicationInfo aInfo, int _iconId) {
786 this(aInfo.packageName, _iconId);
787 }
788
789 ResourceName(ComponentInfo cInfo, int _iconId) {
790 this(cInfo.applicationInfo.packageName, _iconId);
791 }
792
793 ResourceName(ResolveInfo rInfo, int _iconId) {
794 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
795 }
796
797 @Override
798 public boolean equals(Object o) {
799 if (this == o) return true;
800 if (o == null || getClass() != o.getClass()) return false;
801
802 ResourceName that = (ResourceName) o;
803
804 if (iconId != that.iconId) return false;
805 return !(packageName != null ?
806 !packageName.equals(that.packageName) : that.packageName != null);
807
808 }
809
810 @Override
811 public int hashCode() {
812 int result;
813 result = packageName.hashCode();
814 result = 31 * result + iconId;
815 return result;
816 }
817
818 @Override
819 public String toString() {
820 return "{ResourceName " + packageName + " / " + iconId + "}";
821 }
822 }
823
824 private CharSequence getCachedString(ResourceName name) {
825 synchronized (sSync) {
826 WeakReference<CharSequence> wr = sStringCache.get(name);
827 if (wr != null) { // we have the activity
828 CharSequence cs = wr.get();
829 if (cs != null) {
830 return cs;
831 }
832 // our entry has been purged
833 sStringCache.remove(name);
834 }
835 }
836 return null;
837 }
838
839 private void putCachedString(ResourceName name, CharSequence cs) {
840 synchronized (sSync) {
841 sStringCache.put(name, new WeakReference<CharSequence>(cs));
842 }
843 }
844
845 @Override
846 public CharSequence getText(String packageName, int resid,
847 ApplicationInfo appInfo) {
848 ResourceName name = new ResourceName(packageName, resid);
849 CharSequence text = getCachedString(name);
850 if (text != null) {
851 return text;
852 }
853 if (appInfo == null) {
854 try {
855 appInfo = getApplicationInfo(packageName, 0);
856 } catch (NameNotFoundException e) {
857 return null;
858 }
859 }
860 try {
861 Resources r = getResourcesForApplication(appInfo);
862 text = r.getText(resid);
863 putCachedString(name, text);
864 return text;
865 } catch (NameNotFoundException e) {
866 Log.w("PackageManager", "Failure retrieving resources for"
867 + appInfo.packageName);
868 } catch (RuntimeException e) {
869 // If an exception was thrown, fall through to return
870 // default icon.
871 Log.w("PackageManager", "Failure retrieving text 0x"
872 + Integer.toHexString(resid) + " in package "
873 + packageName, e);
874 }
875 return null;
876 }
877
878 @Override
879 public XmlResourceParser getXml(String packageName, int resid,
880 ApplicationInfo appInfo) {
881 if (appInfo == null) {
882 try {
883 appInfo = getApplicationInfo(packageName, 0);
884 } catch (NameNotFoundException e) {
885 return null;
886 }
887 }
888 try {
889 Resources r = getResourcesForApplication(appInfo);
890 return r.getXml(resid);
891 } catch (RuntimeException e) {
892 // If an exception was thrown, fall through to return
893 // default icon.
894 Log.w("PackageManager", "Failure retrieving xml 0x"
895 + Integer.toHexString(resid) + " in package "
896 + packageName, e);
897 } catch (NameNotFoundException e) {
Alon Albert3fa51e32010-11-11 09:24:04 -0800898 Log.w("PackageManager", "Failure retrieving resources for "
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800899 + appInfo.packageName);
900 }
901 return null;
902 }
903
904 @Override
905 public CharSequence getApplicationLabel(ApplicationInfo info) {
906 return info.loadLabel(this);
907 }
908
909 @Override
910 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
911 String installerPackageName) {
912 try {
913 mPM.installPackage(packageURI, observer, flags, installerPackageName);
914 } catch (RemoteException e) {
915 // Should never happen!
916 }
917 }
918
919 @Override
Dianne Hackborn880119b2010-11-18 22:26:40 -0800920 public void setInstallerPackageName(String targetPackage,
921 String installerPackageName) {
922 try {
923 mPM.setInstallerPackageName(targetPackage, installerPackageName);
924 } catch (RemoteException e) {
925 // Should never happen!
926 }
927 }
928
929 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800930 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
931 try {
932 mPM.movePackage(packageName, observer, flags);
933 } catch (RemoteException e) {
934 // Should never happen!
935 }
936 }
937
938 @Override
939 public String getInstallerPackageName(String packageName) {
940 try {
941 return mPM.getInstallerPackageName(packageName);
942 } catch (RemoteException e) {
943 // Should never happen!
944 }
945 return null;
946 }
947
948 @Override
949 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
950 try {
951 mPM.deletePackage(packageName, observer, flags);
952 } catch (RemoteException e) {
953 // Should never happen!
954 }
955 }
956 @Override
957 public void clearApplicationUserData(String packageName,
958 IPackageDataObserver observer) {
959 try {
960 mPM.clearApplicationUserData(packageName, observer);
961 } catch (RemoteException e) {
962 // Should never happen!
963 }
964 }
965 @Override
966 public void deleteApplicationCacheFiles(String packageName,
967 IPackageDataObserver observer) {
968 try {
969 mPM.deleteApplicationCacheFiles(packageName, observer);
970 } catch (RemoteException e) {
971 // Should never happen!
972 }
973 }
974 @Override
975 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
976 try {
977 mPM.freeStorageAndNotify(idealStorageSize, observer);
978 } catch (RemoteException e) {
979 // Should never happen!
980 }
981 }
982
983 @Override
984 public void freeStorage(long freeStorageSize, IntentSender pi) {
985 try {
986 mPM.freeStorage(freeStorageSize, pi);
987 } catch (RemoteException e) {
988 // Should never happen!
989 }
990 }
991
992 @Override
993 public void getPackageSizeInfo(String packageName,
994 IPackageStatsObserver observer) {
995 try {
996 mPM.getPackageSizeInfo(packageName, observer);
997 } catch (RemoteException e) {
998 // Should never happen!
999 }
1000 }
1001 @Override
1002 public void addPackageToPreferred(String packageName) {
1003 try {
1004 mPM.addPackageToPreferred(packageName);
1005 } catch (RemoteException e) {
1006 // Should never happen!
1007 }
1008 }
1009
1010 @Override
1011 public void removePackageFromPreferred(String packageName) {
1012 try {
1013 mPM.removePackageFromPreferred(packageName);
1014 } catch (RemoteException e) {
1015 // Should never happen!
1016 }
1017 }
1018
1019 @Override
1020 public List<PackageInfo> getPreferredPackages(int flags) {
1021 try {
1022 return mPM.getPreferredPackages(flags);
1023 } catch (RemoteException e) {
1024 // Should never happen!
1025 }
1026 return new ArrayList<PackageInfo>();
1027 }
1028
1029 @Override
1030 public void addPreferredActivity(IntentFilter filter,
1031 int match, ComponentName[] set, ComponentName activity) {
1032 try {
1033 mPM.addPreferredActivity(filter, match, set, activity);
1034 } catch (RemoteException e) {
1035 // Should never happen!
1036 }
1037 }
1038
1039 @Override
1040 public void replacePreferredActivity(IntentFilter filter,
1041 int match, ComponentName[] set, ComponentName activity) {
1042 try {
1043 mPM.replacePreferredActivity(filter, match, set, activity);
1044 } catch (RemoteException e) {
1045 // Should never happen!
1046 }
1047 }
1048
1049 @Override
1050 public void clearPackagePreferredActivities(String packageName) {
1051 try {
1052 mPM.clearPackagePreferredActivities(packageName);
1053 } catch (RemoteException e) {
1054 // Should never happen!
1055 }
1056 }
1057
1058 @Override
1059 public int getPreferredActivities(List<IntentFilter> outFilters,
1060 List<ComponentName> outActivities, String packageName) {
1061 try {
1062 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1063 } catch (RemoteException e) {
1064 // Should never happen!
1065 }
1066 return 0;
1067 }
1068
1069 @Override
1070 public void setComponentEnabledSetting(ComponentName componentName,
1071 int newState, int flags) {
1072 try {
1073 mPM.setComponentEnabledSetting(componentName, newState, flags);
1074 } catch (RemoteException e) {
1075 // Should never happen!
1076 }
1077 }
1078
1079 @Override
1080 public int getComponentEnabledSetting(ComponentName componentName) {
1081 try {
1082 return mPM.getComponentEnabledSetting(componentName);
1083 } catch (RemoteException e) {
1084 // Should never happen!
1085 }
1086 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1087 }
1088
1089 @Override
1090 public void setApplicationEnabledSetting(String packageName,
1091 int newState, int flags) {
1092 try {
1093 mPM.setApplicationEnabledSetting(packageName, newState, flags);
1094 } catch (RemoteException e) {
1095 // Should never happen!
1096 }
1097 }
1098
1099 @Override
1100 public int getApplicationEnabledSetting(String packageName) {
1101 try {
1102 return mPM.getApplicationEnabledSetting(packageName);
1103 } catch (RemoteException e) {
1104 // Should never happen!
1105 }
1106 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1107 }
1108
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001109 private final ContextImpl mContext;
1110 private final IPackageManager mPM;
1111
1112 private static final Object sSync = new Object();
1113 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
1114 = new HashMap<ResourceName, WeakReference<Drawable> >();
1115 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
1116 = new HashMap<ResourceName, WeakReference<CharSequence> >();
1117}