ApplicationPackageManager.java revision cd65448ccd13c4c2d0fe9e9623fec3a898ab9372
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.app; 18 19import android.annotation.DrawableRes; 20import android.annotation.NonNull; 21import android.annotation.Nullable; 22import android.annotation.StringRes; 23import android.annotation.XmlRes; 24import android.content.ComponentName; 25import android.content.ContentResolver; 26import android.content.Intent; 27import android.content.IntentFilter; 28import android.content.IntentSender; 29import android.content.pm.ActivityInfo; 30import android.content.pm.ApplicationInfo; 31import android.content.pm.ComponentInfo; 32import android.content.pm.ContainerEncryptionParams; 33import android.content.pm.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.VerificationParams; 57import android.content.pm.VerifierDeviceIdentity; 58import android.content.res.Resources; 59import android.content.res.XmlResourceParser; 60import android.graphics.Bitmap; 61import android.graphics.Canvas; 62import android.graphics.Rect; 63import android.graphics.drawable.BitmapDrawable; 64import android.graphics.drawable.Drawable; 65import android.net.Uri; 66import android.os.Bundle; 67import android.os.Handler; 68import android.os.Looper; 69import android.os.Message; 70import android.os.Process; 71import android.os.RemoteException; 72import android.os.SystemProperties; 73import android.os.UserHandle; 74import android.os.UserManager; 75import android.os.storage.StorageManager; 76import android.os.storage.VolumeInfo; 77import android.provider.Settings; 78import android.util.ArrayMap; 79import android.util.Log; 80import android.view.Display; 81 82import dalvik.system.VMRuntime; 83 84import com.android.internal.annotations.GuardedBy; 85import com.android.internal.os.SomeArgs; 86import com.android.internal.util.Preconditions; 87import com.android.internal.util.UserIcons; 88import libcore.util.EmptyArray; 89 90import java.lang.ref.WeakReference; 91import java.util.ArrayList; 92import java.util.Collections; 93import java.util.Iterator; 94import java.util.List; 95import java.util.Map; 96import java.util.Objects; 97 98/** @hide */ 99public class ApplicationPackageManager extends PackageManager { 100 private static final String TAG = "ApplicationPackageManager"; 101 private final static boolean DEBUG_ICONS = false; 102 103 private static final int DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES = 16384; // 16KB 104 105 // Default flags to use with PackageManager when no flags are given. 106 private final static int sDefaultFlags = PackageManager.GET_SHARED_LIBRARY_FILES; 107 108 private final Object mLock = new Object(); 109 110 @GuardedBy("mLock") 111 private UserManager mUserManager; 112 @GuardedBy("mLock") 113 private PackageInstaller mInstaller; 114 115 @GuardedBy("mDelegates") 116 private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>(); 117 118 @GuardedBy("mLock") 119 private String mPermissionsControllerPackageName; 120 121 UserManager getUserManager() { 122 synchronized (mLock) { 123 if (mUserManager == null) { 124 mUserManager = UserManager.get(mContext); 125 } 126 return mUserManager; 127 } 128 } 129 130 @Override 131 public PackageInfo getPackageInfo(String packageName, int flags) 132 throws NameNotFoundException { 133 return getPackageInfoAsUser(packageName, flags, mContext.getUserId()); 134 } 135 136 @Override 137 public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId) 138 throws NameNotFoundException { 139 try { 140 PackageInfo pi = mPM.getPackageInfo(packageName, flags, userId); 141 if (pi != null) { 142 return pi; 143 } 144 } catch (RemoteException e) { 145 throw new RuntimeException("Package manager has died", e); 146 } 147 148 throw new NameNotFoundException(packageName); 149 } 150 151 @Override 152 public String[] currentToCanonicalPackageNames(String[] names) { 153 try { 154 return mPM.currentToCanonicalPackageNames(names); 155 } catch (RemoteException e) { 156 throw new RuntimeException("Package manager has died", e); 157 } 158 } 159 160 @Override 161 public String[] canonicalToCurrentPackageNames(String[] names) { 162 try { 163 return mPM.canonicalToCurrentPackageNames(names); 164 } catch (RemoteException e) { 165 throw new RuntimeException("Package manager has died", e); 166 } 167 } 168 169 @Override 170 public Intent getLaunchIntentForPackage(String packageName) { 171 // First see if the package has an INFO activity; the existence of 172 // such an activity is implied to be the desired front-door for the 173 // overall package (such as if it has multiple launcher entries). 174 Intent intentToResolve = new Intent(Intent.ACTION_MAIN); 175 intentToResolve.addCategory(Intent.CATEGORY_INFO); 176 intentToResolve.setPackage(packageName); 177 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0); 178 179 // Otherwise, try to find a main launcher activity. 180 if (ris == null || ris.size() <= 0) { 181 // reuse the intent instance 182 intentToResolve.removeCategory(Intent.CATEGORY_INFO); 183 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER); 184 intentToResolve.setPackage(packageName); 185 ris = queryIntentActivities(intentToResolve, 0); 186 } 187 if (ris == null || ris.size() <= 0) { 188 return null; 189 } 190 Intent intent = new Intent(intentToResolve); 191 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 192 intent.setClassName(ris.get(0).activityInfo.packageName, 193 ris.get(0).activityInfo.name); 194 return intent; 195 } 196 197 @Override 198 public Intent getLeanbackLaunchIntentForPackage(String packageName) { 199 // Try to find a main leanback_launcher activity. 200 Intent intentToResolve = new Intent(Intent.ACTION_MAIN); 201 intentToResolve.addCategory(Intent.CATEGORY_LEANBACK_LAUNCHER); 202 intentToResolve.setPackage(packageName); 203 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0); 204 205 if (ris == null || ris.size() <= 0) { 206 return null; 207 } 208 Intent intent = new Intent(intentToResolve); 209 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 210 intent.setClassName(ris.get(0).activityInfo.packageName, 211 ris.get(0).activityInfo.name); 212 return intent; 213 } 214 215 @Override 216 public int[] getPackageGids(String packageName) throws NameNotFoundException { 217 return getPackageGids(packageName, 0); 218 } 219 220 @Override 221 public int[] getPackageGids(String packageName, int flags) 222 throws NameNotFoundException { 223 try { 224 int[] gids = mPM.getPackageGids(packageName, flags, mContext.getUserId()); 225 if (gids != null) { 226 return gids; 227 } 228 } catch (RemoteException e) { 229 throw new RuntimeException("Package manager has died", e); 230 } 231 232 throw new NameNotFoundException(packageName); 233 } 234 235 @Override 236 public int getPackageUid(String packageName, int flags) throws NameNotFoundException { 237 return getPackageUidAsUser(packageName, flags, mContext.getUserId()); 238 } 239 240 @Override 241 public int getPackageUidAsUser(String packageName, int userId) throws NameNotFoundException { 242 return getPackageUidAsUser(packageName, 0, userId); 243 } 244 245 @Override 246 public int getPackageUidAsUser(String packageName, int flags, int userId) 247 throws NameNotFoundException { 248 try { 249 int uid = mPM.getPackageUid(packageName, flags, userId); 250 if (uid >= 0) { 251 return uid; 252 } 253 } catch (RemoteException e) { 254 throw new RuntimeException("Package manager has died", e); 255 } 256 257 throw new NameNotFoundException(packageName); 258 } 259 260 @Override 261 public PermissionInfo getPermissionInfo(String name, int flags) 262 throws NameNotFoundException { 263 try { 264 PermissionInfo pi = mPM.getPermissionInfo(name, flags); 265 if (pi != null) { 266 return pi; 267 } 268 } catch (RemoteException e) { 269 throw new RuntimeException("Package manager has died", e); 270 } 271 272 throw new NameNotFoundException(name); 273 } 274 275 @Override 276 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) 277 throws NameNotFoundException { 278 try { 279 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags); 280 if (pi != null) { 281 return pi; 282 } 283 } catch (RemoteException e) { 284 throw new RuntimeException("Package manager has died", e); 285 } 286 287 throw new NameNotFoundException(group); 288 } 289 290 @Override 291 public PermissionGroupInfo getPermissionGroupInfo(String name, 292 int flags) throws NameNotFoundException { 293 try { 294 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags); 295 if (pgi != null) { 296 return pgi; 297 } 298 } catch (RemoteException e) { 299 throw new RuntimeException("Package manager has died", e); 300 } 301 302 throw new NameNotFoundException(name); 303 } 304 305 @Override 306 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 307 try { 308 return mPM.getAllPermissionGroups(flags); 309 } catch (RemoteException e) { 310 throw new RuntimeException("Package manager has died", e); 311 } 312 } 313 314 @Override 315 public ApplicationInfo getApplicationInfo(String packageName, int flags) 316 throws NameNotFoundException { 317 return getApplicationInfoAsUser(packageName, flags, mContext.getUserId()); 318 } 319 320 @Override 321 public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId) 322 throws NameNotFoundException { 323 try { 324 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, userId); 325 if (ai != null) { 326 // This is a temporary hack. Callers must use 327 // createPackageContext(packageName).getApplicationInfo() to 328 // get the right paths. 329 maybeAdjustApplicationInfo(ai); 330 return ai; 331 } 332 } catch (RemoteException e) { 333 throw new RuntimeException("Package manager has died", e); 334 } 335 336 throw new NameNotFoundException(packageName); 337 } 338 339 private static void maybeAdjustApplicationInfo(ApplicationInfo info) { 340 // If we're dealing with a multi-arch application that has both 341 // 32 and 64 bit shared libraries, we might need to choose the secondary 342 // depending on what the current runtime's instruction set is. 343 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) { 344 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet(); 345 346 // Get the instruction set that the libraries of secondary Abi is supported. 347 // In presence of a native bridge this might be different than the one secondary Abi used. 348 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi); 349 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa); 350 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa; 351 352 // If the runtimeIsa is the same as the primary isa, then we do nothing. 353 // Everything will be set up correctly because info.nativeLibraryDir will 354 // correspond to the right ISA. 355 if (runtimeIsa.equals(secondaryIsa)) { 356 info.nativeLibraryDir = info.secondaryNativeLibraryDir; 357 } 358 } 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 UserInfo userInfo = getUserIfProfile(user.getIdentifier()); 1103 if (userInfo != null && userInfo.isManagedProfile()) { 1104 if (density <= 0) { 1105 density = mContext.getResources().getDisplayMetrics().densityDpi; 1106 } 1107 return Resources.getSystem().getDrawableForDensity( 1108 com.android.internal.R.drawable.ic_corp_badge, density); 1109 } 1110 return null; 1111 } 1112 1113 @Override 1114 public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) { 1115 UserInfo userInfo = getUserIfProfile(user.getIdentifier()); 1116 if (userInfo != null && userInfo.isManagedProfile()) { 1117 return Resources.getSystem().getString( 1118 com.android.internal.R.string.managed_profile_label_badge, label); 1119 } 1120 return label; 1121 } 1122 1123 @Override 1124 public Resources getResourcesForActivity(ComponentName activityName) 1125 throws NameNotFoundException { 1126 return getResourcesForApplication( 1127 getActivityInfo(activityName, sDefaultFlags).applicationInfo); 1128 } 1129 1130 @Override 1131 public Resources getResourcesForApplication(@NonNull ApplicationInfo app) 1132 throws NameNotFoundException { 1133 if (app.packageName.equals("system")) { 1134 return mContext.mMainThread.getSystemContext().getResources(); 1135 } 1136 final boolean sameUid = (app.uid == Process.myUid()); 1137 final Resources r = mContext.mMainThread.getTopLevelResources( 1138 sameUid ? app.sourceDir : app.publicSourceDir, 1139 sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs, 1140 app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY, 1141 null, mContext.mPackageInfo); 1142 if (r != null) { 1143 return r; 1144 } 1145 throw new NameNotFoundException("Unable to open " + app.publicSourceDir); 1146 } 1147 1148 @Override 1149 public Resources getResourcesForApplication(String appPackageName) 1150 throws NameNotFoundException { 1151 return getResourcesForApplication( 1152 getApplicationInfo(appPackageName, sDefaultFlags)); 1153 } 1154 1155 /** @hide */ 1156 @Override 1157 public Resources getResourcesForApplicationAsUser(String appPackageName, int userId) 1158 throws NameNotFoundException { 1159 if (userId < 0) { 1160 throw new IllegalArgumentException( 1161 "Call does not support special user #" + userId); 1162 } 1163 if ("system".equals(appPackageName)) { 1164 return mContext.mMainThread.getSystemContext().getResources(); 1165 } 1166 try { 1167 ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId); 1168 if (ai != null) { 1169 return getResourcesForApplication(ai); 1170 } 1171 } catch (RemoteException e) { 1172 throw new RuntimeException("Package manager has died", e); 1173 } 1174 throw new NameNotFoundException("Package " + appPackageName + " doesn't exist"); 1175 } 1176 1177 volatile int mCachedSafeMode = -1; 1178 1179 @Override 1180 public boolean isSafeMode() { 1181 try { 1182 if (mCachedSafeMode < 0) { 1183 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0; 1184 } 1185 return mCachedSafeMode != 0; 1186 } catch (RemoteException e) { 1187 throw new RuntimeException("Package manager has died", e); 1188 } 1189 } 1190 1191 @Override 1192 public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) { 1193 synchronized (mPermissionListeners) { 1194 if (mPermissionListeners.get(listener) != null) { 1195 return; 1196 } 1197 OnPermissionsChangeListenerDelegate delegate = 1198 new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper()); 1199 try { 1200 mPM.addOnPermissionsChangeListener(delegate); 1201 mPermissionListeners.put(listener, delegate); 1202 } catch (RemoteException e) { 1203 throw new RuntimeException("Package manager has died", e); 1204 } 1205 } 1206 } 1207 1208 @Override 1209 public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) { 1210 synchronized (mPermissionListeners) { 1211 IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener); 1212 if (delegate != null) { 1213 try { 1214 mPM.removeOnPermissionsChangeListener(delegate); 1215 mPermissionListeners.remove(listener); 1216 } catch (RemoteException e) { 1217 throw new RuntimeException("Package manager has died", e); 1218 } 1219 } 1220 } 1221 } 1222 1223 static void configurationChanged() { 1224 synchronized (sSync) { 1225 sIconCache.clear(); 1226 sStringCache.clear(); 1227 } 1228 } 1229 1230 ApplicationPackageManager(ContextImpl context, 1231 IPackageManager pm) { 1232 mContext = context; 1233 mPM = pm; 1234 } 1235 1236 @Nullable 1237 private Drawable getCachedIcon(@NonNull ResourceName name) { 1238 synchronized (sSync) { 1239 final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name); 1240 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for " 1241 + name + ": " + wr); 1242 if (wr != null) { // we have the activity 1243 final Drawable.ConstantState state = wr.get(); 1244 if (state != null) { 1245 if (DEBUG_ICONS) { 1246 Log.v(TAG, "Get cached drawable state for " + name + ": " + state); 1247 } 1248 // Note: It's okay here to not use the newDrawable(Resources) variant 1249 // of the API. The ConstantState comes from a drawable that was 1250 // originally created by passing the proper app Resources instance 1251 // which means the state should already contain the proper 1252 // resources specific information (like density.) See 1253 // BitmapDrawable.BitmapState for instance. 1254 return state.newDrawable(); 1255 } 1256 // our entry has been purged 1257 sIconCache.remove(name); 1258 } 1259 } 1260 return null; 1261 } 1262 1263 private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) { 1264 synchronized (sSync) { 1265 sIconCache.put(name, new WeakReference<>(dr.getConstantState())); 1266 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr); 1267 } 1268 } 1269 1270 static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) { 1271 boolean immediateGc = false; 1272 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) { 1273 immediateGc = true; 1274 } 1275 if (pkgList != null && (pkgList.length > 0)) { 1276 boolean needCleanup = false; 1277 for (String ssp : pkgList) { 1278 synchronized (sSync) { 1279 for (int i=sIconCache.size()-1; i>=0; i--) { 1280 ResourceName nm = sIconCache.keyAt(i); 1281 if (nm.packageName.equals(ssp)) { 1282 //Log.i(TAG, "Removing cached drawable for " + nm); 1283 sIconCache.removeAt(i); 1284 needCleanup = true; 1285 } 1286 } 1287 for (int i=sStringCache.size()-1; i>=0; i--) { 1288 ResourceName nm = sStringCache.keyAt(i); 1289 if (nm.packageName.equals(ssp)) { 1290 //Log.i(TAG, "Removing cached string for " + nm); 1291 sStringCache.removeAt(i); 1292 needCleanup = true; 1293 } 1294 } 1295 } 1296 } 1297 if (needCleanup || hasPkgInfo) { 1298 if (immediateGc) { 1299 // Schedule an immediate gc. 1300 Runtime.getRuntime().gc(); 1301 } else { 1302 ActivityThread.currentActivityThread().scheduleGcIdler(); 1303 } 1304 } 1305 } 1306 } 1307 1308 private static final class ResourceName { 1309 final String packageName; 1310 final int iconId; 1311 1312 ResourceName(String _packageName, int _iconId) { 1313 packageName = _packageName; 1314 iconId = _iconId; 1315 } 1316 1317 ResourceName(ApplicationInfo aInfo, int _iconId) { 1318 this(aInfo.packageName, _iconId); 1319 } 1320 1321 ResourceName(ComponentInfo cInfo, int _iconId) { 1322 this(cInfo.applicationInfo.packageName, _iconId); 1323 } 1324 1325 ResourceName(ResolveInfo rInfo, int _iconId) { 1326 this(rInfo.activityInfo.applicationInfo.packageName, _iconId); 1327 } 1328 1329 @Override 1330 public boolean equals(Object o) { 1331 if (this == o) return true; 1332 if (o == null || getClass() != o.getClass()) return false; 1333 1334 ResourceName that = (ResourceName) o; 1335 1336 if (iconId != that.iconId) return false; 1337 return !(packageName != null ? 1338 !packageName.equals(that.packageName) : that.packageName != null); 1339 1340 } 1341 1342 @Override 1343 public int hashCode() { 1344 int result; 1345 result = packageName.hashCode(); 1346 result = 31 * result + iconId; 1347 return result; 1348 } 1349 1350 @Override 1351 public String toString() { 1352 return "{ResourceName " + packageName + " / " + iconId + "}"; 1353 } 1354 } 1355 1356 private CharSequence getCachedString(ResourceName name) { 1357 synchronized (sSync) { 1358 WeakReference<CharSequence> wr = sStringCache.get(name); 1359 if (wr != null) { // we have the activity 1360 CharSequence cs = wr.get(); 1361 if (cs != null) { 1362 return cs; 1363 } 1364 // our entry has been purged 1365 sStringCache.remove(name); 1366 } 1367 } 1368 return null; 1369 } 1370 1371 private void putCachedString(ResourceName name, CharSequence cs) { 1372 synchronized (sSync) { 1373 sStringCache.put(name, new WeakReference<CharSequence>(cs)); 1374 } 1375 } 1376 1377 @Override 1378 public CharSequence getText(String packageName, @StringRes int resid, 1379 ApplicationInfo appInfo) { 1380 ResourceName name = new ResourceName(packageName, resid); 1381 CharSequence text = getCachedString(name); 1382 if (text != null) { 1383 return text; 1384 } 1385 if (appInfo == null) { 1386 try { 1387 appInfo = getApplicationInfo(packageName, sDefaultFlags); 1388 } catch (NameNotFoundException e) { 1389 return null; 1390 } 1391 } 1392 try { 1393 Resources r = getResourcesForApplication(appInfo); 1394 text = r.getText(resid); 1395 putCachedString(name, text); 1396 return text; 1397 } catch (NameNotFoundException e) { 1398 Log.w("PackageManager", "Failure retrieving resources for " 1399 + appInfo.packageName); 1400 } catch (RuntimeException e) { 1401 // If an exception was thrown, fall through to return 1402 // default icon. 1403 Log.w("PackageManager", "Failure retrieving text 0x" 1404 + Integer.toHexString(resid) + " in package " 1405 + packageName, e); 1406 } 1407 return null; 1408 } 1409 1410 @Override 1411 public XmlResourceParser getXml(String packageName, @XmlRes int resid, 1412 ApplicationInfo appInfo) { 1413 if (appInfo == null) { 1414 try { 1415 appInfo = getApplicationInfo(packageName, sDefaultFlags); 1416 } catch (NameNotFoundException e) { 1417 return null; 1418 } 1419 } 1420 try { 1421 Resources r = getResourcesForApplication(appInfo); 1422 return r.getXml(resid); 1423 } catch (RuntimeException e) { 1424 // If an exception was thrown, fall through to return 1425 // default icon. 1426 Log.w("PackageManager", "Failure retrieving xml 0x" 1427 + Integer.toHexString(resid) + " in package " 1428 + packageName, e); 1429 } catch (NameNotFoundException e) { 1430 Log.w("PackageManager", "Failure retrieving resources for " 1431 + appInfo.packageName); 1432 } 1433 return null; 1434 } 1435 1436 @Override 1437 public CharSequence getApplicationLabel(ApplicationInfo info) { 1438 return info.loadLabel(this); 1439 } 1440 1441 @Override 1442 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, 1443 String installerPackageName) { 1444 final VerificationParams verificationParams = new VerificationParams(null, null, 1445 null, VerificationParams.NO_UID); 1446 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags, 1447 installerPackageName, verificationParams, null, mContext.getUserId()); 1448 } 1449 1450 @Override 1451 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, 1452 int flags, String installerPackageName, Uri verificationURI, 1453 ContainerEncryptionParams encryptionParams) { 1454 final VerificationParams verificationParams = new VerificationParams(verificationURI, null, 1455 null, VerificationParams.NO_UID); 1456 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags, 1457 installerPackageName, verificationParams, encryptionParams, mContext.getUserId()); 1458 } 1459 1460 @Override 1461 public void installPackageWithVerificationAndEncryption(Uri packageURI, 1462 IPackageInstallObserver observer, int flags, String installerPackageName, 1463 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { 1464 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags, 1465 installerPackageName, verificationParams, encryptionParams, mContext.getUserId()); 1466 } 1467 1468 @Override 1469 public void installPackage(Uri packageURI, PackageInstallObserver observer, 1470 int flags, String installerPackageName) { 1471 installPackageAsUser(packageURI, observer, flags, installerPackageName, 1472 mContext.getUserId()); 1473 } 1474 1475 @Override 1476 public void installPackageAsUser(Uri packageURI, PackageInstallObserver observer, int flags, 1477 String installerPackageName, int userId) { 1478 final VerificationParams verificationParams = new VerificationParams(null, null, 1479 null, VerificationParams.NO_UID); 1480 installCommon(packageURI, observer, flags, installerPackageName, verificationParams, null, 1481 userId); 1482 } 1483 1484 @Override 1485 public void installPackageWithVerification(Uri packageURI, 1486 PackageInstallObserver observer, int flags, String installerPackageName, 1487 Uri verificationURI, 1488 ContainerEncryptionParams encryptionParams) { 1489 final VerificationParams verificationParams = new VerificationParams(verificationURI, null, 1490 null, VerificationParams.NO_UID); 1491 installCommon(packageURI, observer, flags, installerPackageName, verificationParams, 1492 encryptionParams, mContext.getUserId()); 1493 } 1494 1495 @Override 1496 public void installPackageWithVerificationAndEncryption(Uri packageURI, 1497 PackageInstallObserver observer, int flags, String installerPackageName, 1498 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { 1499 installCommon(packageURI, observer, flags, installerPackageName, verificationParams, 1500 encryptionParams, mContext.getUserId()); 1501 } 1502 1503 private void installCommon(Uri packageURI, 1504 PackageInstallObserver observer, int flags, String installerPackageName, 1505 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams, 1506 int userId) { 1507 if (!"file".equals(packageURI.getScheme())) { 1508 throw new UnsupportedOperationException("Only file:// URIs are supported"); 1509 } 1510 if (encryptionParams != null) { 1511 throw new UnsupportedOperationException("ContainerEncryptionParams not supported"); 1512 } 1513 1514 final String originPath = packageURI.getPath(); 1515 try { 1516 mPM.installPackageAsUser(originPath, observer.getBinder(), flags, installerPackageName, 1517 verificationParams, null, userId); 1518 } catch (RemoteException ignored) { 1519 } 1520 } 1521 1522 @Override 1523 public int installExistingPackage(String packageName) throws NameNotFoundException { 1524 return installExistingPackageAsUser(packageName, mContext.getUserId()); 1525 } 1526 1527 @Override 1528 public int installExistingPackageAsUser(String packageName, int userId) 1529 throws NameNotFoundException { 1530 try { 1531 int res = mPM.installExistingPackageAsUser(packageName, userId); 1532 if (res == INSTALL_FAILED_INVALID_URI) { 1533 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 1534 } 1535 return res; 1536 } catch (RemoteException e) { 1537 // Should never happen! 1538 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 1539 } 1540 } 1541 1542 @Override 1543 public void verifyPendingInstall(int id, int response) { 1544 try { 1545 mPM.verifyPendingInstall(id, response); 1546 } catch (RemoteException e) { 1547 // Should never happen! 1548 } 1549 } 1550 1551 @Override 1552 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 1553 long millisecondsToDelay) { 1554 try { 1555 mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay); 1556 } catch (RemoteException e) { 1557 // Should never happen! 1558 } 1559 } 1560 1561 @Override 1562 public void verifyIntentFilter(int id, int verificationCode, List<String> outFailedDomains) { 1563 try { 1564 mPM.verifyIntentFilter(id, verificationCode, outFailedDomains); 1565 } catch (RemoteException e) { 1566 // Should never happen! 1567 } 1568 } 1569 1570 @Override 1571 public int getIntentVerificationStatusAsUser(String packageName, int userId) { 1572 try { 1573 return mPM.getIntentVerificationStatus(packageName, userId); 1574 } catch (RemoteException e) { 1575 // Should never happen! 1576 return PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 1577 } 1578 } 1579 1580 @Override 1581 public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) { 1582 try { 1583 return mPM.updateIntentVerificationStatus(packageName, status, userId); 1584 } catch (RemoteException e) { 1585 // Should never happen! 1586 return false; 1587 } 1588 } 1589 1590 @Override 1591 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 1592 try { 1593 return mPM.getIntentFilterVerifications(packageName); 1594 } catch (RemoteException e) { 1595 // Should never happen! 1596 return null; 1597 } 1598 } 1599 1600 @Override 1601 public List<IntentFilter> getAllIntentFilters(String packageName) { 1602 try { 1603 return mPM.getAllIntentFilters(packageName); 1604 } catch (RemoteException e) { 1605 // Should never happen! 1606 return null; 1607 } 1608 } 1609 1610 @Override 1611 public String getDefaultBrowserPackageNameAsUser(int userId) { 1612 try { 1613 return mPM.getDefaultBrowserPackageName(userId); 1614 } catch (RemoteException e) { 1615 // Should never happen! 1616 return null; 1617 } 1618 } 1619 1620 @Override 1621 public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) { 1622 try { 1623 return mPM.setDefaultBrowserPackageName(packageName, userId); 1624 } catch (RemoteException e) { 1625 // Should never happen! 1626 return false; 1627 } 1628 } 1629 1630 @Override 1631 public void setInstallerPackageName(String targetPackage, 1632 String installerPackageName) { 1633 try { 1634 mPM.setInstallerPackageName(targetPackage, installerPackageName); 1635 } catch (RemoteException e) { 1636 // Should never happen! 1637 } 1638 } 1639 1640 @Override 1641 public String getInstallerPackageName(String packageName) { 1642 try { 1643 return mPM.getInstallerPackageName(packageName); 1644 } catch (RemoteException e) { 1645 // Should never happen! 1646 } 1647 return null; 1648 } 1649 1650 @Override 1651 public int getMoveStatus(int moveId) { 1652 try { 1653 return mPM.getMoveStatus(moveId); 1654 } catch (RemoteException e) { 1655 throw e.rethrowAsRuntimeException(); 1656 } 1657 } 1658 1659 @Override 1660 public void registerMoveCallback(MoveCallback callback, Handler handler) { 1661 synchronized (mDelegates) { 1662 final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback, 1663 handler.getLooper()); 1664 try { 1665 mPM.registerMoveCallback(delegate); 1666 } catch (RemoteException e) { 1667 throw e.rethrowAsRuntimeException(); 1668 } 1669 mDelegates.add(delegate); 1670 } 1671 } 1672 1673 @Override 1674 public void unregisterMoveCallback(MoveCallback callback) { 1675 synchronized (mDelegates) { 1676 for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) { 1677 final MoveCallbackDelegate delegate = i.next(); 1678 if (delegate.mCallback == callback) { 1679 try { 1680 mPM.unregisterMoveCallback(delegate); 1681 } catch (RemoteException e) { 1682 throw e.rethrowAsRuntimeException(); 1683 } 1684 i.remove(); 1685 } 1686 } 1687 } 1688 } 1689 1690 @Override 1691 public int movePackage(String packageName, VolumeInfo vol) { 1692 try { 1693 final String volumeUuid; 1694 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) { 1695 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL; 1696 } else if (vol.isPrimaryPhysical()) { 1697 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 1698 } else { 1699 volumeUuid = Preconditions.checkNotNull(vol.fsUuid); 1700 } 1701 1702 return mPM.movePackage(packageName, volumeUuid); 1703 } catch (RemoteException e) { 1704 throw e.rethrowAsRuntimeException(); 1705 } 1706 } 1707 1708 @Override 1709 public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) { 1710 final StorageManager storage = mContext.getSystemService(StorageManager.class); 1711 if (app.isInternal()) { 1712 return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL); 1713 } else if (app.isExternalAsec()) { 1714 return storage.getPrimaryPhysicalVolume(); 1715 } else { 1716 return storage.findVolumeByUuid(app.volumeUuid); 1717 } 1718 } 1719 1720 @Override 1721 public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) { 1722 final StorageManager storage = mContext.getSystemService(StorageManager.class); 1723 final VolumeInfo currentVol = getPackageCurrentVolume(app); 1724 final List<VolumeInfo> vols = storage.getVolumes(); 1725 final List<VolumeInfo> candidates = new ArrayList<>(); 1726 for (VolumeInfo vol : vols) { 1727 if (Objects.equals(vol, currentVol) || isPackageCandidateVolume(mContext, app, vol)) { 1728 candidates.add(vol); 1729 } 1730 } 1731 return candidates; 1732 } 1733 1734 private static boolean isPackageCandidateVolume( 1735 ContextImpl context, ApplicationInfo app, VolumeInfo vol) { 1736 final boolean forceAllowOnExternal = Settings.Global.getInt( 1737 context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0; 1738 // Private internal is always an option 1739 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) { 1740 return true; 1741 } 1742 1743 // System apps and apps demanding internal storage can't be moved 1744 // anywhere else 1745 if (app.isSystemApp()) { 1746 return false; 1747 } 1748 if (!forceAllowOnExternal 1749 && (app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY 1750 || app.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED)) { 1751 return false; 1752 } 1753 1754 // Gotta be able to write there 1755 if (!vol.isMountedWritable()) { 1756 return false; 1757 } 1758 1759 // Moving into an ASEC on public primary is only option internal 1760 if (vol.isPrimaryPhysical()) { 1761 return app.isInternal(); 1762 } 1763 1764 // Otherwise we can move to any private volume 1765 return (vol.getType() == VolumeInfo.TYPE_PRIVATE); 1766 } 1767 1768 @Override 1769 public int movePrimaryStorage(VolumeInfo vol) { 1770 try { 1771 final String volumeUuid; 1772 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) { 1773 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL; 1774 } else if (vol.isPrimaryPhysical()) { 1775 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 1776 } else { 1777 volumeUuid = Preconditions.checkNotNull(vol.fsUuid); 1778 } 1779 1780 return mPM.movePrimaryStorage(volumeUuid); 1781 } catch (RemoteException e) { 1782 throw e.rethrowAsRuntimeException(); 1783 } 1784 } 1785 1786 @Override 1787 public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() { 1788 final StorageManager storage = mContext.getSystemService(StorageManager.class); 1789 final String volumeUuid = storage.getPrimaryStorageUuid(); 1790 return storage.findVolumeByQualifiedUuid(volumeUuid); 1791 } 1792 1793 @Override 1794 public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() { 1795 final StorageManager storage = mContext.getSystemService(StorageManager.class); 1796 final VolumeInfo currentVol = getPrimaryStorageCurrentVolume(); 1797 final List<VolumeInfo> vols = storage.getVolumes(); 1798 final List<VolumeInfo> candidates = new ArrayList<>(); 1799 if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, 1800 storage.getPrimaryStorageUuid()) && currentVol != null) { 1801 // TODO: support moving primary physical to emulated volume 1802 candidates.add(currentVol); 1803 } else { 1804 for (VolumeInfo vol : vols) { 1805 if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) { 1806 candidates.add(vol); 1807 } 1808 } 1809 } 1810 return candidates; 1811 } 1812 1813 private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) { 1814 // Private internal is always an option 1815 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) { 1816 return true; 1817 } 1818 1819 // Gotta be able to write there 1820 if (!vol.isMountedWritable()) { 1821 return false; 1822 } 1823 1824 // We can move to any private volume 1825 return (vol.getType() == VolumeInfo.TYPE_PRIVATE); 1826 } 1827 1828 @Override 1829 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) { 1830 deletePackageAsUser(packageName, observer, flags, mContext.getUserId()); 1831 } 1832 1833 @Override 1834 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags, 1835 int userId) { 1836 try { 1837 mPM.deletePackageAsUser(packageName, observer, userId, flags); 1838 } catch (RemoteException e) { 1839 // Should never happen! 1840 } 1841 } 1842 1843 @Override 1844 public void clearApplicationUserData(String packageName, 1845 IPackageDataObserver observer) { 1846 try { 1847 mPM.clearApplicationUserData(packageName, observer, mContext.getUserId()); 1848 } catch (RemoteException e) { 1849 // Should never happen! 1850 } 1851 } 1852 @Override 1853 public void deleteApplicationCacheFiles(String packageName, 1854 IPackageDataObserver observer) { 1855 try { 1856 mPM.deleteApplicationCacheFiles(packageName, observer); 1857 } catch (RemoteException e) { 1858 // Should never happen! 1859 } 1860 } 1861 1862 @Override 1863 public void freeStorageAndNotify(String volumeUuid, long idealStorageSize, 1864 IPackageDataObserver observer) { 1865 try { 1866 mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer); 1867 } catch (RemoteException e) { 1868 // Should never happen! 1869 } 1870 } 1871 1872 @Override 1873 public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) { 1874 try { 1875 mPM.freeStorage(volumeUuid, freeStorageSize, pi); 1876 } catch (RemoteException e) { 1877 // Should never happen! 1878 } 1879 } 1880 1881 @Override 1882 public boolean setPackageSuspendedAsUser(String packageName, boolean suspended, int userId) { 1883 try { 1884 return mPM.setPackageSuspendedAsUser(packageName, suspended, userId); 1885 } catch (RemoteException e) { 1886 // Should never happen! 1887 } 1888 return false; 1889 } 1890 1891 @Override 1892 public void getPackageSizeInfoAsUser(String packageName, int userHandle, 1893 IPackageStatsObserver observer) { 1894 try { 1895 mPM.getPackageSizeInfo(packageName, userHandle, observer); 1896 } catch (RemoteException e) { 1897 // Should never happen! 1898 } 1899 } 1900 @Override 1901 public void addPackageToPreferred(String packageName) { 1902 try { 1903 mPM.addPackageToPreferred(packageName); 1904 } catch (RemoteException e) { 1905 // Should never happen! 1906 } 1907 } 1908 1909 @Override 1910 public void removePackageFromPreferred(String packageName) { 1911 try { 1912 mPM.removePackageFromPreferred(packageName); 1913 } catch (RemoteException e) { 1914 // Should never happen! 1915 } 1916 } 1917 1918 @Override 1919 public List<PackageInfo> getPreferredPackages(int flags) { 1920 try { 1921 return mPM.getPreferredPackages(flags); 1922 } catch (RemoteException e) { 1923 // Should never happen! 1924 } 1925 return new ArrayList<PackageInfo>(); 1926 } 1927 1928 @Override 1929 public void addPreferredActivity(IntentFilter filter, 1930 int match, ComponentName[] set, ComponentName activity) { 1931 try { 1932 mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId()); 1933 } catch (RemoteException e) { 1934 // Should never happen! 1935 } 1936 } 1937 1938 @Override 1939 public void addPreferredActivityAsUser(IntentFilter filter, int match, 1940 ComponentName[] set, ComponentName activity, int userId) { 1941 try { 1942 mPM.addPreferredActivity(filter, match, set, activity, userId); 1943 } catch (RemoteException e) { 1944 // Should never happen! 1945 } 1946 } 1947 1948 @Override 1949 public void replacePreferredActivity(IntentFilter filter, 1950 int match, ComponentName[] set, ComponentName activity) { 1951 try { 1952 mPM.replacePreferredActivity(filter, match, set, activity, mContext.getUserId()); 1953 } catch (RemoteException e) { 1954 // Should never happen! 1955 } 1956 } 1957 1958 @Override 1959 public void replacePreferredActivityAsUser(IntentFilter filter, 1960 int match, ComponentName[] set, ComponentName activity, 1961 int userId) { 1962 try { 1963 mPM.replacePreferredActivity(filter, match, set, activity, userId); 1964 } catch (RemoteException e) { 1965 // Should never happen! 1966 } 1967 } 1968 1969 @Override 1970 public void clearPackagePreferredActivities(String packageName) { 1971 try { 1972 mPM.clearPackagePreferredActivities(packageName); 1973 } catch (RemoteException e) { 1974 // Should never happen! 1975 } 1976 } 1977 1978 @Override 1979 public int getPreferredActivities(List<IntentFilter> outFilters, 1980 List<ComponentName> outActivities, String packageName) { 1981 try { 1982 return mPM.getPreferredActivities(outFilters, outActivities, packageName); 1983 } catch (RemoteException e) { 1984 // Should never happen! 1985 } 1986 return 0; 1987 } 1988 1989 @Override 1990 public ComponentName getHomeActivities(List<ResolveInfo> outActivities) { 1991 try { 1992 return mPM.getHomeActivities(outActivities); 1993 } catch (RemoteException e) { 1994 // Should never happen! 1995 } 1996 return null; 1997 } 1998 1999 @Override 2000 public void setComponentEnabledSetting(ComponentName componentName, 2001 int newState, int flags) { 2002 try { 2003 mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId()); 2004 } catch (RemoteException e) { 2005 // Should never happen! 2006 } 2007 } 2008 2009 @Override 2010 public int getComponentEnabledSetting(ComponentName componentName) { 2011 try { 2012 return mPM.getComponentEnabledSetting(componentName, mContext.getUserId()); 2013 } catch (RemoteException e) { 2014 // Should never happen! 2015 } 2016 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 2017 } 2018 2019 @Override 2020 public void setApplicationEnabledSetting(String packageName, 2021 int newState, int flags) { 2022 try { 2023 mPM.setApplicationEnabledSetting(packageName, newState, flags, 2024 mContext.getUserId(), mContext.getOpPackageName()); 2025 } catch (RemoteException e) { 2026 // Should never happen! 2027 } 2028 } 2029 2030 @Override 2031 public int getApplicationEnabledSetting(String packageName) { 2032 try { 2033 return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId()); 2034 } catch (RemoteException e) { 2035 // Should never happen! 2036 } 2037 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 2038 } 2039 2040 @Override 2041 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 2042 UserHandle user) { 2043 try { 2044 return mPM.setApplicationHiddenSettingAsUser(packageName, hidden, 2045 user.getIdentifier()); 2046 } catch (RemoteException re) { 2047 // Should never happen! 2048 } 2049 return false; 2050 } 2051 2052 @Override 2053 public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) { 2054 try { 2055 return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier()); 2056 } catch (RemoteException re) { 2057 // Should never happen! 2058 } 2059 return false; 2060 } 2061 2062 /** @hide */ 2063 @Override 2064 public KeySet getKeySetByAlias(String packageName, String alias) { 2065 Preconditions.checkNotNull(packageName); 2066 Preconditions.checkNotNull(alias); 2067 KeySet ks; 2068 try { 2069 ks = mPM.getKeySetByAlias(packageName, alias); 2070 } catch (RemoteException e) { 2071 return null; 2072 } 2073 return ks; 2074 } 2075 2076 /** @hide */ 2077 @Override 2078 public KeySet getSigningKeySet(String packageName) { 2079 Preconditions.checkNotNull(packageName); 2080 KeySet ks; 2081 try { 2082 ks = mPM.getSigningKeySet(packageName); 2083 } catch (RemoteException e) { 2084 return null; 2085 } 2086 return ks; 2087 } 2088 2089 /** @hide */ 2090 @Override 2091 public boolean isSignedBy(String packageName, KeySet ks) { 2092 Preconditions.checkNotNull(packageName); 2093 Preconditions.checkNotNull(ks); 2094 try { 2095 return mPM.isPackageSignedByKeySet(packageName, ks); 2096 } catch (RemoteException e) { 2097 return false; 2098 } 2099 } 2100 2101 /** @hide */ 2102 @Override 2103 public boolean isSignedByExactly(String packageName, KeySet ks) { 2104 Preconditions.checkNotNull(packageName); 2105 Preconditions.checkNotNull(ks); 2106 try { 2107 return mPM.isPackageSignedByKeySetExactly(packageName, ks); 2108 } catch (RemoteException e) { 2109 return false; 2110 } 2111 } 2112 2113 /** 2114 * @hide 2115 */ 2116 @Override 2117 public VerifierDeviceIdentity getVerifierDeviceIdentity() { 2118 try { 2119 return mPM.getVerifierDeviceIdentity(); 2120 } catch (RemoteException e) { 2121 // Should never happen! 2122 } 2123 return null; 2124 } 2125 2126 /** 2127 * @hide 2128 */ 2129 @Override 2130 public boolean isUpgrade() { 2131 try { 2132 return mPM.isUpgrade(); 2133 } catch (RemoteException e) { 2134 return false; 2135 } 2136 } 2137 2138 @Override 2139 public PackageInstaller getPackageInstaller() { 2140 synchronized (mLock) { 2141 if (mInstaller == null) { 2142 try { 2143 mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(), 2144 mContext.getPackageName(), mContext.getUserId()); 2145 } catch (RemoteException e) { 2146 throw e.rethrowAsRuntimeException(); 2147 } 2148 } 2149 return mInstaller; 2150 } 2151 } 2152 2153 @Override 2154 public boolean isPackageAvailable(String packageName) { 2155 try { 2156 return mPM.isPackageAvailable(packageName, mContext.getUserId()); 2157 } catch (RemoteException e) { 2158 throw e.rethrowAsRuntimeException(); 2159 } 2160 } 2161 2162 /** 2163 * @hide 2164 */ 2165 @Override 2166 public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId, 2167 int flags) { 2168 try { 2169 mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(), 2170 sourceUserId, targetUserId, flags); 2171 } catch (RemoteException e) { 2172 // Should never happen! 2173 } 2174 } 2175 2176 /** 2177 * @hide 2178 */ 2179 @Override 2180 public void clearCrossProfileIntentFilters(int sourceUserId) { 2181 try { 2182 mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName()); 2183 } catch (RemoteException e) { 2184 // Should never happen! 2185 } 2186 } 2187 2188 /** 2189 * @hide 2190 */ 2191 public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) { 2192 Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo); 2193 if (itemInfo.showUserIcon != UserHandle.USER_NULL) { 2194 return dr; 2195 } 2196 return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId())); 2197 } 2198 2199 /** 2200 * @hide 2201 */ 2202 public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) { 2203 if (itemInfo.showUserIcon != UserHandle.USER_NULL) { 2204 Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon); 2205 if (bitmap == null) { 2206 return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false); 2207 } 2208 return new BitmapDrawable(bitmap); 2209 } 2210 Drawable dr = null; 2211 if (itemInfo.packageName != null) { 2212 dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo); 2213 } 2214 if (dr == null) { 2215 dr = itemInfo.loadDefaultIcon(this); 2216 } 2217 return dr; 2218 } 2219 2220 private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable, 2221 Rect badgeLocation, boolean tryBadgeInPlace) { 2222 final int badgedWidth = drawable.getIntrinsicWidth(); 2223 final int badgedHeight = drawable.getIntrinsicHeight(); 2224 final boolean canBadgeInPlace = tryBadgeInPlace 2225 && (drawable instanceof BitmapDrawable) 2226 && ((BitmapDrawable) drawable).getBitmap().isMutable(); 2227 2228 final Bitmap bitmap; 2229 if (canBadgeInPlace) { 2230 bitmap = ((BitmapDrawable) drawable).getBitmap(); 2231 } else { 2232 bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888); 2233 } 2234 Canvas canvas = new Canvas(bitmap); 2235 2236 if (!canBadgeInPlace) { 2237 drawable.setBounds(0, 0, badgedWidth, badgedHeight); 2238 drawable.draw(canvas); 2239 } 2240 2241 if (badgeLocation != null) { 2242 if (badgeLocation.left < 0 || badgeLocation.top < 0 2243 || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) { 2244 throw new IllegalArgumentException("Badge location " + badgeLocation 2245 + " not in badged drawable bounds " 2246 + new Rect(0, 0, badgedWidth, badgedHeight)); 2247 } 2248 badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height()); 2249 2250 canvas.save(); 2251 canvas.translate(badgeLocation.left, badgeLocation.top); 2252 badgeDrawable.draw(canvas); 2253 canvas.restore(); 2254 } else { 2255 badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight); 2256 badgeDrawable.draw(canvas); 2257 } 2258 2259 if (!canBadgeInPlace) { 2260 BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap); 2261 2262 if (drawable instanceof BitmapDrawable) { 2263 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; 2264 mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity()); 2265 } 2266 2267 return mergedDrawable; 2268 } 2269 2270 return drawable; 2271 } 2272 2273 private int getBadgeResIdForUser(int userHandle) { 2274 // Return the framework-provided badge. 2275 UserInfo userInfo = getUserIfProfile(userHandle); 2276 if (userInfo != null && userInfo.isManagedProfile()) { 2277 return com.android.internal.R.drawable.ic_corp_icon_badge; 2278 } 2279 return 0; 2280 } 2281 2282 private UserInfo getUserIfProfile(int userHandle) { 2283 List<UserInfo> userProfiles = getUserManager().getProfiles(mContext.getUserId()); 2284 for (UserInfo user : userProfiles) { 2285 if (user.id == userHandle) { 2286 return user; 2287 } 2288 } 2289 return null; 2290 } 2291 2292 /** {@hide} */ 2293 private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements 2294 Handler.Callback { 2295 private static final int MSG_CREATED = 1; 2296 private static final int MSG_STATUS_CHANGED = 2; 2297 2298 final MoveCallback mCallback; 2299 final Handler mHandler; 2300 2301 public MoveCallbackDelegate(MoveCallback callback, Looper looper) { 2302 mCallback = callback; 2303 mHandler = new Handler(looper, this); 2304 } 2305 2306 @Override 2307 public boolean handleMessage(Message msg) { 2308 switch (msg.what) { 2309 case MSG_CREATED: { 2310 final SomeArgs args = (SomeArgs) msg.obj; 2311 mCallback.onCreated(args.argi1, (Bundle) args.arg2); 2312 args.recycle(); 2313 return true; 2314 } 2315 case MSG_STATUS_CHANGED: { 2316 final SomeArgs args = (SomeArgs) msg.obj; 2317 mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 2318 args.recycle(); 2319 return true; 2320 } 2321 } 2322 return false; 2323 } 2324 2325 @Override 2326 public void onCreated(int moveId, Bundle extras) { 2327 final SomeArgs args = SomeArgs.obtain(); 2328 args.argi1 = moveId; 2329 args.arg2 = extras; 2330 mHandler.obtainMessage(MSG_CREATED, args).sendToTarget(); 2331 } 2332 2333 @Override 2334 public void onStatusChanged(int moveId, int status, long estMillis) { 2335 final SomeArgs args = SomeArgs.obtain(); 2336 args.argi1 = moveId; 2337 args.argi2 = status; 2338 args.arg3 = estMillis; 2339 mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 2340 } 2341 } 2342 2343 private final ContextImpl mContext; 2344 private final IPackageManager mPM; 2345 2346 private static final Object sSync = new Object(); 2347 private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache 2348 = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>(); 2349 private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache 2350 = new ArrayMap<ResourceName, WeakReference<CharSequence>>(); 2351 2352 private final Map<OnPermissionsChangedListener, IOnPermissionsChangeListener> 2353 mPermissionListeners = new ArrayMap<>(); 2354 2355 public class OnPermissionsChangeListenerDelegate extends IOnPermissionsChangeListener.Stub 2356 implements Handler.Callback{ 2357 private static final int MSG_PERMISSIONS_CHANGED = 1; 2358 2359 private final OnPermissionsChangedListener mListener; 2360 private final Handler mHandler; 2361 2362 2363 public OnPermissionsChangeListenerDelegate(OnPermissionsChangedListener listener, 2364 Looper looper) { 2365 mListener = listener; 2366 mHandler = new Handler(looper, this); 2367 } 2368 2369 @Override 2370 public void onPermissionsChanged(int uid) { 2371 mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 2372 } 2373 2374 @Override 2375 public boolean handleMessage(Message msg) { 2376 switch (msg.what) { 2377 case MSG_PERMISSIONS_CHANGED: { 2378 final int uid = msg.arg1; 2379 mListener.onPermissionsChanged(uid); 2380 return true; 2381 } 2382 } 2383 return false; 2384 } 2385 } 2386} 2387