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