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