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