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