ApplicationPackageManager.java revision 151ec4c9f8ca34625733730a4551a23eb97cda23
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 return getInstalledPackages(flags, UserHandle.myUserId()); 411 } 412 413 /** @hide */ 414 @Override 415 public List<PackageInfo> getInstalledPackages(int flags, int userId) { 416 try { 417 final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>(); 418 PackageInfo lastItem = null; 419 ParceledListSlice<PackageInfo> slice; 420 421 do { 422 final String lastKey = lastItem != null ? lastItem.packageName : null; 423 slice = mPM.getInstalledPackages(flags, lastKey, userId); 424 lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR); 425 } while (!slice.isLastSlice()); 426 427 return packageInfos; 428 } catch (RemoteException e) { 429 throw new RuntimeException("Package manager has died", e); 430 } 431 } 432 433 @SuppressWarnings("unchecked") 434 @Override 435 public List<ApplicationInfo> getInstalledApplications(int flags) { 436 int userId = UserHandle.getUserId(Process.myUid()); 437 try { 438 final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>(); 439 ApplicationInfo lastItem = null; 440 ParceledListSlice<ApplicationInfo> slice; 441 442 do { 443 final String lastKey = lastItem != null ? lastItem.packageName : null; 444 slice = mPM.getInstalledApplications(flags, lastKey, userId); 445 lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR); 446 } while (!slice.isLastSlice()); 447 448 return applicationInfos; 449 } catch (RemoteException e) { 450 throw new RuntimeException("Package manager has died", e); 451 } 452 } 453 454 @Override 455 public ResolveInfo resolveActivity(Intent intent, int flags) { 456 try { 457 return mPM.resolveIntent( 458 intent, 459 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 460 flags, UserHandle.myUserId()); 461 } catch (RemoteException e) { 462 throw new RuntimeException("Package manager has died", e); 463 } 464 } 465 466 @Override 467 public List<ResolveInfo> queryIntentActivities(Intent intent, 468 int flags) { 469 return queryIntentActivitiesForUser(intent, flags, UserHandle.myUserId()); 470 } 471 472 /** @hide Same as above but for a specific user */ 473 @Override 474 public List<ResolveInfo> queryIntentActivitiesForUser(Intent intent, 475 int flags, int userId) { 476 try { 477 return mPM.queryIntentActivities( 478 intent, 479 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 480 flags, 481 userId); 482 } catch (RemoteException e) { 483 throw new RuntimeException("Package manager has died", e); 484 } 485 } 486 487 @Override 488 public List<ResolveInfo> queryIntentActivityOptions( 489 ComponentName caller, Intent[] specifics, Intent intent, 490 int flags) { 491 final ContentResolver resolver = mContext.getContentResolver(); 492 493 String[] specificTypes = null; 494 if (specifics != null) { 495 final int N = specifics.length; 496 for (int i=0; i<N; i++) { 497 Intent sp = specifics[i]; 498 if (sp != null) { 499 String t = sp.resolveTypeIfNeeded(resolver); 500 if (t != null) { 501 if (specificTypes == null) { 502 specificTypes = new String[N]; 503 } 504 specificTypes[i] = t; 505 } 506 } 507 } 508 } 509 510 try { 511 return mPM.queryIntentActivityOptions(caller, specifics, 512 specificTypes, intent, intent.resolveTypeIfNeeded(resolver), 513 flags, UserHandle.myUserId()); 514 } catch (RemoteException e) { 515 throw new RuntimeException("Package manager has died", e); 516 } 517 } 518 519 /** 520 * @hide 521 */ 522 @Override 523 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags, int userId) { 524 try { 525 return mPM.queryIntentReceivers( 526 intent, 527 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 528 flags, 529 userId); 530 } catch (RemoteException e) { 531 throw new RuntimeException("Package manager has died", e); 532 } 533 } 534 535 @Override 536 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) { 537 return queryBroadcastReceivers(intent, flags, UserHandle.myUserId()); 538 } 539 540 @Override 541 public ResolveInfo resolveService(Intent intent, int flags) { 542 try { 543 return mPM.resolveService( 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 List<ResolveInfo> queryIntentServices(Intent intent, int flags) { 555 try { 556 return mPM.queryIntentServices( 557 intent, 558 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 559 flags, 560 UserHandle.myUserId()); 561 } catch (RemoteException e) { 562 throw new RuntimeException("Package manager has died", e); 563 } 564 } 565 566 @Override 567 public ProviderInfo resolveContentProvider(String name, 568 int flags) { 569 try { 570 return mPM.resolveContentProvider(name, flags, UserHandle.myUserId()); 571 } catch (RemoteException e) { 572 throw new RuntimeException("Package manager has died", e); 573 } 574 } 575 576 @Override 577 public List<ProviderInfo> queryContentProviders(String processName, 578 int uid, int flags) { 579 try { 580 return mPM.queryContentProviders(processName, uid, flags); 581 } catch (RemoteException e) { 582 throw new RuntimeException("Package manager has died", e); 583 } 584 } 585 586 @Override 587 public InstrumentationInfo getInstrumentationInfo( 588 ComponentName className, int flags) 589 throws NameNotFoundException { 590 try { 591 InstrumentationInfo ii = mPM.getInstrumentationInfo( 592 className, flags); 593 if (ii != null) { 594 return ii; 595 } 596 } catch (RemoteException e) { 597 throw new RuntimeException("Package manager has died", e); 598 } 599 600 throw new NameNotFoundException(className.toString()); 601 } 602 603 @Override 604 public List<InstrumentationInfo> queryInstrumentation( 605 String targetPackage, int flags) { 606 try { 607 return mPM.queryInstrumentation(targetPackage, flags); 608 } catch (RemoteException e) { 609 throw new RuntimeException("Package manager has died", e); 610 } 611 } 612 613 @Override public Drawable getDrawable(String packageName, int resid, 614 ApplicationInfo appInfo) { 615 ResourceName name = new ResourceName(packageName, resid); 616 Drawable dr = getCachedIcon(name); 617 if (dr != null) { 618 return dr; 619 } 620 if (appInfo == null) { 621 try { 622 appInfo = getApplicationInfo(packageName, 0); 623 } catch (NameNotFoundException e) { 624 return null; 625 } 626 } 627 try { 628 Resources r = getResourcesForApplication(appInfo); 629 dr = r.getDrawable(resid); 630 if (false) { 631 RuntimeException e = new RuntimeException("here"); 632 e.fillInStackTrace(); 633 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid) 634 + " from package " + packageName 635 + ": app scale=" + r.getCompatibilityInfo().applicationScale 636 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale, 637 e); 638 } 639 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x" 640 + Integer.toHexString(resid) + " from " + r 641 + ": " + dr); 642 putCachedIcon(name, dr); 643 return dr; 644 } catch (NameNotFoundException e) { 645 Log.w("PackageManager", "Failure retrieving resources for" 646 + appInfo.packageName); 647 } catch (Resources.NotFoundException e) { 648 Log.w("PackageManager", "Failure retrieving resources for" 649 + appInfo.packageName + ": " + e.getMessage()); 650 } catch (RuntimeException e) { 651 // If an exception was thrown, fall through to return 652 // default icon. 653 Log.w("PackageManager", "Failure retrieving icon 0x" 654 + Integer.toHexString(resid) + " in package " 655 + packageName, e); 656 } 657 return null; 658 } 659 660 @Override public Drawable getActivityIcon(ComponentName activityName) 661 throws NameNotFoundException { 662 return getActivityInfo(activityName, 0).loadIcon(this); 663 } 664 665 @Override public Drawable getActivityIcon(Intent intent) 666 throws NameNotFoundException { 667 if (intent.getComponent() != null) { 668 return getActivityIcon(intent.getComponent()); 669 } 670 671 ResolveInfo info = resolveActivity( 672 intent, PackageManager.MATCH_DEFAULT_ONLY); 673 if (info != null) { 674 return info.activityInfo.loadIcon(this); 675 } 676 677 throw new NameNotFoundException(intent.toUri(0)); 678 } 679 680 @Override public Drawable getDefaultActivityIcon() { 681 return Resources.getSystem().getDrawable( 682 com.android.internal.R.drawable.sym_def_app_icon); 683 } 684 685 @Override public Drawable getApplicationIcon(ApplicationInfo info) { 686 return info.loadIcon(this); 687 } 688 689 @Override public Drawable getApplicationIcon(String packageName) 690 throws NameNotFoundException { 691 return getApplicationIcon(getApplicationInfo(packageName, 0)); 692 } 693 694 @Override 695 public Drawable getActivityLogo(ComponentName activityName) 696 throws NameNotFoundException { 697 return getActivityInfo(activityName, 0).loadLogo(this); 698 } 699 700 @Override 701 public Drawable getActivityLogo(Intent intent) 702 throws NameNotFoundException { 703 if (intent.getComponent() != null) { 704 return getActivityLogo(intent.getComponent()); 705 } 706 707 ResolveInfo info = resolveActivity( 708 intent, PackageManager.MATCH_DEFAULT_ONLY); 709 if (info != null) { 710 return info.activityInfo.loadLogo(this); 711 } 712 713 throw new NameNotFoundException(intent.toUri(0)); 714 } 715 716 @Override 717 public Drawable getApplicationLogo(ApplicationInfo info) { 718 return info.loadLogo(this); 719 } 720 721 @Override 722 public Drawable getApplicationLogo(String packageName) 723 throws NameNotFoundException { 724 return getApplicationLogo(getApplicationInfo(packageName, 0)); 725 } 726 727 @Override public Resources getResourcesForActivity( 728 ComponentName activityName) throws NameNotFoundException { 729 return getResourcesForApplication( 730 getActivityInfo(activityName, 0).applicationInfo); 731 } 732 733 @Override public Resources getResourcesForApplication( 734 ApplicationInfo app) throws NameNotFoundException { 735 if (app.packageName.equals("system")) { 736 return mContext.mMainThread.getSystemContext().getResources(); 737 } 738 Resources r = mContext.mMainThread.getTopLevelResources( 739 app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir, 740 Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo); 741 if (r != null) { 742 return r; 743 } 744 throw new NameNotFoundException("Unable to open " + app.publicSourceDir); 745 } 746 747 @Override public Resources getResourcesForApplication( 748 String appPackageName) throws NameNotFoundException { 749 return getResourcesForApplication( 750 getApplicationInfo(appPackageName, 0)); 751 } 752 753 int mCachedSafeMode = -1; 754 @Override public boolean isSafeMode() { 755 try { 756 if (mCachedSafeMode < 0) { 757 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0; 758 } 759 return mCachedSafeMode != 0; 760 } catch (RemoteException e) { 761 throw new RuntimeException("Package manager has died", e); 762 } 763 } 764 765 static void configurationChanged() { 766 synchronized (sSync) { 767 sIconCache.clear(); 768 sStringCache.clear(); 769 } 770 } 771 772 ApplicationPackageManager(ContextImpl context, 773 IPackageManager pm) { 774 mContext = context; 775 mPM = pm; 776 } 777 778 private Drawable getCachedIcon(ResourceName name) { 779 synchronized (sSync) { 780 WeakReference<Drawable.ConstantState> wr = sIconCache.get(name); 781 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for " 782 + name + ": " + wr); 783 if (wr != null) { // we have the activity 784 Drawable.ConstantState state = wr.get(); 785 if (state != null) { 786 if (DEBUG_ICONS) { 787 Log.v(TAG, "Get cached drawable state for " + name + ": " + state); 788 } 789 // Note: It's okay here to not use the newDrawable(Resources) variant 790 // of the API. The ConstantState comes from a drawable that was 791 // originally created by passing the proper app Resources instance 792 // which means the state should already contain the proper 793 // resources specific information (like density.) See 794 // BitmapDrawable.BitmapState for instance. 795 return state.newDrawable(); 796 } 797 // our entry has been purged 798 sIconCache.remove(name); 799 } 800 } 801 return null; 802 } 803 804 private void putCachedIcon(ResourceName name, Drawable dr) { 805 synchronized (sSync) { 806 sIconCache.put(name, new WeakReference<Drawable.ConstantState>(dr.getConstantState())); 807 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr); 808 } 809 } 810 811 static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) { 812 boolean immediateGc = false; 813 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) { 814 immediateGc = true; 815 } 816 if (pkgList != null && (pkgList.length > 0)) { 817 boolean needCleanup = false; 818 for (String ssp : pkgList) { 819 synchronized (sSync) { 820 if (sIconCache.size() > 0) { 821 Iterator<ResourceName> it = sIconCache.keySet().iterator(); 822 while (it.hasNext()) { 823 ResourceName nm = it.next(); 824 if (nm.packageName.equals(ssp)) { 825 //Log.i(TAG, "Removing cached drawable for " + nm); 826 it.remove(); 827 needCleanup = true; 828 } 829 } 830 } 831 if (sStringCache.size() > 0) { 832 Iterator<ResourceName> it = sStringCache.keySet().iterator(); 833 while (it.hasNext()) { 834 ResourceName nm = it.next(); 835 if (nm.packageName.equals(ssp)) { 836 //Log.i(TAG, "Removing cached string for " + nm); 837 it.remove(); 838 needCleanup = true; 839 } 840 } 841 } 842 } 843 } 844 if (needCleanup || hasPkgInfo) { 845 if (immediateGc) { 846 // Schedule an immediate gc. 847 Runtime.getRuntime().gc(); 848 } else { 849 ActivityThread.currentActivityThread().scheduleGcIdler(); 850 } 851 } 852 } 853 } 854 855 private static final class ResourceName { 856 final String packageName; 857 final int iconId; 858 859 ResourceName(String _packageName, int _iconId) { 860 packageName = _packageName; 861 iconId = _iconId; 862 } 863 864 ResourceName(ApplicationInfo aInfo, int _iconId) { 865 this(aInfo.packageName, _iconId); 866 } 867 868 ResourceName(ComponentInfo cInfo, int _iconId) { 869 this(cInfo.applicationInfo.packageName, _iconId); 870 } 871 872 ResourceName(ResolveInfo rInfo, int _iconId) { 873 this(rInfo.activityInfo.applicationInfo.packageName, _iconId); 874 } 875 876 @Override 877 public boolean equals(Object o) { 878 if (this == o) return true; 879 if (o == null || getClass() != o.getClass()) return false; 880 881 ResourceName that = (ResourceName) o; 882 883 if (iconId != that.iconId) return false; 884 return !(packageName != null ? 885 !packageName.equals(that.packageName) : that.packageName != null); 886 887 } 888 889 @Override 890 public int hashCode() { 891 int result; 892 result = packageName.hashCode(); 893 result = 31 * result + iconId; 894 return result; 895 } 896 897 @Override 898 public String toString() { 899 return "{ResourceName " + packageName + " / " + iconId + "}"; 900 } 901 } 902 903 private CharSequence getCachedString(ResourceName name) { 904 synchronized (sSync) { 905 WeakReference<CharSequence> wr = sStringCache.get(name); 906 if (wr != null) { // we have the activity 907 CharSequence cs = wr.get(); 908 if (cs != null) { 909 return cs; 910 } 911 // our entry has been purged 912 sStringCache.remove(name); 913 } 914 } 915 return null; 916 } 917 918 private void putCachedString(ResourceName name, CharSequence cs) { 919 synchronized (sSync) { 920 sStringCache.put(name, new WeakReference<CharSequence>(cs)); 921 } 922 } 923 924 @Override 925 public CharSequence getText(String packageName, int resid, 926 ApplicationInfo appInfo) { 927 ResourceName name = new ResourceName(packageName, resid); 928 CharSequence text = getCachedString(name); 929 if (text != null) { 930 return text; 931 } 932 if (appInfo == null) { 933 try { 934 appInfo = getApplicationInfo(packageName, 0); 935 } catch (NameNotFoundException e) { 936 return null; 937 } 938 } 939 try { 940 Resources r = getResourcesForApplication(appInfo); 941 text = r.getText(resid); 942 putCachedString(name, text); 943 return text; 944 } catch (NameNotFoundException e) { 945 Log.w("PackageManager", "Failure retrieving resources for" 946 + appInfo.packageName); 947 } catch (RuntimeException e) { 948 // If an exception was thrown, fall through to return 949 // default icon. 950 Log.w("PackageManager", "Failure retrieving text 0x" 951 + Integer.toHexString(resid) + " in package " 952 + packageName, e); 953 } 954 return null; 955 } 956 957 @Override 958 public XmlResourceParser getXml(String packageName, int resid, 959 ApplicationInfo appInfo) { 960 if (appInfo == null) { 961 try { 962 appInfo = getApplicationInfo(packageName, 0); 963 } catch (NameNotFoundException e) { 964 return null; 965 } 966 } 967 try { 968 Resources r = getResourcesForApplication(appInfo); 969 return r.getXml(resid); 970 } catch (RuntimeException e) { 971 // If an exception was thrown, fall through to return 972 // default icon. 973 Log.w("PackageManager", "Failure retrieving xml 0x" 974 + Integer.toHexString(resid) + " in package " 975 + packageName, e); 976 } catch (NameNotFoundException e) { 977 Log.w("PackageManager", "Failure retrieving resources for " 978 + appInfo.packageName); 979 } 980 return null; 981 } 982 983 @Override 984 public CharSequence getApplicationLabel(ApplicationInfo info) { 985 return info.loadLabel(this); 986 } 987 988 @Override 989 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, 990 String installerPackageName) { 991 try { 992 mPM.installPackage(packageURI, observer, flags, installerPackageName); 993 } catch (RemoteException e) { 994 // Should never happen! 995 } 996 } 997 998 @Override 999 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, 1000 int flags, String installerPackageName, Uri verificationURI, 1001 ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) { 1002 try { 1003 mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName, 1004 verificationURI, manifestDigest, encryptionParams); 1005 } catch (RemoteException e) { 1006 // Should never happen! 1007 } 1008 } 1009 1010 @Override 1011 public void installPackageWithVerificationAndEncryption(Uri packageURI, 1012 IPackageInstallObserver observer, int flags, String installerPackageName, 1013 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { 1014 try { 1015 mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags, 1016 installerPackageName, verificationParams, encryptionParams); 1017 } catch (RemoteException e) { 1018 // Should never happen! 1019 } 1020 } 1021 1022 @Override 1023 public int installExistingPackage(String packageName) 1024 throws NameNotFoundException { 1025 try { 1026 int res = mPM.installExistingPackage(packageName); 1027 if (res == INSTALL_FAILED_INVALID_URI) { 1028 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 1029 } 1030 return res; 1031 } catch (RemoteException e) { 1032 // Should never happen! 1033 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 1034 } 1035 } 1036 1037 @Override 1038 public void verifyPendingInstall(int id, int response) { 1039 try { 1040 mPM.verifyPendingInstall(id, response); 1041 } catch (RemoteException e) { 1042 // Should never happen! 1043 } 1044 } 1045 1046 @Override 1047 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 1048 long millisecondsToDelay) { 1049 try { 1050 mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay); 1051 } catch (RemoteException e) { 1052 // Should never happen! 1053 } 1054 } 1055 1056 @Override 1057 public void setInstallerPackageName(String targetPackage, 1058 String installerPackageName) { 1059 try { 1060 mPM.setInstallerPackageName(targetPackage, installerPackageName); 1061 } catch (RemoteException e) { 1062 // Should never happen! 1063 } 1064 } 1065 1066 @Override 1067 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) { 1068 try { 1069 mPM.movePackage(packageName, observer, flags); 1070 } catch (RemoteException e) { 1071 // Should never happen! 1072 } 1073 } 1074 1075 @Override 1076 public String getInstallerPackageName(String packageName) { 1077 try { 1078 return mPM.getInstallerPackageName(packageName); 1079 } catch (RemoteException e) { 1080 // Should never happen! 1081 } 1082 return null; 1083 } 1084 1085 @Override 1086 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) { 1087 try { 1088 mPM.deletePackage(packageName, observer, flags); 1089 } catch (RemoteException e) { 1090 // Should never happen! 1091 } 1092 } 1093 @Override 1094 public void clearApplicationUserData(String packageName, 1095 IPackageDataObserver observer) { 1096 try { 1097 mPM.clearApplicationUserData(packageName, observer, UserHandle.myUserId()); 1098 } catch (RemoteException e) { 1099 // Should never happen! 1100 } 1101 } 1102 @Override 1103 public void deleteApplicationCacheFiles(String packageName, 1104 IPackageDataObserver observer) { 1105 try { 1106 mPM.deleteApplicationCacheFiles(packageName, observer); 1107 } catch (RemoteException e) { 1108 // Should never happen! 1109 } 1110 } 1111 @Override 1112 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) { 1113 try { 1114 mPM.freeStorageAndNotify(idealStorageSize, observer); 1115 } catch (RemoteException e) { 1116 // Should never happen! 1117 } 1118 } 1119 1120 @Override 1121 public void freeStorage(long freeStorageSize, IntentSender pi) { 1122 try { 1123 mPM.freeStorage(freeStorageSize, pi); 1124 } catch (RemoteException e) { 1125 // Should never happen! 1126 } 1127 } 1128 1129 @Override 1130 public void getPackageSizeInfo(String packageName, int userHandle, 1131 IPackageStatsObserver observer) { 1132 try { 1133 mPM.getPackageSizeInfo(packageName, userHandle, observer); 1134 } catch (RemoteException e) { 1135 // Should never happen! 1136 } 1137 } 1138 @Override 1139 public void addPackageToPreferred(String packageName) { 1140 try { 1141 mPM.addPackageToPreferred(packageName); 1142 } catch (RemoteException e) { 1143 // Should never happen! 1144 } 1145 } 1146 1147 @Override 1148 public void removePackageFromPreferred(String packageName) { 1149 try { 1150 mPM.removePackageFromPreferred(packageName); 1151 } catch (RemoteException e) { 1152 // Should never happen! 1153 } 1154 } 1155 1156 @Override 1157 public List<PackageInfo> getPreferredPackages(int flags) { 1158 try { 1159 return mPM.getPreferredPackages(flags); 1160 } catch (RemoteException e) { 1161 // Should never happen! 1162 } 1163 return new ArrayList<PackageInfo>(); 1164 } 1165 1166 @Override 1167 public void addPreferredActivity(IntentFilter filter, 1168 int match, ComponentName[] set, ComponentName activity) { 1169 try { 1170 mPM.addPreferredActivity(filter, match, set, activity, UserHandle.myUserId()); 1171 } catch (RemoteException e) { 1172 // Should never happen! 1173 } 1174 } 1175 1176 @Override 1177 public void addPreferredActivity(IntentFilter filter, int match, 1178 ComponentName[] set, ComponentName activity, int userId) { 1179 try { 1180 mPM.addPreferredActivity(filter, match, set, activity, userId); 1181 } catch (RemoteException e) { 1182 // Should never happen! 1183 } 1184 } 1185 1186 @Override 1187 public void replacePreferredActivity(IntentFilter filter, 1188 int match, ComponentName[] set, ComponentName activity) { 1189 try { 1190 mPM.replacePreferredActivity(filter, match, set, activity); 1191 } catch (RemoteException e) { 1192 // Should never happen! 1193 } 1194 } 1195 1196 @Override 1197 public void clearPackagePreferredActivities(String packageName) { 1198 try { 1199 mPM.clearPackagePreferredActivities(packageName); 1200 } catch (RemoteException e) { 1201 // Should never happen! 1202 } 1203 } 1204 1205 @Override 1206 public int getPreferredActivities(List<IntentFilter> outFilters, 1207 List<ComponentName> outActivities, String packageName) { 1208 try { 1209 return mPM.getPreferredActivities(outFilters, outActivities, packageName); 1210 } catch (RemoteException e) { 1211 // Should never happen! 1212 } 1213 return 0; 1214 } 1215 1216 @Override 1217 public void setComponentEnabledSetting(ComponentName componentName, 1218 int newState, int flags) { 1219 try { 1220 mPM.setComponentEnabledSetting(componentName, newState, flags, UserHandle.myUserId()); 1221 } catch (RemoteException e) { 1222 // Should never happen! 1223 } 1224 } 1225 1226 @Override 1227 public int getComponentEnabledSetting(ComponentName componentName) { 1228 try { 1229 return mPM.getComponentEnabledSetting(componentName, UserHandle.myUserId()); 1230 } catch (RemoteException e) { 1231 // Should never happen! 1232 } 1233 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 1234 } 1235 1236 @Override 1237 public void setApplicationEnabledSetting(String packageName, 1238 int newState, int flags) { 1239 try { 1240 mPM.setApplicationEnabledSetting(packageName, newState, flags, UserHandle.myUserId()); 1241 } catch (RemoteException e) { 1242 // Should never happen! 1243 } 1244 } 1245 1246 @Override 1247 public int getApplicationEnabledSetting(String packageName) { 1248 try { 1249 return mPM.getApplicationEnabledSetting(packageName, UserHandle.myUserId()); 1250 } catch (RemoteException e) { 1251 // Should never happen! 1252 } 1253 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 1254 } 1255 1256 /** 1257 * @hide 1258 */ 1259 @Override 1260 public VerifierDeviceIdentity getVerifierDeviceIdentity() { 1261 try { 1262 return mPM.getVerifierDeviceIdentity(); 1263 } catch (RemoteException e) { 1264 // Should never happen! 1265 } 1266 return null; 1267 } 1268 1269 private final ContextImpl mContext; 1270 private final IPackageManager mPM; 1271 1272 private static final Object sSync = new Object(); 1273 private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache 1274 = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>(); 1275 private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache 1276 = new HashMap<ResourceName, WeakReference<CharSequence>>(); 1277} 1278