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