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