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