ApplicationPackageManager.java revision 5ab2157bf1f105b02d3e2913cd3a33f9765b74ca
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; 37import android.content.pm.ParceledListSlice; 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.pm.UserInfo; 44import android.content.pm.ManifestDigest; 45import android.content.res.Resources; 46import android.content.res.XmlResourceParser; 47import android.graphics.drawable.Drawable; 48import android.net.Uri; 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 installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, 945 int flags, String installerPackageName, Uri verificationURI, 946 ManifestDigest manifestDigest) { 947 try { 948 mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName, 949 verificationURI, manifestDigest); 950 } catch (RemoteException e) { 951 // Should never happen! 952 } 953 } 954 955 @Override 956 public void verifyPendingInstall(int id, boolean verified, String failureMessage) { 957 try { 958 mPM.verifyPendingInstall(id, verified, failureMessage); 959 } catch (RemoteException e) { 960 // Should never happen! 961 } 962 } 963 964 @Override 965 public void setInstallerPackageName(String targetPackage, 966 String installerPackageName) { 967 try { 968 mPM.setInstallerPackageName(targetPackage, installerPackageName); 969 } catch (RemoteException e) { 970 // Should never happen! 971 } 972 } 973 974 @Override 975 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) { 976 try { 977 mPM.movePackage(packageName, observer, flags); 978 } catch (RemoteException e) { 979 // Should never happen! 980 } 981 } 982 983 @Override 984 public String getInstallerPackageName(String packageName) { 985 try { 986 return mPM.getInstallerPackageName(packageName); 987 } catch (RemoteException e) { 988 // Should never happen! 989 } 990 return null; 991 } 992 993 @Override 994 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) { 995 try { 996 mPM.deletePackage(packageName, observer, flags); 997 } catch (RemoteException e) { 998 // Should never happen! 999 } 1000 } 1001 @Override 1002 public void clearApplicationUserData(String packageName, 1003 IPackageDataObserver observer) { 1004 try { 1005 mPM.clearApplicationUserData(packageName, observer); 1006 } catch (RemoteException e) { 1007 // Should never happen! 1008 } 1009 } 1010 @Override 1011 public void deleteApplicationCacheFiles(String packageName, 1012 IPackageDataObserver observer) { 1013 try { 1014 mPM.deleteApplicationCacheFiles(packageName, observer); 1015 } catch (RemoteException e) { 1016 // Should never happen! 1017 } 1018 } 1019 @Override 1020 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) { 1021 try { 1022 mPM.freeStorageAndNotify(idealStorageSize, observer); 1023 } catch (RemoteException e) { 1024 // Should never happen! 1025 } 1026 } 1027 1028 @Override 1029 public void freeStorage(long freeStorageSize, IntentSender pi) { 1030 try { 1031 mPM.freeStorage(freeStorageSize, pi); 1032 } catch (RemoteException e) { 1033 // Should never happen! 1034 } 1035 } 1036 1037 @Override 1038 public void getPackageSizeInfo(String packageName, 1039 IPackageStatsObserver observer) { 1040 try { 1041 mPM.getPackageSizeInfo(packageName, observer); 1042 } catch (RemoteException e) { 1043 // Should never happen! 1044 } 1045 } 1046 @Override 1047 public void addPackageToPreferred(String packageName) { 1048 try { 1049 mPM.addPackageToPreferred(packageName); 1050 } catch (RemoteException e) { 1051 // Should never happen! 1052 } 1053 } 1054 1055 @Override 1056 public void removePackageFromPreferred(String packageName) { 1057 try { 1058 mPM.removePackageFromPreferred(packageName); 1059 } catch (RemoteException e) { 1060 // Should never happen! 1061 } 1062 } 1063 1064 @Override 1065 public List<PackageInfo> getPreferredPackages(int flags) { 1066 try { 1067 return mPM.getPreferredPackages(flags); 1068 } catch (RemoteException e) { 1069 // Should never happen! 1070 } 1071 return new ArrayList<PackageInfo>(); 1072 } 1073 1074 @Override 1075 public void addPreferredActivity(IntentFilter filter, 1076 int match, ComponentName[] set, ComponentName activity) { 1077 try { 1078 mPM.addPreferredActivity(filter, match, set, activity); 1079 } catch (RemoteException e) { 1080 // Should never happen! 1081 } 1082 } 1083 1084 @Override 1085 public void replacePreferredActivity(IntentFilter filter, 1086 int match, ComponentName[] set, ComponentName activity) { 1087 try { 1088 mPM.replacePreferredActivity(filter, match, set, activity); 1089 } catch (RemoteException e) { 1090 // Should never happen! 1091 } 1092 } 1093 1094 @Override 1095 public void clearPackagePreferredActivities(String packageName) { 1096 try { 1097 mPM.clearPackagePreferredActivities(packageName); 1098 } catch (RemoteException e) { 1099 // Should never happen! 1100 } 1101 } 1102 1103 @Override 1104 public int getPreferredActivities(List<IntentFilter> outFilters, 1105 List<ComponentName> outActivities, String packageName) { 1106 try { 1107 return mPM.getPreferredActivities(outFilters, outActivities, packageName); 1108 } catch (RemoteException e) { 1109 // Should never happen! 1110 } 1111 return 0; 1112 } 1113 1114 @Override 1115 public void setComponentEnabledSetting(ComponentName componentName, 1116 int newState, int flags) { 1117 try { 1118 mPM.setComponentEnabledSetting(componentName, newState, flags); 1119 } catch (RemoteException e) { 1120 // Should never happen! 1121 } 1122 } 1123 1124 @Override 1125 public int getComponentEnabledSetting(ComponentName componentName) { 1126 try { 1127 return mPM.getComponentEnabledSetting(componentName); 1128 } catch (RemoteException e) { 1129 // Should never happen! 1130 } 1131 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 1132 } 1133 1134 @Override 1135 public void setApplicationEnabledSetting(String packageName, 1136 int newState, int flags) { 1137 try { 1138 mPM.setApplicationEnabledSetting(packageName, newState, flags); 1139 } catch (RemoteException e) { 1140 // Should never happen! 1141 } 1142 } 1143 1144 @Override 1145 public int getApplicationEnabledSetting(String packageName) { 1146 try { 1147 return mPM.getApplicationEnabledSetting(packageName); 1148 } catch (RemoteException e) { 1149 // Should never happen! 1150 } 1151 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 1152 } 1153 1154 // Multi-user support 1155 1156 /** 1157 * @hide 1158 */ 1159 @Override 1160 public UserInfo createUser(String name, int flags) { 1161 try { 1162 return mPM.createUser(name, flags); 1163 } catch (RemoteException e) { 1164 // Should never happen! 1165 } 1166 return null; 1167 } 1168 1169 /** 1170 * @hide 1171 */ 1172 @Override 1173 public List<UserInfo> getUsers() { 1174 // TODO: 1175 // Dummy code, always returns just the primary user 1176 ArrayList<UserInfo> users = new ArrayList<UserInfo>(); 1177 UserInfo primary = new UserInfo(0, "Root!", 1178 UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY); 1179 users.add(primary); 1180 return users; 1181 } 1182 1183 /** 1184 * @hide 1185 */ 1186 @Override 1187 public boolean removeUser(int id) { 1188 try { 1189 return mPM.removeUser(id); 1190 } catch (RemoteException e) { 1191 return false; 1192 } 1193 } 1194 1195 /** 1196 * @hide 1197 */ 1198 @Override 1199 public void updateUserName(int id, String name) { 1200 // TODO: 1201 } 1202 1203 /** 1204 * @hide 1205 */ 1206 @Override 1207 public void updateUserFlags(int id, int flags) { 1208 // TODO: 1209 } 1210 1211 private final ContextImpl mContext; 1212 private final IPackageManager mPM; 1213 1214 private static final Object sSync = new Object(); 1215 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache 1216 = new HashMap<ResourceName, WeakReference<Drawable> >(); 1217 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache 1218 = new HashMap<ResourceName, WeakReference<CharSequence> >(); 1219} 1220