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