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