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