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 17 package android.app; 18 19 import android.content.ComponentName; 20 import android.content.ContentResolver; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.content.IntentSender; 24 import android.content.pm.ActivityInfo; 25 import android.content.pm.ApplicationInfo; 26 import android.content.pm.ComponentInfo; 27 import android.content.pm.ContainerEncryptionParams; 28 import android.content.pm.FeatureInfo; 29 import android.content.pm.IPackageDataObserver; 30 import android.content.pm.IPackageDeleteObserver; 31 import android.content.pm.IPackageInstallObserver; 32 import android.content.pm.IPackageManager; 33 import android.content.pm.IPackageMoveObserver; 34 import android.content.pm.IPackageStatsObserver; 35 import android.content.pm.InstrumentationInfo; 36 import android.content.pm.PackageInfo; 37 import android.content.pm.PackageManager; 38 import android.content.pm.ParceledListSlice; 39 import android.content.pm.PermissionGroupInfo; 40 import android.content.pm.PermissionInfo; 41 import android.content.pm.ProviderInfo; 42 import android.content.pm.ResolveInfo; 43 import android.content.pm.ServiceInfo; 44 import android.content.pm.ManifestDigest; 45 import android.content.pm.VerificationParams; 46 import android.content.pm.VerifierDeviceIdentity; 47 import android.content.res.Resources; 48 import android.content.res.XmlResourceParser; 49 import android.graphics.drawable.Drawable; 50 import android.net.Uri; 51 import android.os.Process; 52 import android.os.RemoteException; 53 import android.util.Log; 54 import android.view.Display; 55 56 import java.lang.ref.WeakReference; 57 import java.util.ArrayList; 58 import java.util.HashMap; 59 import java.util.Iterator; 60 import java.util.List; 61 62 /*package*/ 63 final 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, mContext.getUserId()); 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, mContext.getUserId()); 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, mContext.getUserId()); 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, mContext.getUserId()); 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, mContext.getUserId()); 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, mContext.getUserId()); 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 return getInstalledPackages(flags, mContext.getUserId()); 408 } 409 410 /** @hide */ 411 @Override 412 public List<PackageInfo> getInstalledPackages(int flags, int userId) { 413 try { 414 final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>(); 415 PackageInfo lastItem = null; 416 ParceledListSlice<PackageInfo> slice; 417 418 do { 419 final String lastKey = lastItem != null ? lastItem.packageName : null; 420 slice = mPM.getInstalledPackages(flags, lastKey, userId); 421 lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR); 422 } while (!slice.isLastSlice()); 423 424 return packageInfos; 425 } catch (RemoteException e) { 426 throw new RuntimeException("Package manager has died", e); 427 } 428 } 429 430 @SuppressWarnings("unchecked") 431 @Override 432 public List<ApplicationInfo> getInstalledApplications(int flags) { 433 final int userId = mContext.getUserId(); 434 try { 435 final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>(); 436 ApplicationInfo lastItem = null; 437 ParceledListSlice<ApplicationInfo> slice; 438 439 do { 440 final String lastKey = lastItem != null ? lastItem.packageName : null; 441 slice = mPM.getInstalledApplications(flags, lastKey, userId); 442 lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR); 443 } while (!slice.isLastSlice()); 444 445 return applicationInfos; 446 } catch (RemoteException e) { 447 throw new RuntimeException("Package manager has died", e); 448 } 449 } 450 451 @Override 452 public ResolveInfo resolveActivity(Intent intent, int flags) { 453 return resolveActivityAsUser(intent, flags, mContext.getUserId()); 454 } 455 456 @Override 457 public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) { 458 try { 459 return mPM.resolveIntent( 460 intent, 461 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 462 flags, 463 userId); 464 } catch (RemoteException e) { 465 throw new RuntimeException("Package manager has died", e); 466 } 467 } 468 469 @Override 470 public List<ResolveInfo> queryIntentActivities(Intent intent, 471 int flags) { 472 return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId()); 473 } 474 475 /** @hide Same as above but for a specific user */ 476 @Override 477 public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, 478 int flags, int userId) { 479 try { 480 return mPM.queryIntentActivities( 481 intent, 482 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 483 flags, 484 userId); 485 } catch (RemoteException e) { 486 throw new RuntimeException("Package manager has died", e); 487 } 488 } 489 490 @Override 491 public List<ResolveInfo> queryIntentActivityOptions( 492 ComponentName caller, Intent[] specifics, Intent intent, 493 int flags) { 494 final ContentResolver resolver = mContext.getContentResolver(); 495 496 String[] specificTypes = null; 497 if (specifics != null) { 498 final int N = specifics.length; 499 for (int i=0; i<N; i++) { 500 Intent sp = specifics[i]; 501 if (sp != null) { 502 String t = sp.resolveTypeIfNeeded(resolver); 503 if (t != null) { 504 if (specificTypes == null) { 505 specificTypes = new String[N]; 506 } 507 specificTypes[i] = t; 508 } 509 } 510 } 511 } 512 513 try { 514 return mPM.queryIntentActivityOptions(caller, specifics, 515 specificTypes, intent, intent.resolveTypeIfNeeded(resolver), 516 flags, mContext.getUserId()); 517 } catch (RemoteException e) { 518 throw new RuntimeException("Package manager has died", e); 519 } 520 } 521 522 /** 523 * @hide 524 */ 525 @Override 526 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags, int userId) { 527 try { 528 return mPM.queryIntentReceivers( 529 intent, 530 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 531 flags, 532 userId); 533 } catch (RemoteException e) { 534 throw new RuntimeException("Package manager has died", e); 535 } 536 } 537 538 @Override 539 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) { 540 return queryBroadcastReceivers(intent, flags, mContext.getUserId()); 541 } 542 543 @Override 544 public ResolveInfo resolveService(Intent intent, int flags) { 545 try { 546 return mPM.resolveService( 547 intent, 548 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 549 flags, 550 mContext.getUserId()); 551 } catch (RemoteException e) { 552 throw new RuntimeException("Package manager has died", e); 553 } 554 } 555 556 @Override 557 public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) { 558 try { 559 return mPM.queryIntentServices( 560 intent, 561 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 562 flags, 563 userId); 564 } catch (RemoteException e) { 565 throw new RuntimeException("Package manager has died", e); 566 } 567 } 568 569 @Override 570 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) { 571 return queryIntentServicesAsUser(intent, flags, mContext.getUserId()); 572 } 573 574 @Override 575 public ProviderInfo resolveContentProvider(String name, 576 int flags) { 577 try { 578 return mPM.resolveContentProvider(name, flags, mContext.getUserId()); 579 } catch (RemoteException e) { 580 throw new RuntimeException("Package manager has died", e); 581 } 582 } 583 584 @Override 585 public List<ProviderInfo> queryContentProviders(String processName, 586 int uid, int flags) { 587 try { 588 return mPM.queryContentProviders(processName, uid, flags); 589 } catch (RemoteException e) { 590 throw new RuntimeException("Package manager has died", e); 591 } 592 } 593 594 @Override 595 public InstrumentationInfo getInstrumentationInfo( 596 ComponentName className, int flags) 597 throws NameNotFoundException { 598 try { 599 InstrumentationInfo ii = mPM.getInstrumentationInfo( 600 className, flags); 601 if (ii != null) { 602 return ii; 603 } 604 } catch (RemoteException e) { 605 throw new RuntimeException("Package manager has died", e); 606 } 607 608 throw new NameNotFoundException(className.toString()); 609 } 610 611 @Override 612 public List<InstrumentationInfo> queryInstrumentation( 613 String targetPackage, int flags) { 614 try { 615 return mPM.queryInstrumentation(targetPackage, flags); 616 } catch (RemoteException e) { 617 throw new RuntimeException("Package manager has died", e); 618 } 619 } 620 621 @Override public Drawable getDrawable(String packageName, int resid, 622 ApplicationInfo appInfo) { 623 ResourceName name = new ResourceName(packageName, resid); 624 Drawable dr = getCachedIcon(name); 625 if (dr != null) { 626 return dr; 627 } 628 if (appInfo == null) { 629 try { 630 appInfo = getApplicationInfo(packageName, 0); 631 } catch (NameNotFoundException e) { 632 return null; 633 } 634 } 635 try { 636 Resources r = getResourcesForApplication(appInfo); 637 dr = r.getDrawable(resid); 638 if (false) { 639 RuntimeException e = new RuntimeException("here"); 640 e.fillInStackTrace(); 641 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid) 642 + " from package " + packageName 643 + ": app scale=" + r.getCompatibilityInfo().applicationScale 644 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale, 645 e); 646 } 647 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x" 648 + Integer.toHexString(resid) + " from " + r 649 + ": " + dr); 650 putCachedIcon(name, dr); 651 return dr; 652 } catch (NameNotFoundException e) { 653 Log.w("PackageManager", "Failure retrieving resources for" 654 + appInfo.packageName); 655 } catch (Resources.NotFoundException e) { 656 Log.w("PackageManager", "Failure retrieving resources for" 657 + appInfo.packageName + ": " + e.getMessage()); 658 } catch (RuntimeException e) { 659 // If an exception was thrown, fall through to return 660 // default icon. 661 Log.w("PackageManager", "Failure retrieving icon 0x" 662 + Integer.toHexString(resid) + " in package " 663 + packageName, e); 664 } 665 return null; 666 } 667 668 @Override public Drawable getActivityIcon(ComponentName activityName) 669 throws NameNotFoundException { 670 return getActivityInfo(activityName, 0).loadIcon(this); 671 } 672 673 @Override public Drawable getActivityIcon(Intent intent) 674 throws NameNotFoundException { 675 if (intent.getComponent() != null) { 676 return getActivityIcon(intent.getComponent()); 677 } 678 679 ResolveInfo info = resolveActivity( 680 intent, PackageManager.MATCH_DEFAULT_ONLY); 681 if (info != null) { 682 return info.activityInfo.loadIcon(this); 683 } 684 685 throw new NameNotFoundException(intent.toUri(0)); 686 } 687 688 @Override public Drawable getDefaultActivityIcon() { 689 return Resources.getSystem().getDrawable( 690 com.android.internal.R.drawable.sym_def_app_icon); 691 } 692 693 @Override public Drawable getApplicationIcon(ApplicationInfo info) { 694 return info.loadIcon(this); 695 } 696 697 @Override public Drawable getApplicationIcon(String packageName) 698 throws NameNotFoundException { 699 return getApplicationIcon(getApplicationInfo(packageName, 0)); 700 } 701 702 @Override 703 public Drawable getActivityLogo(ComponentName activityName) 704 throws NameNotFoundException { 705 return getActivityInfo(activityName, 0).loadLogo(this); 706 } 707 708 @Override 709 public Drawable getActivityLogo(Intent intent) 710 throws NameNotFoundException { 711 if (intent.getComponent() != null) { 712 return getActivityLogo(intent.getComponent()); 713 } 714 715 ResolveInfo info = resolveActivity( 716 intent, PackageManager.MATCH_DEFAULT_ONLY); 717 if (info != null) { 718 return info.activityInfo.loadLogo(this); 719 } 720 721 throw new NameNotFoundException(intent.toUri(0)); 722 } 723 724 @Override 725 public Drawable getApplicationLogo(ApplicationInfo info) { 726 return info.loadLogo(this); 727 } 728 729 @Override 730 public Drawable getApplicationLogo(String packageName) 731 throws NameNotFoundException { 732 return getApplicationLogo(getApplicationInfo(packageName, 0)); 733 } 734 735 @Override public Resources getResourcesForActivity( 736 ComponentName activityName) throws NameNotFoundException { 737 return getResourcesForApplication( 738 getActivityInfo(activityName, 0).applicationInfo); 739 } 740 741 @Override public Resources getResourcesForApplication( 742 ApplicationInfo app) throws NameNotFoundException { 743 if (app.packageName.equals("system")) { 744 return mContext.mMainThread.getSystemContext().getResources(); 745 } 746 Resources r = mContext.mMainThread.getTopLevelResources( 747 app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir, 748 Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo); 749 if (r != null) { 750 return r; 751 } 752 throw new NameNotFoundException("Unable to open " + app.publicSourceDir); 753 } 754 755 @Override public Resources getResourcesForApplication( 756 String appPackageName) throws NameNotFoundException { 757 return getResourcesForApplication( 758 getApplicationInfo(appPackageName, 0)); 759 } 760 761 /** @hide */ 762 @Override 763 public Resources getResourcesForApplicationAsUser(String appPackageName, int userId) 764 throws NameNotFoundException { 765 if (userId < 0) { 766 throw new IllegalArgumentException( 767 "Call does not support special user #" + userId); 768 } 769 if ("system".equals(appPackageName)) { 770 return mContext.mMainThread.getSystemContext().getResources(); 771 } 772 try { 773 ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, 0, userId); 774 if (ai != null) { 775 return getResourcesForApplication(ai); 776 } 777 } catch (RemoteException e) { 778 throw new RuntimeException("Package manager has died", e); 779 } 780 throw new NameNotFoundException("Package " + appPackageName + " doesn't exist"); 781 } 782 783 int mCachedSafeMode = -1; 784 @Override public boolean isSafeMode() { 785 try { 786 if (mCachedSafeMode < 0) { 787 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0; 788 } 789 return mCachedSafeMode != 0; 790 } catch (RemoteException e) { 791 throw new RuntimeException("Package manager has died", e); 792 } 793 } 794 795 static void configurationChanged() { 796 synchronized (sSync) { 797 sIconCache.clear(); 798 sStringCache.clear(); 799 } 800 } 801 802 ApplicationPackageManager(ContextImpl context, 803 IPackageManager pm) { 804 mContext = context; 805 mPM = pm; 806 } 807 808 private Drawable getCachedIcon(ResourceName name) { 809 synchronized (sSync) { 810 WeakReference<Drawable.ConstantState> wr = sIconCache.get(name); 811 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for " 812 + name + ": " + wr); 813 if (wr != null) { // we have the activity 814 Drawable.ConstantState state = wr.get(); 815 if (state != null) { 816 if (DEBUG_ICONS) { 817 Log.v(TAG, "Get cached drawable state for " + name + ": " + state); 818 } 819 // Note: It's okay here to not use the newDrawable(Resources) variant 820 // of the API. The ConstantState comes from a drawable that was 821 // originally created by passing the proper app Resources instance 822 // which means the state should already contain the proper 823 // resources specific information (like density.) See 824 // BitmapDrawable.BitmapState for instance. 825 return state.newDrawable(); 826 } 827 // our entry has been purged 828 sIconCache.remove(name); 829 } 830 } 831 return null; 832 } 833 834 private void putCachedIcon(ResourceName name, Drawable dr) { 835 synchronized (sSync) { 836 sIconCache.put(name, new WeakReference<Drawable.ConstantState>(dr.getConstantState())); 837 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr); 838 } 839 } 840 841 static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) { 842 boolean immediateGc = false; 843 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) { 844 immediateGc = true; 845 } 846 if (pkgList != null && (pkgList.length > 0)) { 847 boolean needCleanup = false; 848 for (String ssp : pkgList) { 849 synchronized (sSync) { 850 if (sIconCache.size() > 0) { 851 Iterator<ResourceName> it = sIconCache.keySet().iterator(); 852 while (it.hasNext()) { 853 ResourceName nm = it.next(); 854 if (nm.packageName.equals(ssp)) { 855 //Log.i(TAG, "Removing cached drawable for " + nm); 856 it.remove(); 857 needCleanup = true; 858 } 859 } 860 } 861 if (sStringCache.size() > 0) { 862 Iterator<ResourceName> it = sStringCache.keySet().iterator(); 863 while (it.hasNext()) { 864 ResourceName nm = it.next(); 865 if (nm.packageName.equals(ssp)) { 866 //Log.i(TAG, "Removing cached string for " + nm); 867 it.remove(); 868 needCleanup = true; 869 } 870 } 871 } 872 } 873 } 874 if (needCleanup || hasPkgInfo) { 875 if (immediateGc) { 876 // Schedule an immediate gc. 877 Runtime.getRuntime().gc(); 878 } else { 879 ActivityThread.currentActivityThread().scheduleGcIdler(); 880 } 881 } 882 } 883 } 884 885 private static final class ResourceName { 886 final String packageName; 887 final int iconId; 888 889 ResourceName(String _packageName, int _iconId) { 890 packageName = _packageName; 891 iconId = _iconId; 892 } 893 894 ResourceName(ApplicationInfo aInfo, int _iconId) { 895 this(aInfo.packageName, _iconId); 896 } 897 898 ResourceName(ComponentInfo cInfo, int _iconId) { 899 this(cInfo.applicationInfo.packageName, _iconId); 900 } 901 902 ResourceName(ResolveInfo rInfo, int _iconId) { 903 this(rInfo.activityInfo.applicationInfo.packageName, _iconId); 904 } 905 906 @Override 907 public boolean equals(Object o) { 908 if (this == o) return true; 909 if (o == null || getClass() != o.getClass()) return false; 910 911 ResourceName that = (ResourceName) o; 912 913 if (iconId != that.iconId) return false; 914 return !(packageName != null ? 915 !packageName.equals(that.packageName) : that.packageName != null); 916 917 } 918 919 @Override 920 public int hashCode() { 921 int result; 922 result = packageName.hashCode(); 923 result = 31 * result + iconId; 924 return result; 925 } 926 927 @Override 928 public String toString() { 929 return "{ResourceName " + packageName + " / " + iconId + "}"; 930 } 931 } 932 933 private CharSequence getCachedString(ResourceName name) { 934 synchronized (sSync) { 935 WeakReference<CharSequence> wr = sStringCache.get(name); 936 if (wr != null) { // we have the activity 937 CharSequence cs = wr.get(); 938 if (cs != null) { 939 return cs; 940 } 941 // our entry has been purged 942 sStringCache.remove(name); 943 } 944 } 945 return null; 946 } 947 948 private void putCachedString(ResourceName name, CharSequence cs) { 949 synchronized (sSync) { 950 sStringCache.put(name, new WeakReference<CharSequence>(cs)); 951 } 952 } 953 954 @Override 955 public CharSequence getText(String packageName, int resid, 956 ApplicationInfo appInfo) { 957 ResourceName name = new ResourceName(packageName, resid); 958 CharSequence text = getCachedString(name); 959 if (text != null) { 960 return text; 961 } 962 if (appInfo == null) { 963 try { 964 appInfo = getApplicationInfo(packageName, 0); 965 } catch (NameNotFoundException e) { 966 return null; 967 } 968 } 969 try { 970 Resources r = getResourcesForApplication(appInfo); 971 text = r.getText(resid); 972 putCachedString(name, text); 973 return text; 974 } catch (NameNotFoundException e) { 975 Log.w("PackageManager", "Failure retrieving resources for" 976 + appInfo.packageName); 977 } catch (RuntimeException e) { 978 // If an exception was thrown, fall through to return 979 // default icon. 980 Log.w("PackageManager", "Failure retrieving text 0x" 981 + Integer.toHexString(resid) + " in package " 982 + packageName, e); 983 } 984 return null; 985 } 986 987 @Override 988 public XmlResourceParser getXml(String packageName, int resid, 989 ApplicationInfo appInfo) { 990 if (appInfo == null) { 991 try { 992 appInfo = getApplicationInfo(packageName, 0); 993 } catch (NameNotFoundException e) { 994 return null; 995 } 996 } 997 try { 998 Resources r = getResourcesForApplication(appInfo); 999 return r.getXml(resid); 1000 } catch (RuntimeException e) { 1001 // If an exception was thrown, fall through to return 1002 // default icon. 1003 Log.w("PackageManager", "Failure retrieving xml 0x" 1004 + Integer.toHexString(resid) + " in package " 1005 + packageName, e); 1006 } catch (NameNotFoundException e) { 1007 Log.w("PackageManager", "Failure retrieving resources for " 1008 + appInfo.packageName); 1009 } 1010 return null; 1011 } 1012 1013 @Override 1014 public CharSequence getApplicationLabel(ApplicationInfo info) { 1015 return info.loadLabel(this); 1016 } 1017 1018 @Override 1019 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, 1020 String installerPackageName) { 1021 try { 1022 mPM.installPackage(packageURI, observer, flags, installerPackageName); 1023 } catch (RemoteException e) { 1024 // Should never happen! 1025 } 1026 } 1027 1028 @Override 1029 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, 1030 int flags, String installerPackageName, Uri verificationURI, 1031 ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) { 1032 try { 1033 mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName, 1034 verificationURI, manifestDigest, encryptionParams); 1035 } catch (RemoteException e) { 1036 // Should never happen! 1037 } 1038 } 1039 1040 @Override 1041 public void installPackageWithVerificationAndEncryption(Uri packageURI, 1042 IPackageInstallObserver observer, int flags, String installerPackageName, 1043 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { 1044 try { 1045 mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags, 1046 installerPackageName, verificationParams, encryptionParams); 1047 } catch (RemoteException e) { 1048 // Should never happen! 1049 } 1050 } 1051 1052 @Override 1053 public int installExistingPackage(String packageName) 1054 throws NameNotFoundException { 1055 try { 1056 int res = mPM.installExistingPackage(packageName); 1057 if (res == INSTALL_FAILED_INVALID_URI) { 1058 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 1059 } 1060 return res; 1061 } catch (RemoteException e) { 1062 // Should never happen! 1063 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 1064 } 1065 } 1066 1067 @Override 1068 public void verifyPendingInstall(int id, int response) { 1069 try { 1070 mPM.verifyPendingInstall(id, response); 1071 } catch (RemoteException e) { 1072 // Should never happen! 1073 } 1074 } 1075 1076 @Override 1077 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 1078 long millisecondsToDelay) { 1079 try { 1080 mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay); 1081 } catch (RemoteException e) { 1082 // Should never happen! 1083 } 1084 } 1085 1086 @Override 1087 public void setInstallerPackageName(String targetPackage, 1088 String installerPackageName) { 1089 try { 1090 mPM.setInstallerPackageName(targetPackage, installerPackageName); 1091 } catch (RemoteException e) { 1092 // Should never happen! 1093 } 1094 } 1095 1096 @Override 1097 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) { 1098 try { 1099 mPM.movePackage(packageName, observer, flags); 1100 } catch (RemoteException e) { 1101 // Should never happen! 1102 } 1103 } 1104 1105 @Override 1106 public String getInstallerPackageName(String packageName) { 1107 try { 1108 return mPM.getInstallerPackageName(packageName); 1109 } catch (RemoteException e) { 1110 // Should never happen! 1111 } 1112 return null; 1113 } 1114 1115 @Override 1116 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) { 1117 try { 1118 mPM.deletePackage(packageName, observer, flags); 1119 } catch (RemoteException e) { 1120 // Should never happen! 1121 } 1122 } 1123 @Override 1124 public void clearApplicationUserData(String packageName, 1125 IPackageDataObserver observer) { 1126 try { 1127 mPM.clearApplicationUserData(packageName, observer, mContext.getUserId()); 1128 } catch (RemoteException e) { 1129 // Should never happen! 1130 } 1131 } 1132 @Override 1133 public void deleteApplicationCacheFiles(String packageName, 1134 IPackageDataObserver observer) { 1135 try { 1136 mPM.deleteApplicationCacheFiles(packageName, observer); 1137 } catch (RemoteException e) { 1138 // Should never happen! 1139 } 1140 } 1141 @Override 1142 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) { 1143 try { 1144 mPM.freeStorageAndNotify(idealStorageSize, observer); 1145 } catch (RemoteException e) { 1146 // Should never happen! 1147 } 1148 } 1149 1150 @Override 1151 public void freeStorage(long freeStorageSize, IntentSender pi) { 1152 try { 1153 mPM.freeStorage(freeStorageSize, pi); 1154 } catch (RemoteException e) { 1155 // Should never happen! 1156 } 1157 } 1158 1159 @Override 1160 public void getPackageSizeInfo(String packageName, int userHandle, 1161 IPackageStatsObserver observer) { 1162 try { 1163 mPM.getPackageSizeInfo(packageName, userHandle, observer); 1164 } catch (RemoteException e) { 1165 // Should never happen! 1166 } 1167 } 1168 @Override 1169 public void addPackageToPreferred(String packageName) { 1170 try { 1171 mPM.addPackageToPreferred(packageName); 1172 } catch (RemoteException e) { 1173 // Should never happen! 1174 } 1175 } 1176 1177 @Override 1178 public void removePackageFromPreferred(String packageName) { 1179 try { 1180 mPM.removePackageFromPreferred(packageName); 1181 } catch (RemoteException e) { 1182 // Should never happen! 1183 } 1184 } 1185 1186 @Override 1187 public List<PackageInfo> getPreferredPackages(int flags) { 1188 try { 1189 return mPM.getPreferredPackages(flags); 1190 } catch (RemoteException e) { 1191 // Should never happen! 1192 } 1193 return new ArrayList<PackageInfo>(); 1194 } 1195 1196 @Override 1197 public void addPreferredActivity(IntentFilter filter, 1198 int match, ComponentName[] set, ComponentName activity) { 1199 try { 1200 mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId()); 1201 } catch (RemoteException e) { 1202 // Should never happen! 1203 } 1204 } 1205 1206 @Override 1207 public void addPreferredActivity(IntentFilter filter, int match, 1208 ComponentName[] set, ComponentName activity, int userId) { 1209 try { 1210 mPM.addPreferredActivity(filter, match, set, activity, userId); 1211 } catch (RemoteException e) { 1212 // Should never happen! 1213 } 1214 } 1215 1216 @Override 1217 public void replacePreferredActivity(IntentFilter filter, 1218 int match, ComponentName[] set, ComponentName activity) { 1219 try { 1220 mPM.replacePreferredActivity(filter, match, set, activity); 1221 } catch (RemoteException e) { 1222 // Should never happen! 1223 } 1224 } 1225 1226 @Override 1227 public void clearPackagePreferredActivities(String packageName) { 1228 try { 1229 mPM.clearPackagePreferredActivities(packageName); 1230 } catch (RemoteException e) { 1231 // Should never happen! 1232 } 1233 } 1234 1235 @Override 1236 public int getPreferredActivities(List<IntentFilter> outFilters, 1237 List<ComponentName> outActivities, String packageName) { 1238 try { 1239 return mPM.getPreferredActivities(outFilters, outActivities, packageName); 1240 } catch (RemoteException e) { 1241 // Should never happen! 1242 } 1243 return 0; 1244 } 1245 1246 @Override 1247 public void setComponentEnabledSetting(ComponentName componentName, 1248 int newState, int flags) { 1249 try { 1250 mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId()); 1251 } catch (RemoteException e) { 1252 // Should never happen! 1253 } 1254 } 1255 1256 @Override 1257 public int getComponentEnabledSetting(ComponentName componentName) { 1258 try { 1259 return mPM.getComponentEnabledSetting(componentName, mContext.getUserId()); 1260 } catch (RemoteException e) { 1261 // Should never happen! 1262 } 1263 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 1264 } 1265 1266 @Override 1267 public void setApplicationEnabledSetting(String packageName, 1268 int newState, int flags) { 1269 try { 1270 mPM.setApplicationEnabledSetting(packageName, newState, flags, mContext.getUserId()); 1271 } catch (RemoteException e) { 1272 // Should never happen! 1273 } 1274 } 1275 1276 @Override 1277 public int getApplicationEnabledSetting(String packageName) { 1278 try { 1279 return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId()); 1280 } catch (RemoteException e) { 1281 // Should never happen! 1282 } 1283 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 1284 } 1285 1286 /** 1287 * @hide 1288 */ 1289 @Override 1290 public VerifierDeviceIdentity getVerifierDeviceIdentity() { 1291 try { 1292 return mPM.getVerifierDeviceIdentity(); 1293 } catch (RemoteException e) { 1294 // Should never happen! 1295 } 1296 return null; 1297 } 1298 1299 private final ContextImpl mContext; 1300 private final IPackageManager mPM; 1301 1302 private static final Object sSync = new Object(); 1303 private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache 1304 = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>(); 1305 private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache 1306 = new HashMap<ResourceName, WeakReference<CharSequence>>(); 1307 } 1308