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