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