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