ApplicationPackageManager.java revision d9ef3e5495db1c46bcfcc1a2d4386af8db6deb0c
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 extendVerificationTimeout(int id, int verificationCodeAtTimeout, 1010 long millisecondsToDelay) { 1011 try { 1012 mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay); 1013 } catch (RemoteException e) { 1014 // Should never happen! 1015 } 1016 } 1017 1018 @Override 1019 public void setInstallerPackageName(String targetPackage, 1020 String installerPackageName) { 1021 try { 1022 mPM.setInstallerPackageName(targetPackage, installerPackageName); 1023 } catch (RemoteException e) { 1024 // Should never happen! 1025 } 1026 } 1027 1028 @Override 1029 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) { 1030 try { 1031 mPM.movePackage(packageName, observer, flags); 1032 } catch (RemoteException e) { 1033 // Should never happen! 1034 } 1035 } 1036 1037 @Override 1038 public String getInstallerPackageName(String packageName) { 1039 try { 1040 return mPM.getInstallerPackageName(packageName); 1041 } catch (RemoteException e) { 1042 // Should never happen! 1043 } 1044 return null; 1045 } 1046 1047 @Override 1048 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) { 1049 try { 1050 mPM.deletePackage(packageName, observer, flags); 1051 } catch (RemoteException e) { 1052 // Should never happen! 1053 } 1054 } 1055 @Override 1056 public void clearApplicationUserData(String packageName, 1057 IPackageDataObserver observer) { 1058 try { 1059 mPM.clearApplicationUserData(packageName, observer, UserHandle.myUserId()); 1060 } catch (RemoteException e) { 1061 // Should never happen! 1062 } 1063 } 1064 @Override 1065 public void deleteApplicationCacheFiles(String packageName, 1066 IPackageDataObserver observer) { 1067 try { 1068 mPM.deleteApplicationCacheFiles(packageName, observer); 1069 } catch (RemoteException e) { 1070 // Should never happen! 1071 } 1072 } 1073 @Override 1074 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) { 1075 try { 1076 mPM.freeStorageAndNotify(idealStorageSize, observer); 1077 } catch (RemoteException e) { 1078 // Should never happen! 1079 } 1080 } 1081 1082 @Override 1083 public void freeStorage(long freeStorageSize, IntentSender pi) { 1084 try { 1085 mPM.freeStorage(freeStorageSize, pi); 1086 } catch (RemoteException e) { 1087 // Should never happen! 1088 } 1089 } 1090 1091 @Override 1092 public void getPackageSizeInfo(String packageName, int userHandle, 1093 IPackageStatsObserver observer) { 1094 try { 1095 mPM.getPackageSizeInfo(packageName, userHandle, observer); 1096 } catch (RemoteException e) { 1097 // Should never happen! 1098 } 1099 } 1100 @Override 1101 public void addPackageToPreferred(String packageName) { 1102 try { 1103 mPM.addPackageToPreferred(packageName); 1104 } catch (RemoteException e) { 1105 // Should never happen! 1106 } 1107 } 1108 1109 @Override 1110 public void removePackageFromPreferred(String packageName) { 1111 try { 1112 mPM.removePackageFromPreferred(packageName); 1113 } catch (RemoteException e) { 1114 // Should never happen! 1115 } 1116 } 1117 1118 @Override 1119 public List<PackageInfo> getPreferredPackages(int flags) { 1120 try { 1121 return mPM.getPreferredPackages(flags); 1122 } catch (RemoteException e) { 1123 // Should never happen! 1124 } 1125 return new ArrayList<PackageInfo>(); 1126 } 1127 1128 @Override 1129 public void addPreferredActivity(IntentFilter filter, 1130 int match, ComponentName[] set, ComponentName activity) { 1131 try { 1132 mPM.addPreferredActivity(filter, match, set, activity, UserHandle.myUserId()); 1133 } catch (RemoteException e) { 1134 // Should never happen! 1135 } 1136 } 1137 1138 @Override 1139 public void addPreferredActivity(IntentFilter filter, int match, 1140 ComponentName[] set, ComponentName activity, int userId) { 1141 try { 1142 mPM.addPreferredActivity(filter, match, set, activity, userId); 1143 } catch (RemoteException e) { 1144 // Should never happen! 1145 } 1146 } 1147 1148 @Override 1149 public void replacePreferredActivity(IntentFilter filter, 1150 int match, ComponentName[] set, ComponentName activity) { 1151 try { 1152 mPM.replacePreferredActivity(filter, match, set, activity); 1153 } catch (RemoteException e) { 1154 // Should never happen! 1155 } 1156 } 1157 1158 @Override 1159 public void clearPackagePreferredActivities(String packageName) { 1160 try { 1161 mPM.clearPackagePreferredActivities(packageName); 1162 } catch (RemoteException e) { 1163 // Should never happen! 1164 } 1165 } 1166 1167 @Override 1168 public int getPreferredActivities(List<IntentFilter> outFilters, 1169 List<ComponentName> outActivities, String packageName) { 1170 try { 1171 return mPM.getPreferredActivities(outFilters, outActivities, packageName); 1172 } catch (RemoteException e) { 1173 // Should never happen! 1174 } 1175 return 0; 1176 } 1177 1178 @Override 1179 public void setComponentEnabledSetting(ComponentName componentName, 1180 int newState, int flags) { 1181 try { 1182 mPM.setComponentEnabledSetting(componentName, newState, flags, UserHandle.myUserId()); 1183 } catch (RemoteException e) { 1184 // Should never happen! 1185 } 1186 } 1187 1188 @Override 1189 public int getComponentEnabledSetting(ComponentName componentName) { 1190 try { 1191 return mPM.getComponentEnabledSetting(componentName, UserHandle.myUserId()); 1192 } catch (RemoteException e) { 1193 // Should never happen! 1194 } 1195 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 1196 } 1197 1198 @Override 1199 public void setApplicationEnabledSetting(String packageName, 1200 int newState, int flags) { 1201 try { 1202 mPM.setApplicationEnabledSetting(packageName, newState, flags, UserHandle.myUserId()); 1203 } catch (RemoteException e) { 1204 // Should never happen! 1205 } 1206 } 1207 1208 @Override 1209 public int getApplicationEnabledSetting(String packageName) { 1210 try { 1211 return mPM.getApplicationEnabledSetting(packageName, UserHandle.myUserId()); 1212 } catch (RemoteException e) { 1213 // Should never happen! 1214 } 1215 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 1216 } 1217 1218 /** 1219 * @hide 1220 */ 1221 @Override 1222 public VerifierDeviceIdentity getVerifierDeviceIdentity() { 1223 try { 1224 return mPM.getVerifierDeviceIdentity(); 1225 } catch (RemoteException e) { 1226 // Should never happen! 1227 } 1228 return null; 1229 } 1230 1231 private final ContextImpl mContext; 1232 private final IPackageManager mPM; 1233 1234 private static final Object sSync = new Object(); 1235 private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache 1236 = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>(); 1237 private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache 1238 = new HashMap<ResourceName, WeakReference<CharSequence>>(); 1239} 1240