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