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