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