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 17 package android.app; 18 19 import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_COLORED; 20 import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_NOT_COLORED; 21 import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON; 22 import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON_BADGE; 23 import static android.app.admin.DevicePolicyResources.UNDEFINED; 24 import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256; 25 import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512; 26 import static android.content.pm.Checksum.TYPE_WHOLE_MD5; 27 import static android.content.pm.Checksum.TYPE_WHOLE_MERKLE_ROOT_4K_SHA256; 28 import static android.content.pm.Checksum.TYPE_WHOLE_SHA1; 29 import static android.content.pm.Checksum.TYPE_WHOLE_SHA256; 30 import static android.content.pm.Checksum.TYPE_WHOLE_SHA512; 31 32 import android.annotation.CallbackExecutor; 33 import android.annotation.DrawableRes; 34 import android.annotation.NonNull; 35 import android.annotation.Nullable; 36 import android.annotation.StringRes; 37 import android.annotation.UserIdInt; 38 import android.annotation.XmlRes; 39 import android.app.admin.DevicePolicyManager; 40 import android.app.role.RoleManager; 41 import android.compat.annotation.UnsupportedAppUsage; 42 import android.content.ComponentName; 43 import android.content.ContentResolver; 44 import android.content.Context; 45 import android.content.Intent; 46 import android.content.IntentFilter; 47 import android.content.IntentSender; 48 import android.content.pm.ActivityInfo; 49 import android.content.pm.ApkChecksum; 50 import android.content.pm.ApplicationInfo; 51 import android.content.pm.ArchivedPackageInfo; 52 import android.content.pm.ChangedPackages; 53 import android.content.pm.Checksum; 54 import android.content.pm.ComponentInfo; 55 import android.content.pm.FeatureInfo; 56 import android.content.pm.IOnChecksumsReadyListener; 57 import android.content.pm.IPackageDataObserver; 58 import android.content.pm.IPackageDeleteObserver; 59 import android.content.pm.IPackageManager; 60 import android.content.pm.IPackageMoveObserver; 61 import android.content.pm.IPackageStatsObserver; 62 import android.content.pm.InstallSourceInfo; 63 import android.content.pm.InstantAppInfo; 64 import android.content.pm.InstrumentationInfo; 65 import android.content.pm.IntentFilterVerificationInfo; 66 import android.content.pm.KeySet; 67 import android.content.pm.ModuleInfo; 68 import android.content.pm.PackageInfo; 69 import android.content.pm.PackageInstaller; 70 import android.content.pm.PackageItemInfo; 71 import android.content.pm.PackageManager; 72 import android.content.pm.ParceledListSlice; 73 import android.content.pm.PermissionGroupInfo; 74 import android.content.pm.PermissionInfo; 75 import android.content.pm.ProviderInfo; 76 import android.content.pm.ResolveInfo; 77 import android.content.pm.ServiceInfo; 78 import android.content.pm.SharedLibraryInfo; 79 import android.content.pm.SuspendDialogInfo; 80 import android.content.pm.VerifierDeviceIdentity; 81 import android.content.pm.VersionedPackage; 82 import android.content.pm.dex.ArtManager; 83 import android.content.pm.parsing.ApkLiteParseUtils; 84 import android.content.res.ApkAssets; 85 import android.content.res.Configuration; 86 import android.content.res.Resources; 87 import android.content.res.TypedArray; 88 import android.content.res.XmlResourceParser; 89 import android.graphics.Bitmap; 90 import android.graphics.Canvas; 91 import android.graphics.Rect; 92 import android.graphics.drawable.BitmapDrawable; 93 import android.graphics.drawable.Drawable; 94 import android.graphics.drawable.LayerDrawable; 95 import android.os.Build; 96 import android.os.Bundle; 97 import android.os.Handler; 98 import android.os.IRemoteCallback; 99 import android.os.Looper; 100 import android.os.Message; 101 import android.os.ParcelFileDescriptor; 102 import android.os.ParcelableException; 103 import android.os.PersistableBundle; 104 import android.os.Process; 105 import android.os.RemoteException; 106 import android.os.StrictMode; 107 import android.os.SystemProperties; 108 import android.os.UserHandle; 109 import android.os.UserManager; 110 import android.os.storage.StorageManager; 111 import android.os.storage.VolumeInfo; 112 import android.permission.PermissionControllerManager; 113 import android.permission.PermissionManager; 114 import android.provider.Settings; 115 import android.system.ErrnoException; 116 import android.system.Os; 117 import android.system.OsConstants; 118 import android.system.StructStat; 119 import android.text.TextUtils; 120 import android.util.ArrayMap; 121 import android.util.ArraySet; 122 import android.util.AttributeSet; 123 import android.util.LauncherIcons; 124 import android.util.Log; 125 import android.util.Slog; 126 import android.util.Xml; 127 128 import com.android.internal.annotations.GuardedBy; 129 import com.android.internal.annotations.Immutable; 130 import com.android.internal.annotations.VisibleForTesting; 131 import com.android.internal.os.SomeArgs; 132 import com.android.internal.util.UserIcons; 133 134 import dalvik.system.VMRuntime; 135 136 import libcore.util.EmptyArray; 137 138 import org.xmlpull.v1.XmlPullParser; 139 import org.xmlpull.v1.XmlPullParserException; 140 141 import java.io.File; 142 import java.io.IOException; 143 import java.io.InputStream; 144 import java.lang.ref.WeakReference; 145 import java.security.cert.Certificate; 146 import java.security.cert.CertificateEncodingException; 147 import java.security.cert.X509Certificate; 148 import java.util.ArrayList; 149 import java.util.Arrays; 150 import java.util.Collections; 151 import java.util.Iterator; 152 import java.util.List; 153 import java.util.Objects; 154 import java.util.Set; 155 import java.util.concurrent.Executor; 156 import java.util.function.Consumer; 157 import java.util.function.Function; 158 159 /** @hide */ 160 public class ApplicationPackageManager extends PackageManager { 161 private static final String TAG = "ApplicationPackageManager"; 162 private static final boolean DEBUG_ICONS = false; 163 164 private static final int DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES = 16384; // 16KB 165 166 // Default flags to use with PackageManager when no flags are given. 167 private static final int sDefaultFlags = GET_SHARED_LIBRARY_FILES; 168 169 /** Default set of checksums - includes all available checksums. 170 * @see PackageManager#requestChecksums */ 171 private static final int DEFAULT_CHECKSUMS = 172 TYPE_WHOLE_MERKLE_ROOT_4K_SHA256 | TYPE_WHOLE_MD5 | TYPE_WHOLE_SHA1 | TYPE_WHOLE_SHA256 173 | TYPE_WHOLE_SHA512 | TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256 174 | TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512; 175 176 // Name of the resource which provides background permission button string 177 public static final String APP_PERMISSION_BUTTON_ALLOW_ALWAYS = 178 "app_permission_button_allow_always"; 179 180 // Name of the package which the permission controller's resources are in. 181 public static final String PERMISSION_CONTROLLER_RESOURCE_PACKAGE = 182 "com.android.permissioncontroller"; 183 184 private volatile UserManager mUserManager; 185 private volatile PermissionManager mPermissionManager; 186 private volatile PackageInstaller mInstaller; 187 private volatile ArtManager mArtManager; 188 private volatile DevicePolicyManager mDevicePolicyManager; 189 private volatile String mPermissionsControllerPackageName; 190 191 @GuardedBy("mDelegates") 192 private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>(); 193 194 @NonNull 195 @GuardedBy("mPackageMonitorCallbacks") 196 private final ArraySet<IRemoteCallback> mPackageMonitorCallbacks = new ArraySet<>(); 197 getUserManager()198 UserManager getUserManager() { 199 if (mUserManager == null) { 200 mUserManager = UserManager.get(mContext); 201 } 202 return mUserManager; 203 } 204 getDevicePolicyManager()205 DevicePolicyManager getDevicePolicyManager() { 206 if (mDevicePolicyManager == null) { 207 mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class); 208 } 209 return mDevicePolicyManager; 210 } 211 getPermissionManager()212 private PermissionManager getPermissionManager() { 213 if (mPermissionManager == null) { 214 mPermissionManager = mContext.getSystemService(PermissionManager.class); 215 } 216 return mPermissionManager; 217 } 218 219 @Override getUserId()220 public int getUserId() { 221 return mContext.getUserId(); 222 } 223 224 @Override getPackageInfo(String packageName, int flags)225 public PackageInfo getPackageInfo(String packageName, int flags) 226 throws NameNotFoundException { 227 return getPackageInfo(packageName, PackageInfoFlags.of(flags)); 228 } 229 230 @Override getPackageInfo(String packageName, PackageInfoFlags flags)231 public PackageInfo getPackageInfo(String packageName, PackageInfoFlags flags) 232 throws NameNotFoundException { 233 return getPackageInfoAsUser(packageName, flags, getUserId()); 234 } 235 236 @Override getPackageInfo(VersionedPackage versionedPackage, int flags)237 public PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags) 238 throws NameNotFoundException { 239 return getPackageInfo(versionedPackage, PackageInfoFlags.of(flags)); 240 } 241 242 @Override getPackageInfo(VersionedPackage versionedPackage, PackageInfoFlags flags)243 public PackageInfo getPackageInfo(VersionedPackage versionedPackage, PackageInfoFlags flags) 244 throws NameNotFoundException { 245 final int userId = getUserId(); 246 try { 247 PackageInfo pi = mPM.getPackageInfoVersioned(versionedPackage, 248 updateFlagsForPackage(flags.getValue(), userId), userId); 249 if (pi != null) { 250 return pi; 251 } 252 } catch (RemoteException e) { 253 throw e.rethrowFromSystemServer(); 254 } 255 throw new NameNotFoundException(versionedPackage.toString()); 256 } 257 258 @Override getPackageInfoAsUser(String packageName, int flags, int userId)259 public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId) 260 throws NameNotFoundException { 261 return getPackageInfoAsUser(packageName, PackageInfoFlags.of(flags), userId); 262 } 263 264 @Override getPackageInfoAsUser(String packageName, PackageInfoFlags flags, int userId)265 public PackageInfo getPackageInfoAsUser(String packageName, PackageInfoFlags flags, int userId) 266 throws NameNotFoundException { 267 PackageInfo pi = 268 getPackageInfoAsUserCached( 269 packageName, 270 updateFlagsForPackage(flags.getValue(), userId), 271 userId); 272 if (pi == null) { 273 throw new NameNotFoundException(packageName); 274 } 275 return pi; 276 } 277 278 @Override currentToCanonicalPackageNames(String[] names)279 public String[] currentToCanonicalPackageNames(String[] names) { 280 try { 281 return mPM.currentToCanonicalPackageNames(names); 282 } catch (RemoteException e) { 283 throw e.rethrowFromSystemServer(); 284 } 285 } 286 287 @Override canonicalToCurrentPackageNames(String[] names)288 public String[] canonicalToCurrentPackageNames(String[] names) { 289 try { 290 return mPM.canonicalToCurrentPackageNames(names); 291 } catch (RemoteException e) { 292 throw e.rethrowFromSystemServer(); 293 } 294 } 295 296 @Override getLaunchIntentForPackage(String packageName)297 public Intent getLaunchIntentForPackage(String packageName) { 298 // First see if the package has an INFO activity; the existence of 299 // such an activity is implied to be the desired front-door for the 300 // overall package (such as if it has multiple launcher entries). 301 Intent intentToResolve = new Intent(Intent.ACTION_MAIN); 302 intentToResolve.addCategory(Intent.CATEGORY_INFO); 303 intentToResolve.setPackage(packageName); 304 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0); 305 306 // Otherwise, try to find a main launcher activity. 307 if (ris == null || ris.size() <= 0) { 308 // reuse the intent instance 309 intentToResolve.removeCategory(Intent.CATEGORY_INFO); 310 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER); 311 intentToResolve.setPackage(packageName); 312 ris = queryIntentActivities(intentToResolve, 0); 313 } 314 if (ris == null || ris.size() <= 0) { 315 return null; 316 } 317 Intent intent = new Intent(intentToResolve); 318 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 319 intent.setClassName(ris.get(0).activityInfo.packageName, 320 ris.get(0).activityInfo.name); 321 return intent; 322 } 323 324 @Override getLeanbackLaunchIntentForPackage(String packageName)325 public Intent getLeanbackLaunchIntentForPackage(String packageName) { 326 return getLaunchIntentForPackageAndCategory(packageName, Intent.CATEGORY_LEANBACK_LAUNCHER); 327 } 328 329 @Override getCarLaunchIntentForPackage(String packageName)330 public Intent getCarLaunchIntentForPackage(String packageName) { 331 return getLaunchIntentForPackageAndCategory(packageName, Intent.CATEGORY_CAR_LAUNCHER); 332 } 333 getLaunchIntentForPackageAndCategory(String packageName, String category)334 private Intent getLaunchIntentForPackageAndCategory(String packageName, String category) { 335 // Try to find a main launcher activity for the given categories. 336 Intent intentToResolve = new Intent(Intent.ACTION_MAIN); 337 intentToResolve.addCategory(category); 338 intentToResolve.setPackage(packageName); 339 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0); 340 341 if (ris == null || ris.size() <= 0) { 342 return null; 343 } 344 Intent intent = new Intent(intentToResolve); 345 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 346 intent.setClassName(ris.get(0).activityInfo.packageName, 347 ris.get(0).activityInfo.name); 348 return intent; 349 } 350 351 @Override getLaunchIntentSenderForPackage(@onNull String packageName)352 public @NonNull IntentSender getLaunchIntentSenderForPackage(@NonNull String packageName) { 353 try { 354 return mPM.getLaunchIntentSenderForPackage(packageName, mContext.getPackageName(), 355 mContext.getAttributionTag(), getUserId()); 356 } catch (RemoteException e) { 357 throw e.rethrowFromSystemServer(); 358 } 359 } 360 361 @Override getPackageGids(String packageName)362 public int[] getPackageGids(String packageName) throws NameNotFoundException { 363 return getPackageGids(packageName, 0); 364 } 365 366 @Override getPackageGids(String packageName, int flags)367 public int[] getPackageGids(String packageName, int flags) 368 throws NameNotFoundException { 369 return getPackageGids(packageName, PackageInfoFlags.of(flags)); 370 } 371 372 @Override getPackageGids(String packageName, PackageInfoFlags flags)373 public int[] getPackageGids(String packageName, PackageInfoFlags flags) 374 throws NameNotFoundException { 375 final int userId = getUserId(); 376 try { 377 int[] gids = mPM.getPackageGids(packageName, 378 updateFlagsForPackage(flags.getValue(), userId), userId); 379 if (gids != null) { 380 return gids; 381 } 382 } catch (RemoteException e) { 383 throw e.rethrowFromSystemServer(); 384 } 385 386 throw new NameNotFoundException(packageName); 387 } 388 389 @Override getPackageUid(String packageName, int flags)390 public int getPackageUid(String packageName, int flags) throws NameNotFoundException { 391 return getPackageUid(packageName, PackageInfoFlags.of(flags)); 392 } 393 394 @Override getPackageUid(String packageName, PackageInfoFlags flags)395 public int getPackageUid(String packageName, PackageInfoFlags flags) 396 throws NameNotFoundException { 397 return getPackageUidAsUser(packageName, flags, getUserId()); 398 } 399 400 @Override getPackageUidAsUser(String packageName, int userId)401 public int getPackageUidAsUser(String packageName, int userId) throws NameNotFoundException { 402 return getPackageUidAsUser(packageName, 0, userId); 403 } 404 405 @Override getPackageUidAsUser(String packageName, int flags, int userId)406 public int getPackageUidAsUser(String packageName, int flags, int userId) 407 throws NameNotFoundException { 408 return getPackageUidAsUser(packageName, PackageInfoFlags.of(flags), userId); 409 } 410 411 @Override getPackageUidAsUser(String packageName, PackageInfoFlags flags, int userId)412 public int getPackageUidAsUser(String packageName, PackageInfoFlags flags, int userId) 413 throws NameNotFoundException { 414 try { 415 int uid = mPM.getPackageUid(packageName, 416 updateFlagsForPackage(flags.getValue(), userId), userId); 417 if (uid >= 0) { 418 return uid; 419 } 420 } catch (RemoteException e) { 421 throw e.rethrowFromSystemServer(); 422 } 423 424 throw new NameNotFoundException(packageName); 425 } 426 427 @Override 428 @SuppressWarnings("unchecked") getAllPermissionGroups(int flags)429 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 430 return getPermissionManager().getAllPermissionGroups(flags); 431 } 432 433 @Override getPermissionGroupInfo(String groupName, int flags)434 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) 435 throws NameNotFoundException { 436 final PermissionGroupInfo permissionGroupInfo = getPermissionManager() 437 .getPermissionGroupInfo(groupName, flags); 438 if (permissionGroupInfo == null) { 439 throw new NameNotFoundException(groupName); 440 } 441 return permissionGroupInfo; 442 } 443 444 @Override getPermissionInfo(String permName, int flags)445 public PermissionInfo getPermissionInfo(String permName, int flags) 446 throws NameNotFoundException { 447 final PermissionInfo permissionInfo = getPermissionManager().getPermissionInfo(permName, 448 flags); 449 if (permissionInfo == null) { 450 throw new NameNotFoundException(permName); 451 } 452 return permissionInfo; 453 } 454 455 @Override 456 @SuppressWarnings("unchecked") queryPermissionsByGroup(String groupName, int flags)457 public List<PermissionInfo> queryPermissionsByGroup(String groupName, int flags) 458 throws NameNotFoundException { 459 final List<PermissionInfo> permissionInfos = getPermissionManager().queryPermissionsByGroup( 460 groupName, flags); 461 if (permissionInfos == null) { 462 throw new NameNotFoundException(groupName); 463 } 464 return permissionInfos; 465 } 466 467 @Override getPlatformPermissionsForGroup(@onNull String permissionGroupName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<List<String>> callback)468 public void getPlatformPermissionsForGroup(@NonNull String permissionGroupName, 469 @NonNull @CallbackExecutor Executor executor, 470 @NonNull Consumer<List<String>> callback) { 471 final PermissionControllerManager permissionControllerManager = mContext.getSystemService( 472 PermissionControllerManager.class); 473 permissionControllerManager.getPlatformPermissionsForGroup(permissionGroupName, executor, 474 callback); 475 } 476 477 @Override getGroupOfPlatformPermission(@onNull String permissionName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<String> callback)478 public void getGroupOfPlatformPermission(@NonNull String permissionName, 479 @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<String> callback) { 480 final PermissionControllerManager permissionControllerManager = mContext.getSystemService( 481 PermissionControllerManager.class); 482 permissionControllerManager.getGroupOfPlatformPermission(permissionName, executor, 483 callback); 484 } 485 486 @Override arePermissionsIndividuallyControlled()487 public boolean arePermissionsIndividuallyControlled() { 488 return mContext.getResources().getBoolean( 489 com.android.internal.R.bool.config_permissionsIndividuallyControlled); 490 } 491 492 @Override isWirelessConsentModeEnabled()493 public boolean isWirelessConsentModeEnabled() { 494 return mContext.getResources().getBoolean( 495 com.android.internal.R.bool.config_wirelessConsentRequired); 496 } 497 498 @Override getApplicationInfo(String packageName, int flags)499 public ApplicationInfo getApplicationInfo(String packageName, int flags) 500 throws NameNotFoundException { 501 return getApplicationInfo(packageName, ApplicationInfoFlags.of(flags)); 502 } 503 504 @Override getApplicationInfo(String packageName, ApplicationInfoFlags flags)505 public ApplicationInfo getApplicationInfo(String packageName, ApplicationInfoFlags flags) 506 throws NameNotFoundException { 507 return getApplicationInfoAsUser(packageName, flags, getUserId()); 508 } 509 510 @Override getApplicationInfoAsUser(String packageName, int flags, int userId)511 public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId) 512 throws NameNotFoundException { 513 return getApplicationInfoAsUser(packageName, ApplicationInfoFlags.of(flags), userId); 514 } 515 516 @Override getApplicationInfoAsUser(String packageName, ApplicationInfoFlags flags, int userId)517 public ApplicationInfo getApplicationInfoAsUser(String packageName, ApplicationInfoFlags flags, 518 int userId) throws NameNotFoundException { 519 ApplicationInfo ai = getApplicationInfoAsUserCached( 520 packageName, 521 updateFlagsForApplication(flags.getValue(), userId), 522 userId); 523 if (ai == null) { 524 throw new NameNotFoundException(packageName); 525 } 526 return maybeAdjustApplicationInfo(ai); 527 } 528 maybeAdjustApplicationInfo(ApplicationInfo info)529 private static ApplicationInfo maybeAdjustApplicationInfo(ApplicationInfo info) { 530 // If we're dealing with a multi-arch application that has both 531 // 32 and 64 bit shared libraries, we might need to choose the secondary 532 // depending on what the current runtime's instruction set is. 533 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) { 534 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet(); 535 536 // Get the instruction set that the libraries of secondary Abi is supported. 537 // In presence of a native bridge this might be different than the one secondary Abi used. 538 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi); 539 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa); 540 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa; 541 542 // If the runtimeIsa is the same as the primary isa, then we do nothing. 543 // Everything will be set up correctly because info.nativeLibraryDir will 544 // correspond to the right ISA. 545 if (runtimeIsa.equals(secondaryIsa)) { 546 ApplicationInfo modified = new ApplicationInfo(info); 547 modified.nativeLibraryDir = info.secondaryNativeLibraryDir; 548 return modified; 549 } 550 } 551 return info; 552 } 553 554 @Override getTargetSdkVersion(@onNull String packageName)555 public int getTargetSdkVersion(@NonNull String packageName) throws NameNotFoundException { 556 try { 557 int version = mPM.getTargetSdkVersion(packageName); 558 if (version != -1) { 559 return version; 560 } 561 } catch (RemoteException e) { 562 throw e.rethrowFromSystemServer(); 563 } 564 throw new PackageManager.NameNotFoundException(packageName); 565 } 566 567 @Override getActivityInfo(ComponentName className, int flags)568 public ActivityInfo getActivityInfo(ComponentName className, int flags) 569 throws NameNotFoundException { 570 return getActivityInfo(className, ComponentInfoFlags.of(flags)); 571 } 572 573 @Override getActivityInfo(ComponentName className, ComponentInfoFlags flags)574 public ActivityInfo getActivityInfo(ComponentName className, ComponentInfoFlags flags) 575 throws NameNotFoundException { 576 final int userId = getUserId(); 577 try { 578 ActivityInfo ai = mPM.getActivityInfo(className, 579 updateFlagsForComponent(flags.getValue(), userId, null), userId); 580 if (ai != null) { 581 return ai; 582 } 583 } catch (RemoteException e) { 584 throw e.rethrowFromSystemServer(); 585 } 586 587 throw new NameNotFoundException(className.toString()); 588 } 589 590 @Override getReceiverInfo(ComponentName className, int flags)591 public ActivityInfo getReceiverInfo(ComponentName className, int flags) 592 throws NameNotFoundException { 593 return getReceiverInfo(className, ComponentInfoFlags.of(flags)); 594 } 595 596 @Override getReceiverInfo(ComponentName className, ComponentInfoFlags flags)597 public ActivityInfo getReceiverInfo(ComponentName className, ComponentInfoFlags flags) 598 throws NameNotFoundException { 599 final int userId = getUserId(); 600 try { 601 ActivityInfo ai = mPM.getReceiverInfo(className, 602 updateFlagsForComponent(flags.getValue(), userId, null), userId); 603 if (ai != null) { 604 return ai; 605 } 606 } catch (RemoteException e) { 607 throw e.rethrowFromSystemServer(); 608 } 609 610 throw new NameNotFoundException(className.toString()); 611 } 612 613 @Override getServiceInfo(ComponentName className, int flags)614 public ServiceInfo getServiceInfo(ComponentName className, int flags) 615 throws NameNotFoundException { 616 return getServiceInfo(className, ComponentInfoFlags.of(flags)); 617 } 618 619 @Override getServiceInfo(ComponentName className, ComponentInfoFlags flags)620 public ServiceInfo getServiceInfo(ComponentName className, ComponentInfoFlags flags) 621 throws NameNotFoundException { 622 final int userId = getUserId(); 623 try { 624 ServiceInfo si = mPM.getServiceInfo(className, 625 updateFlagsForComponent(flags.getValue(), userId, null), userId); 626 if (si != null) { 627 return si; 628 } 629 } catch (RemoteException e) { 630 throw e.rethrowFromSystemServer(); 631 } 632 633 throw new NameNotFoundException(className.toString()); 634 } 635 636 @Override getProviderInfo(ComponentName className, int flags)637 public ProviderInfo getProviderInfo(ComponentName className, int flags) 638 throws NameNotFoundException { 639 return getProviderInfo(className, ComponentInfoFlags.of(flags)); 640 } 641 642 @Override getProviderInfo(ComponentName className, ComponentInfoFlags flags)643 public ProviderInfo getProviderInfo(ComponentName className, ComponentInfoFlags flags) 644 throws NameNotFoundException { 645 final int userId = getUserId(); 646 try { 647 ProviderInfo pi = mPM.getProviderInfo(className, 648 updateFlagsForComponent(flags.getValue(), userId, null), userId); 649 if (pi != null) { 650 return pi; 651 } 652 } catch (RemoteException e) { 653 throw e.rethrowFromSystemServer(); 654 } 655 656 throw new NameNotFoundException(className.toString()); 657 } 658 659 @Override getSystemSharedLibraryNames()660 public String[] getSystemSharedLibraryNames() { 661 try { 662 return mPM.getSystemSharedLibraryNames(); 663 } catch (RemoteException e) { 664 throw e.rethrowFromSystemServer(); 665 } 666 } 667 668 /** @hide */ 669 @Override getSharedLibraries(int flags)670 public @NonNull List<SharedLibraryInfo> getSharedLibraries(int flags) { 671 return this.getSharedLibraries(PackageInfoFlags.of(flags)); 672 } 673 674 /** @hide 675 * @param flags */ 676 @Override getSharedLibraries(PackageInfoFlags flags)677 public @NonNull List<SharedLibraryInfo> getSharedLibraries(PackageInfoFlags flags) { 678 return getSharedLibrariesAsUser(flags, getUserId()); 679 } 680 681 /** @hide */ 682 @Override getSharedLibrariesAsUser(int flags, int userId)683 public @NonNull List<SharedLibraryInfo> getSharedLibrariesAsUser(int flags, int userId) { 684 return getSharedLibrariesAsUser(PackageInfoFlags.of(flags), userId); 685 } 686 687 /** @hide */ 688 @Override 689 @SuppressWarnings("unchecked") getSharedLibrariesAsUser(PackageInfoFlags flags, int userId)690 public @NonNull List<SharedLibraryInfo> getSharedLibrariesAsUser(PackageInfoFlags flags, 691 int userId) { 692 try { 693 ParceledListSlice<SharedLibraryInfo> sharedLibs = mPM.getSharedLibraries( 694 mContext.getOpPackageName(), flags.getValue(), userId); 695 if (sharedLibs == null) { 696 return Collections.emptyList(); 697 } 698 return sharedLibs.getList(); 699 } catch (RemoteException e) { 700 throw e.rethrowFromSystemServer(); 701 } 702 } 703 704 @NonNull 705 @Override getDeclaredSharedLibraries(@onNull String packageName, int flags)706 public List<SharedLibraryInfo> getDeclaredSharedLibraries(@NonNull String packageName, 707 int flags) { 708 return getDeclaredSharedLibraries(packageName, PackageInfoFlags.of(flags)); 709 } 710 711 @NonNull 712 @Override 713 @SuppressWarnings("unchecked") getDeclaredSharedLibraries(@onNull String packageName, PackageInfoFlags flags)714 public List<SharedLibraryInfo> getDeclaredSharedLibraries(@NonNull String packageName, 715 PackageInfoFlags flags) { 716 try { 717 ParceledListSlice<SharedLibraryInfo> sharedLibraries = mPM.getDeclaredSharedLibraries( 718 packageName, flags.getValue(), mContext.getUserId()); 719 return sharedLibraries != null ? sharedLibraries.getList() : Collections.emptyList(); 720 } catch (RemoteException e) { 721 throw e.rethrowFromSystemServer(); 722 } 723 } 724 725 /** @hide */ 726 @Override getServicesSystemSharedLibraryPackageName()727 public @NonNull String getServicesSystemSharedLibraryPackageName() { 728 try { 729 return mPM.getServicesSystemSharedLibraryPackageName(); 730 } catch (RemoteException e) { 731 throw e.rethrowFromSystemServer(); 732 } 733 } 734 735 /** 736 * @hide 737 */ getSharedSystemSharedLibraryPackageName()738 public @NonNull String getSharedSystemSharedLibraryPackageName() { 739 try { 740 return mPM.getSharedSystemSharedLibraryPackageName(); 741 } catch (RemoteException e) { 742 throw e.rethrowFromSystemServer(); 743 } 744 } 745 746 @Override getChangedPackages(int sequenceNumber)747 public ChangedPackages getChangedPackages(int sequenceNumber) { 748 try { 749 return mPM.getChangedPackages(sequenceNumber, getUserId()); 750 } catch (RemoteException e) { 751 throw e.rethrowFromSystemServer(); 752 } 753 } 754 755 @Override 756 @SuppressWarnings("unchecked") getSystemAvailableFeatures()757 public FeatureInfo[] getSystemAvailableFeatures() { 758 try { 759 ParceledListSlice<FeatureInfo> parceledList = 760 mPM.getSystemAvailableFeatures(); 761 if (parceledList == null) { 762 return new FeatureInfo[0]; 763 } 764 final List<FeatureInfo> list = parceledList.getList(); 765 final FeatureInfo[] res = new FeatureInfo[list.size()]; 766 for (int i = 0; i < res.length; i++) { 767 res[i] = list.get(i); 768 } 769 return res; 770 } catch (RemoteException e) { 771 throw e.rethrowFromSystemServer(); 772 } 773 } 774 775 @Override hasSystemFeature(String name)776 public boolean hasSystemFeature(String name) { 777 return hasSystemFeature(name, 0); 778 } 779 780 /** 781 * Identifies a single hasSystemFeature query. 782 */ 783 @Immutable 784 private static final class HasSystemFeatureQuery { 785 public final String name; 786 public final int version; HasSystemFeatureQuery(String n, int v)787 public HasSystemFeatureQuery(String n, int v) { 788 name = n; 789 version = v; 790 } 791 @Override toString()792 public String toString() { 793 return String.format("HasSystemFeatureQuery(name=\"%s\", version=%d)", 794 name, version); 795 } 796 @Override equals(@ullable Object o)797 public boolean equals(@Nullable Object o) { 798 if (o instanceof HasSystemFeatureQuery) { 799 HasSystemFeatureQuery r = (HasSystemFeatureQuery) o; 800 return Objects.equals(name, r.name) && version == r.version; 801 } else { 802 return false; 803 } 804 } 805 @Override hashCode()806 public int hashCode() { 807 return Objects.hashCode(name) * 13 + version; 808 } 809 } 810 811 // Make this cache relatively large. There are many system features and 812 // none are ever invalidated. MPTS tests suggests that the cache should 813 // hold at least 150 entries. 814 private final static PropertyInvalidatedCache<HasSystemFeatureQuery, Boolean> 815 mHasSystemFeatureCache = 816 new PropertyInvalidatedCache<HasSystemFeatureQuery, Boolean>( 817 256, "cache_key.has_system_feature") { 818 @Override 819 public Boolean recompute(HasSystemFeatureQuery query) { 820 try { 821 return ActivityThread.currentActivityThread().getPackageManager(). 822 hasSystemFeature(query.name, query.version); 823 } catch (RemoteException e) { 824 throw e.rethrowFromSystemServer(); 825 } 826 } 827 }; 828 829 @Override hasSystemFeature(String name, int version)830 public boolean hasSystemFeature(String name, int version) { 831 return mHasSystemFeatureCache.query(new HasSystemFeatureQuery(name, version)); 832 } 833 834 /** @hide */ disableHasSystemFeatureCache()835 public void disableHasSystemFeatureCache() { 836 mHasSystemFeatureCache.disableLocal(); 837 } 838 839 /** @hide */ invalidateHasSystemFeatureCache()840 public static void invalidateHasSystemFeatureCache() { 841 mHasSystemFeatureCache.invalidateCache(); 842 } 843 844 @Override checkPermission(String permName, String pkgName)845 public int checkPermission(String permName, String pkgName) { 846 return getPermissionManager().checkPackageNamePermission(permName, pkgName, 847 mContext.getDeviceId(), getUserId()); 848 } 849 850 @Override isPermissionRevokedByPolicy(String permName, String pkgName)851 public boolean isPermissionRevokedByPolicy(String permName, String pkgName) { 852 return getPermissionManager().isPermissionRevokedByPolicy(pkgName, permName); 853 } 854 855 /** 856 * @hide 857 */ 858 @Override getPermissionControllerPackageName()859 public String getPermissionControllerPackageName() { 860 if (mPermissionsControllerPackageName == null) { 861 try { 862 mPermissionsControllerPackageName = mPM.getPermissionControllerPackageName(); 863 } catch (RemoteException e) { 864 throw e.rethrowFromSystemServer(); 865 } 866 } 867 return mPermissionsControllerPackageName; 868 } 869 870 /** 871 * @hide 872 */ 873 @Override getSdkSandboxPackageName()874 public String getSdkSandboxPackageName() { 875 try { 876 return mPM.getSdkSandboxPackageName(); 877 } catch (RemoteException e) { 878 throw e.rethrowFromSystemServer(); 879 } 880 } 881 882 @Override addPermission(PermissionInfo info)883 public boolean addPermission(PermissionInfo info) { 884 return getPermissionManager().addPermission(info, false); 885 } 886 887 @Override addPermissionAsync(PermissionInfo info)888 public boolean addPermissionAsync(PermissionInfo info) { 889 return getPermissionManager().addPermission(info, true); 890 } 891 892 @Override removePermission(String name)893 public void removePermission(String name) { 894 getPermissionManager().removePermission(name); 895 } 896 897 @Override grantRuntimePermission(String packageName, String permissionName, UserHandle user)898 public void grantRuntimePermission(String packageName, String permissionName, 899 UserHandle user) { 900 getPermissionManager().grantRuntimePermission(packageName, permissionName, user); 901 } 902 903 @Override revokeRuntimePermission(String packageName, String permName, UserHandle user)904 public void revokeRuntimePermission(String packageName, String permName, UserHandle user) { 905 revokeRuntimePermission(packageName, permName, user, null); 906 } 907 908 @Override revokeRuntimePermission(String packageName, String permName, UserHandle user, String reason)909 public void revokeRuntimePermission(String packageName, String permName, UserHandle user, 910 String reason) { 911 getPermissionManager().revokeRuntimePermission(packageName, permName, user, reason); 912 } 913 914 @Override getPermissionFlags(String permName, String packageName, UserHandle user)915 public int getPermissionFlags(String permName, String packageName, UserHandle user) { 916 return getPermissionManager().getPermissionFlags(packageName, permName, user); 917 } 918 919 @Override updatePermissionFlags(String permName, String packageName, int flagMask, int flagValues, UserHandle user)920 public void updatePermissionFlags(String permName, String packageName, 921 int flagMask, int flagValues, UserHandle user) { 922 getPermissionManager().updatePermissionFlags(packageName, permName, flagMask, flagValues, 923 user); 924 } 925 926 @Override getWhitelistedRestrictedPermissions( @onNull String packageName, @PermissionWhitelistFlags int flags)927 public @NonNull Set<String> getWhitelistedRestrictedPermissions( 928 @NonNull String packageName, @PermissionWhitelistFlags int flags) { 929 return getPermissionManager().getAllowlistedRestrictedPermissions(packageName, flags); 930 } 931 932 @Override addWhitelistedRestrictedPermission(@onNull String packageName, @NonNull String permName, @PermissionWhitelistFlags int flags)933 public boolean addWhitelistedRestrictedPermission(@NonNull String packageName, 934 @NonNull String permName, @PermissionWhitelistFlags int flags) { 935 return getPermissionManager().addAllowlistedRestrictedPermission(packageName, permName, 936 flags); 937 } 938 939 @Override setAutoRevokeWhitelisted(@onNull String packageName, boolean whitelisted)940 public boolean setAutoRevokeWhitelisted(@NonNull String packageName, boolean whitelisted) { 941 return getPermissionManager().setAutoRevokeExempted(packageName, whitelisted); 942 } 943 944 @Override isAutoRevokeWhitelisted(@onNull String packageName)945 public boolean isAutoRevokeWhitelisted(@NonNull String packageName) { 946 return getPermissionManager().isAutoRevokeExempted(packageName); 947 } 948 949 @Override removeWhitelistedRestrictedPermission(@onNull String packageName, @NonNull String permName, @PermissionWhitelistFlags int flags)950 public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName, 951 @NonNull String permName, @PermissionWhitelistFlags int flags) { 952 return getPermissionManager().removeAllowlistedRestrictedPermission(packageName, permName, 953 flags); 954 } 955 956 @Override 957 @UnsupportedAppUsage shouldShowRequestPermissionRationale(String permName)958 public boolean shouldShowRequestPermissionRationale(String permName) { 959 return getPermissionManager().shouldShowRequestPermissionRationale(permName); 960 } 961 962 @Override buildRequestPermissionsIntent(@onNull String[] permissions)963 public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) { 964 Intent intent = super.buildRequestPermissionsIntent(permissions); 965 intent.putExtra(EXTRA_REQUEST_PERMISSIONS_DEVICE_ID, mContext.getDeviceId()); 966 return intent; 967 } 968 969 @Override getBackgroundPermissionOptionLabel()970 public CharSequence getBackgroundPermissionOptionLabel() { 971 try { 972 973 String permissionController = getPermissionControllerPackageName(); 974 Context context = 975 mContext.createPackageContext(permissionController, 0); 976 977 int textId = context.getResources().getIdentifier(APP_PERMISSION_BUTTON_ALLOW_ALWAYS, 978 "string", PERMISSION_CONTROLLER_RESOURCE_PACKAGE); 979 if (textId != 0) { 980 return context.getText(textId); 981 } 982 } catch (NameNotFoundException e) { 983 Log.e(TAG, "Permission controller not found.", e); 984 } 985 return ""; 986 } 987 988 @Override checkSignatures(String pkg1, String pkg2)989 public int checkSignatures(String pkg1, String pkg2) { 990 try { 991 return mPM.checkSignatures(pkg1, pkg2, getUserId()); 992 } catch (RemoteException e) { 993 throw e.rethrowFromSystemServer(); 994 } 995 } 996 997 @Override checkSignatures(int uid1, int uid2)998 public int checkSignatures(int uid1, int uid2) { 999 try { 1000 return mPM.checkUidSignatures(uid1, uid2); 1001 } catch (RemoteException e) { 1002 throw e.rethrowFromSystemServer(); 1003 } 1004 } 1005 1006 @Override hasSigningCertificate( String packageName, byte[] certificate, @CertificateInputType int type)1007 public boolean hasSigningCertificate( 1008 String packageName, byte[] certificate, @CertificateInputType int type) { 1009 try { 1010 return mPM.hasSigningCertificate(packageName, certificate, type); 1011 } catch (RemoteException e) { 1012 throw e.rethrowFromSystemServer(); 1013 } 1014 } 1015 1016 @Override hasSigningCertificate( int uid, byte[] certificate, @CertificateInputType int type)1017 public boolean hasSigningCertificate( 1018 int uid, byte[] certificate, @CertificateInputType int type) { 1019 try { 1020 return mPM.hasUidSigningCertificate(uid, certificate, type); 1021 } catch (RemoteException e) { 1022 throw e.rethrowFromSystemServer(); 1023 } 1024 } 1025 encodeCertificates(List<Certificate> certs)1026 private static List<byte[]> encodeCertificates(List<Certificate> certs) throws 1027 CertificateEncodingException { 1028 if (certs == null) { 1029 return null; 1030 } 1031 List<byte[]> result = new ArrayList<>(certs.size()); 1032 for (Certificate cert : certs) { 1033 if (!(cert instanceof X509Certificate)) { 1034 throw new CertificateEncodingException("Only X509 certificates supported."); 1035 } 1036 result.add(cert.getEncoded()); 1037 } 1038 return result; 1039 } 1040 1041 @Override requestChecksums(@onNull String packageName, boolean includeSplits, @Checksum.TypeMask int required, @NonNull List<Certificate> trustedInstallers, @NonNull OnChecksumsReadyListener onChecksumsReadyListener)1042 public void requestChecksums(@NonNull String packageName, boolean includeSplits, 1043 @Checksum.TypeMask int required, @NonNull List<Certificate> trustedInstallers, 1044 @NonNull OnChecksumsReadyListener onChecksumsReadyListener) 1045 throws CertificateEncodingException, NameNotFoundException { 1046 Objects.requireNonNull(packageName); 1047 Objects.requireNonNull(onChecksumsReadyListener); 1048 Objects.requireNonNull(trustedInstallers); 1049 if (trustedInstallers == TRUST_ALL) { 1050 trustedInstallers = null; 1051 } else if (trustedInstallers == TRUST_NONE) { 1052 trustedInstallers = Collections.emptyList(); 1053 } else if (trustedInstallers.isEmpty()) { 1054 throw new IllegalArgumentException( 1055 "trustedInstallers has to be one of TRUST_ALL/TRUST_NONE or a non-empty " 1056 + "list of certificates."); 1057 } 1058 try { 1059 IOnChecksumsReadyListener onChecksumsReadyListenerDelegate = 1060 new IOnChecksumsReadyListener.Stub() { 1061 @Override 1062 public void onChecksumsReady(List<ApkChecksum> checksums) 1063 throws RemoteException { 1064 onChecksumsReadyListener.onChecksumsReady(checksums); 1065 } 1066 }; 1067 mPM.requestPackageChecksums(packageName, includeSplits, DEFAULT_CHECKSUMS, required, 1068 encodeCertificates(trustedInstallers), onChecksumsReadyListenerDelegate, 1069 getUserId()); 1070 } catch (ParcelableException e) { 1071 e.maybeRethrow(PackageManager.NameNotFoundException.class); 1072 throw new RuntimeException(e); 1073 } catch (RemoteException e) { 1074 throw e.rethrowFromSystemServer(); 1075 } 1076 } 1077 1078 /** 1079 * Wrap the cached value in a class that does deep compares on string 1080 * arrays. The comparison is needed only for the verification mode of 1081 * PropertyInvalidatedCache; this mode is only enabled for debugging. 1082 * The return result is an array of strings but the order in the array 1083 * is not important. To properly compare two arrays, the arrays are 1084 * sorted before the comparison. 1085 */ 1086 private static class GetPackagesForUidResult { 1087 private final String [] mValue; GetPackagesForUidResult(String []s)1088 GetPackagesForUidResult(String []s) { 1089 mValue = s; 1090 } value()1091 public String[] value() { 1092 return mValue; 1093 } 1094 @Override toString()1095 public String toString() { 1096 return Arrays.toString(mValue); 1097 } 1098 @Override hashCode()1099 public int hashCode() { 1100 return Arrays.hashCode(mValue); 1101 } 1102 /** 1103 * Arrays.sort() throws an NPE if passed a null pointer, so nulls 1104 * are handled first. 1105 */ 1106 @Override equals(@ullable Object o)1107 public boolean equals(@Nullable Object o) { 1108 if (o instanceof GetPackagesForUidResult) { 1109 String [] r = ((GetPackagesForUidResult) o).mValue; 1110 String [] l = mValue; 1111 if ((r == null) != (l == null)) { 1112 return false; 1113 } else if (r == null) { 1114 return true; 1115 } 1116 // Both arrays are non-null. Sort before comparing. 1117 Arrays.sort(r); 1118 Arrays.sort(l); 1119 return Arrays.equals(l, r); 1120 } else { 1121 return false; 1122 } 1123 } 1124 } 1125 1126 private static final String CACHE_KEY_PACKAGES_FOR_UID_PROPERTY = 1127 "cache_key.get_packages_for_uid"; 1128 private static final PropertyInvalidatedCache<Integer, GetPackagesForUidResult> 1129 mGetPackagesForUidCache = 1130 new PropertyInvalidatedCache<Integer, GetPackagesForUidResult>( 1131 32, CACHE_KEY_PACKAGES_FOR_UID_PROPERTY) { 1132 @Override 1133 public GetPackagesForUidResult recompute(Integer uid) { 1134 try { 1135 return new GetPackagesForUidResult( 1136 ActivityThread.currentActivityThread(). 1137 getPackageManager().getPackagesForUid(uid)); 1138 } catch (RemoteException e) { 1139 throw e.rethrowFromSystemServer(); 1140 } 1141 } 1142 @Override 1143 public String queryToString(Integer uid) { 1144 return String.format("uid=%d", uid.intValue()); 1145 } 1146 }; 1147 1148 @Override getPackagesForUid(int uid)1149 public String[] getPackagesForUid(int uid) { 1150 return mGetPackagesForUidCache.query(uid).value(); 1151 } 1152 1153 /** @hide */ disableGetPackagesForUidCache()1154 public static void disableGetPackagesForUidCache() { 1155 mGetPackagesForUidCache.disableLocal(); 1156 } 1157 1158 /** @hide */ invalidateGetPackagesForUidCache()1159 public static void invalidateGetPackagesForUidCache() { 1160 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_PACKAGES_FOR_UID_PROPERTY); 1161 } 1162 1163 @Override getNameForUid(int uid)1164 public String getNameForUid(int uid) { 1165 try { 1166 return mPM.getNameForUid(uid); 1167 } catch (RemoteException e) { 1168 throw e.rethrowFromSystemServer(); 1169 } 1170 } 1171 1172 @Override getNamesForUids(int[] uids)1173 public String[] getNamesForUids(int[] uids) { 1174 try { 1175 return mPM.getNamesForUids(uids); 1176 } catch (RemoteException e) { 1177 throw e.rethrowFromSystemServer(); 1178 } 1179 } 1180 1181 @Override getUidForSharedUser(String sharedUserName)1182 public int getUidForSharedUser(String sharedUserName) 1183 throws NameNotFoundException { 1184 try { 1185 int uid = mPM.getUidForSharedUser(sharedUserName); 1186 if (uid != Process.INVALID_UID) { 1187 return uid; 1188 } 1189 } catch (RemoteException e) { 1190 throw e.rethrowFromSystemServer(); 1191 } 1192 throw new NameNotFoundException("No shared userid for user:"+sharedUserName); 1193 } 1194 1195 @Override getInstalledModules(int flags)1196 public List<ModuleInfo> getInstalledModules(int flags) { 1197 try { 1198 return mPM.getInstalledModules(flags); 1199 } catch (RemoteException e) { 1200 throw e.rethrowFromSystemServer(); 1201 } 1202 } 1203 1204 @Override getModuleInfo(String packageName, int flags)1205 public ModuleInfo getModuleInfo(String packageName, int flags) throws NameNotFoundException { 1206 try { 1207 ModuleInfo mi = mPM.getModuleInfo(packageName, flags); 1208 if (mi != null) { 1209 return mi; 1210 } 1211 } catch (RemoteException e) { 1212 throw e.rethrowFromSystemServer(); 1213 } 1214 1215 throw new NameNotFoundException("No module info for package: " + packageName); 1216 } 1217 1218 @SuppressWarnings("unchecked") 1219 @Override getInstalledPackages(int flags)1220 public List<PackageInfo> getInstalledPackages(int flags) { 1221 return getInstalledPackages(PackageInfoFlags.of(flags)); 1222 } 1223 1224 @SuppressWarnings("unchecked") 1225 @Override getInstalledPackages(PackageInfoFlags flags)1226 public List<PackageInfo> getInstalledPackages(PackageInfoFlags flags) { 1227 return getInstalledPackagesAsUser(flags, getUserId()); 1228 } 1229 1230 /** @hide */ 1231 @Override 1232 @SuppressWarnings("unchecked") getInstalledPackagesAsUser(int flags, int userId)1233 public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) { 1234 return getInstalledPackagesAsUser(PackageInfoFlags.of(flags), userId); 1235 } 1236 1237 /** @hide */ 1238 @Override 1239 @SuppressWarnings("unchecked") getInstalledPackagesAsUser(PackageInfoFlags flags, int userId)1240 public List<PackageInfo> getInstalledPackagesAsUser(PackageInfoFlags flags, int userId) { 1241 try { 1242 ParceledListSlice<PackageInfo> parceledList = 1243 mPM.getInstalledPackages(updateFlagsForPackage(flags.getValue(), userId), 1244 userId); 1245 if (parceledList == null) { 1246 return Collections.emptyList(); 1247 } 1248 return parceledList.getList(); 1249 } catch (RemoteException e) { 1250 throw e.rethrowFromSystemServer(); 1251 } 1252 } 1253 1254 @Override 1255 @NonNull getAppMetadata(@onNull String packageName)1256 public PersistableBundle getAppMetadata(@NonNull String packageName) 1257 throws NameNotFoundException { 1258 PersistableBundle appMetadata = null; 1259 ParcelFileDescriptor pfd = null; 1260 try { 1261 pfd = mPM.getAppMetadataFd(packageName, getUserId()); 1262 } catch (ParcelableException e) { 1263 e.maybeRethrow(NameNotFoundException.class); 1264 throw new RuntimeException(e); 1265 } catch (RemoteException e) { 1266 throw e.rethrowFromSystemServer(); 1267 } 1268 if (pfd != null) { 1269 try (InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) { 1270 appMetadata = PersistableBundle.readFromStream(inputStream); 1271 } catch (IOException e) { 1272 throw new RuntimeException(e); 1273 } 1274 } 1275 1276 return appMetadata != null ? appMetadata : new PersistableBundle(); 1277 } 1278 1279 @Override getAppMetadataSource(@onNull String packageName)1280 public @AppMetadataSource int getAppMetadataSource(@NonNull String packageName) 1281 throws NameNotFoundException { 1282 Objects.requireNonNull(packageName, "packageName cannot be null"); 1283 int source = PackageManager.APP_METADATA_SOURCE_UNKNOWN; 1284 try { 1285 source = mPM.getAppMetadataSource(packageName, getUserId()); 1286 } catch (ParcelableException e) { 1287 e.maybeRethrow(NameNotFoundException.class); 1288 throw new RuntimeException(e); 1289 } catch (RemoteException e) { 1290 throw e.rethrowFromSystemServer(); 1291 } 1292 return source; 1293 } 1294 1295 @SuppressWarnings("unchecked") 1296 @Override getPackagesHoldingPermissions(String[] permissions, int flags)1297 public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags) { 1298 return this.getPackagesHoldingPermissions(permissions, PackageInfoFlags.of(flags)); 1299 } 1300 1301 @SuppressWarnings("unchecked") 1302 @Override getPackagesHoldingPermissions(String[] permissions, PackageInfoFlags flags)1303 public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, 1304 PackageInfoFlags flags) { 1305 final int userId = getUserId(); 1306 try { 1307 ParceledListSlice<PackageInfo> parceledList = 1308 mPM.getPackagesHoldingPermissions(permissions, 1309 updateFlagsForPackage(flags.getValue(), userId), userId); 1310 if (parceledList == null) { 1311 return Collections.emptyList(); 1312 } 1313 return parceledList.getList(); 1314 } catch (RemoteException e) { 1315 throw e.rethrowFromSystemServer(); 1316 } 1317 } 1318 1319 @SuppressWarnings("unchecked") 1320 @Override getInstalledApplications(int flags)1321 public List<ApplicationInfo> getInstalledApplications(int flags) { 1322 return getInstalledApplicationsAsUser(flags, getUserId()); 1323 } 1324 1325 @Override getInstalledApplications(ApplicationInfoFlags flags)1326 public List<ApplicationInfo> getInstalledApplications(ApplicationInfoFlags flags) { 1327 return getInstalledApplicationsAsUser(flags, getUserId()); 1328 } 1329 1330 /** @hide */ 1331 @SuppressWarnings("unchecked") 1332 @Override getInstalledApplicationsAsUser(int flags, int userId)1333 public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) { 1334 return getInstalledApplicationsAsUser(ApplicationInfoFlags.of(flags), userId); 1335 } 1336 1337 /** @hide */ 1338 @SuppressWarnings("unchecked") 1339 @Override getInstalledApplicationsAsUser(ApplicationInfoFlags flags, int userId)1340 public List<ApplicationInfo> getInstalledApplicationsAsUser(ApplicationInfoFlags flags, 1341 int userId) { 1342 try { 1343 ParceledListSlice<ApplicationInfo> parceledList = 1344 mPM.getInstalledApplications(updateFlagsForApplication( 1345 flags.getValue(), userId), userId); 1346 if (parceledList == null) { 1347 return Collections.emptyList(); 1348 } 1349 return parceledList.getList(); 1350 } catch (RemoteException e) { 1351 throw e.rethrowFromSystemServer(); 1352 } 1353 } 1354 1355 /** @hide */ 1356 @SuppressWarnings("unchecked") 1357 @Override getInstantApps()1358 public List<InstantAppInfo> getInstantApps() { 1359 try { 1360 ParceledListSlice<InstantAppInfo> slice = mPM.getInstantApps(getUserId()); 1361 if (slice != null) { 1362 return slice.getList(); 1363 } 1364 return Collections.emptyList(); 1365 } catch (RemoteException e) { 1366 throw e.rethrowFromSystemServer(); 1367 } 1368 } 1369 1370 /** @hide */ 1371 @Override getInstantAppIcon(String packageName)1372 public Drawable getInstantAppIcon(String packageName) { 1373 try { 1374 Bitmap bitmap = mPM.getInstantAppIcon(packageName, getUserId()); 1375 if (bitmap != null) { 1376 return new BitmapDrawable(null, bitmap); 1377 } 1378 return null; 1379 } catch (RemoteException e) { 1380 throw e.rethrowFromSystemServer(); 1381 } 1382 } 1383 1384 @Override isInstantApp()1385 public boolean isInstantApp() { 1386 return isInstantApp(mContext.getPackageName()); 1387 } 1388 1389 @Override isInstantApp(String packageName)1390 public boolean isInstantApp(String packageName) { 1391 try { 1392 return mPM.isInstantApp(packageName, getUserId()); 1393 } catch (RemoteException e) { 1394 throw e.rethrowFromSystemServer(); 1395 } 1396 } 1397 getInstantAppCookieMaxBytes()1398 public int getInstantAppCookieMaxBytes() { 1399 return Settings.Global.getInt(mContext.getContentResolver(), 1400 Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES, 1401 DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES); 1402 } 1403 1404 @Override getInstantAppCookieMaxSize()1405 public int getInstantAppCookieMaxSize() { 1406 return getInstantAppCookieMaxBytes(); 1407 } 1408 1409 @Override getInstantAppCookie()1410 public @NonNull byte[] getInstantAppCookie() { 1411 try { 1412 final byte[] cookie = mPM.getInstantAppCookie(mContext.getPackageName(), getUserId()); 1413 if (cookie != null) { 1414 return cookie; 1415 } else { 1416 return EmptyArray.BYTE; 1417 } 1418 } catch (RemoteException e) { 1419 throw e.rethrowFromSystemServer(); 1420 } 1421 } 1422 1423 @Override clearInstantAppCookie()1424 public void clearInstantAppCookie() { 1425 updateInstantAppCookie(null); 1426 } 1427 1428 @Override updateInstantAppCookie(@onNull byte[] cookie)1429 public void updateInstantAppCookie(@NonNull byte[] cookie) { 1430 if (cookie != null && cookie.length > getInstantAppCookieMaxBytes()) { 1431 throw new IllegalArgumentException("instant cookie longer than " 1432 + getInstantAppCookieMaxBytes()); 1433 } 1434 try { 1435 mPM.setInstantAppCookie(mContext.getPackageName(), cookie, getUserId()); 1436 } catch (RemoteException e) { 1437 throw e.rethrowFromSystemServer(); 1438 } 1439 } 1440 1441 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1442 @Override setInstantAppCookie(@onNull byte[] cookie)1443 public boolean setInstantAppCookie(@NonNull byte[] cookie) { 1444 try { 1445 return mPM.setInstantAppCookie(mContext.getPackageName(), cookie, getUserId()); 1446 } catch (RemoteException e) { 1447 throw e.rethrowFromSystemServer(); 1448 } 1449 } 1450 1451 @Override resolveActivity(Intent intent, int flags)1452 public ResolveInfo resolveActivity(Intent intent, int flags) { 1453 return resolveActivity(intent, ResolveInfoFlags.of(flags)); 1454 } 1455 1456 @Override resolveActivity(Intent intent, ResolveInfoFlags flags)1457 public ResolveInfo resolveActivity(Intent intent, ResolveInfoFlags flags) { 1458 return resolveActivityAsUser(intent, flags, getUserId()); 1459 } 1460 1461 @Override resolveActivityAsUser(Intent intent, int flags, int userId)1462 public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) { 1463 return resolveActivityAsUser(intent, ResolveInfoFlags.of(flags), userId); 1464 } 1465 1466 @Override resolveActivityAsUser(Intent intent, ResolveInfoFlags flags, int userId)1467 public ResolveInfo resolveActivityAsUser(Intent intent, ResolveInfoFlags flags, int userId) { 1468 try { 1469 return mPM.resolveIntent( 1470 intent, 1471 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 1472 updateFlagsForComponent(flags.getValue(), userId, intent), 1473 userId); 1474 } catch (RemoteException e) { 1475 throw e.rethrowFromSystemServer(); 1476 } 1477 } 1478 1479 @Override queryIntentActivities(Intent intent, int flags)1480 public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) { 1481 return queryIntentActivities(intent, ResolveInfoFlags.of(flags)); 1482 } 1483 1484 @Override queryIntentActivities(Intent intent, ResolveInfoFlags flags)1485 public List<ResolveInfo> queryIntentActivities(Intent intent, ResolveInfoFlags flags) { 1486 return queryIntentActivitiesAsUser(intent, flags, getUserId()); 1487 } 1488 1489 /** @hide Same as above but for a specific user */ 1490 @Override queryIntentActivitiesAsUser(Intent intent, int flags, int userId)1491 public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) { 1492 return queryIntentActivitiesAsUser(intent, ResolveInfoFlags.of(flags), userId); 1493 } 1494 1495 /** @hide Same as above but for a specific user */ 1496 @Override 1497 @SuppressWarnings("unchecked") queryIntentActivitiesAsUser(Intent intent, ResolveInfoFlags flags, int userId)1498 public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, ResolveInfoFlags flags, 1499 int userId) { 1500 try { 1501 ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivities( 1502 intent, 1503 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 1504 updateFlagsForComponent(flags.getValue(), userId, intent), 1505 userId); 1506 if (parceledList == null) { 1507 return Collections.emptyList(); 1508 } 1509 return parceledList.getList(); 1510 } catch (RemoteException e) { 1511 throw e.rethrowFromSystemServer(); 1512 } 1513 } 1514 1515 @Override queryIntentActivityOptions(ComponentName caller, Intent[] specifics, Intent intent, int flags)1516 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics, 1517 Intent intent, int flags) { 1518 return queryIntentActivityOptions(caller, 1519 specifics == null ? null : new ArrayList<>(Arrays.asList(specifics)), 1520 intent, ResolveInfoFlags.of(flags)); 1521 } 1522 1523 @Override 1524 @SuppressWarnings("unchecked") queryIntentActivityOptions(ComponentName caller, List<Intent> specifics, Intent intent, ResolveInfoFlags flags)1525 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 1526 List<Intent> specifics, Intent intent, ResolveInfoFlags flags) { 1527 final int userId = getUserId(); 1528 final ContentResolver resolver = mContext.getContentResolver(); 1529 1530 String[] specificTypes = null; 1531 if (specifics != null) { 1532 final int numSpecifics = specifics.size(); 1533 for (int i = 0; i < numSpecifics; i++) { 1534 Intent sp = specifics.get(i); 1535 if (sp != null) { 1536 String t = sp.resolveTypeIfNeeded(resolver); 1537 if (t != null) { 1538 if (specificTypes == null) { 1539 specificTypes = new String[numSpecifics]; 1540 } 1541 specificTypes[i] = t; 1542 } 1543 } 1544 } 1545 } 1546 1547 try { 1548 ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivityOptions( 1549 caller, 1550 specifics == null ? null : specifics.toArray(new Intent[0]), 1551 specificTypes, 1552 intent, 1553 intent.resolveTypeIfNeeded(resolver), 1554 updateFlagsForComponent(flags.getValue(), userId, intent), 1555 userId); 1556 if (parceledList == null) { 1557 return Collections.emptyList(); 1558 } 1559 return parceledList.getList(); 1560 } catch (RemoteException e) { 1561 throw e.rethrowFromSystemServer(); 1562 } 1563 } 1564 1565 /** 1566 * @hide 1567 */ 1568 @Override queryBroadcastReceiversAsUser(Intent intent, int flags, int userId)1569 public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) { 1570 return queryBroadcastReceiversAsUser(intent, ResolveInfoFlags.of(flags), userId); 1571 } 1572 1573 /** 1574 * @hide 1575 */ 1576 @Override 1577 @SuppressWarnings("unchecked") queryBroadcastReceiversAsUser(Intent intent, ResolveInfoFlags flags, int userId)1578 public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, ResolveInfoFlags flags, 1579 int userId) { 1580 try { 1581 ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentReceivers( 1582 intent, 1583 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 1584 updateFlagsForComponent(flags.getValue(), userId, intent), 1585 userId); 1586 if (parceledList == null) { 1587 return Collections.emptyList(); 1588 } 1589 return parceledList.getList(); 1590 } catch (RemoteException e) { 1591 throw e.rethrowFromSystemServer(); 1592 } 1593 } 1594 1595 @Override queryBroadcastReceivers(Intent intent, int flags)1596 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) { 1597 return queryBroadcastReceivers(intent, ResolveInfoFlags.of(flags)); 1598 } 1599 1600 @Override queryBroadcastReceivers(Intent intent, ResolveInfoFlags flags)1601 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, ResolveInfoFlags flags) { 1602 return queryBroadcastReceiversAsUser(intent, flags, getUserId()); 1603 } 1604 1605 @Override resolveServiceAsUser(Intent intent, int flags, @UserIdInt int userId)1606 public ResolveInfo resolveServiceAsUser(Intent intent, int flags, @UserIdInt int userId) { 1607 return resolveServiceAsUser(intent, ResolveInfoFlags.of(flags), userId); 1608 } 1609 1610 @Override resolveServiceAsUser(Intent intent, ResolveInfoFlags flags, @UserIdInt int userId)1611 public ResolveInfo resolveServiceAsUser(Intent intent, ResolveInfoFlags flags, 1612 @UserIdInt int userId) { 1613 try { 1614 return mPM.resolveService( 1615 intent, 1616 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 1617 updateFlagsForComponent(flags.getValue(), userId, intent), 1618 userId); 1619 } catch (RemoteException e) { 1620 throw e.rethrowFromSystemServer(); 1621 } 1622 } 1623 1624 @Override resolveService(Intent intent, int flags)1625 public ResolveInfo resolveService(Intent intent, int flags) { 1626 return resolveService(intent, ResolveInfoFlags.of(flags)); 1627 } 1628 1629 @Override resolveService(Intent intent, ResolveInfoFlags flags)1630 public ResolveInfo resolveService(Intent intent, ResolveInfoFlags flags) { 1631 return resolveServiceAsUser(intent, flags, getUserId()); 1632 } 1633 1634 @Override queryIntentServicesAsUser(Intent intent, int flags, int userId)1635 public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) { 1636 return queryIntentServicesAsUser(intent, ResolveInfoFlags.of(flags), userId); 1637 } 1638 1639 @Override 1640 @SuppressWarnings("unchecked") queryIntentServicesAsUser(Intent intent, ResolveInfoFlags flags, int userId)1641 public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, ResolveInfoFlags flags, 1642 int userId) { 1643 try { 1644 ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentServices( 1645 intent, 1646 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 1647 updateFlagsForComponent(flags.getValue(), userId, intent), 1648 userId); 1649 if (parceledList == null) { 1650 return Collections.emptyList(); 1651 } 1652 return parceledList.getList(); 1653 } catch (RemoteException e) { 1654 throw e.rethrowFromSystemServer(); 1655 } 1656 } 1657 1658 @Override queryIntentServices(Intent intent, int flags)1659 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) { 1660 return queryIntentServices(intent, ResolveInfoFlags.of(flags)); 1661 } 1662 1663 @Override queryIntentServices(Intent intent, ResolveInfoFlags flags)1664 public List<ResolveInfo> queryIntentServices(Intent intent, ResolveInfoFlags flags) { 1665 return queryIntentServicesAsUser(intent, flags, getUserId()); 1666 } 1667 1668 @Override queryIntentContentProvidersAsUser( Intent intent, int flags, int userId)1669 public List<ResolveInfo> queryIntentContentProvidersAsUser( 1670 Intent intent, int flags, int userId) { 1671 return queryIntentContentProvidersAsUser(intent, ResolveInfoFlags.of(flags), userId); 1672 } 1673 1674 @Override 1675 @SuppressWarnings("unchecked") queryIntentContentProvidersAsUser( Intent intent, ResolveInfoFlags flags, int userId)1676 public List<ResolveInfo> queryIntentContentProvidersAsUser( 1677 Intent intent, ResolveInfoFlags flags, int userId) { 1678 try { 1679 ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentContentProviders( 1680 intent, 1681 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 1682 updateFlagsForComponent(flags.getValue(), userId, intent), 1683 userId); 1684 if (parceledList == null) { 1685 return Collections.emptyList(); 1686 } 1687 return parceledList.getList(); 1688 } catch (RemoteException e) { 1689 throw e.rethrowFromSystemServer(); 1690 } 1691 } 1692 1693 @Override queryIntentContentProviders(Intent intent, int flags)1694 public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) { 1695 return queryIntentContentProviders(intent, ResolveInfoFlags.of(flags)); 1696 } 1697 1698 @Override queryIntentContentProviders(Intent intent, ResolveInfoFlags flags)1699 public List<ResolveInfo> queryIntentContentProviders(Intent intent, ResolveInfoFlags flags) { 1700 return queryIntentContentProvidersAsUser(intent, flags, getUserId()); 1701 } 1702 1703 @Override resolveContentProvider(String name, int flags)1704 public ProviderInfo resolveContentProvider(String name, int flags) { 1705 return resolveContentProvider(name, ComponentInfoFlags.of(flags)); 1706 } 1707 1708 @Override resolveContentProvider(String name, ComponentInfoFlags flags)1709 public ProviderInfo resolveContentProvider(String name, ComponentInfoFlags flags) { 1710 return resolveContentProviderAsUser(name, flags, getUserId()); 1711 } 1712 1713 /** @hide **/ 1714 @Override resolveContentProviderAsUser(String name, int flags, int userId)1715 public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) { 1716 return resolveContentProviderAsUser(name, ComponentInfoFlags.of(flags), userId); 1717 } 1718 1719 /** @hide **/ 1720 @Override resolveContentProviderAsUser(String name, ComponentInfoFlags flags, int userId)1721 public ProviderInfo resolveContentProviderAsUser(String name, ComponentInfoFlags flags, 1722 int userId) { 1723 try { 1724 return mPM.resolveContentProvider(name, 1725 updateFlagsForComponent(flags.getValue(), userId, null), userId); 1726 } catch (RemoteException e) { 1727 throw e.rethrowFromSystemServer(); 1728 } 1729 } 1730 1731 @Override queryContentProviders(String processName, int uid, int flags)1732 public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) { 1733 return queryContentProviders(processName, uid, ComponentInfoFlags.of(flags)); 1734 } 1735 1736 @Override queryContentProviders(String processName, int uid, ComponentInfoFlags flags)1737 public List<ProviderInfo> queryContentProviders(String processName, int uid, 1738 ComponentInfoFlags flags) { 1739 return queryContentProviders(processName, uid, flags, null); 1740 } 1741 1742 @Override queryContentProviders(String processName, int uid, int flags, String metaDataKey)1743 public List<ProviderInfo> queryContentProviders(String processName, 1744 int uid, int flags, String metaDataKey) { 1745 return queryContentProviders(processName, uid, ComponentInfoFlags.of(flags), metaDataKey); 1746 } 1747 1748 @Override 1749 @SuppressWarnings("unchecked") queryContentProviders(String processName, int uid, ComponentInfoFlags flags, String metaDataKey)1750 public List<ProviderInfo> queryContentProviders(String processName, 1751 int uid, ComponentInfoFlags flags, String metaDataKey) { 1752 try { 1753 ParceledListSlice<ProviderInfo> slice = mPM.queryContentProviders(processName, uid, 1754 updateFlagsForComponent(flags.getValue(), UserHandle.getUserId(uid), 1755 null), metaDataKey); 1756 return slice != null ? slice.getList() : Collections.emptyList(); 1757 } catch (RemoteException e) { 1758 throw e.rethrowFromSystemServer(); 1759 } 1760 } 1761 1762 @Override getInstrumentationInfo( ComponentName className, int flags)1763 public InstrumentationInfo getInstrumentationInfo( 1764 ComponentName className, int flags) 1765 throws NameNotFoundException { 1766 try { 1767 InstrumentationInfo ii = mPM.getInstrumentationInfoAsUser( 1768 className, flags, getUserId()); 1769 if (ii != null) { 1770 return ii; 1771 } 1772 } catch (RemoteException e) { 1773 throw e.rethrowFromSystemServer(); 1774 } 1775 1776 throw new NameNotFoundException(className.toString()); 1777 } 1778 1779 @Override 1780 @SuppressWarnings("unchecked") queryInstrumentation( String targetPackage, int flags)1781 public List<InstrumentationInfo> queryInstrumentation( 1782 String targetPackage, int flags) { 1783 try { 1784 ParceledListSlice<InstrumentationInfo> parceledList = 1785 mPM.queryInstrumentationAsUser(targetPackage, flags, getUserId()); 1786 if (parceledList == null) { 1787 return Collections.emptyList(); 1788 } 1789 return parceledList.getList(); 1790 } catch (RemoteException e) { 1791 throw e.rethrowFromSystemServer(); 1792 } 1793 } 1794 1795 @Nullable 1796 @Override getDrawable(String packageName, @DrawableRes int resId, @Nullable ApplicationInfo appInfo)1797 public Drawable getDrawable(String packageName, @DrawableRes int resId, 1798 @Nullable ApplicationInfo appInfo) { 1799 final ResourceName name = new ResourceName(packageName, resId); 1800 final Drawable cachedIcon = getCachedIcon(name); 1801 if (cachedIcon != null) { 1802 return cachedIcon; 1803 } 1804 1805 if (appInfo == null) { 1806 try { 1807 appInfo = getApplicationInfo(packageName, sDefaultFlags); 1808 } catch (NameNotFoundException e) { 1809 return null; 1810 } 1811 } 1812 1813 if (resId != 0) { 1814 try { 1815 final Resources r = getResourcesForApplication(appInfo); 1816 final Drawable dr = r.getDrawable(resId, null); 1817 if (dr != null) { 1818 putCachedIcon(name, dr); 1819 } 1820 1821 if (false) { 1822 RuntimeException e = new RuntimeException("here"); 1823 e.fillInStackTrace(); 1824 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resId) 1825 + " from package " + packageName 1826 + ": app scale=" + r.getCompatibilityInfo().applicationScale 1827 + ", caller scale=" + mContext.getResources() 1828 .getCompatibilityInfo().applicationScale, 1829 e); 1830 } 1831 if (DEBUG_ICONS) { 1832 Log.v(TAG, "Getting drawable 0x" 1833 + Integer.toHexString(resId) + " from " + r 1834 + ": " + dr); 1835 } 1836 return dr; 1837 } catch (NameNotFoundException e) { 1838 Log.w("PackageManager", "Failure retrieving resources for " 1839 + appInfo.packageName); 1840 } catch (Resources.NotFoundException e) { 1841 Log.w("PackageManager", "Failure retrieving resources for " 1842 + appInfo.packageName + ": " + e.getMessage()); 1843 } catch (Exception e) { 1844 // If an exception was thrown, fall through to return 1845 // default icon. 1846 Log.w("PackageManager", "Failure retrieving icon 0x" 1847 + Integer.toHexString(resId) + " in package " 1848 + packageName, e); 1849 } 1850 } 1851 1852 return null; 1853 } 1854 getActivityIcon(ComponentName activityName)1855 @Override public Drawable getActivityIcon(ComponentName activityName) 1856 throws NameNotFoundException { 1857 return getActivityInfo(activityName, sDefaultFlags).loadIcon(this); 1858 } 1859 getActivityIcon(Intent intent)1860 @Override public Drawable getActivityIcon(Intent intent) 1861 throws NameNotFoundException { 1862 if (intent.getComponent() != null) { 1863 return getActivityIcon(intent.getComponent()); 1864 } 1865 1866 ResolveInfo info = resolveActivity(intent, MATCH_DEFAULT_ONLY); 1867 if (info != null) { 1868 return info.activityInfo.loadIcon(this); 1869 } 1870 1871 throw new NameNotFoundException(intent.toUri(0)); 1872 } 1873 getDefaultActivityIcon()1874 @Override public Drawable getDefaultActivityIcon() { 1875 return mContext.getDrawable(com.android.internal.R.drawable.sym_def_app_icon); 1876 } 1877 getApplicationIcon(ApplicationInfo info)1878 @Override public Drawable getApplicationIcon(ApplicationInfo info) { 1879 return info.loadIcon(this); 1880 } 1881 getApplicationIcon(String packageName)1882 @Override public Drawable getApplicationIcon(String packageName) 1883 throws NameNotFoundException { 1884 return getApplicationIcon(getApplicationInfo(packageName, sDefaultFlags)); 1885 } 1886 1887 @Override getActivityBanner(ComponentName activityName)1888 public Drawable getActivityBanner(ComponentName activityName) 1889 throws NameNotFoundException { 1890 return getActivityInfo(activityName, sDefaultFlags).loadBanner(this); 1891 } 1892 1893 @Override getActivityBanner(Intent intent)1894 public Drawable getActivityBanner(Intent intent) 1895 throws NameNotFoundException { 1896 if (intent.getComponent() != null) { 1897 return getActivityBanner(intent.getComponent()); 1898 } 1899 1900 ResolveInfo info = resolveActivity( 1901 intent, MATCH_DEFAULT_ONLY); 1902 if (info != null) { 1903 return info.activityInfo.loadBanner(this); 1904 } 1905 1906 throw new NameNotFoundException(intent.toUri(0)); 1907 } 1908 1909 @Override getApplicationBanner(ApplicationInfo info)1910 public Drawable getApplicationBanner(ApplicationInfo info) { 1911 return info.loadBanner(this); 1912 } 1913 1914 @Override getApplicationBanner(String packageName)1915 public Drawable getApplicationBanner(String packageName) 1916 throws NameNotFoundException { 1917 return getApplicationBanner(getApplicationInfo(packageName, sDefaultFlags)); 1918 } 1919 1920 @Override getActivityLogo(ComponentName activityName)1921 public Drawable getActivityLogo(ComponentName activityName) 1922 throws NameNotFoundException { 1923 return getActivityInfo(activityName, sDefaultFlags).loadLogo(this); 1924 } 1925 1926 @Override getActivityLogo(Intent intent)1927 public Drawable getActivityLogo(Intent intent) 1928 throws NameNotFoundException { 1929 if (intent.getComponent() != null) { 1930 return getActivityLogo(intent.getComponent()); 1931 } 1932 1933 ResolveInfo info = resolveActivity(intent, MATCH_DEFAULT_ONLY); 1934 if (info != null) { 1935 return info.activityInfo.loadLogo(this); 1936 } 1937 1938 throw new NameNotFoundException(intent.toUri(0)); 1939 } 1940 1941 @Override getApplicationLogo(ApplicationInfo info)1942 public Drawable getApplicationLogo(ApplicationInfo info) { 1943 return info.loadLogo(this); 1944 } 1945 1946 @Override getApplicationLogo(String packageName)1947 public Drawable getApplicationLogo(String packageName) 1948 throws NameNotFoundException { 1949 return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags)); 1950 } 1951 1952 @Override getUserBadgedIcon(Drawable icon, UserHandle user)1953 public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) { 1954 if (!hasUserBadge(user.getIdentifier())) { 1955 return icon; 1956 } 1957 1958 final Drawable badgeForeground = getDevicePolicyManager().getResources().getDrawable( 1959 getUpdatableUserIconBadgeId(user), 1960 SOLID_COLORED, 1961 () -> getDefaultUserIconBadge(user)); 1962 1963 Drawable badge = new LauncherIcons(mContext).getBadgeDrawable( 1964 badgeForeground, 1965 getUserBadgeColor(user, false)); 1966 return getBadgedDrawable(icon, badge, null, true); 1967 } 1968 getUpdatableUserIconBadgeId(UserHandle user)1969 private String getUpdatableUserIconBadgeId(UserHandle user) { 1970 return getUserManager().isManagedProfile(user.getIdentifier()) 1971 ? WORK_PROFILE_ICON_BADGE : UNDEFINED; 1972 } 1973 getDefaultUserIconBadge(UserHandle user)1974 private Drawable getDefaultUserIconBadge(UserHandle user) { 1975 return mContext.getDrawable(getUserManager().getUserIconBadgeResId(user.getIdentifier())); 1976 } 1977 1978 @Override getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user, Rect badgeLocation, int badgeDensity)1979 public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user, 1980 Rect badgeLocation, int badgeDensity) { 1981 Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity); 1982 if (badgeDrawable == null) { 1983 return drawable; 1984 } 1985 return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true); 1986 } 1987 1988 /** 1989 * Returns the color of the user's actual badge (not the badge's shadow). 1990 * @param checkTheme whether to check the theme to determine the badge color. This should be 1991 * true if the background is determined by the theme. Otherwise, if 1992 * checkTheme is false, returns the color assuming a light background. 1993 */ getUserBadgeColor(UserHandle user, boolean checkTheme)1994 private int getUserBadgeColor(UserHandle user, boolean checkTheme) { 1995 if (checkTheme && mContext.getResources().getConfiguration().isNightModeActive()) { 1996 return getUserManager().getUserBadgeDarkColor(user.getIdentifier()); 1997 } 1998 return getUserManager().getUserBadgeColor(user.getIdentifier()); 1999 } 2000 2001 @Override getUserBadgeForDensity(UserHandle user, int density)2002 public Drawable getUserBadgeForDensity(UserHandle user, int density) { 2003 // This is part of the shadow, not the main color, and is not actually corp-specific. 2004 Drawable badgeColor = getProfileIconForDensity(user, 2005 com.android.internal.R.drawable.ic_corp_badge_color, density); 2006 if (badgeColor == null) { 2007 return null; 2008 } 2009 2010 final Drawable badgeForeground = getDevicePolicyManager().getResources() 2011 .getDrawableForDensity( 2012 getUpdatableUserBadgeId(user), 2013 SOLID_COLORED, 2014 density, 2015 () -> getDefaultUserBadgeForDensity(user, density)); 2016 2017 badgeForeground.setTint(getUserBadgeColor(user, false)); 2018 Drawable badge = new LayerDrawable(new Drawable[] {badgeColor, badgeForeground }); 2019 return badge; 2020 } 2021 getUpdatableUserBadgeId(UserHandle user)2022 private String getUpdatableUserBadgeId(UserHandle user) { 2023 return getUserManager().isManagedProfile(user.getIdentifier()) 2024 ? WORK_PROFILE_ICON : UNDEFINED; 2025 } 2026 getDefaultUserBadgeForDensity(UserHandle user, int density)2027 private Drawable getDefaultUserBadgeForDensity(UserHandle user, int density) { 2028 return getDrawableForDensity( 2029 getUserManager().getUserBadgeResId(user.getIdentifier()), density); 2030 } 2031 2032 /** 2033 * Returns the badge color based on whether device has dark theme enabled or not. 2034 */ 2035 @Override getUserBadgeForDensityNoBackground(UserHandle user, int density)2036 public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) { 2037 if (!hasUserBadge(user.getIdentifier())) { 2038 return null; 2039 } 2040 2041 final Drawable badge = getDevicePolicyManager().getResources().getDrawableForDensity( 2042 getUpdatableUserBadgeId(user), 2043 SOLID_NOT_COLORED, 2044 density, 2045 () -> getDefaultUserBadgeNoBackgroundForDensity(user, density)); 2046 2047 if (badge != null) { 2048 badge.setTint(getUserBadgeColor(user, true)); 2049 } 2050 return badge; 2051 } 2052 getDefaultUserBadgeNoBackgroundForDensity(UserHandle user, int density)2053 private Drawable getDefaultUserBadgeNoBackgroundForDensity(UserHandle user, int density) { 2054 return getDrawableForDensity( 2055 getUserManager().getUserBadgeNoBackgroundResId(user.getIdentifier()), density); 2056 } 2057 getDrawableForDensity(int drawableId, int density)2058 private Drawable getDrawableForDensity(int drawableId, int density) { 2059 if (density <= 0) { 2060 density = mContext.getResources().getDisplayMetrics().densityDpi; 2061 } 2062 return mContext.getResources().getDrawableForDensity(drawableId, density); 2063 } 2064 getProfileIconForDensity(UserHandle user, int drawableId, int density)2065 private Drawable getProfileIconForDensity(UserHandle user, int drawableId, int density) { 2066 if (hasUserBadge(user.getIdentifier())) { 2067 return getDrawableForDensity(drawableId, density); 2068 } 2069 return null; 2070 } 2071 2072 @Override getUserBadgedLabel(CharSequence label, UserHandle user)2073 public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) { 2074 return getUserManager().getBadgedLabelForUser(label, user); 2075 } 2076 2077 @Override getResourcesForActivity(ComponentName activityName)2078 public Resources getResourcesForActivity(ComponentName activityName) 2079 throws NameNotFoundException { 2080 return getResourcesForApplication( 2081 getActivityInfo(activityName, sDefaultFlags).applicationInfo); 2082 } 2083 2084 @Override getResourcesForApplication(@onNull ApplicationInfo app)2085 public Resources getResourcesForApplication(@NonNull ApplicationInfo app) 2086 throws NameNotFoundException { 2087 return getResourcesForApplication(app, null); 2088 } 2089 2090 @Override getResourcesForApplication(@onNull ApplicationInfo app, @Nullable Configuration configuration)2091 public Resources getResourcesForApplication(@NonNull ApplicationInfo app, 2092 @Nullable Configuration configuration) throws NameNotFoundException { 2093 if (app.packageName.equals("system")) { 2094 Context sysuiContext = mContext.mMainThread.getSystemUiContext(); 2095 if (configuration != null) { 2096 sysuiContext = sysuiContext.createConfigurationContext(configuration); 2097 } 2098 return sysuiContext.getResources(); 2099 } 2100 final boolean sameUid = (app.uid == Process.myUid()); 2101 final Resources r = mContext.mMainThread.getTopLevelResources( 2102 sameUid ? app.sourceDir : app.publicSourceDir, 2103 sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs, 2104 app.resourceDirs, app.overlayPaths, app.sharedLibraryFiles, 2105 mContext.mPackageInfo, configuration); 2106 if (r != null) { 2107 return r; 2108 } 2109 throw new NameNotFoundException("Unable to open " + app.publicSourceDir); 2110 } 2111 2112 @Override getResourcesForApplication(String appPackageName)2113 public Resources getResourcesForApplication(String appPackageName) 2114 throws NameNotFoundException { 2115 return getResourcesForApplication( 2116 getApplicationInfo(appPackageName, sDefaultFlags)); 2117 } 2118 2119 /** @hide */ 2120 @Override getResourcesForApplicationAsUser(String appPackageName, int userId)2121 public Resources getResourcesForApplicationAsUser(String appPackageName, int userId) 2122 throws NameNotFoundException { 2123 if (userId < 0) { 2124 throw new IllegalArgumentException( 2125 "Call does not support special user #" + userId); 2126 } 2127 if ("system".equals(appPackageName)) { 2128 return mContext.mMainThread.getSystemUiContext().getResources(); 2129 } 2130 try { 2131 ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId); 2132 if (ai != null) { 2133 return getResourcesForApplication(ai); 2134 } 2135 } catch (RemoteException e) { 2136 throw e.rethrowFromSystemServer(); 2137 } 2138 throw new NameNotFoundException("Package " + appPackageName + " doesn't exist"); 2139 } 2140 2141 volatile int mCachedSafeMode = -1; 2142 2143 @Override isSafeMode()2144 public boolean isSafeMode() { 2145 try { 2146 if (mCachedSafeMode < 0) { 2147 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0; 2148 } 2149 return mCachedSafeMode != 0; 2150 } catch (RemoteException e) { 2151 throw e.rethrowFromSystemServer(); 2152 } 2153 } 2154 2155 @Override addOnPermissionsChangeListener(OnPermissionsChangedListener listener)2156 public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) { 2157 getPermissionManager().addOnPermissionsChangeListener(listener); 2158 } 2159 2160 @Override removeOnPermissionsChangeListener(OnPermissionsChangedListener listener)2161 public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) { 2162 getPermissionManager().removeOnPermissionsChangeListener(listener); 2163 } 2164 2165 @UnsupportedAppUsage configurationChanged()2166 static void configurationChanged() { 2167 synchronized (sSync) { 2168 sIconCache.clear(); 2169 sStringCache.clear(); 2170 } 2171 } 2172 2173 @UnsupportedAppUsage ApplicationPackageManager(ContextImpl context, IPackageManager pm)2174 protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) { 2175 mContext = context; 2176 mPM = pm; 2177 } 2178 2179 /** 2180 * Update given flags when being used to request {@link PackageInfo}. 2181 */ updateFlagsForPackage(long flags, int userId)2182 private long updateFlagsForPackage(long flags, int userId) { 2183 if ((flags & (GET_ACTIVITIES | GET_RECEIVERS | GET_SERVICES | GET_PROVIDERS)) != 0) { 2184 // Caller is asking for component details, so they'd better be 2185 // asking for specific Direct Boot matching behavior 2186 if ((flags & (MATCH_DIRECT_BOOT_UNAWARE 2187 | MATCH_DIRECT_BOOT_AWARE 2188 | MATCH_DIRECT_BOOT_AUTO)) == 0) { 2189 onImplicitDirectBoot(userId); 2190 } 2191 } 2192 return flags; 2193 } 2194 2195 /** 2196 * Update given flags when being used to request {@link ApplicationInfo}. 2197 */ updateFlagsForApplication(long flags, int userId)2198 private long updateFlagsForApplication(long flags, int userId) { 2199 return updateFlagsForPackage(flags, userId); 2200 } 2201 2202 /** 2203 * Update given flags when being used to request {@link ComponentInfo}. 2204 */ updateFlagsForComponent(@omponentInfoFlagsBits long flags, int userId, Intent intent)2205 private long updateFlagsForComponent(@ComponentInfoFlagsBits long flags, int userId, 2206 Intent intent) { 2207 if (intent != null) { 2208 if ((intent.getFlags() & Intent.FLAG_DIRECT_BOOT_AUTO) != 0) { 2209 flags |= MATCH_DIRECT_BOOT_AUTO; 2210 } 2211 } 2212 2213 // Caller is asking for component details, so they'd better be 2214 // asking for specific Direct Boot matching behavior 2215 if ((flags & (MATCH_DIRECT_BOOT_UNAWARE 2216 | MATCH_DIRECT_BOOT_AWARE 2217 | MATCH_DIRECT_BOOT_AUTO)) == 0) { 2218 onImplicitDirectBoot(userId); 2219 } 2220 return flags; 2221 } 2222 onImplicitDirectBoot(int userId)2223 private void onImplicitDirectBoot(int userId) { 2224 // Only report if someone is relying on implicit behavior while the user 2225 // is locked; code running when unlocked is going to see both aware and 2226 // unaware components. 2227 if (StrictMode.vmImplicitDirectBootEnabled()) { 2228 // We can cache the unlocked state for the userId we're running as, 2229 // since any relocking of that user will always result in our 2230 // process being killed to release any CE FDs we're holding onto. 2231 if (userId == UserHandle.myUserId()) { 2232 if (mUserUnlocked) { 2233 return; 2234 } else if (mContext.getSystemService(UserManager.class) 2235 .isUserUnlockingOrUnlocked(userId)) { 2236 mUserUnlocked = true; 2237 } else { 2238 StrictMode.onImplicitDirectBoot(); 2239 } 2240 } else if (!mContext.getSystemService(UserManager.class) 2241 .isUserUnlockingOrUnlocked(userId)) { 2242 StrictMode.onImplicitDirectBoot(); 2243 } 2244 } 2245 } 2246 2247 @Nullable getCachedIcon(@onNull ResourceName name)2248 private Drawable getCachedIcon(@NonNull ResourceName name) { 2249 synchronized (sSync) { 2250 final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name); 2251 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for " 2252 + name + ": " + wr); 2253 if (wr != null) { // we have the activity 2254 final Drawable.ConstantState state = wr.get(); 2255 if (state != null) { 2256 if (DEBUG_ICONS) { 2257 Log.v(TAG, "Get cached drawable state for " + name + ": " + state); 2258 } 2259 // Note: It's okay here to not use the newDrawable(Resources) variant 2260 // of the API. The ConstantState comes from a drawable that was 2261 // originally created by passing the proper app Resources instance 2262 // which means the state should already contain the proper 2263 // resources specific information (like density.) See 2264 // BitmapDrawable.BitmapState for instance. 2265 return state.newDrawable(); 2266 } 2267 // our entry has been purged 2268 sIconCache.remove(name); 2269 } 2270 } 2271 return null; 2272 } 2273 putCachedIcon(@onNull ResourceName name, @NonNull Drawable dr)2274 private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) { 2275 synchronized (sSync) { 2276 sIconCache.put(name, new WeakReference<>(dr.getConstantState())); 2277 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr); 2278 } 2279 } 2280 handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo)2281 static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) { 2282 boolean immediateGc = false; 2283 if (cmd == ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE) { 2284 immediateGc = true; 2285 } 2286 if (pkgList != null && (pkgList.length > 0)) { 2287 boolean needCleanup = false; 2288 for (String ssp : pkgList) { 2289 synchronized (sSync) { 2290 for (int i=sIconCache.size()-1; i>=0; i--) { 2291 ResourceName nm = sIconCache.keyAt(i); 2292 if (nm.packageName.equals(ssp)) { 2293 //Log.i(TAG, "Removing cached drawable for " + nm); 2294 sIconCache.removeAt(i); 2295 needCleanup = true; 2296 } 2297 } 2298 for (int i=sStringCache.size()-1; i>=0; i--) { 2299 ResourceName nm = sStringCache.keyAt(i); 2300 if (nm.packageName.equals(ssp)) { 2301 //Log.i(TAG, "Removing cached string for " + nm); 2302 sStringCache.removeAt(i); 2303 needCleanup = true; 2304 } 2305 } 2306 } 2307 } 2308 if (needCleanup || hasPkgInfo) { 2309 if (immediateGc) { 2310 // Schedule an immediate gc. 2311 Runtime.getRuntime().gc(); 2312 } else { 2313 ActivityThread.currentActivityThread().scheduleGcIdler(); 2314 } 2315 } 2316 } 2317 } 2318 2319 private static final class ResourceName { 2320 final String packageName; 2321 final int iconId; 2322 ResourceName(String _packageName, int _iconId)2323 ResourceName(String _packageName, int _iconId) { 2324 packageName = _packageName; 2325 iconId = _iconId; 2326 } 2327 ResourceName(ApplicationInfo aInfo, int _iconId)2328 ResourceName(ApplicationInfo aInfo, int _iconId) { 2329 this(aInfo.packageName, _iconId); 2330 } 2331 ResourceName(ComponentInfo cInfo, int _iconId)2332 ResourceName(ComponentInfo cInfo, int _iconId) { 2333 this(cInfo.applicationInfo.packageName, _iconId); 2334 } 2335 ResourceName(ResolveInfo rInfo, int _iconId)2336 ResourceName(ResolveInfo rInfo, int _iconId) { 2337 this(rInfo.activityInfo.applicationInfo.packageName, _iconId); 2338 } 2339 2340 @Override equals(@ullable Object o)2341 public boolean equals(@Nullable Object o) { 2342 if (this == o) return true; 2343 if (o == null || getClass() != o.getClass()) return false; 2344 2345 ResourceName that = (ResourceName) o; 2346 2347 if (iconId != that.iconId) return false; 2348 return !(packageName != null ? 2349 !packageName.equals(that.packageName) : that.packageName != null); 2350 2351 } 2352 2353 @Override hashCode()2354 public int hashCode() { 2355 int result; 2356 result = packageName.hashCode(); 2357 result = 31 * result + iconId; 2358 return result; 2359 } 2360 2361 @Override toString()2362 public String toString() { 2363 return "{ResourceName " + packageName + " / " + iconId + "}"; 2364 } 2365 } 2366 getCachedString(ResourceName name)2367 private CharSequence getCachedString(ResourceName name) { 2368 synchronized (sSync) { 2369 WeakReference<CharSequence> wr = sStringCache.get(name); 2370 if (wr != null) { // we have the activity 2371 CharSequence cs = wr.get(); 2372 if (cs != null) { 2373 return cs; 2374 } 2375 // our entry has been purged 2376 sStringCache.remove(name); 2377 } 2378 } 2379 return null; 2380 } 2381 putCachedString(ResourceName name, CharSequence cs)2382 private void putCachedString(ResourceName name, CharSequence cs) { 2383 synchronized (sSync) { 2384 sStringCache.put(name, new WeakReference<CharSequence>(cs)); 2385 } 2386 } 2387 2388 @Override getText(String packageName, @StringRes int resid, ApplicationInfo appInfo)2389 public CharSequence getText(String packageName, @StringRes int resid, 2390 ApplicationInfo appInfo) { 2391 ResourceName name = new ResourceName(packageName, resid); 2392 CharSequence text = getCachedString(name); 2393 if (text != null) { 2394 return text; 2395 } 2396 if (appInfo == null) { 2397 try { 2398 appInfo = getApplicationInfo(packageName, sDefaultFlags); 2399 } catch (NameNotFoundException e) { 2400 return null; 2401 } 2402 } 2403 try { 2404 Resources r = getResourcesForApplication(appInfo); 2405 text = r.getText(resid); 2406 putCachedString(name, text); 2407 return text; 2408 } catch (NameNotFoundException e) { 2409 Log.w("PackageManager", "Failure retrieving resources for " 2410 + appInfo.packageName); 2411 } catch (RuntimeException e) { 2412 // If an exception was thrown, fall through to return 2413 // default icon. 2414 Log.w("PackageManager", "Failure retrieving text 0x" 2415 + Integer.toHexString(resid) + " in package " 2416 + packageName, e); 2417 } 2418 return null; 2419 } 2420 2421 @Override getXml(String packageName, @XmlRes int resid, ApplicationInfo appInfo)2422 public XmlResourceParser getXml(String packageName, @XmlRes int resid, 2423 ApplicationInfo appInfo) { 2424 if (appInfo == null) { 2425 try { 2426 appInfo = getApplicationInfo(packageName, sDefaultFlags); 2427 } catch (NameNotFoundException e) { 2428 return null; 2429 } 2430 } 2431 try { 2432 Resources r = getResourcesForApplication(appInfo); 2433 return r.getXml(resid); 2434 } catch (RuntimeException e) { 2435 // If an exception was thrown, fall through to return 2436 // default icon. 2437 Log.w("PackageManager", "Failure retrieving xml 0x" 2438 + Integer.toHexString(resid) + " in package " 2439 + packageName, e); 2440 } catch (NameNotFoundException e) { 2441 Log.w("PackageManager", "Failure retrieving resources for " 2442 + appInfo.packageName); 2443 } 2444 return null; 2445 } 2446 2447 @Override getApplicationLabel(ApplicationInfo info)2448 public CharSequence getApplicationLabel(ApplicationInfo info) { 2449 return info.loadLabel(this); 2450 } 2451 2452 @Override installExistingPackage(String packageName)2453 public int installExistingPackage(String packageName) throws NameNotFoundException { 2454 return installExistingPackage(packageName, INSTALL_REASON_UNKNOWN); 2455 } 2456 2457 @Override installExistingPackage(String packageName, int installReason)2458 public int installExistingPackage(String packageName, int installReason) 2459 throws NameNotFoundException { 2460 return installExistingPackageAsUser(packageName, installReason, getUserId()); 2461 } 2462 2463 @Override installExistingPackageAsUser(String packageName, int userId)2464 public int installExistingPackageAsUser(String packageName, int userId) 2465 throws NameNotFoundException { 2466 return installExistingPackageAsUser(packageName, INSTALL_REASON_UNKNOWN, 2467 userId); 2468 } 2469 installExistingPackageAsUser(String packageName, int installReason, int userId)2470 private int installExistingPackageAsUser(String packageName, int installReason, int userId) 2471 throws NameNotFoundException { 2472 try { 2473 int res = mPM.installExistingPackageAsUser(packageName, userId, 2474 INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS, installReason, null); 2475 if (res == INSTALL_FAILED_INVALID_URI) { 2476 throw new NameNotFoundException("Package " + packageName + " doesn't exist"); 2477 } 2478 return res; 2479 } catch (RemoteException e) { 2480 throw e.rethrowFromSystemServer(); 2481 } 2482 } 2483 2484 @Override verifyPendingInstall(int id, int response)2485 public void verifyPendingInstall(int id, int response) { 2486 try { 2487 mPM.verifyPendingInstall(id, response); 2488 } catch (RemoteException e) { 2489 throw e.rethrowFromSystemServer(); 2490 } 2491 } 2492 2493 @Override extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)2494 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 2495 long millisecondsToDelay) { 2496 try { 2497 mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay); 2498 } catch (RemoteException e) { 2499 throw e.rethrowFromSystemServer(); 2500 } 2501 } 2502 2503 @Override verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)2504 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) { 2505 try { 2506 mPM.verifyIntentFilter(id, verificationCode, failedDomains); 2507 } catch (RemoteException e) { 2508 throw e.rethrowFromSystemServer(); 2509 } 2510 } 2511 2512 @Override getIntentVerificationStatusAsUser(String packageName, int userId)2513 public int getIntentVerificationStatusAsUser(String packageName, int userId) { 2514 try { 2515 return mPM.getIntentVerificationStatus(packageName, userId); 2516 } catch (RemoteException e) { 2517 throw e.rethrowFromSystemServer(); 2518 } 2519 } 2520 2521 @Override updateIntentVerificationStatusAsUser(String packageName, int status, int userId)2522 public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) { 2523 try { 2524 return mPM.updateIntentVerificationStatus(packageName, status, userId); 2525 } catch (RemoteException e) { 2526 throw e.rethrowFromSystemServer(); 2527 } 2528 } 2529 2530 @Override 2531 @SuppressWarnings("unchecked") getIntentFilterVerifications(String packageName)2532 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 2533 try { 2534 ParceledListSlice<IntentFilterVerificationInfo> parceledList = 2535 mPM.getIntentFilterVerifications(packageName); 2536 if (parceledList == null) { 2537 return Collections.emptyList(); 2538 } 2539 return parceledList.getList(); 2540 } catch (RemoteException e) { 2541 throw e.rethrowFromSystemServer(); 2542 } 2543 } 2544 2545 @Override 2546 @SuppressWarnings("unchecked") getAllIntentFilters(String packageName)2547 public List<IntentFilter> getAllIntentFilters(String packageName) { 2548 try { 2549 ParceledListSlice<IntentFilter> parceledList = 2550 mPM.getAllIntentFilters(packageName); 2551 if (parceledList == null) { 2552 return Collections.emptyList(); 2553 } 2554 return parceledList.getList(); 2555 } catch (RemoteException e) { 2556 throw e.rethrowFromSystemServer(); 2557 } 2558 } 2559 2560 @Override getDefaultBrowserPackageNameAsUser(int userId)2561 public String getDefaultBrowserPackageNameAsUser(int userId) { 2562 RoleManager roleManager = mContext.getSystemService(RoleManager.class); 2563 return roleManager.getBrowserRoleHolder(userId); 2564 } 2565 2566 @Override setDefaultBrowserPackageNameAsUser(String packageName, int userId)2567 public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) { 2568 RoleManager roleManager = mContext.getSystemService(RoleManager.class); 2569 return roleManager.setBrowserRoleHolder(packageName, userId); 2570 } 2571 2572 @Override setInstallerPackageName(String targetPackage, String installerPackageName)2573 public void setInstallerPackageName(String targetPackage, 2574 String installerPackageName) { 2575 try { 2576 mPM.setInstallerPackageName(targetPackage, installerPackageName); 2577 } catch (RemoteException e) { 2578 throw e.rethrowFromSystemServer(); 2579 } 2580 } 2581 2582 @Override setUpdateAvailable(String packageName, boolean updateAvailable)2583 public void setUpdateAvailable(String packageName, boolean updateAvailable) { 2584 try { 2585 mPM.setUpdateAvailable(packageName, updateAvailable); 2586 } catch (RemoteException e) { 2587 throw e.rethrowFromSystemServer(); 2588 } 2589 } 2590 2591 @Override getInstallerPackageName(String packageName)2592 public String getInstallerPackageName(String packageName) { 2593 try { 2594 return mPM.getInstallerPackageName(packageName); 2595 } catch (RemoteException e) { 2596 throw e.rethrowFromSystemServer(); 2597 } 2598 } 2599 2600 @Override 2601 @NonNull getInstallSourceInfo(String packageName)2602 public InstallSourceInfo getInstallSourceInfo(String packageName) throws NameNotFoundException { 2603 final InstallSourceInfo installSourceInfo; 2604 try { 2605 installSourceInfo = mPM.getInstallSourceInfo(packageName, getUserId()); 2606 } catch (RemoteException e) { 2607 throw e.rethrowFromSystemServer(); 2608 } 2609 if (installSourceInfo == null) { 2610 throw new NameNotFoundException(packageName); 2611 } 2612 return installSourceInfo; 2613 } 2614 2615 @Override isAppArchivable(String packageName)2616 public boolean isAppArchivable(String packageName) throws NameNotFoundException { 2617 try { 2618 Objects.requireNonNull(packageName); 2619 return mPM.isAppArchivable(packageName, new UserHandle(getUserId())); 2620 } catch (ParcelableException e) { 2621 e.maybeRethrow(NameNotFoundException.class); 2622 throw new RuntimeException(e); 2623 } catch (RemoteException e) { 2624 throw e.rethrowFromSystemServer(); 2625 } 2626 } 2627 2628 @Override getMoveStatus(int moveId)2629 public int getMoveStatus(int moveId) { 2630 try { 2631 return mPM.getMoveStatus(moveId); 2632 } catch (RemoteException e) { 2633 throw e.rethrowFromSystemServer(); 2634 } 2635 } 2636 2637 @Override registerMoveCallback(MoveCallback callback, Handler handler)2638 public void registerMoveCallback(MoveCallback callback, Handler handler) { 2639 synchronized (mDelegates) { 2640 final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback, 2641 handler.getLooper()); 2642 try { 2643 mPM.registerMoveCallback(delegate); 2644 } catch (RemoteException e) { 2645 throw e.rethrowFromSystemServer(); 2646 } 2647 mDelegates.add(delegate); 2648 } 2649 } 2650 2651 @Override unregisterMoveCallback(MoveCallback callback)2652 public void unregisterMoveCallback(MoveCallback callback) { 2653 synchronized (mDelegates) { 2654 for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) { 2655 final MoveCallbackDelegate delegate = i.next(); 2656 if (delegate.mCallback == callback) { 2657 try { 2658 mPM.unregisterMoveCallback(delegate); 2659 } catch (RemoteException e) { 2660 throw e.rethrowFromSystemServer(); 2661 } 2662 i.remove(); 2663 } 2664 } 2665 } 2666 } 2667 2668 @Override movePackage(String packageName, VolumeInfo vol)2669 public int movePackage(String packageName, VolumeInfo vol) { 2670 try { 2671 final String volumeUuid; 2672 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) { 2673 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL; 2674 } else if (vol.isPrimaryPhysical()) { 2675 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 2676 } else { 2677 volumeUuid = Objects.requireNonNull(vol.fsUuid); 2678 } 2679 2680 return mPM.movePackage(packageName, volumeUuid); 2681 } catch (RemoteException e) { 2682 throw e.rethrowFromSystemServer(); 2683 } 2684 } 2685 2686 @Override 2687 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getPackageCurrentVolume(ApplicationInfo app)2688 public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) { 2689 final StorageManager storage = mContext.getSystemService(StorageManager.class); 2690 return getPackageCurrentVolume(app, storage); 2691 } 2692 2693 @VisibleForTesting getPackageCurrentVolume(ApplicationInfo app, StorageManager storage)2694 protected @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app, 2695 StorageManager storage) { 2696 if (app.isInternal()) { 2697 return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL); 2698 } else { 2699 return storage.findVolumeByUuid(app.volumeUuid); 2700 } 2701 } 2702 2703 @Override getPackageCandidateVolumes(ApplicationInfo app)2704 public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) { 2705 final StorageManager storageManager = mContext.getSystemService(StorageManager.class); 2706 return getPackageCandidateVolumes(app, storageManager, mPM); 2707 } 2708 2709 @VisibleForTesting getPackageCandidateVolumes(ApplicationInfo app, StorageManager storageManager, IPackageManager pm)2710 protected @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app, 2711 StorageManager storageManager, IPackageManager pm) { 2712 final VolumeInfo currentVol = getPackageCurrentVolume(app, storageManager); 2713 final List<VolumeInfo> vols = storageManager.getVolumes(); 2714 final List<VolumeInfo> candidates = new ArrayList<>(); 2715 for (VolumeInfo vol : vols) { 2716 if (Objects.equals(vol, currentVol) 2717 || isPackageCandidateVolume(mContext, app, vol, pm)) { 2718 candidates.add(vol); 2719 } 2720 } 2721 return candidates; 2722 } 2723 2724 @VisibleForTesting isForceAllowOnExternal(Context context)2725 protected boolean isForceAllowOnExternal(Context context) { 2726 return Settings.Global.getInt( 2727 context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0; 2728 } 2729 2730 @VisibleForTesting isAllow3rdPartyOnInternal(Context context)2731 protected boolean isAllow3rdPartyOnInternal(Context context) { 2732 return context.getResources().getBoolean( 2733 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal); 2734 } 2735 isPackageCandidateVolume( ContextImpl context, ApplicationInfo app, VolumeInfo vol, IPackageManager pm)2736 private boolean isPackageCandidateVolume( 2737 ContextImpl context, ApplicationInfo app, VolumeInfo vol, IPackageManager pm) { 2738 final boolean forceAllowOnExternal = isForceAllowOnExternal(context); 2739 2740 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) { 2741 return app.isSystemApp() || isAllow3rdPartyOnInternal(context); 2742 } 2743 2744 // System apps and apps demanding internal storage can't be moved 2745 // anywhere else 2746 if (app.isSystemApp()) { 2747 return false; 2748 } 2749 if (!forceAllowOnExternal 2750 && (app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY 2751 || app.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED)) { 2752 return false; 2753 } 2754 2755 // Gotta be able to write there 2756 if (!vol.isMountedWritable()) { 2757 return false; 2758 } 2759 2760 // Moving into an ASEC on public primary is only option internal 2761 if (vol.isPrimaryPhysical()) { 2762 return app.isInternal(); 2763 } 2764 2765 // Some apps can't be moved. (e.g. device admins) 2766 try { 2767 if (pm.isPackageDeviceAdminOnAnyUser(app.packageName)) { 2768 return false; 2769 } 2770 } catch (RemoteException e) { 2771 throw e.rethrowFromSystemServer(); 2772 } 2773 2774 // Otherwise we can move to any private volume 2775 return (vol.getType() == VolumeInfo.TYPE_PRIVATE); 2776 } 2777 2778 @Override movePrimaryStorage(VolumeInfo vol)2779 public int movePrimaryStorage(VolumeInfo vol) { 2780 try { 2781 final String volumeUuid; 2782 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) { 2783 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL; 2784 } else if (vol.isPrimaryPhysical()) { 2785 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 2786 } else { 2787 volumeUuid = Objects.requireNonNull(vol.fsUuid); 2788 } 2789 2790 return mPM.movePrimaryStorage(volumeUuid); 2791 } catch (RemoteException e) { 2792 throw e.rethrowFromSystemServer(); 2793 } 2794 } 2795 2796 @Override getPrimaryStorageCurrentVolume()2797 public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() { 2798 final StorageManager storage = mContext.getSystemService(StorageManager.class); 2799 final String volumeUuid = storage.getPrimaryStorageUuid(); 2800 return storage.findVolumeByQualifiedUuid(volumeUuid); 2801 } 2802 2803 @Override getPrimaryStorageCandidateVolumes()2804 public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() { 2805 final StorageManager storage = mContext.getSystemService(StorageManager.class); 2806 final VolumeInfo currentVol = getPrimaryStorageCurrentVolume(); 2807 final List<VolumeInfo> vols = storage.getVolumes(); 2808 final List<VolumeInfo> candidates = new ArrayList<>(); 2809 if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, 2810 storage.getPrimaryStorageUuid()) && currentVol != null) { 2811 // TODO: support moving primary physical to emulated volume 2812 candidates.add(currentVol); 2813 } else { 2814 for (VolumeInfo vol : vols) { 2815 if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) { 2816 candidates.add(vol); 2817 } 2818 } 2819 } 2820 return candidates; 2821 } 2822 isPrimaryStorageCandidateVolume(VolumeInfo vol)2823 private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) { 2824 // Private internal is always an option 2825 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) { 2826 return true; 2827 } 2828 2829 // Gotta be able to write there 2830 if (!vol.isMountedWritable()) { 2831 return false; 2832 } 2833 2834 // We can move to any private volume 2835 return (vol.getType() == VolumeInfo.TYPE_PRIVATE); 2836 } 2837 2838 @Override 2839 @UnsupportedAppUsage deletePackage(String packageName, IPackageDeleteObserver observer, int flags)2840 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) { 2841 deletePackageAsUser(packageName, observer, flags, getUserId()); 2842 } 2843 2844 @Override deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags, int userId)2845 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, 2846 int flags, int userId) { 2847 try { 2848 mPM.deletePackageAsUser(packageName, VERSION_CODE_HIGHEST, 2849 observer, userId, flags); 2850 } catch (RemoteException e) { 2851 throw e.rethrowFromSystemServer(); 2852 } 2853 } 2854 2855 @Override clearApplicationUserData(String packageName, IPackageDataObserver observer)2856 public void clearApplicationUserData(String packageName, 2857 IPackageDataObserver observer) { 2858 try { 2859 mPM.clearApplicationUserData(packageName, observer, getUserId()); 2860 } catch (RemoteException e) { 2861 throw e.rethrowFromSystemServer(); 2862 } 2863 } 2864 @Override deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer)2865 public void deleteApplicationCacheFiles(String packageName, 2866 IPackageDataObserver observer) { 2867 try { 2868 mPM.deleteApplicationCacheFiles(packageName, observer); 2869 } catch (RemoteException e) { 2870 throw e.rethrowFromSystemServer(); 2871 } 2872 } 2873 2874 @Override deleteApplicationCacheFilesAsUser(String packageName, int userId, IPackageDataObserver observer)2875 public void deleteApplicationCacheFilesAsUser(String packageName, int userId, 2876 IPackageDataObserver observer) { 2877 try { 2878 mPM.deleteApplicationCacheFilesAsUser(packageName, userId, observer); 2879 } catch (RemoteException e) { 2880 throw e.rethrowFromSystemServer(); 2881 } 2882 } 2883 2884 @Override freeStorageAndNotify(String volumeUuid, long idealStorageSize, IPackageDataObserver observer)2885 public void freeStorageAndNotify(String volumeUuid, long idealStorageSize, 2886 IPackageDataObserver observer) { 2887 try { 2888 mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, 0, observer); 2889 } catch (RemoteException e) { 2890 throw e.rethrowFromSystemServer(); 2891 } 2892 } 2893 2894 @Override freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi)2895 public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) { 2896 try { 2897 mPM.freeStorage(volumeUuid, freeStorageSize, 0, pi); 2898 } catch (RemoteException e) { 2899 throw e.rethrowFromSystemServer(); 2900 } 2901 } 2902 2903 @Override setDistractingPackageRestrictions(String[] packages, int distractionFlags)2904 public String[] setDistractingPackageRestrictions(String[] packages, int distractionFlags) { 2905 try { 2906 return mPM.setDistractingPackageRestrictionsAsUser(packages, distractionFlags, 2907 mContext.getUserId()); 2908 } catch (RemoteException e) { 2909 throw e.rethrowFromSystemServer(); 2910 } 2911 } 2912 2913 @Override setPackagesSuspended(String[] packageNames, boolean suspended, PersistableBundle appExtras, PersistableBundle launcherExtras, String dialogMessage)2914 public String[] setPackagesSuspended(String[] packageNames, boolean suspended, 2915 PersistableBundle appExtras, PersistableBundle launcherExtras, 2916 String dialogMessage) { 2917 final SuspendDialogInfo dialogInfo = !TextUtils.isEmpty(dialogMessage) 2918 ? new SuspendDialogInfo.Builder().setMessage(dialogMessage).build() 2919 : null; 2920 return setPackagesSuspended(packageNames, suspended, appExtras, launcherExtras, 2921 dialogInfo, 0); 2922 } 2923 2924 @Override setPackagesSuspended(String[] packageNames, boolean suspended, PersistableBundle appExtras, PersistableBundle launcherExtras, SuspendDialogInfo dialogInfo)2925 public String[] setPackagesSuspended(String[] packageNames, boolean suspended, 2926 PersistableBundle appExtras, PersistableBundle launcherExtras, 2927 SuspendDialogInfo dialogInfo) { 2928 return setPackagesSuspended(packageNames, suspended, appExtras, launcherExtras, 2929 dialogInfo, 0); 2930 } 2931 2932 @Override setPackagesSuspended(String[] packageNames, boolean suspended, PersistableBundle appExtras, PersistableBundle launcherExtras, SuspendDialogInfo dialogInfo, int flags)2933 public String[] setPackagesSuspended(String[] packageNames, boolean suspended, 2934 PersistableBundle appExtras, PersistableBundle launcherExtras, 2935 SuspendDialogInfo dialogInfo, int flags) { 2936 try { 2937 return mPM.setPackagesSuspendedAsUser(packageNames, suspended, appExtras, 2938 launcherExtras, dialogInfo, flags, mContext.getOpPackageName(), 2939 UserHandle.myUserId() /* suspendingUserId */, getUserId() /* targetUserId */); 2940 } catch (RemoteException e) { 2941 throw e.rethrowFromSystemServer(); 2942 } 2943 } 2944 2945 @Override getUnsuspendablePackages(String[] packageNames)2946 public String[] getUnsuspendablePackages(String[] packageNames) { 2947 try { 2948 return mPM.getUnsuspendablePackagesForUser(packageNames, mContext.getUserId()); 2949 } catch (RemoteException e) { 2950 throw e.rethrowFromSystemServer(); 2951 } 2952 } 2953 2954 @Override getSuspendedPackageAppExtras()2955 public Bundle getSuspendedPackageAppExtras() { 2956 try { 2957 return mPM.getSuspendedPackageAppExtras(mContext.getOpPackageName(), getUserId()); 2958 } catch (RemoteException e) { 2959 throw e.rethrowFromSystemServer(); 2960 } 2961 } 2962 2963 @Override getSuspendingPackage(String suspendedPackage)2964 public String getSuspendingPackage(String suspendedPackage) { 2965 try { 2966 return mPM.getSuspendingPackage(suspendedPackage, getUserId()); 2967 } catch (RemoteException e) { 2968 throw e.rethrowFromSystemServer(); 2969 } 2970 } 2971 2972 @Override isPackageSuspendedForUser(String packageName, int userId)2973 public boolean isPackageSuspendedForUser(String packageName, int userId) { 2974 try { 2975 return mPM.isPackageSuspendedForUser(packageName, userId); 2976 } catch (RemoteException e) { 2977 throw e.rethrowFromSystemServer(); 2978 } 2979 } 2980 2981 /** @hide */ 2982 @Override isPackageSuspended(String packageName)2983 public boolean isPackageSuspended(String packageName) throws NameNotFoundException { 2984 try { 2985 return isPackageSuspendedForUser(packageName, getUserId()); 2986 } catch (IllegalArgumentException ie) { 2987 throw new NameNotFoundException(packageName); 2988 } 2989 } 2990 2991 @Override isPackageSuspended()2992 public boolean isPackageSuspended() { 2993 return isPackageSuspendedForUser(mContext.getOpPackageName(), getUserId()); 2994 } 2995 2996 @Override isPackageQuarantined(@onNull String packageName)2997 public boolean isPackageQuarantined(@NonNull String packageName) throws NameNotFoundException { 2998 try { 2999 return mPM.isPackageQuarantinedForUser(packageName, getUserId()); 3000 } catch (IllegalArgumentException ie) { 3001 throw new NameNotFoundException(packageName); 3002 } catch (RemoteException e) { 3003 throw e.rethrowFromSystemServer(); 3004 } 3005 } 3006 3007 @Override isPackageStopped(@onNull String packageName)3008 public boolean isPackageStopped(@NonNull String packageName) throws NameNotFoundException { 3009 try { 3010 return mPM.isPackageStoppedForUser(packageName, getUserId()); 3011 } catch (IllegalArgumentException ie) { 3012 throw new NameNotFoundException(packageName); 3013 } catch (RemoteException e) { 3014 throw e.rethrowFromSystemServer(); 3015 } 3016 } 3017 3018 /** @hide */ 3019 @Override setApplicationCategoryHint(String packageName, int categoryHint)3020 public void setApplicationCategoryHint(String packageName, int categoryHint) { 3021 try { 3022 mPM.setApplicationCategoryHint(packageName, categoryHint, 3023 mContext.getOpPackageName()); 3024 } catch (RemoteException e) { 3025 throw e.rethrowFromSystemServer(); 3026 } 3027 } 3028 3029 @Override 3030 @UnsupportedAppUsage getPackageSizeInfoAsUser(String packageName, int userHandle, IPackageStatsObserver observer)3031 public void getPackageSizeInfoAsUser(String packageName, int userHandle, 3032 IPackageStatsObserver observer) { 3033 final String msg = "Shame on you for calling the hidden API " 3034 + "getPackageSizeInfoAsUser(). Shame!"; 3035 if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) { 3036 throw new UnsupportedOperationException(msg); 3037 } else if (observer != null) { 3038 Log.d(TAG, msg); 3039 try { 3040 observer.onGetStatsCompleted(null, false); 3041 } catch (RemoteException ignored) { 3042 } 3043 } 3044 } 3045 3046 @Override addPackageToPreferred(String packageName)3047 public void addPackageToPreferred(String packageName) { 3048 Log.w(TAG, "addPackageToPreferred() is a no-op"); 3049 } 3050 3051 @Override removePackageFromPreferred(String packageName)3052 public void removePackageFromPreferred(String packageName) { 3053 Log.w(TAG, "removePackageFromPreferred() is a no-op"); 3054 } 3055 3056 @Override getPreferredPackages(int flags)3057 public List<PackageInfo> getPreferredPackages(int flags) { 3058 Log.w(TAG, "getPreferredPackages() is a no-op"); 3059 return Collections.emptyList(); 3060 } 3061 3062 @Override addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)3063 public void addPreferredActivity(IntentFilter filter, 3064 int match, ComponentName[] set, ComponentName activity) { 3065 try { 3066 mPM.addPreferredActivity(filter, match, set, activity, getUserId(), false); 3067 } catch (RemoteException e) { 3068 throw e.rethrowFromSystemServer(); 3069 } 3070 } 3071 3072 @Override addPreferredActivityAsUser(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)3073 public void addPreferredActivityAsUser(IntentFilter filter, int match, 3074 ComponentName[] set, ComponentName activity, int userId) { 3075 try { 3076 mPM.addPreferredActivity(filter, match, set, activity, userId, false); 3077 } catch (RemoteException e) { 3078 throw e.rethrowFromSystemServer(); 3079 } 3080 } 3081 3082 @Override replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)3083 public void replacePreferredActivity(IntentFilter filter, 3084 int match, ComponentName[] set, ComponentName activity) { 3085 try { 3086 mPM.replacePreferredActivity(filter, match, set, activity, getUserId()); 3087 } catch (RemoteException e) { 3088 throw e.rethrowFromSystemServer(); 3089 } 3090 } 3091 3092 @Override replacePreferredActivityAsUser(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)3093 public void replacePreferredActivityAsUser(IntentFilter filter, 3094 int match, ComponentName[] set, ComponentName activity, 3095 int userId) { 3096 try { 3097 mPM.replacePreferredActivity(filter, match, set, activity, userId); 3098 } catch (RemoteException e) { 3099 throw e.rethrowFromSystemServer(); 3100 } 3101 } 3102 3103 @Override clearPackagePreferredActivities(String packageName)3104 public void clearPackagePreferredActivities(String packageName) { 3105 try { 3106 mPM.clearPackagePreferredActivities(packageName); 3107 } catch (RemoteException e) { 3108 throw e.rethrowFromSystemServer(); 3109 } 3110 } 3111 3112 @Override addUniquePreferredActivity(@onNull IntentFilter filter, int match, @Nullable ComponentName[] set, @NonNull ComponentName activity)3113 public void addUniquePreferredActivity(@NonNull IntentFilter filter, int match, 3114 @Nullable ComponentName[] set, @NonNull ComponentName activity) { 3115 try { 3116 mPM.addPreferredActivity(filter, match, set, activity, getUserId(), true); 3117 } catch (RemoteException e) { 3118 throw e.rethrowFromSystemServer(); 3119 } 3120 } 3121 3122 @Override getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)3123 public int getPreferredActivities(List<IntentFilter> outFilters, 3124 List<ComponentName> outActivities, String packageName) { 3125 try { 3126 return mPM.getPreferredActivities(outFilters, outActivities, packageName); 3127 } catch (RemoteException e) { 3128 throw e.rethrowFromSystemServer(); 3129 } 3130 } 3131 3132 @Override getHomeActivities(List<ResolveInfo> outActivities)3133 public ComponentName getHomeActivities(List<ResolveInfo> outActivities) { 3134 try { 3135 return mPM.getHomeActivities(outActivities); 3136 } catch (RemoteException e) { 3137 throw e.rethrowFromSystemServer(); 3138 } 3139 } 3140 3141 @Override setSyntheticAppDetailsActivityEnabled(String packageName, boolean enabled)3142 public void setSyntheticAppDetailsActivityEnabled(String packageName, boolean enabled) { 3143 try { 3144 ComponentName componentName = new ComponentName(packageName, 3145 APP_DETAILS_ACTIVITY_CLASS_NAME); 3146 mPM.setComponentEnabledSetting(componentName, enabled 3147 ? COMPONENT_ENABLED_STATE_DEFAULT 3148 : COMPONENT_ENABLED_STATE_DISABLED, 3149 DONT_KILL_APP, getUserId(), mContext.getOpPackageName()); 3150 } catch (RemoteException e) { 3151 throw e.rethrowFromSystemServer(); 3152 } 3153 } 3154 3155 @Override getSyntheticAppDetailsActivityEnabled(String packageName)3156 public boolean getSyntheticAppDetailsActivityEnabled(String packageName) { 3157 try { 3158 ComponentName componentName = new ComponentName(packageName, 3159 APP_DETAILS_ACTIVITY_CLASS_NAME); 3160 int state = mPM.getComponentEnabledSetting(componentName, getUserId()); 3161 return state == COMPONENT_ENABLED_STATE_ENABLED 3162 || state == COMPONENT_ENABLED_STATE_DEFAULT; 3163 } catch (RemoteException e) { 3164 throw e.rethrowFromSystemServer(); 3165 } 3166 } 3167 3168 @Override setComponentEnabledSetting(ComponentName componentName, int newState, int flags)3169 public void setComponentEnabledSetting(ComponentName componentName, 3170 int newState, int flags) { 3171 try { 3172 mPM.setComponentEnabledSetting(componentName, newState, flags, getUserId(), 3173 mContext.getOpPackageName()); 3174 } catch (RemoteException e) { 3175 throw e.rethrowFromSystemServer(); 3176 } 3177 } 3178 3179 @Override setComponentEnabledSettings(List<ComponentEnabledSetting> settings)3180 public void setComponentEnabledSettings(List<ComponentEnabledSetting> settings) { 3181 try { 3182 mPM.setComponentEnabledSettings(settings, getUserId(), mContext.getOpPackageName()); 3183 } catch (RemoteException e) { 3184 throw e.rethrowFromSystemServer(); 3185 } 3186 } 3187 3188 @Override getComponentEnabledSetting(ComponentName componentName)3189 public int getComponentEnabledSetting(ComponentName componentName) { 3190 try { 3191 return mPM.getComponentEnabledSetting(componentName, getUserId()); 3192 } catch (RemoteException e) { 3193 throw e.rethrowFromSystemServer(); 3194 } 3195 } 3196 3197 @Override setApplicationEnabledSetting(String packageName, int newState, int flags)3198 public void setApplicationEnabledSetting(String packageName, 3199 int newState, int flags) { 3200 try { 3201 mPM.setApplicationEnabledSetting(packageName, newState, flags, 3202 getUserId(), mContext.getOpPackageName()); 3203 } catch (RemoteException e) { 3204 throw e.rethrowFromSystemServer(); 3205 } 3206 } 3207 3208 @Override getApplicationEnabledSetting(String packageName)3209 public int getApplicationEnabledSetting(String packageName) { 3210 try { 3211 return mPM.getApplicationEnabledSetting(packageName, getUserId()); 3212 } catch (RemoteException e) { 3213 throw e.rethrowFromSystemServer(); 3214 } 3215 } 3216 3217 @Override flushPackageRestrictionsAsUser(int userId)3218 public void flushPackageRestrictionsAsUser(int userId) { 3219 try { 3220 mPM.flushPackageRestrictionsAsUser(userId); 3221 } catch (RemoteException e) { 3222 throw e.rethrowFromSystemServer(); 3223 } 3224 } 3225 3226 @Override setApplicationHiddenSettingAsUser(String packageName, boolean hidden, UserHandle user)3227 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 3228 UserHandle user) { 3229 try { 3230 return mPM.setApplicationHiddenSettingAsUser(packageName, hidden, 3231 user.getIdentifier()); 3232 } catch (RemoteException e) { 3233 throw e.rethrowFromSystemServer(); 3234 } 3235 } 3236 3237 @Override getApplicationHiddenSettingAsUser(String packageName, UserHandle user)3238 public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) { 3239 try { 3240 return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier()); 3241 } catch (RemoteException e) { 3242 throw e.rethrowFromSystemServer(); 3243 } 3244 } 3245 3246 /** @hide */ 3247 @Override setSystemAppState(String packageName, @SystemAppState int state)3248 public void setSystemAppState(String packageName, @SystemAppState int state) { 3249 try { 3250 switch (state) { 3251 case SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN: 3252 mPM.setSystemAppHiddenUntilInstalled(packageName, true); 3253 break; 3254 case SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE: 3255 mPM.setSystemAppHiddenUntilInstalled(packageName, false); 3256 break; 3257 case SYSTEM_APP_STATE_INSTALLED: 3258 mPM.setSystemAppInstallState(packageName, true, getUserId()); 3259 break; 3260 case SYSTEM_APP_STATE_UNINSTALLED: 3261 mPM.setSystemAppInstallState(packageName, false, getUserId()); 3262 break; 3263 default: 3264 } 3265 } catch (RemoteException e) { 3266 throw e.rethrowFromSystemServer(); 3267 } 3268 } 3269 3270 /** @hide */ 3271 @Override getKeySetByAlias(String packageName, String alias)3272 public KeySet getKeySetByAlias(String packageName, String alias) { 3273 Objects.requireNonNull(packageName); 3274 Objects.requireNonNull(alias); 3275 try { 3276 return mPM.getKeySetByAlias(packageName, alias); 3277 } catch (RemoteException e) { 3278 throw e.rethrowFromSystemServer(); 3279 } 3280 } 3281 3282 /** @hide */ 3283 @Override getSigningKeySet(String packageName)3284 public KeySet getSigningKeySet(String packageName) { 3285 Objects.requireNonNull(packageName); 3286 try { 3287 return mPM.getSigningKeySet(packageName); 3288 } catch (RemoteException e) { 3289 throw e.rethrowFromSystemServer(); 3290 } 3291 } 3292 3293 /** @hide */ 3294 @Override isSignedBy(String packageName, KeySet ks)3295 public boolean isSignedBy(String packageName, KeySet ks) { 3296 Objects.requireNonNull(packageName); 3297 Objects.requireNonNull(ks); 3298 try { 3299 return mPM.isPackageSignedByKeySet(packageName, ks); 3300 } catch (RemoteException e) { 3301 throw e.rethrowFromSystemServer(); 3302 } 3303 } 3304 3305 /** @hide */ 3306 @Override isSignedByExactly(String packageName, KeySet ks)3307 public boolean isSignedByExactly(String packageName, KeySet ks) { 3308 Objects.requireNonNull(packageName); 3309 Objects.requireNonNull(ks); 3310 try { 3311 return mPM.isPackageSignedByKeySetExactly(packageName, ks); 3312 } catch (RemoteException e) { 3313 throw e.rethrowFromSystemServer(); 3314 } 3315 } 3316 3317 /** 3318 * @hide 3319 */ 3320 @Override getVerifierDeviceIdentity()3321 public VerifierDeviceIdentity getVerifierDeviceIdentity() { 3322 try { 3323 return mPM.getVerifierDeviceIdentity(); 3324 } catch (RemoteException e) { 3325 throw e.rethrowFromSystemServer(); 3326 } 3327 } 3328 3329 @Override isUpgrade()3330 public boolean isUpgrade() { 3331 return isDeviceUpgrading(); 3332 } 3333 3334 @Override isDeviceUpgrading()3335 public boolean isDeviceUpgrading() { 3336 try { 3337 return mPM.isDeviceUpgrading(); 3338 } catch (RemoteException e) { 3339 throw e.rethrowFromSystemServer(); 3340 } 3341 } 3342 3343 @Override getPackageInstaller()3344 public PackageInstaller getPackageInstaller() { 3345 if (mInstaller == null) { 3346 try { 3347 mInstaller = new PackageInstaller(mPM.getPackageInstaller(), 3348 mContext.getPackageName(), mContext.getAttributionTag(), getUserId()); 3349 } catch (RemoteException e) { 3350 throw e.rethrowFromSystemServer(); 3351 } 3352 } 3353 return mInstaller; 3354 } 3355 3356 @Override isPackageAvailable(String packageName)3357 public boolean isPackageAvailable(String packageName) { 3358 try { 3359 return mPM.isPackageAvailable(packageName, getUserId()); 3360 } catch (RemoteException e) { 3361 throw e.rethrowFromSystemServer(); 3362 } 3363 } 3364 3365 /** 3366 * @hide 3367 */ 3368 @Override addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId, int flags)3369 public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId, 3370 int flags) { 3371 try { 3372 mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(), 3373 sourceUserId, targetUserId, flags); 3374 } catch (RemoteException e) { 3375 throw e.rethrowFromSystemServer(); 3376 } 3377 } 3378 3379 /** 3380 * @hide 3381 */ 3382 @Override removeCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId, int flags)3383 public boolean removeCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, 3384 int targetUserId, int flags) { 3385 try { 3386 return mPM.removeCrossProfileIntentFilter(filter, mContext.getOpPackageName(), 3387 sourceUserId, targetUserId, flags); 3388 } catch (RemoteException e) { 3389 throw e.rethrowFromSystemServer(); 3390 } 3391 } 3392 3393 /** 3394 * @hide 3395 */ 3396 @Override clearCrossProfileIntentFilters(int sourceUserId)3397 public void clearCrossProfileIntentFilters(int sourceUserId) { 3398 try { 3399 mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName()); 3400 } catch (RemoteException e) { 3401 throw e.rethrowFromSystemServer(); 3402 } 3403 } 3404 3405 /** 3406 * @hide 3407 */ loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo)3408 public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) { 3409 Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo); 3410 if (itemInfo.showUserIcon != UserHandle.USER_NULL) { 3411 return dr; 3412 } 3413 return getUserBadgedIcon(dr, new UserHandle(getUserId())); 3414 } 3415 3416 /** 3417 * @hide 3418 */ loadUnbadgedItemIcon(@onNull PackageItemInfo itemInfo, @Nullable ApplicationInfo appInfo)3419 public Drawable loadUnbadgedItemIcon(@NonNull PackageItemInfo itemInfo, 3420 @Nullable ApplicationInfo appInfo) { 3421 if (itemInfo.showUserIcon != UserHandle.USER_NULL) { 3422 // Indicates itemInfo is for a different user (e.g. a profile's parent), so use a 3423 // generic user icon (users generally lack permission to view each other's actual icons) 3424 int targetUserId = itemInfo.showUserIcon; 3425 return UserIcons.getDefaultUserIcon( 3426 mContext.getResources(), targetUserId, /* light= */ false); 3427 } 3428 Drawable dr = null; 3429 if (itemInfo.packageName != null) { 3430 if (itemInfo.isArchived) { 3431 dr = getArchivedAppIcon(itemInfo.packageName); 3432 } else { 3433 dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo); 3434 } 3435 } 3436 if (dr == null && itemInfo != appInfo && appInfo != null) { 3437 dr = loadUnbadgedItemIcon(appInfo, appInfo); 3438 } 3439 if (dr == null) { 3440 dr = itemInfo.loadDefaultIcon(this); 3441 } 3442 return dr; 3443 } 3444 getBadgedDrawable(Drawable drawable, Drawable badgeDrawable, Rect badgeLocation, boolean tryBadgeInPlace)3445 private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable, 3446 Rect badgeLocation, boolean tryBadgeInPlace) { 3447 final int badgedWidth = drawable.getIntrinsicWidth(); 3448 final int badgedHeight = drawable.getIntrinsicHeight(); 3449 final boolean canBadgeInPlace = tryBadgeInPlace 3450 && (drawable instanceof BitmapDrawable) 3451 && ((BitmapDrawable) drawable).getBitmap().isMutable(); 3452 3453 final Bitmap bitmap; 3454 if (canBadgeInPlace) { 3455 bitmap = ((BitmapDrawable) drawable).getBitmap(); 3456 } else { 3457 bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888); 3458 } 3459 Canvas canvas = new Canvas(bitmap); 3460 3461 if (!canBadgeInPlace) { 3462 drawable.setBounds(0, 0, badgedWidth, badgedHeight); 3463 drawable.draw(canvas); 3464 } 3465 3466 if (badgeLocation != null) { 3467 if (badgeLocation.left < 0 || badgeLocation.top < 0 3468 || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) { 3469 throw new IllegalArgumentException("Badge location " + badgeLocation 3470 + " not in badged drawable bounds " 3471 + new Rect(0, 0, badgedWidth, badgedHeight)); 3472 } 3473 badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height()); 3474 3475 canvas.save(); 3476 canvas.translate(badgeLocation.left, badgeLocation.top); 3477 badgeDrawable.draw(canvas); 3478 canvas.restore(); 3479 } else { 3480 badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight); 3481 badgeDrawable.draw(canvas); 3482 } 3483 3484 if (!canBadgeInPlace) { 3485 BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap); 3486 3487 if (drawable instanceof BitmapDrawable) { 3488 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; 3489 mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity()); 3490 } 3491 3492 return mergedDrawable; 3493 } 3494 3495 return drawable; 3496 } 3497 hasUserBadge(int userId)3498 private boolean hasUserBadge(int userId) { 3499 return getUserManager().hasBadge(userId); 3500 } 3501 3502 /** 3503 * @hide 3504 */ 3505 @Override getInstallReason(String packageName, UserHandle user)3506 public int getInstallReason(String packageName, UserHandle user) { 3507 try { 3508 return mPM.getInstallReason(packageName, user.getIdentifier()); 3509 } catch (RemoteException e) { 3510 throw e.rethrowFromSystemServer(); 3511 } 3512 } 3513 3514 /** {@hide} */ 3515 private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements 3516 Handler.Callback { 3517 private static final int MSG_CREATED = 1; 3518 private static final int MSG_STATUS_CHANGED = 2; 3519 3520 final MoveCallback mCallback; 3521 final Handler mHandler; 3522 MoveCallbackDelegate(MoveCallback callback, Looper looper)3523 public MoveCallbackDelegate(MoveCallback callback, Looper looper) { 3524 mCallback = callback; 3525 mHandler = new Handler(looper, this); 3526 } 3527 3528 @Override handleMessage(Message msg)3529 public boolean handleMessage(Message msg) { 3530 switch (msg.what) { 3531 case MSG_CREATED: { 3532 final SomeArgs args = (SomeArgs) msg.obj; 3533 mCallback.onCreated(args.argi1, (Bundle) args.arg2); 3534 args.recycle(); 3535 return true; 3536 } 3537 case MSG_STATUS_CHANGED: { 3538 final SomeArgs args = (SomeArgs) msg.obj; 3539 mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 3540 args.recycle(); 3541 return true; 3542 } 3543 } 3544 return false; 3545 } 3546 3547 @Override onCreated(int moveId, Bundle extras)3548 public void onCreated(int moveId, Bundle extras) { 3549 final SomeArgs args = SomeArgs.obtain(); 3550 args.argi1 = moveId; 3551 args.arg2 = extras; 3552 mHandler.obtainMessage(MSG_CREATED, args).sendToTarget(); 3553 } 3554 3555 @Override onStatusChanged(int moveId, int status, long estMillis)3556 public void onStatusChanged(int moveId, int status, long estMillis) { 3557 final SomeArgs args = SomeArgs.obtain(); 3558 args.argi1 = moveId; 3559 args.argi2 = status; 3560 args.arg3 = estMillis; 3561 mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 3562 } 3563 } 3564 3565 private final ContextImpl mContext; 3566 @UnsupportedAppUsage 3567 private final IPackageManager mPM; 3568 3569 /** Assume locked until we hear otherwise */ 3570 private volatile boolean mUserUnlocked = false; 3571 3572 private static final Object sSync = new Object(); 3573 private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache 3574 = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>(); 3575 private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache 3576 = new ArrayMap<ResourceName, WeakReference<CharSequence>>(); 3577 3578 @Override canRequestPackageInstalls()3579 public boolean canRequestPackageInstalls() { 3580 try { 3581 return mPM.canRequestPackageInstalls(mContext.getPackageName(), getUserId()); 3582 } catch (RemoteException e) { 3583 throw e.rethrowAsRuntimeException(); 3584 } 3585 } 3586 3587 @Override getInstantAppResolverSettingsComponent()3588 public ComponentName getInstantAppResolverSettingsComponent() { 3589 try { 3590 return mPM.getInstantAppResolverSettingsComponent(); 3591 } catch (RemoteException e) { 3592 throw e.rethrowAsRuntimeException(); 3593 } 3594 } 3595 3596 @Override getInstantAppInstallerComponent()3597 public ComponentName getInstantAppInstallerComponent() { 3598 try { 3599 return mPM.getInstantAppInstallerComponent(); 3600 } catch (RemoteException e) { 3601 throw e.rethrowAsRuntimeException(); 3602 } 3603 } 3604 3605 @Override getInstantAppAndroidId(String packageName, UserHandle user)3606 public String getInstantAppAndroidId(String packageName, UserHandle user) { 3607 try { 3608 return mPM.getInstantAppAndroidId(packageName, user.getIdentifier()); 3609 } catch (RemoteException e) { 3610 throw e.rethrowAsRuntimeException(); 3611 } 3612 } 3613 3614 private static class DexModuleRegisterResult { 3615 final String dexModulePath; 3616 final boolean success; 3617 final String message; 3618 DexModuleRegisterResult(String dexModulePath, boolean success, String message)3619 private DexModuleRegisterResult(String dexModulePath, boolean success, String message) { 3620 this.dexModulePath = dexModulePath; 3621 this.success = success; 3622 this.message = message; 3623 } 3624 } 3625 3626 private static class DexModuleRegisterCallbackDelegate 3627 extends android.content.pm.IDexModuleRegisterCallback.Stub 3628 implements Handler.Callback { 3629 private static final int MSG_DEX_MODULE_REGISTERED = 1; 3630 private final DexModuleRegisterCallback callback; 3631 private final Handler mHandler; 3632 DexModuleRegisterCallbackDelegate(@onNull DexModuleRegisterCallback callback)3633 DexModuleRegisterCallbackDelegate(@NonNull DexModuleRegisterCallback callback) { 3634 this.callback = callback; 3635 mHandler = new Handler(Looper.getMainLooper(), this); 3636 } 3637 3638 @Override onDexModuleRegistered(@onNull String dexModulePath, boolean success, @Nullable String message)3639 public void onDexModuleRegistered(@NonNull String dexModulePath, boolean success, 3640 @Nullable String message)throws RemoteException { 3641 mHandler.obtainMessage(MSG_DEX_MODULE_REGISTERED, 3642 new DexModuleRegisterResult(dexModulePath, success, message)).sendToTarget(); 3643 } 3644 3645 @Override handleMessage(Message msg)3646 public boolean handleMessage(Message msg) { 3647 if (msg.what != MSG_DEX_MODULE_REGISTERED) { 3648 return false; 3649 } 3650 DexModuleRegisterResult result = (DexModuleRegisterResult)msg.obj; 3651 callback.onDexModuleRegistered(result.dexModulePath, result.success, result.message); 3652 return true; 3653 } 3654 } 3655 3656 @Override registerDexModule(@onNull String dexModule, @Nullable DexModuleRegisterCallback callback)3657 public void registerDexModule(@NonNull String dexModule, 3658 @Nullable DexModuleRegisterCallback callback) { 3659 // Create the callback delegate to be passed to package manager service. 3660 DexModuleRegisterCallbackDelegate callbackDelegate = null; 3661 if (callback != null) { 3662 callbackDelegate = new DexModuleRegisterCallbackDelegate(callback); 3663 } 3664 3665 // Check if this is a shared module by looking if the others can read it. 3666 boolean isSharedModule = false; 3667 try { 3668 StructStat stat = Os.stat(dexModule); 3669 if ((OsConstants.S_IROTH & stat.st_mode) != 0) { 3670 isSharedModule = true; 3671 } 3672 } catch (ErrnoException e) { 3673 if (callbackDelegate != null) { 3674 callback.onDexModuleRegistered(dexModule, false, 3675 "Could not get stat the module file: " + e.getMessage()); 3676 } 3677 return; 3678 } 3679 3680 // Invoke the package manager service. 3681 try { 3682 mPM.registerDexModule(mContext.getPackageName(), dexModule, 3683 isSharedModule, callbackDelegate); 3684 } catch (RemoteException e) { 3685 throw e.rethrowAsRuntimeException(); 3686 } 3687 } 3688 3689 @Override getHarmfulAppWarning(String packageName)3690 public CharSequence getHarmfulAppWarning(String packageName) { 3691 try { 3692 return mPM.getHarmfulAppWarning(packageName, getUserId()); 3693 } catch (RemoteException e) { 3694 throw e.rethrowAsRuntimeException(); 3695 } 3696 } 3697 3698 @Override setHarmfulAppWarning(String packageName, CharSequence warning)3699 public void setHarmfulAppWarning(String packageName, CharSequence warning) { 3700 try { 3701 mPM.setHarmfulAppWarning(packageName, warning, getUserId()); 3702 } catch (RemoteException e) { 3703 throw e.rethrowAsRuntimeException(); 3704 } 3705 } 3706 3707 @Override getArtManager()3708 public ArtManager getArtManager() { 3709 if (mArtManager == null) { 3710 try { 3711 mArtManager = new ArtManager(mContext, mPM.getArtManager()); 3712 } catch (RemoteException e) { 3713 throw e.rethrowFromSystemServer(); 3714 } 3715 } 3716 return mArtManager; 3717 } 3718 3719 @Override getDefaultTextClassifierPackageName()3720 public String getDefaultTextClassifierPackageName() { 3721 try { 3722 return mPM.getDefaultTextClassifierPackageName(); 3723 } catch (RemoteException e) { 3724 throw e.rethrowAsRuntimeException(); 3725 } 3726 } 3727 3728 @Override getSystemTextClassifierPackageName()3729 public String getSystemTextClassifierPackageName() { 3730 try { 3731 return mPM.getSystemTextClassifierPackageName(); 3732 } catch (RemoteException e) { 3733 throw e.rethrowAsRuntimeException(); 3734 } 3735 } 3736 3737 @Override getAttentionServicePackageName()3738 public String getAttentionServicePackageName() { 3739 try { 3740 return mPM.getAttentionServicePackageName(); 3741 } catch (RemoteException e) { 3742 throw e.rethrowAsRuntimeException(); 3743 } 3744 } 3745 3746 @Override getRotationResolverPackageName()3747 public String getRotationResolverPackageName() { 3748 try { 3749 return mPM.getRotationResolverPackageName(); 3750 } catch (RemoteException e) { 3751 throw e.rethrowAsRuntimeException(); 3752 } 3753 } 3754 3755 @Override getWellbeingPackageName()3756 public String getWellbeingPackageName() { 3757 try { 3758 return mPM.getWellbeingPackageName(); 3759 } catch (RemoteException e) { 3760 throw e.rethrowAsRuntimeException(); 3761 } 3762 } 3763 3764 @Override getAppPredictionServicePackageName()3765 public String getAppPredictionServicePackageName() { 3766 try { 3767 return mPM.getAppPredictionServicePackageName(); 3768 } catch (RemoteException e) { 3769 throw e.rethrowAsRuntimeException(); 3770 } 3771 } 3772 3773 @Override getSystemCaptionsServicePackageName()3774 public String getSystemCaptionsServicePackageName() { 3775 try { 3776 return mPM.getSystemCaptionsServicePackageName(); 3777 } catch (RemoteException e) { 3778 throw e.rethrowAsRuntimeException(); 3779 } 3780 } 3781 3782 @Override getSetupWizardPackageName()3783 public String getSetupWizardPackageName() { 3784 try { 3785 return mPM.getSetupWizardPackageName(); 3786 } catch (RemoteException e) { 3787 throw e.rethrowAsRuntimeException(); 3788 } 3789 } 3790 3791 @Override getIncidentReportApproverPackageName()3792 public String getIncidentReportApproverPackageName() { 3793 try { 3794 return mPM.getIncidentReportApproverPackageName(); 3795 } catch (RemoteException e) { 3796 throw e.rethrowAsRuntimeException(); 3797 } 3798 } 3799 3800 @Override isPackageStateProtected(String packageName, int userId)3801 public boolean isPackageStateProtected(String packageName, int userId) { 3802 try { 3803 return mPM.isPackageStateProtected(packageName, userId); 3804 } catch (RemoteException e) { 3805 throw e.rethrowAsRuntimeException(); 3806 } 3807 } 3808 sendDeviceCustomizationReadyBroadcast()3809 public void sendDeviceCustomizationReadyBroadcast() { 3810 try { 3811 mPM.sendDeviceCustomizationReadyBroadcast(); 3812 } catch (RemoteException e) { 3813 throw e.rethrowAsRuntimeException(); 3814 } 3815 } 3816 3817 @Override isAutoRevokeWhitelisted()3818 public boolean isAutoRevokeWhitelisted() { 3819 try { 3820 return mPM.isAutoRevokeWhitelisted(mContext.getPackageName()); 3821 } catch (RemoteException e) { 3822 throw e.rethrowAsRuntimeException(); 3823 } 3824 } 3825 3826 @Override setMimeGroup(String mimeGroup, Set<String> mimeTypes)3827 public void setMimeGroup(String mimeGroup, Set<String> mimeTypes) { 3828 try { 3829 mPM.setMimeGroup(mContext.getPackageName(), mimeGroup, new ArrayList<>(mimeTypes)); 3830 } catch (RemoteException e) { 3831 throw e.rethrowAsRuntimeException(); 3832 } 3833 } 3834 3835 @NonNull 3836 @Override getMimeGroup(String group)3837 public Set<String> getMimeGroup(String group) { 3838 try { 3839 List<String> mimeGroup = mPM.getMimeGroup(mContext.getPackageName(), group); 3840 return new ArraySet<>(mimeGroup); 3841 } catch (RemoteException e) { 3842 throw e.rethrowAsRuntimeException(); 3843 } 3844 } 3845 3846 @Override getProperty(String propertyName, String packageName)3847 public Property getProperty(String propertyName, String packageName) 3848 throws NameNotFoundException { 3849 Objects.requireNonNull(packageName); 3850 Objects.requireNonNull(propertyName); 3851 return getPropertyAsUser(propertyName, packageName, null /* className */, getUserId()); 3852 } 3853 3854 @Override getProperty(String propertyName, ComponentName component)3855 public Property getProperty(String propertyName, ComponentName component) 3856 throws NameNotFoundException { 3857 Objects.requireNonNull(component); 3858 Objects.requireNonNull(propertyName); 3859 return getPropertyAsUser(propertyName, 3860 component.getPackageName(), component.getClassName(), getUserId()); 3861 } 3862 3863 @Override getPropertyAsUser(@onNull String propertyName, @NonNull String packageName, @Nullable String className, int userId)3864 public Property getPropertyAsUser(@NonNull String propertyName, @NonNull String packageName, 3865 @Nullable String className, int userId) throws NameNotFoundException { 3866 Objects.requireNonNull(packageName); 3867 Objects.requireNonNull(propertyName); 3868 try { 3869 final Property property = mPM.getPropertyAsUser(propertyName, 3870 packageName, className, userId); 3871 if (property == null) { 3872 throw new NameNotFoundException(); 3873 } 3874 return property; 3875 } catch (RemoteException e) { 3876 throw e.rethrowAsRuntimeException(); 3877 } 3878 } 3879 3880 @Override queryApplicationProperty(String propertyName)3881 public List<Property> queryApplicationProperty(String propertyName) { 3882 Objects.requireNonNull(propertyName); 3883 try { 3884 final ParceledListSlice<Property> parceledList = 3885 mPM.queryProperty(propertyName, TYPE_APPLICATION); 3886 if (parceledList == null) { 3887 return Collections.emptyList(); 3888 } 3889 return parceledList.getList(); 3890 } catch (RemoteException e) { 3891 throw e.rethrowAsRuntimeException(); 3892 } 3893 } 3894 3895 @Override queryActivityProperty(String propertyName)3896 public List<Property> queryActivityProperty(String propertyName) { 3897 Objects.requireNonNull(propertyName); 3898 try { 3899 final ParceledListSlice<Property> parceledList = 3900 mPM.queryProperty(propertyName, TYPE_ACTIVITY); 3901 if (parceledList == null) { 3902 return Collections.emptyList(); 3903 } 3904 return parceledList.getList(); 3905 } catch (RemoteException e) { 3906 throw e.rethrowAsRuntimeException(); 3907 } 3908 } 3909 3910 @Override queryProviderProperty(String propertyName)3911 public List<Property> queryProviderProperty(String propertyName) { 3912 Objects.requireNonNull(propertyName); 3913 try { 3914 final ParceledListSlice<Property> parceledList = 3915 mPM.queryProperty(propertyName, TYPE_PROVIDER); 3916 if (parceledList == null) { 3917 return Collections.emptyList(); 3918 } 3919 return parceledList.getList(); 3920 } catch (RemoteException e) { 3921 throw e.rethrowAsRuntimeException(); 3922 } 3923 } 3924 3925 @Override queryReceiverProperty(String propertyName)3926 public List<Property> queryReceiverProperty(String propertyName) { 3927 Objects.requireNonNull(propertyName); 3928 try { 3929 final ParceledListSlice<Property> parceledList = 3930 mPM.queryProperty(propertyName, TYPE_RECEIVER); 3931 if (parceledList == null) { 3932 return Collections.emptyList(); 3933 } 3934 return parceledList.getList(); 3935 } catch (RemoteException e) { 3936 throw e.rethrowAsRuntimeException(); 3937 } 3938 } 3939 3940 @Override queryServiceProperty(String propertyName)3941 public List<Property> queryServiceProperty(String propertyName) { 3942 Objects.requireNonNull(propertyName); 3943 try { 3944 final ParceledListSlice<Property> parceledList = 3945 mPM.queryProperty(propertyName, TYPE_SERVICE); 3946 if (parceledList == null) { 3947 return Collections.emptyList(); 3948 } 3949 return parceledList.getList(); 3950 } catch (RemoteException e) { 3951 throw e.rethrowAsRuntimeException(); 3952 } 3953 } 3954 3955 @Override canPackageQuery(@onNull String sourcePackageName, @NonNull String targetPackageName)3956 public boolean canPackageQuery(@NonNull String sourcePackageName, 3957 @NonNull String targetPackageName) throws NameNotFoundException { 3958 Objects.requireNonNull(sourcePackageName); 3959 Objects.requireNonNull(targetPackageName); 3960 return canPackageQuery(sourcePackageName, new String[]{targetPackageName})[0]; 3961 } 3962 3963 @Override 3964 @NonNull canPackageQuery(@onNull String sourcePackageName, @NonNull String[] targetPackageNames)3965 public boolean[] canPackageQuery(@NonNull String sourcePackageName, 3966 @NonNull String[] targetPackageNames) throws NameNotFoundException { 3967 Objects.requireNonNull(sourcePackageName); 3968 Objects.requireNonNull(targetPackageNames); 3969 try { 3970 return mPM.canPackageQuery(sourcePackageName, targetPackageNames, getUserId()); 3971 } catch (ParcelableException e) { 3972 e.maybeRethrow(PackageManager.NameNotFoundException.class); 3973 throw new RuntimeException(e); 3974 } catch (RemoteException re) { 3975 throw re.rethrowAsRuntimeException(); 3976 } 3977 } 3978 3979 @Override makeUidVisible(int recipientUid, int visibleUid)3980 public void makeUidVisible(int recipientUid, int visibleUid) { 3981 try { 3982 mPM.makeUidVisible(recipientUid, visibleUid); 3983 } catch (RemoteException e) { 3984 throw e.rethrowAsRuntimeException(); 3985 } 3986 } 3987 3988 @Override getArchivedPackage(@onNull String packageName)3989 public @Nullable ArchivedPackageInfo getArchivedPackage(@NonNull String packageName) { 3990 try { 3991 var parcel = mPM.getArchivedPackage(packageName, mContext.getUserId()); 3992 if (parcel == null) { 3993 return null; 3994 } 3995 return new ArchivedPackageInfo(parcel); 3996 } catch (RemoteException e) { 3997 throw e.rethrowAsRuntimeException(); 3998 } 3999 } 4000 4001 @Override canUserUninstall(String packageName, UserHandle user)4002 public boolean canUserUninstall(String packageName, UserHandle user) { 4003 try { 4004 return mPM.getBlockUninstallForUser(packageName, user.getIdentifier()); 4005 } catch (RemoteException e) { 4006 throw e.rethrowAsRuntimeException(); 4007 } 4008 } 4009 4010 @Override shouldShowNewAppInstalledNotification()4011 public boolean shouldShowNewAppInstalledNotification() { 4012 return Settings.Global.getInt(mContext.getContentResolver(), 4013 Settings.Global.SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED, 0) == 1; 4014 } 4015 4016 @Override relinquishUpdateOwnership(String targetPackage)4017 public void relinquishUpdateOwnership(String targetPackage) { 4018 Objects.requireNonNull(targetPackage); 4019 try { 4020 mPM.relinquishUpdateOwnership(targetPackage); 4021 } catch (RemoteException e) { 4022 throw e.rethrowFromSystemServer(); 4023 } 4024 } 4025 4026 @Override registerPackageMonitorCallback(@onNull IRemoteCallback callback, int userId)4027 public void registerPackageMonitorCallback(@NonNull IRemoteCallback callback, int userId) { 4028 Objects.requireNonNull(callback); 4029 try { 4030 mPM.registerPackageMonitorCallback(callback, userId); 4031 synchronized (mPackageMonitorCallbacks) { 4032 if (mPackageMonitorCallbacks.contains(callback)) { 4033 throw new IllegalStateException( 4034 "registerPackageMonitorCallback: callback already registered: " 4035 + callback); 4036 } 4037 mPackageMonitorCallbacks.add(callback); 4038 } 4039 } catch (RemoteException e) { 4040 throw e.rethrowFromSystemServer(); 4041 } 4042 } 4043 4044 @Override unregisterPackageMonitorCallback(@onNull IRemoteCallback callback)4045 public void unregisterPackageMonitorCallback(@NonNull IRemoteCallback callback) { 4046 Objects.requireNonNull(callback); 4047 try { 4048 mPM.unregisterPackageMonitorCallback(callback); 4049 synchronized (mPackageMonitorCallbacks) { 4050 mPackageMonitorCallbacks.remove(callback); 4051 } 4052 } catch (RemoteException e) { 4053 throw e.rethrowFromSystemServer(); 4054 } 4055 } 4056 4057 @Nullable getArchivedAppIcon(String packageName)4058 private Drawable getArchivedAppIcon(String packageName) { 4059 try { 4060 Bitmap archivedAppIcon = mPM.getArchivedAppIcon(packageName, 4061 new UserHandle(getUserId()), 4062 mContext.getPackageName()); 4063 if (archivedAppIcon == null) { 4064 return null; 4065 } 4066 return new BitmapDrawable(null, archivedAppIcon); 4067 } catch (RemoteException e) { 4068 Slog.e(TAG, "Failed to retrieve archived app icon: " + e.getMessage()); 4069 return null; 4070 } 4071 } 4072 4073 @Override parseAndroidManifest(@onNull File apkFile, @NonNull Function<XmlResourceParser, T> parserFunction)4074 public <T> T parseAndroidManifest(@NonNull File apkFile, 4075 @NonNull Function<XmlResourceParser, T> parserFunction) throws IOException { 4076 Objects.requireNonNull(apkFile, "apkFile cannot be null"); 4077 Objects.requireNonNull(parserFunction, "parserFunction cannot be null"); 4078 try (XmlResourceParser xmlResourceParser = getAndroidManifestParser(apkFile)) { 4079 return parserFunction.apply(xmlResourceParser); 4080 } catch (IOException e) { 4081 Log.w(TAG, "Failed to get the android manifest parser", e); 4082 throw e; 4083 } 4084 } 4085 getAndroidManifestParser(@onNull File apkFile)4086 private static XmlResourceParser getAndroidManifestParser(@NonNull File apkFile) 4087 throws IOException { 4088 ApkAssets apkAssets = null; 4089 try { 4090 apkAssets = ApkAssets.loadFromPath(apkFile.getAbsolutePath()); 4091 return apkAssets.openXml(ApkLiteParseUtils.ANDROID_MANIFEST_FILENAME); 4092 } finally { 4093 if (apkAssets != null) { 4094 try { 4095 apkAssets.close(); 4096 } catch (Throwable ignored) { 4097 Log.w(TAG, "Failed to close apkAssets", ignored); 4098 } 4099 } 4100 } 4101 } 4102 4103 4104 @Override parseAndroidManifest(@onNull ParcelFileDescriptor apkFileDescriptor, @NonNull Function<XmlResourceParser, T> parserFunction)4105 public <T> T parseAndroidManifest(@NonNull ParcelFileDescriptor apkFileDescriptor, 4106 @NonNull Function<XmlResourceParser, T> parserFunction) throws IOException { 4107 Objects.requireNonNull(apkFileDescriptor, "apkFileDescriptor cannot be null"); 4108 Objects.requireNonNull(parserFunction, "parserFunction cannot be null"); 4109 try (XmlResourceParser xmlResourceParser = getAndroidManifestParser(apkFileDescriptor)) { 4110 return parserFunction.apply(xmlResourceParser); 4111 } catch (IOException e) { 4112 Log.w(TAG, "Failed to get the android manifest parser", e); 4113 throw e; 4114 } 4115 } 4116 getAndroidManifestParser(@onNull ParcelFileDescriptor fd)4117 private static XmlResourceParser getAndroidManifestParser(@NonNull ParcelFileDescriptor fd) 4118 throws IOException { 4119 ApkAssets apkAssets = null; 4120 try { 4121 apkAssets = ApkAssets.loadFromFd( 4122 fd.getFileDescriptor(), fd.toString(), /* flags= */ 0 , /* assets= */null); 4123 return apkAssets.openXml(ApkLiteParseUtils.ANDROID_MANIFEST_FILENAME); 4124 } finally { 4125 if (apkAssets != null) { 4126 try { 4127 apkAssets.close(); 4128 } catch (Throwable ignored) { 4129 Log.w(TAG, "Failed to close apkAssets", ignored); 4130 } 4131 } 4132 } 4133 } 4134 4135 @Override extractPackageItemInfoAttributes(PackageItemInfo info, String name, String rootTag, int[] attributes)4136 public TypedArray extractPackageItemInfoAttributes(PackageItemInfo info, String name, 4137 String rootTag, int[] attributes) { 4138 if (info == null || info.metaData == null) { 4139 return null; 4140 } 4141 4142 try (XmlResourceParser parser = info.loadXmlMetaData(this, name)) { 4143 if (parser == null) { 4144 Log.w(TAG, "No " + name + " metadata"); 4145 return null; 4146 } 4147 4148 final AttributeSet attrs = Xml.asAttributeSet(parser); 4149 while (true) { 4150 final int type = parser.next(); 4151 if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) { 4152 break; 4153 } 4154 } 4155 4156 if (!TextUtils.equals(parser.getName(), rootTag)) { 4157 Log.w(TAG, "Metadata does not start with " + name + " tag"); 4158 return null; 4159 } 4160 4161 return getResourcesForApplication(info.getApplicationInfo()) 4162 .obtainAttributes(attrs, attributes); 4163 } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) { 4164 Log.e(TAG, "Error parsing: " + info.packageName, e); 4165 return null; 4166 } 4167 } 4168 } 4169