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