ApplicationPackageManager.java revision 275e3e43f2fba72fa99001cafa2a70e5478fc545
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.annotation.DrawableRes; 20import android.annotation.NonNull; 21import android.annotation.Nullable; 22import android.annotation.StringRes; 23import android.annotation.XmlRes; 24import android.content.ComponentName; 25import android.content.ContentResolver; 26import android.content.Intent; 27import android.content.IntentFilter; 28import android.content.IntentSender; 29import android.content.pm.ActivityInfo; 30import android.content.pm.ApplicationInfo; 31import android.content.pm.ComponentInfo; 32import android.content.pm.ContainerEncryptionParams; 33import android.content.pm.FeatureInfo; 34import android.content.pm.IPackageDataObserver; 35import android.content.pm.IPackageDeleteObserver; 36import android.content.pm.IPackageInstallObserver; 37import android.content.pm.IPackageManager; 38import android.content.pm.IPackageMoveObserver; 39import android.content.pm.IPackageStatsObserver; 40import android.content.pm.InstrumentationInfo; 41import android.content.pm.IntentFilterVerificationInfo; 42import android.content.pm.KeySet; 43import android.content.pm.ManifestDigest; 44import android.content.pm.PackageInfo; 45import android.content.pm.PackageInstaller; 46import android.content.pm.PackageItemInfo; 47import android.content.pm.PackageManager; 48import android.content.pm.ParceledListSlice; 49import android.content.pm.PermissionGroupInfo; 50import android.content.pm.PermissionInfo; 51import android.content.pm.ProviderInfo; 52import android.content.pm.ResolveInfo; 53import android.content.pm.ServiceInfo; 54import android.content.pm.UserInfo; 55import android.content.pm.VerificationParams; 56import android.content.pm.VerifierDeviceIdentity; 57import android.content.res.Resources; 58import android.content.res.XmlResourceParser; 59import android.graphics.Bitmap; 60import android.graphics.Canvas; 61import android.graphics.Rect; 62import android.graphics.drawable.BitmapDrawable; 63import android.graphics.drawable.Drawable; 64import android.net.Uri; 65import android.os.Handler; 66import android.os.Looper; 67import android.os.Message; 68import android.os.Process; 69import android.os.RemoteException; 70import android.os.SystemProperties; 71import android.os.UserHandle; 72import android.os.UserManager; 73import android.os.storage.StorageManager; 74import android.os.storage.VolumeInfo; 75import android.util.ArrayMap; 76import android.util.Log; 77import android.view.Display; 78 79import dalvik.system.VMRuntime; 80 81import com.android.internal.annotations.GuardedBy; 82import com.android.internal.util.Preconditions; 83import com.android.internal.util.UserIcons; 84 85import java.lang.ref.WeakReference; 86import java.util.ArrayList; 87import java.util.Iterator; 88import java.util.List; 89import java.util.Objects; 90 91/*package*/ 92final class ApplicationPackageManager extends PackageManager { 93 private static final String TAG = "ApplicationPackageManager"; 94 private final static boolean DEBUG_ICONS = false; 95 96 // Default flags to use with PackageManager when no flags are given. 97 private final static int sDefaultFlags = PackageManager.GET_SHARED_LIBRARY_FILES; 98 99 private final Object mLock = new Object(); 100 101 @GuardedBy("mLock") 102 private UserManager mUserManager; 103 @GuardedBy("mLock") 104 private PackageInstaller mInstaller; 105 106 @GuardedBy("mDelegates") 107 private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>(); 108 109 UserManager getUserManager() { 110 synchronized (mLock) { 111 if (mUserManager == null) { 112 mUserManager = UserManager.get(mContext); 113 } 114 return mUserManager; 115 } 116 } 117 118 @Override 119 public PackageInfo getPackageInfo(String packageName, int flags) 120 throws NameNotFoundException { 121 try { 122 PackageInfo pi = mPM.getPackageInfo(packageName, flags, mContext.getUserId()); 123 if (pi != null) { 124 return pi; 125 } 126 } catch (RemoteException e) { 127 throw new RuntimeException("Package manager has died", e); 128 } 129 130 throw new NameNotFoundException(packageName); 131 } 132 133 @Override 134 public String[] currentToCanonicalPackageNames(String[] names) { 135 try { 136 return mPM.currentToCanonicalPackageNames(names); 137 } catch (RemoteException e) { 138 throw new RuntimeException("Package manager has died", e); 139 } 140 } 141 142 @Override 143 public String[] canonicalToCurrentPackageNames(String[] names) { 144 try { 145 return mPM.canonicalToCurrentPackageNames(names); 146 } catch (RemoteException e) { 147 throw new RuntimeException("Package manager has died", e); 148 } 149 } 150 151 @Override 152 public Intent getLaunchIntentForPackage(String packageName) { 153 // First see if the package has an INFO activity; the existence of 154 // such an activity is implied to be the desired front-door for the 155 // overall package (such as if it has multiple launcher entries). 156 Intent intentToResolve = new Intent(Intent.ACTION_MAIN); 157 intentToResolve.addCategory(Intent.CATEGORY_INFO); 158 intentToResolve.setPackage(packageName); 159 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0); 160 161 // Otherwise, try to find a main launcher activity. 162 if (ris == null || ris.size() <= 0) { 163 // reuse the intent instance 164 intentToResolve.removeCategory(Intent.CATEGORY_INFO); 165 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER); 166 intentToResolve.setPackage(packageName); 167 ris = queryIntentActivities(intentToResolve, 0); 168 } 169 if (ris == null || ris.size() <= 0) { 170 return null; 171 } 172 Intent intent = new Intent(intentToResolve); 173 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 174 intent.setClassName(ris.get(0).activityInfo.packageName, 175 ris.get(0).activityInfo.name); 176 return intent; 177 } 178 179 @Override 180 public Intent getLeanbackLaunchIntentForPackage(String packageName) { 181 // Try to find a main leanback_launcher activity. 182 Intent intentToResolve = new Intent(Intent.ACTION_MAIN); 183 intentToResolve.addCategory(Intent.CATEGORY_LEANBACK_LAUNCHER); 184 intentToResolve.setPackage(packageName); 185 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0); 186 187 if (ris == null || ris.size() <= 0) { 188 return null; 189 } 190 Intent intent = new Intent(intentToResolve); 191 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 192 intent.setClassName(ris.get(0).activityInfo.packageName, 193 ris.get(0).activityInfo.name); 194 return intent; 195 } 196 197 @Override 198 public int[] getPackageGids(String packageName) 199 throws NameNotFoundException { 200 try { 201 int[] gids = mPM.getPackageGids(packageName, mContext.getUserId()); 202 if (gids != null) { 203 return gids; 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 int getPackageUid(String packageName, int userHandle) 214 throws NameNotFoundException { 215 try { 216 int uid = mPM.getPackageUid(packageName, userHandle); 217 if (uid >= 0) { 218 return uid; 219 } 220 } catch (RemoteException e) { 221 throw new RuntimeException("Package manager has died", e); 222 } 223 224 throw new NameNotFoundException(packageName); 225 } 226 227 @Override 228 public PermissionInfo getPermissionInfo(String name, int flags) 229 throws NameNotFoundException { 230 try { 231 PermissionInfo pi = mPM.getPermissionInfo(name, flags); 232 if (pi != null) { 233 return pi; 234 } 235 } catch (RemoteException e) { 236 throw new RuntimeException("Package manager has died", e); 237 } 238 239 throw new NameNotFoundException(name); 240 } 241 242 @Override 243 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) 244 throws NameNotFoundException { 245 try { 246 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags); 247 if (pi != null) { 248 return pi; 249 } 250 } catch (RemoteException e) { 251 throw new RuntimeException("Package manager has died", e); 252 } 253 254 throw new NameNotFoundException(group); 255 } 256 257 @Override 258 public PermissionGroupInfo getPermissionGroupInfo(String name, 259 int flags) throws NameNotFoundException { 260 try { 261 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags); 262 if (pgi != null) { 263 return pgi; 264 } 265 } catch (RemoteException e) { 266 throw new RuntimeException("Package manager has died", e); 267 } 268 269 throw new NameNotFoundException(name); 270 } 271 272 @Override 273 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 274 try { 275 return mPM.getAllPermissionGroups(flags); 276 } catch (RemoteException e) { 277 throw new RuntimeException("Package manager has died", e); 278 } 279 } 280 281 @Override 282 public ApplicationInfo getApplicationInfo(String packageName, int flags) 283 throws NameNotFoundException { 284 try { 285 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, mContext.getUserId()); 286 if (ai != null) { 287 // This is a temporary hack. Callers must use 288 // createPackageContext(packageName).getApplicationInfo() to 289 // get the right paths. 290 maybeAdjustApplicationInfo(ai); 291 return ai; 292 } 293 } catch (RemoteException e) { 294 throw new RuntimeException("Package manager has died", e); 295 } 296 297 throw new NameNotFoundException(packageName); 298 } 299 300 private static void maybeAdjustApplicationInfo(ApplicationInfo info) { 301 // If we're dealing with a multi-arch application that has both 302 // 32 and 64 bit shared libraries, we might need to choose the secondary 303 // depending on what the current runtime's instruction set is. 304 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) { 305 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet(); 306 307 // Get the instruction set that the libraries of secondary Abi is supported. 308 // In presence of a native bridge this might be different than the one secondary Abi used. 309 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi); 310 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa); 311 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa; 312 313 // If the runtimeIsa is the same as the primary isa, then we do nothing. 314 // Everything will be set up correctly because info.nativeLibraryDir will 315 // correspond to the right ISA. 316 if (runtimeIsa.equals(secondaryIsa)) { 317 info.nativeLibraryDir = info.secondaryNativeLibraryDir; 318 } 319 } 320 } 321 322 323 @Override 324 public ActivityInfo getActivityInfo(ComponentName className, int flags) 325 throws NameNotFoundException { 326 try { 327 ActivityInfo ai = mPM.getActivityInfo(className, flags, mContext.getUserId()); 328 if (ai != null) { 329 return ai; 330 } 331 } catch (RemoteException e) { 332 throw new RuntimeException("Package manager has died", e); 333 } 334 335 throw new NameNotFoundException(className.toString()); 336 } 337 338 @Override 339 public ActivityInfo getReceiverInfo(ComponentName className, int flags) 340 throws NameNotFoundException { 341 try { 342 ActivityInfo ai = mPM.getReceiverInfo(className, flags, mContext.getUserId()); 343 if (ai != null) { 344 return ai; 345 } 346 } catch (RemoteException e) { 347 throw new RuntimeException("Package manager has died", e); 348 } 349 350 throw new NameNotFoundException(className.toString()); 351 } 352 353 @Override 354 public ServiceInfo getServiceInfo(ComponentName className, int flags) 355 throws NameNotFoundException { 356 try { 357 ServiceInfo si = mPM.getServiceInfo(className, flags, mContext.getUserId()); 358 if (si != null) { 359 return si; 360 } 361 } catch (RemoteException e) { 362 throw new RuntimeException("Package manager has died", e); 363 } 364 365 throw new NameNotFoundException(className.toString()); 366 } 367 368 @Override 369 public ProviderInfo getProviderInfo(ComponentName className, int flags) 370 throws NameNotFoundException { 371 try { 372 ProviderInfo pi = mPM.getProviderInfo(className, flags, mContext.getUserId()); 373 if (pi != null) { 374 return pi; 375 } 376 } catch (RemoteException e) { 377 throw new RuntimeException("Package manager has died", e); 378 } 379 380 throw new NameNotFoundException(className.toString()); 381 } 382 383 @Override 384 public String[] getSystemSharedLibraryNames() { 385 try { 386 return mPM.getSystemSharedLibraryNames(); 387 } catch (RemoteException e) { 388 throw new RuntimeException("Package manager has died", e); 389 } 390 } 391 392 @Override 393 public FeatureInfo[] getSystemAvailableFeatures() { 394 try { 395 return mPM.getSystemAvailableFeatures(); 396 } catch (RemoteException e) { 397 throw new RuntimeException("Package manager has died", e); 398 } 399 } 400 401 @Override 402 public boolean hasSystemFeature(String name) { 403 try { 404 return mPM.hasSystemFeature(name); 405 } catch (RemoteException e) { 406 throw new RuntimeException("Package manager has died", e); 407 } 408 } 409 410 @Override 411 public int checkPermission(String permName, String pkgName) { 412 try { 413 return mPM.checkPermission(permName, pkgName, mContext.getUserId()); 414 } catch (RemoteException e) { 415 throw new RuntimeException("Package manager has died", e); 416 } 417 } 418 419 @Override 420 public boolean addPermission(PermissionInfo info) { 421 try { 422 return mPM.addPermission(info); 423 } catch (RemoteException e) { 424 throw new RuntimeException("Package manager has died", e); 425 } 426 } 427 428 @Override 429 public boolean addPermissionAsync(PermissionInfo info) { 430 try { 431 return mPM.addPermissionAsync(info); 432 } catch (RemoteException e) { 433 throw new RuntimeException("Package manager has died", e); 434 } 435 } 436 437 @Override 438 public void removePermission(String name) { 439 try { 440 mPM.removePermission(name); 441 } catch (RemoteException e) { 442 throw new RuntimeException("Package manager has died", e); 443 } 444 } 445 446 @Override 447 public void grantPermission(String packageName, String permissionName, UserHandle user) { 448 try { 449 mPM.grantPermission(packageName, permissionName, user.getIdentifier()); 450 } catch (RemoteException e) { 451 throw new RuntimeException("Package manager has died", e); 452 } 453 } 454 455 @Override 456 public void revokePermission(String packageName, String permissionName, UserHandle user) { 457 try { 458 mPM.revokePermission(packageName, permissionName, user.getIdentifier()); 459 } catch (RemoteException e) { 460 throw new RuntimeException("Package manager has died", e); 461 } 462 } 463 464 @Override 465 public int checkSignatures(String pkg1, String pkg2) { 466 try { 467 return mPM.checkSignatures(pkg1, pkg2); 468 } catch (RemoteException e) { 469 throw new RuntimeException("Package manager has died", e); 470 } 471 } 472 473 @Override 474 public int checkSignatures(int uid1, int uid2) { 475 try { 476 return mPM.checkUidSignatures(uid1, uid2); 477 } catch (RemoteException e) { 478 throw new RuntimeException("Package manager has died", e); 479 } 480 } 481 482 @Override 483 public String[] getPackagesForUid(int uid) { 484 try { 485 return mPM.getPackagesForUid(uid); 486 } catch (RemoteException e) { 487 throw new RuntimeException("Package manager has died", e); 488 } 489 } 490 491 @Override 492 public String getNameForUid(int uid) { 493 try { 494 return mPM.getNameForUid(uid); 495 } catch (RemoteException e) { 496 throw new RuntimeException("Package manager has died", e); 497 } 498 } 499 500 @Override 501 public int getUidForSharedUser(String sharedUserName) 502 throws NameNotFoundException { 503 try { 504 int uid = mPM.getUidForSharedUser(sharedUserName); 505 if(uid != -1) { 506 return uid; 507 } 508 } catch (RemoteException e) { 509 throw new RuntimeException("Package manager has died", e); 510 } 511 throw new NameNotFoundException("No shared userid for user:"+sharedUserName); 512 } 513 514 @SuppressWarnings("unchecked") 515 @Override 516 public List<PackageInfo> getInstalledPackages(int flags) { 517 return getInstalledPackages(flags, mContext.getUserId()); 518 } 519 520 /** @hide */ 521 @Override 522 public List<PackageInfo> getInstalledPackages(int flags, int userId) { 523 try { 524 ParceledListSlice<PackageInfo> slice = mPM.getInstalledPackages(flags, userId); 525 return slice.getList(); 526 } catch (RemoteException e) { 527 throw new RuntimeException("Package manager has died", e); 528 } 529 } 530 531 @SuppressWarnings("unchecked") 532 @Override 533 public List<PackageInfo> getPackagesHoldingPermissions( 534 String[] permissions, int flags) { 535 final int userId = mContext.getUserId(); 536 try { 537 ParceledListSlice<PackageInfo> slice = mPM.getPackagesHoldingPermissions( 538 permissions, flags, userId); 539 return slice.getList(); 540 } catch (RemoteException e) { 541 throw new RuntimeException("Package manager has died", e); 542 } 543 } 544 545 @SuppressWarnings("unchecked") 546 @Override 547 public List<ApplicationInfo> getInstalledApplications(int flags) { 548 final int userId = mContext.getUserId(); 549 try { 550 ParceledListSlice<ApplicationInfo> slice = mPM.getInstalledApplications(flags, userId); 551 return slice.getList(); 552 } catch (RemoteException e) { 553 throw new RuntimeException("Package manager has died", e); 554 } 555 } 556 557 @Override 558 public ResolveInfo resolveActivity(Intent intent, int flags) { 559 return resolveActivityAsUser(intent, flags, mContext.getUserId()); 560 } 561 562 @Override 563 public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) { 564 try { 565 return mPM.resolveIntent( 566 intent, 567 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 568 flags, 569 userId); 570 } catch (RemoteException e) { 571 throw new RuntimeException("Package manager has died", e); 572 } 573 } 574 575 @Override 576 public List<ResolveInfo> queryIntentActivities(Intent intent, 577 int flags) { 578 return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId()); 579 } 580 581 /** @hide Same as above but for a specific user */ 582 @Override 583 public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, 584 int flags, int userId) { 585 try { 586 return mPM.queryIntentActivities( 587 intent, 588 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 589 flags, 590 userId); 591 } catch (RemoteException e) { 592 throw new RuntimeException("Package manager has died", e); 593 } 594 } 595 596 @Override 597 public List<ResolveInfo> queryIntentActivityOptions( 598 ComponentName caller, Intent[] specifics, Intent intent, 599 int flags) { 600 final ContentResolver resolver = mContext.getContentResolver(); 601 602 String[] specificTypes = null; 603 if (specifics != null) { 604 final int N = specifics.length; 605 for (int i=0; i<N; i++) { 606 Intent sp = specifics[i]; 607 if (sp != null) { 608 String t = sp.resolveTypeIfNeeded(resolver); 609 if (t != null) { 610 if (specificTypes == null) { 611 specificTypes = new String[N]; 612 } 613 specificTypes[i] = t; 614 } 615 } 616 } 617 } 618 619 try { 620 return mPM.queryIntentActivityOptions(caller, specifics, 621 specificTypes, intent, intent.resolveTypeIfNeeded(resolver), 622 flags, mContext.getUserId()); 623 } catch (RemoteException e) { 624 throw new RuntimeException("Package manager has died", e); 625 } 626 } 627 628 /** 629 * @hide 630 */ 631 @Override 632 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags, int userId) { 633 try { 634 return mPM.queryIntentReceivers( 635 intent, 636 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 637 flags, 638 userId); 639 } catch (RemoteException e) { 640 throw new RuntimeException("Package manager has died", e); 641 } 642 } 643 644 @Override 645 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) { 646 return queryBroadcastReceivers(intent, flags, mContext.getUserId()); 647 } 648 649 @Override 650 public ResolveInfo resolveService(Intent intent, int flags) { 651 try { 652 return mPM.resolveService( 653 intent, 654 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 655 flags, 656 mContext.getUserId()); 657 } catch (RemoteException e) { 658 throw new RuntimeException("Package manager has died", e); 659 } 660 } 661 662 @Override 663 public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) { 664 try { 665 return mPM.queryIntentServices( 666 intent, 667 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 668 flags, 669 userId); 670 } catch (RemoteException e) { 671 throw new RuntimeException("Package manager has died", e); 672 } 673 } 674 675 @Override 676 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) { 677 return queryIntentServicesAsUser(intent, flags, mContext.getUserId()); 678 } 679 680 @Override 681 public List<ResolveInfo> queryIntentContentProvidersAsUser( 682 Intent intent, int flags, int userId) { 683 try { 684 return mPM.queryIntentContentProviders(intent, 685 intent.resolveTypeIfNeeded(mContext.getContentResolver()), flags, userId); 686 } catch (RemoteException e) { 687 throw new RuntimeException("Package manager has died", e); 688 } 689 } 690 691 @Override 692 public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) { 693 return queryIntentContentProvidersAsUser(intent, flags, mContext.getUserId()); 694 } 695 696 @Override 697 public ProviderInfo resolveContentProvider(String name, int flags) { 698 return resolveContentProviderAsUser(name, flags, mContext.getUserId()); 699 } 700 701 /** @hide **/ 702 @Override 703 public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) { 704 try { 705 return mPM.resolveContentProvider(name, flags, userId); 706 } catch (RemoteException e) { 707 throw new RuntimeException("Package manager has died", e); 708 } 709 } 710 711 @Override 712 public List<ProviderInfo> queryContentProviders(String processName, 713 int uid, int flags) { 714 try { 715 return mPM.queryContentProviders(processName, uid, flags); 716 } catch (RemoteException e) { 717 throw new RuntimeException("Package manager has died", e); 718 } 719 } 720 721 @Override 722 public InstrumentationInfo getInstrumentationInfo( 723 ComponentName className, int flags) 724 throws NameNotFoundException { 725 try { 726 InstrumentationInfo ii = mPM.getInstrumentationInfo( 727 className, flags); 728 if (ii != null) { 729 return ii; 730 } 731 } catch (RemoteException e) { 732 throw new RuntimeException("Package manager has died", e); 733 } 734 735 throw new NameNotFoundException(className.toString()); 736 } 737 738 @Override 739 public List<InstrumentationInfo> queryInstrumentation( 740 String targetPackage, int flags) { 741 try { 742 return mPM.queryInstrumentation(targetPackage, flags); 743 } catch (RemoteException e) { 744 throw new RuntimeException("Package manager has died", e); 745 } 746 } 747 748 @Nullable 749 @Override 750 public Drawable getDrawable(String packageName, @DrawableRes int resId, 751 @Nullable ApplicationInfo appInfo) { 752 final ResourceName name = new ResourceName(packageName, resId); 753 final Drawable cachedIcon = getCachedIcon(name); 754 if (cachedIcon != null) { 755 return cachedIcon; 756 } 757 758 if (appInfo == null) { 759 try { 760 appInfo = getApplicationInfo(packageName, sDefaultFlags); 761 } catch (NameNotFoundException e) { 762 return null; 763 } 764 } 765 766 if (resId != 0) { 767 try { 768 final Resources r = getResourcesForApplication(appInfo); 769 final Drawable dr = r.getDrawable(resId, null); 770 if (dr != null) { 771 putCachedIcon(name, dr); 772 } 773 774 if (false) { 775 RuntimeException e = new RuntimeException("here"); 776 e.fillInStackTrace(); 777 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resId) 778 + " from package " + packageName 779 + ": app scale=" + r.getCompatibilityInfo().applicationScale 780 + ", caller scale=" + mContext.getResources() 781 .getCompatibilityInfo().applicationScale, 782 e); 783 } 784 if (DEBUG_ICONS) { 785 Log.v(TAG, "Getting drawable 0x" 786 + Integer.toHexString(resId) + " from " + r 787 + ": " + dr); 788 } 789 return dr; 790 } catch (NameNotFoundException e) { 791 Log.w("PackageManager", "Failure retrieving resources for " 792 + appInfo.packageName); 793 } catch (Resources.NotFoundException e) { 794 Log.w("PackageManager", "Failure retrieving resources for " 795 + appInfo.packageName + ": " + e.getMessage()); 796 } catch (Exception e) { 797 // If an exception was thrown, fall through to return 798 // default icon. 799 Log.w("PackageManager", "Failure retrieving icon 0x" 800 + Integer.toHexString(resId) + " in package " 801 + packageName, e); 802 } 803 } 804 805 return null; 806 } 807 808 @Override public Drawable getActivityIcon(ComponentName activityName) 809 throws NameNotFoundException { 810 return getActivityInfo(activityName, sDefaultFlags).loadIcon(this); 811 } 812 813 @Override public Drawable getActivityIcon(Intent intent) 814 throws NameNotFoundException { 815 if (intent.getComponent() != null) { 816 return getActivityIcon(intent.getComponent()); 817 } 818 819 ResolveInfo info = resolveActivity( 820 intent, PackageManager.MATCH_DEFAULT_ONLY); 821 if (info != null) { 822 return info.activityInfo.loadIcon(this); 823 } 824 825 throw new NameNotFoundException(intent.toUri(0)); 826 } 827 828 @Override public Drawable getDefaultActivityIcon() { 829 return Resources.getSystem().getDrawable( 830 com.android.internal.R.drawable.sym_def_app_icon); 831 } 832 833 @Override public Drawable getApplicationIcon(ApplicationInfo info) { 834 return info.loadIcon(this); 835 } 836 837 @Override public Drawable getApplicationIcon(String packageName) 838 throws NameNotFoundException { 839 return getApplicationIcon(getApplicationInfo(packageName, sDefaultFlags)); 840 } 841 842 @Override 843 public Drawable getActivityBanner(ComponentName activityName) 844 throws NameNotFoundException { 845 return getActivityInfo(activityName, sDefaultFlags).loadBanner(this); 846 } 847 848 @Override 849 public Drawable getActivityBanner(Intent intent) 850 throws NameNotFoundException { 851 if (intent.getComponent() != null) { 852 return getActivityBanner(intent.getComponent()); 853 } 854 855 ResolveInfo info = resolveActivity( 856 intent, PackageManager.MATCH_DEFAULT_ONLY); 857 if (info != null) { 858 return info.activityInfo.loadBanner(this); 859 } 860 861 throw new NameNotFoundException(intent.toUri(0)); 862 } 863 864 @Override 865 public Drawable getApplicationBanner(ApplicationInfo info) { 866 return info.loadBanner(this); 867 } 868 869 @Override 870 public Drawable getApplicationBanner(String packageName) 871 throws NameNotFoundException { 872 return getApplicationBanner(getApplicationInfo(packageName, sDefaultFlags)); 873 } 874 875 @Override 876 public Drawable getActivityLogo(ComponentName activityName) 877 throws NameNotFoundException { 878 return getActivityInfo(activityName, sDefaultFlags).loadLogo(this); 879 } 880 881 @Override 882 public Drawable getActivityLogo(Intent intent) 883 throws NameNotFoundException { 884 if (intent.getComponent() != null) { 885 return getActivityLogo(intent.getComponent()); 886 } 887 888 ResolveInfo info = resolveActivity( 889 intent, PackageManager.MATCH_DEFAULT_ONLY); 890 if (info != null) { 891 return info.activityInfo.loadLogo(this); 892 } 893 894 throw new NameNotFoundException(intent.toUri(0)); 895 } 896 897 @Override 898 public Drawable getApplicationLogo(ApplicationInfo info) { 899 return info.loadLogo(this); 900 } 901 902 @Override 903 public Drawable getApplicationLogo(String packageName) 904 throws NameNotFoundException { 905 return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags)); 906 } 907 908 @Override 909 public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) { 910 final int badgeResId = getBadgeResIdForUser(user.getIdentifier()); 911 if (badgeResId == 0) { 912 return icon; 913 } 914 Drawable badgeIcon = getDrawable("system", badgeResId, null); 915 return getBadgedDrawable(icon, badgeIcon, null, true); 916 } 917 918 @Override 919 public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user, 920 Rect badgeLocation, int badgeDensity) { 921 Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity); 922 if (badgeDrawable == null) { 923 return drawable; 924 } 925 return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true); 926 } 927 928 @Override 929 public Drawable getUserBadgeForDensity(UserHandle user, int density) { 930 UserInfo userInfo = getUserIfProfile(user.getIdentifier()); 931 if (userInfo != null && userInfo.isManagedProfile()) { 932 if (density <= 0) { 933 density = mContext.getResources().getDisplayMetrics().densityDpi; 934 } 935 return Resources.getSystem().getDrawableForDensity( 936 com.android.internal.R.drawable.ic_corp_badge, density); 937 } 938 return null; 939 } 940 941 @Override 942 public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) { 943 UserInfo userInfo = getUserIfProfile(user.getIdentifier()); 944 if (userInfo != null && userInfo.isManagedProfile()) { 945 return Resources.getSystem().getString( 946 com.android.internal.R.string.managed_profile_label_badge, label); 947 } 948 return label; 949 } 950 951 @Override 952 public Resources getResourcesForActivity(ComponentName activityName) 953 throws NameNotFoundException { 954 return getResourcesForApplication( 955 getActivityInfo(activityName, sDefaultFlags).applicationInfo); 956 } 957 958 @Override 959 public Resources getResourcesForApplication(@NonNull ApplicationInfo app) 960 throws NameNotFoundException { 961 if (app.packageName.equals("system")) { 962 return mContext.mMainThread.getSystemContext().getResources(); 963 } 964 final boolean sameUid = (app.uid == Process.myUid()); 965 final Resources r = mContext.mMainThread.getTopLevelResources( 966 sameUid ? app.sourceDir : app.publicSourceDir, 967 sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs, 968 app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY, 969 null, mContext.mPackageInfo); 970 if (r != null) { 971 return r; 972 } 973 throw new NameNotFoundException("Unable to open " + app.publicSourceDir); 974 } 975 976 @Override 977 public Resources getResourcesForApplication(String appPackageName) 978 throws NameNotFoundException { 979 return getResourcesForApplication( 980 getApplicationInfo(appPackageName, sDefaultFlags)); 981 } 982 983 /** @hide */ 984 @Override 985 public Resources getResourcesForApplicationAsUser(String appPackageName, int userId) 986 throws NameNotFoundException { 987 if (userId < 0) { 988 throw new IllegalArgumentException( 989 "Call does not support special user #" + userId); 990 } 991 if ("system".equals(appPackageName)) { 992 return mContext.mMainThread.getSystemContext().getResources(); 993 } 994 try { 995 ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId); 996 if (ai != null) { 997 return getResourcesForApplication(ai); 998 } 999 } catch (RemoteException e) { 1000 throw new RuntimeException("Package manager has died", e); 1001 } 1002 throw new NameNotFoundException("Package " + appPackageName + " doesn't exist"); 1003 } 1004 1005 int mCachedSafeMode = -1; 1006 @Override public boolean isSafeMode() { 1007 try { 1008 if (mCachedSafeMode < 0) { 1009 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0; 1010 } 1011 return mCachedSafeMode != 0; 1012 } catch (RemoteException e) { 1013 throw new RuntimeException("Package manager has died", e); 1014 } 1015 } 1016 1017 static void configurationChanged() { 1018 synchronized (sSync) { 1019 sIconCache.clear(); 1020 sStringCache.clear(); 1021 } 1022 } 1023 1024 ApplicationPackageManager(ContextImpl context, 1025 IPackageManager pm) { 1026 mContext = context; 1027 mPM = pm; 1028 } 1029 1030 @Nullable 1031 private Drawable getCachedIcon(@NonNull ResourceName name) { 1032 synchronized (sSync) { 1033 final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name); 1034 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for " 1035 + name + ": " + wr); 1036 if (wr != null) { // we have the activity 1037 final Drawable.ConstantState state = wr.get(); 1038 if (state != null) { 1039 if (DEBUG_ICONS) { 1040 Log.v(TAG, "Get cached drawable state for " + name + ": " + state); 1041 } 1042 // Note: It's okay here to not use the newDrawable(Resources) variant 1043 // of the API. The ConstantState comes from a drawable that was 1044 // originally created by passing the proper app Resources instance 1045 // which means the state should already contain the proper 1046 // resources specific information (like density.) See 1047 // BitmapDrawable.BitmapState for instance. 1048 return state.newDrawable(); 1049 } 1050 // our entry has been purged 1051 sIconCache.remove(name); 1052 } 1053 } 1054 return null; 1055 } 1056 1057 private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) { 1058 synchronized (sSync) { 1059 sIconCache.put(name, new WeakReference<>(dr.getConstantState())); 1060 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr); 1061 } 1062 } 1063 1064 static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) { 1065 boolean immediateGc = false; 1066 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) { 1067 immediateGc = true; 1068 } 1069 if (pkgList != null && (pkgList.length > 0)) { 1070 boolean needCleanup = false; 1071 for (String ssp : pkgList) { 1072 synchronized (sSync) { 1073 for (int i=sIconCache.size()-1; i>=0; i--) { 1074 ResourceName nm = sIconCache.keyAt(i); 1075 if (nm.packageName.equals(ssp)) { 1076 //Log.i(TAG, "Removing cached drawable for " + nm); 1077 sIconCache.removeAt(i); 1078 needCleanup = true; 1079 } 1080 } 1081 for (int i=sStringCache.size()-1; i>=0; i--) { 1082 ResourceName nm = sStringCache.keyAt(i); 1083 if (nm.packageName.equals(ssp)) { 1084 //Log.i(TAG, "Removing cached string for " + nm); 1085 sStringCache.removeAt(i); 1086 needCleanup = true; 1087 } 1088 } 1089 } 1090 } 1091 if (needCleanup || hasPkgInfo) { 1092 if (immediateGc) { 1093 // Schedule an immediate gc. 1094 Runtime.getRuntime().gc(); 1095 } else { 1096 ActivityThread.currentActivityThread().scheduleGcIdler(); 1097 } 1098 } 1099 } 1100 } 1101 1102 private static final class ResourceName { 1103 final String packageName; 1104 final int iconId; 1105 1106 ResourceName(String _packageName, int _iconId) { 1107 packageName = _packageName; 1108 iconId = _iconId; 1109 } 1110 1111 ResourceName(ApplicationInfo aInfo, int _iconId) { 1112 this(aInfo.packageName, _iconId); 1113 } 1114 1115 ResourceName(ComponentInfo cInfo, int _iconId) { 1116 this(cInfo.applicationInfo.packageName, _iconId); 1117 } 1118 1119 ResourceName(ResolveInfo rInfo, int _iconId) { 1120 this(rInfo.activityInfo.applicationInfo.packageName, _iconId); 1121 } 1122 1123 @Override 1124 public boolean equals(Object o) { 1125 if (this == o) return true; 1126 if (o == null || getClass() != o.getClass()) return false; 1127 1128 ResourceName that = (ResourceName) o; 1129 1130 if (iconId != that.iconId) return false; 1131 return !(packageName != null ? 1132 !packageName.equals(that.packageName) : that.packageName != null); 1133 1134 } 1135 1136 @Override 1137 public int hashCode() { 1138 int result; 1139 result = packageName.hashCode(); 1140 result = 31 * result + iconId; 1141 return result; 1142 } 1143 1144 @Override 1145 public String toString() { 1146 return "{ResourceName " + packageName + " / " + iconId + "}"; 1147 } 1148 } 1149 1150 private CharSequence getCachedString(ResourceName name) { 1151 synchronized (sSync) { 1152 WeakReference<CharSequence> wr = sStringCache.get(name); 1153 if (wr != null) { // we have the activity 1154 CharSequence cs = wr.get(); 1155 if (cs != null) { 1156 return cs; 1157 } 1158 // our entry has been purged 1159 sStringCache.remove(name); 1160 } 1161 } 1162 return null; 1163 } 1164 1165 private void putCachedString(ResourceName name, CharSequence cs) { 1166 synchronized (sSync) { 1167 sStringCache.put(name, new WeakReference<CharSequence>(cs)); 1168 } 1169 } 1170 1171 @Override 1172 public CharSequence getText(String packageName, @StringRes int resid, 1173 ApplicationInfo appInfo) { 1174 ResourceName name = new ResourceName(packageName, resid); 1175 CharSequence text = getCachedString(name); 1176 if (text != null) { 1177 return text; 1178 } 1179 if (appInfo == null) { 1180 try { 1181 appInfo = getApplicationInfo(packageName, sDefaultFlags); 1182 } catch (NameNotFoundException e) { 1183 return null; 1184 } 1185 } 1186 try { 1187 Resources r = getResourcesForApplication(appInfo); 1188 text = r.getText(resid); 1189 putCachedString(name, text); 1190 return text; 1191 } catch (NameNotFoundException e) { 1192 Log.w("PackageManager", "Failure retrieving resources for " 1193 + appInfo.packageName); 1194 } catch (RuntimeException e) { 1195 // If an exception was thrown, fall through to return 1196 // default icon. 1197 Log.w("PackageManager", "Failure retrieving text 0x" 1198 + Integer.toHexString(resid) + " in package " 1199 + packageName, e); 1200 } 1201 return null; 1202 } 1203 1204 @Override 1205 public XmlResourceParser getXml(String packageName, @XmlRes int resid, 1206 ApplicationInfo appInfo) { 1207 if (appInfo == null) { 1208 try { 1209 appInfo = getApplicationInfo(packageName, sDefaultFlags); 1210 } catch (NameNotFoundException e) { 1211 return null; 1212 } 1213 } 1214 try { 1215 Resources r = getResourcesForApplication(appInfo); 1216 return r.getXml(resid); 1217 } catch (RuntimeException e) { 1218 // If an exception was thrown, fall through to return 1219 // default icon. 1220 Log.w("PackageManager", "Failure retrieving xml 0x" 1221 + Integer.toHexString(resid) + " in package " 1222 + packageName, e); 1223 } catch (NameNotFoundException e) { 1224 Log.w("PackageManager", "Failure retrieving resources for " 1225 + appInfo.packageName); 1226 } 1227 return null; 1228 } 1229 1230 @Override 1231 public CharSequence getApplicationLabel(ApplicationInfo info) { 1232 return info.loadLabel(this); 1233 } 1234 1235 @Override 1236 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, 1237 String installerPackageName) { 1238 final VerificationParams verificationParams = new VerificationParams(null, null, 1239 null, VerificationParams.NO_UID, null); 1240 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags, 1241 installerPackageName, verificationParams, null); 1242 } 1243 1244 @Override 1245 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, 1246 int flags, String installerPackageName, Uri verificationURI, 1247 ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) { 1248 final VerificationParams verificationParams = new VerificationParams(verificationURI, null, 1249 null, VerificationParams.NO_UID, manifestDigest); 1250 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags, 1251 installerPackageName, verificationParams, encryptionParams); 1252 } 1253 1254 @Override 1255 public void installPackageWithVerificationAndEncryption(Uri packageURI, 1256 IPackageInstallObserver observer, int flags, String installerPackageName, 1257 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { 1258 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags, 1259 installerPackageName, verificationParams, encryptionParams); 1260 } 1261 1262 @Override 1263 public void installPackage(Uri packageURI, PackageInstallObserver observer, 1264 int flags, String installerPackageName) { 1265 final VerificationParams verificationParams = new VerificationParams(null, null, 1266 null, VerificationParams.NO_UID, null); 1267 installCommon(packageURI, observer, flags, installerPackageName, verificationParams, null); 1268 } 1269 1270 @Override 1271 public void installPackageWithVerification(Uri packageURI, 1272 PackageInstallObserver observer, int flags, String installerPackageName, 1273 Uri verificationURI, ManifestDigest manifestDigest, 1274 ContainerEncryptionParams encryptionParams) { 1275 final VerificationParams verificationParams = new VerificationParams(verificationURI, null, 1276 null, VerificationParams.NO_UID, manifestDigest); 1277 installCommon(packageURI, observer, flags, installerPackageName, verificationParams, 1278 encryptionParams); 1279 } 1280 1281 @Override 1282 public void installPackageWithVerificationAndEncryption(Uri packageURI, 1283 PackageInstallObserver observer, int flags, String installerPackageName, 1284 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { 1285 installCommon(packageURI, observer, flags, installerPackageName, verificationParams, 1286 encryptionParams); 1287 } 1288 1289 private void installCommon(Uri packageURI, 1290 PackageInstallObserver observer, int flags, String installerPackageName, 1291 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { 1292 if (!"file".equals(packageURI.getScheme())) { 1293 throw new UnsupportedOperationException("Only file:// URIs are supported"); 1294 } 1295 if (encryptionParams != null) { 1296 throw new UnsupportedOperationException("ContainerEncryptionParams not supported"); 1297 } 1298 1299 final String originPath = packageURI.getPath(); 1300 try { 1301 mPM.installPackage(originPath, observer.getBinder(), flags, installerPackageName, 1302 verificationParams, null); 1303 } catch (RemoteException ignored) { 1304 } 1305 } 1306 1307 @Override 1308 public int installExistingPackage(String packageName) 1309 throws NameNotFoundException { 1310 try { 1311 int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId()); 1312 if (res == INSTALL_FAILED_INVALID_URI) { 1313 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 1314 } 1315 return res; 1316 } catch (RemoteException e) { 1317 // Should never happen! 1318 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 1319 } 1320 } 1321 1322 @Override 1323 public void verifyPendingInstall(int id, int response) { 1324 try { 1325 mPM.verifyPendingInstall(id, response); 1326 } catch (RemoteException e) { 1327 // Should never happen! 1328 } 1329 } 1330 1331 @Override 1332 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 1333 long millisecondsToDelay) { 1334 try { 1335 mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay); 1336 } catch (RemoteException e) { 1337 // Should never happen! 1338 } 1339 } 1340 1341 @Override 1342 public void verifyIntentFilter(int id, int verificationCode, List<String> outFailedDomains) { 1343 try { 1344 mPM.verifyIntentFilter(id, verificationCode, outFailedDomains); 1345 } catch (RemoteException e) { 1346 // Should never happen! 1347 } 1348 } 1349 1350 @Override 1351 public int getIntentVerificationStatus(String packageName, int userId) { 1352 try { 1353 return mPM.getIntentVerificationStatus(packageName, userId); 1354 } catch (RemoteException e) { 1355 // Should never happen! 1356 return PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 1357 } 1358 } 1359 1360 @Override 1361 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 1362 try { 1363 return mPM.updateIntentVerificationStatus(packageName, status, userId); 1364 } catch (RemoteException e) { 1365 // Should never happen! 1366 return false; 1367 } 1368 } 1369 1370 @Override 1371 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 1372 try { 1373 return mPM.getIntentFilterVerifications(packageName); 1374 } catch (RemoteException e) { 1375 // Should never happen! 1376 return null; 1377 } 1378 } 1379 1380 @Override 1381 public List<IntentFilter> getAllIntentFilters(String packageName) { 1382 try { 1383 return mPM.getAllIntentFilters(packageName); 1384 } catch (RemoteException e) { 1385 // Should never happen! 1386 return null; 1387 } 1388 } 1389 1390 @Override 1391 public String getDefaultBrowserPackageName(int userId) { 1392 try { 1393 return mPM.getDefaultBrowserPackageName(userId); 1394 } catch (RemoteException e) { 1395 // Should never happen! 1396 return null; 1397 } 1398 } 1399 1400 @Override 1401 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 1402 try { 1403 return mPM.setDefaultBrowserPackageName(packageName, userId); 1404 } catch (RemoteException e) { 1405 // Should never happen! 1406 return false; 1407 } 1408 } 1409 1410 @Override 1411 public void setInstallerPackageName(String targetPackage, 1412 String installerPackageName) { 1413 try { 1414 mPM.setInstallerPackageName(targetPackage, installerPackageName); 1415 } catch (RemoteException e) { 1416 // Should never happen! 1417 } 1418 } 1419 1420 @Override 1421 public String getInstallerPackageName(String packageName) { 1422 try { 1423 return mPM.getInstallerPackageName(packageName); 1424 } catch (RemoteException e) { 1425 // Should never happen! 1426 } 1427 return null; 1428 } 1429 1430 @Override 1431 public int getMoveStatus(int moveId) { 1432 try { 1433 return mPM.getMoveStatus(moveId); 1434 } catch (RemoteException e) { 1435 throw e.rethrowAsRuntimeException(); 1436 } 1437 } 1438 1439 @Override 1440 public void registerMoveCallback(MoveCallback callback, Handler handler) { 1441 synchronized (mDelegates) { 1442 final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback, 1443 handler.getLooper()); 1444 try { 1445 mPM.registerMoveCallback(delegate); 1446 } catch (RemoteException e) { 1447 throw e.rethrowAsRuntimeException(); 1448 } 1449 mDelegates.add(delegate); 1450 } 1451 } 1452 1453 @Override 1454 public void unregisterMoveCallback(MoveCallback callback) { 1455 synchronized (mDelegates) { 1456 for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) { 1457 final MoveCallbackDelegate delegate = i.next(); 1458 if (delegate.mCallback == callback) { 1459 try { 1460 mPM.unregisterMoveCallback(delegate); 1461 } catch (RemoteException e) { 1462 throw e.rethrowAsRuntimeException(); 1463 } 1464 i.remove(); 1465 } 1466 } 1467 } 1468 } 1469 1470 @Override 1471 public int movePackage(String packageName, VolumeInfo vol) { 1472 try { 1473 final String volumeUuid; 1474 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) { 1475 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL; 1476 } else if (vol.isPrimaryPhysical()) { 1477 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 1478 } else { 1479 volumeUuid = Preconditions.checkNotNull(vol.fsUuid); 1480 } 1481 1482 return mPM.movePackage(packageName, volumeUuid); 1483 } catch (RemoteException e) { 1484 throw e.rethrowAsRuntimeException(); 1485 } 1486 } 1487 1488 @Override 1489 public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) { 1490 final StorageManager storage = mContext.getSystemService(StorageManager.class); 1491 if (app.isInternal()) { 1492 return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL); 1493 } else if (app.isExternalAsec()) { 1494 return storage.getPrimaryPhysicalVolume(); 1495 } else { 1496 return storage.findVolumeByUuid(app.volumeUuid); 1497 } 1498 } 1499 1500 @Override 1501 public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) { 1502 final StorageManager storage = mContext.getSystemService(StorageManager.class); 1503 final VolumeInfo currentVol = getPackageCurrentVolume(app); 1504 final List<VolumeInfo> vols = storage.getVolumes(); 1505 final List<VolumeInfo> candidates = new ArrayList<>(); 1506 for (VolumeInfo vol : vols) { 1507 if (Objects.equals(vol, currentVol) || isPackageCandidateVolume(app, vol)) { 1508 candidates.add(vol); 1509 } 1510 } 1511 return candidates; 1512 } 1513 1514 private static boolean isPackageCandidateVolume(ApplicationInfo app, VolumeInfo vol) { 1515 // Private internal is always an option 1516 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) { 1517 return true; 1518 } 1519 1520 // System apps and apps demanding internal storage can't be moved 1521 // anywhere else 1522 if (app.isSystemApp() 1523 || app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 1524 return false; 1525 } 1526 1527 // Gotta be able to write there 1528 if (!vol.isMountedWritable()) { 1529 return false; 1530 } 1531 1532 // Moving into an ASEC on public primary is only option internal 1533 if (vol.isPrimaryPhysical()) { 1534 return app.isInternal(); 1535 } 1536 1537 // Otherwise we can move to any private volume 1538 return (vol.getType() == VolumeInfo.TYPE_PRIVATE); 1539 } 1540 1541 @Override 1542 public int movePrimaryStorage(VolumeInfo vol) { 1543 try { 1544 final String volumeUuid; 1545 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) { 1546 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL; 1547 } else if (vol.isPrimaryPhysical()) { 1548 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 1549 } else { 1550 volumeUuid = Preconditions.checkNotNull(vol.fsUuid); 1551 } 1552 1553 return mPM.movePrimaryStorage(volumeUuid); 1554 } catch (RemoteException e) { 1555 throw e.rethrowAsRuntimeException(); 1556 } 1557 } 1558 1559 @Override 1560 public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() { 1561 final StorageManager storage = mContext.getSystemService(StorageManager.class); 1562 final String volumeUuid = storage.getPrimaryStorageUuid(); 1563 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 1564 return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL); 1565 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 1566 return storage.getPrimaryPhysicalVolume(); 1567 } else { 1568 return storage.findVolumeByUuid(volumeUuid); 1569 } 1570 } 1571 1572 @Override 1573 public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() { 1574 final StorageManager storage = mContext.getSystemService(StorageManager.class); 1575 final VolumeInfo currentVol = getPrimaryStorageCurrentVolume(); 1576 final List<VolumeInfo> vols = storage.getVolumes(); 1577 final List<VolumeInfo> candidates = new ArrayList<>(); 1578 for (VolumeInfo vol : vols) { 1579 if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) { 1580 candidates.add(vol); 1581 } 1582 } 1583 return candidates; 1584 } 1585 1586 private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) { 1587 // Private internal is always an option 1588 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) { 1589 return true; 1590 } 1591 1592 // Gotta be able to write there 1593 if (!vol.isMountedWritable()) { 1594 return false; 1595 } 1596 1597 // We can move to public volumes on legacy devices 1598 if ((vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.getDisk().isDefaultPrimary()) { 1599 return true; 1600 } 1601 1602 // Otherwise we can move to any private volume 1603 return (vol.getType() == VolumeInfo.TYPE_PRIVATE); 1604 } 1605 1606 @Override 1607 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) { 1608 try { 1609 mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags); 1610 } catch (RemoteException e) { 1611 // Should never happen! 1612 } 1613 } 1614 1615 @Override 1616 public void clearApplicationUserData(String packageName, 1617 IPackageDataObserver observer) { 1618 try { 1619 mPM.clearApplicationUserData(packageName, observer, mContext.getUserId()); 1620 } catch (RemoteException e) { 1621 // Should never happen! 1622 } 1623 } 1624 @Override 1625 public void deleteApplicationCacheFiles(String packageName, 1626 IPackageDataObserver observer) { 1627 try { 1628 mPM.deleteApplicationCacheFiles(packageName, observer); 1629 } catch (RemoteException e) { 1630 // Should never happen! 1631 } 1632 } 1633 1634 @Override 1635 public void freeStorageAndNotify(String volumeUuid, long idealStorageSize, 1636 IPackageDataObserver observer) { 1637 try { 1638 mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer); 1639 } catch (RemoteException e) { 1640 // Should never happen! 1641 } 1642 } 1643 1644 @Override 1645 public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) { 1646 try { 1647 mPM.freeStorage(volumeUuid, freeStorageSize, pi); 1648 } catch (RemoteException e) { 1649 // Should never happen! 1650 } 1651 } 1652 1653 @Override 1654 public void getPackageSizeInfo(String packageName, int userHandle, 1655 IPackageStatsObserver observer) { 1656 try { 1657 mPM.getPackageSizeInfo(packageName, userHandle, observer); 1658 } catch (RemoteException e) { 1659 // Should never happen! 1660 } 1661 } 1662 @Override 1663 public void addPackageToPreferred(String packageName) { 1664 try { 1665 mPM.addPackageToPreferred(packageName); 1666 } catch (RemoteException e) { 1667 // Should never happen! 1668 } 1669 } 1670 1671 @Override 1672 public void removePackageFromPreferred(String packageName) { 1673 try { 1674 mPM.removePackageFromPreferred(packageName); 1675 } catch (RemoteException e) { 1676 // Should never happen! 1677 } 1678 } 1679 1680 @Override 1681 public List<PackageInfo> getPreferredPackages(int flags) { 1682 try { 1683 return mPM.getPreferredPackages(flags); 1684 } catch (RemoteException e) { 1685 // Should never happen! 1686 } 1687 return new ArrayList<PackageInfo>(); 1688 } 1689 1690 @Override 1691 public void addPreferredActivity(IntentFilter filter, 1692 int match, ComponentName[] set, ComponentName activity) { 1693 try { 1694 mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId()); 1695 } catch (RemoteException e) { 1696 // Should never happen! 1697 } 1698 } 1699 1700 @Override 1701 public void addPreferredActivity(IntentFilter filter, int match, 1702 ComponentName[] set, ComponentName activity, int userId) { 1703 try { 1704 mPM.addPreferredActivity(filter, match, set, activity, userId); 1705 } catch (RemoteException e) { 1706 // Should never happen! 1707 } 1708 } 1709 1710 @Override 1711 public void replacePreferredActivity(IntentFilter filter, 1712 int match, ComponentName[] set, ComponentName activity) { 1713 try { 1714 mPM.replacePreferredActivity(filter, match, set, activity, UserHandle.myUserId()); 1715 } catch (RemoteException e) { 1716 // Should never happen! 1717 } 1718 } 1719 1720 @Override 1721 public void replacePreferredActivityAsUser(IntentFilter filter, 1722 int match, ComponentName[] set, ComponentName activity, 1723 int userId) { 1724 try { 1725 mPM.replacePreferredActivity(filter, match, set, activity, userId); 1726 } catch (RemoteException e) { 1727 // Should never happen! 1728 } 1729 } 1730 1731 @Override 1732 public void clearPackagePreferredActivities(String packageName) { 1733 try { 1734 mPM.clearPackagePreferredActivities(packageName); 1735 } catch (RemoteException e) { 1736 // Should never happen! 1737 } 1738 } 1739 1740 @Override 1741 public int getPreferredActivities(List<IntentFilter> outFilters, 1742 List<ComponentName> outActivities, String packageName) { 1743 try { 1744 return mPM.getPreferredActivities(outFilters, outActivities, packageName); 1745 } catch (RemoteException e) { 1746 // Should never happen! 1747 } 1748 return 0; 1749 } 1750 1751 @Override 1752 public ComponentName getHomeActivities(List<ResolveInfo> outActivities) { 1753 try { 1754 return mPM.getHomeActivities(outActivities); 1755 } catch (RemoteException e) { 1756 // Should never happen! 1757 } 1758 return null; 1759 } 1760 1761 @Override 1762 public void setComponentEnabledSetting(ComponentName componentName, 1763 int newState, int flags) { 1764 try { 1765 mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId()); 1766 } catch (RemoteException e) { 1767 // Should never happen! 1768 } 1769 } 1770 1771 @Override 1772 public int getComponentEnabledSetting(ComponentName componentName) { 1773 try { 1774 return mPM.getComponentEnabledSetting(componentName, mContext.getUserId()); 1775 } catch (RemoteException e) { 1776 // Should never happen! 1777 } 1778 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 1779 } 1780 1781 @Override 1782 public void setApplicationEnabledSetting(String packageName, 1783 int newState, int flags) { 1784 try { 1785 mPM.setApplicationEnabledSetting(packageName, newState, flags, 1786 mContext.getUserId(), mContext.getOpPackageName()); 1787 } catch (RemoteException e) { 1788 // Should never happen! 1789 } 1790 } 1791 1792 @Override 1793 public int getApplicationEnabledSetting(String packageName) { 1794 try { 1795 return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId()); 1796 } catch (RemoteException e) { 1797 // Should never happen! 1798 } 1799 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 1800 } 1801 1802 @Override 1803 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 1804 UserHandle user) { 1805 try { 1806 return mPM.setApplicationHiddenSettingAsUser(packageName, hidden, 1807 user.getIdentifier()); 1808 } catch (RemoteException re) { 1809 // Should never happen! 1810 } 1811 return false; 1812 } 1813 1814 @Override 1815 public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) { 1816 try { 1817 return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier()); 1818 } catch (RemoteException re) { 1819 // Should never happen! 1820 } 1821 return false; 1822 } 1823 1824 /** @hide */ 1825 @Override 1826 public KeySet getKeySetByAlias(String packageName, String alias) { 1827 Preconditions.checkNotNull(packageName); 1828 Preconditions.checkNotNull(alias); 1829 KeySet ks; 1830 try { 1831 ks = mPM.getKeySetByAlias(packageName, alias); 1832 } catch (RemoteException e) { 1833 return null; 1834 } 1835 return ks; 1836 } 1837 1838 /** @hide */ 1839 @Override 1840 public KeySet getSigningKeySet(String packageName) { 1841 Preconditions.checkNotNull(packageName); 1842 KeySet ks; 1843 try { 1844 ks = mPM.getSigningKeySet(packageName); 1845 } catch (RemoteException e) { 1846 return null; 1847 } 1848 return ks; 1849 } 1850 1851 /** @hide */ 1852 @Override 1853 public boolean isSignedBy(String packageName, KeySet ks) { 1854 Preconditions.checkNotNull(packageName); 1855 Preconditions.checkNotNull(ks); 1856 try { 1857 return mPM.isPackageSignedByKeySet(packageName, ks); 1858 } catch (RemoteException e) { 1859 return false; 1860 } 1861 } 1862 1863 /** @hide */ 1864 @Override 1865 public boolean isSignedByExactly(String packageName, KeySet ks) { 1866 Preconditions.checkNotNull(packageName); 1867 Preconditions.checkNotNull(ks); 1868 try { 1869 return mPM.isPackageSignedByKeySetExactly(packageName, ks); 1870 } catch (RemoteException e) { 1871 return false; 1872 } 1873 } 1874 1875 /** 1876 * @hide 1877 */ 1878 @Override 1879 public VerifierDeviceIdentity getVerifierDeviceIdentity() { 1880 try { 1881 return mPM.getVerifierDeviceIdentity(); 1882 } catch (RemoteException e) { 1883 // Should never happen! 1884 } 1885 return null; 1886 } 1887 1888 /** 1889 * @hide 1890 */ 1891 @Override 1892 public boolean isUpgrade() { 1893 try { 1894 return mPM.isUpgrade(); 1895 } catch (RemoteException e) { 1896 return false; 1897 } 1898 } 1899 1900 @Override 1901 public PackageInstaller getPackageInstaller() { 1902 synchronized (mLock) { 1903 if (mInstaller == null) { 1904 try { 1905 mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(), 1906 mContext.getPackageName(), mContext.getUserId()); 1907 } catch (RemoteException e) { 1908 throw e.rethrowAsRuntimeException(); 1909 } 1910 } 1911 return mInstaller; 1912 } 1913 } 1914 1915 @Override 1916 public boolean isPackageAvailable(String packageName) { 1917 try { 1918 return mPM.isPackageAvailable(packageName, mContext.getUserId()); 1919 } catch (RemoteException e) { 1920 throw e.rethrowAsRuntimeException(); 1921 } 1922 } 1923 1924 /** 1925 * @hide 1926 */ 1927 @Override 1928 public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId, 1929 int flags) { 1930 try { 1931 mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(), 1932 sourceUserId, targetUserId, flags); 1933 } catch (RemoteException e) { 1934 // Should never happen! 1935 } 1936 } 1937 1938 /** 1939 * @hide 1940 */ 1941 @Override 1942 public void clearCrossProfileIntentFilters(int sourceUserId) { 1943 try { 1944 mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName()); 1945 } catch (RemoteException e) { 1946 // Should never happen! 1947 } 1948 } 1949 1950 /** 1951 * @hide 1952 */ 1953 public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) { 1954 Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo); 1955 if (itemInfo.showUserIcon != UserHandle.USER_NULL) { 1956 return dr; 1957 } 1958 return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId())); 1959 } 1960 1961 /** 1962 * @hide 1963 */ 1964 public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) { 1965 if (itemInfo.showUserIcon != UserHandle.USER_NULL) { 1966 Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon); 1967 if (bitmap == null) { 1968 return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false); 1969 } 1970 return new BitmapDrawable(bitmap); 1971 } 1972 Drawable dr = null; 1973 if (itemInfo.packageName != null) { 1974 dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo); 1975 } 1976 if (dr == null) { 1977 dr = itemInfo.loadDefaultIcon(this); 1978 } 1979 return dr; 1980 } 1981 1982 private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable, 1983 Rect badgeLocation, boolean tryBadgeInPlace) { 1984 final int badgedWidth = drawable.getIntrinsicWidth(); 1985 final int badgedHeight = drawable.getIntrinsicHeight(); 1986 final boolean canBadgeInPlace = tryBadgeInPlace 1987 && (drawable instanceof BitmapDrawable) 1988 && ((BitmapDrawable) drawable).getBitmap().isMutable(); 1989 1990 final Bitmap bitmap; 1991 if (canBadgeInPlace) { 1992 bitmap = ((BitmapDrawable) drawable).getBitmap(); 1993 } else { 1994 bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888); 1995 } 1996 Canvas canvas = new Canvas(bitmap); 1997 1998 if (!canBadgeInPlace) { 1999 drawable.setBounds(0, 0, badgedWidth, badgedHeight); 2000 drawable.draw(canvas); 2001 } 2002 2003 if (badgeLocation != null) { 2004 if (badgeLocation.left < 0 || badgeLocation.top < 0 2005 || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) { 2006 throw new IllegalArgumentException("Badge location " + badgeLocation 2007 + " not in badged drawable bounds " 2008 + new Rect(0, 0, badgedWidth, badgedHeight)); 2009 } 2010 badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height()); 2011 2012 canvas.save(); 2013 canvas.translate(badgeLocation.left, badgeLocation.top); 2014 badgeDrawable.draw(canvas); 2015 canvas.restore(); 2016 } else { 2017 badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight); 2018 badgeDrawable.draw(canvas); 2019 } 2020 2021 if (!canBadgeInPlace) { 2022 BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap); 2023 2024 if (drawable instanceof BitmapDrawable) { 2025 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; 2026 mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity()); 2027 } 2028 2029 return mergedDrawable; 2030 } 2031 2032 return drawable; 2033 } 2034 2035 private int getBadgeResIdForUser(int userHandle) { 2036 // Return the framework-provided badge. 2037 UserInfo userInfo = getUserIfProfile(userHandle); 2038 if (userInfo != null && userInfo.isManagedProfile()) { 2039 return com.android.internal.R.drawable.ic_corp_icon_badge; 2040 } 2041 return 0; 2042 } 2043 2044 private UserInfo getUserIfProfile(int userHandle) { 2045 List<UserInfo> userProfiles = getUserManager().getProfiles(UserHandle.myUserId()); 2046 for (UserInfo user : userProfiles) { 2047 if (user.id == userHandle) { 2048 return user; 2049 } 2050 } 2051 return null; 2052 } 2053 2054 /** {@hide} */ 2055 private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements 2056 Handler.Callback { 2057 private static final int MSG_STARTED = 1; 2058 private static final int MSG_STATUS_CHANGED = 2; 2059 2060 final MoveCallback mCallback; 2061 final Handler mHandler; 2062 2063 public MoveCallbackDelegate(MoveCallback callback, Looper looper) { 2064 mCallback = callback; 2065 mHandler = new Handler(looper, this); 2066 } 2067 2068 @Override 2069 public boolean handleMessage(Message msg) { 2070 final int moveId = msg.arg1; 2071 switch (msg.what) { 2072 case MSG_STARTED: 2073 mCallback.onStarted(moveId, (String) msg.obj); 2074 return true; 2075 case MSG_STATUS_CHANGED: 2076 mCallback.onStatusChanged(moveId, msg.arg2, (long) msg.obj); 2077 return true; 2078 } 2079 return false; 2080 } 2081 2082 @Override 2083 public void onStarted(int moveId, String title) { 2084 mHandler.obtainMessage(MSG_STARTED, moveId, 0, title).sendToTarget(); 2085 } 2086 2087 @Override 2088 public void onStatusChanged(int moveId, int status, long estMillis) { 2089 mHandler.obtainMessage(MSG_STATUS_CHANGED, moveId, status, estMillis).sendToTarget(); 2090 } 2091 } 2092 2093 private final ContextImpl mContext; 2094 private final IPackageManager mPM; 2095 2096 private static final Object sSync = new Object(); 2097 private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache 2098 = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>(); 2099 private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache 2100 = new ArrayMap<ResourceName, WeakReference<CharSequence>>(); 2101} 2102