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