1 /* 2 * Copyright (C) 2020 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 com.android.server.pm.parsing; 18 19 import android.annotation.CheckResult; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.UserIdInt; 23 import android.content.pm.ActivityInfo; 24 import android.content.pm.ApplicationInfo; 25 import android.content.pm.Attribution; 26 import android.content.pm.ComponentInfo; 27 import android.content.pm.ConfigurationInfo; 28 import android.content.pm.FallbackCategoryProvider; 29 import android.content.pm.FeatureGroupInfo; 30 import android.content.pm.FeatureInfo; 31 import android.content.pm.Flags; 32 import android.content.pm.InstrumentationInfo; 33 import android.content.pm.PackageInfo; 34 import android.content.pm.PackageItemInfo; 35 import android.content.pm.PackageManager; 36 import android.content.pm.PathPermission; 37 import android.content.pm.PermissionGroupInfo; 38 import android.content.pm.PermissionInfo; 39 import android.content.pm.ProcessInfo; 40 import android.content.pm.ProviderInfo; 41 import android.content.pm.ServiceInfo; 42 import android.content.pm.SharedLibraryInfo; 43 import android.content.pm.Signature; 44 import android.content.pm.SigningDetails; 45 import android.content.pm.SigningInfo; 46 import android.content.pm.overlay.OverlayPaths; 47 import android.os.Environment; 48 import android.os.PatternMatcher; 49 import android.os.UserHandle; 50 import android.util.ArrayMap; 51 import android.util.ArraySet; 52 import android.util.Pair; 53 import android.util.Slog; 54 55 import com.android.internal.annotations.VisibleForTesting; 56 import com.android.internal.pm.parsing.pkg.AndroidPackageLegacyUtils; 57 import com.android.internal.pm.parsing.pkg.PackageImpl; 58 import com.android.internal.pm.pkg.component.ComponentParseUtils; 59 import com.android.internal.pm.pkg.component.ParsedActivity; 60 import com.android.internal.pm.pkg.component.ParsedAttribution; 61 import com.android.internal.pm.pkg.component.ParsedComponent; 62 import com.android.internal.pm.pkg.component.ParsedInstrumentation; 63 import com.android.internal.pm.pkg.component.ParsedMainComponent; 64 import com.android.internal.pm.pkg.component.ParsedPermission; 65 import com.android.internal.pm.pkg.component.ParsedPermissionGroup; 66 import com.android.internal.pm.pkg.component.ParsedProcess; 67 import com.android.internal.pm.pkg.component.ParsedProvider; 68 import com.android.internal.pm.pkg.component.ParsedService; 69 import com.android.internal.pm.pkg.component.ParsedUsesPermission; 70 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils; 71 import com.android.internal.pm.pkg.parsing.ParsingUtils; 72 import com.android.internal.util.ArrayUtils; 73 import com.android.server.SystemConfig; 74 import com.android.server.pm.PackageArchiver; 75 import com.android.server.pm.parsing.pkg.AndroidPackageUtils; 76 import com.android.server.pm.pkg.AndroidPackage; 77 import com.android.server.pm.pkg.PackageStateInternal; 78 import com.android.server.pm.pkg.PackageStateUnserialized; 79 import com.android.server.pm.pkg.PackageUserState; 80 import com.android.server.pm.pkg.PackageUserStateInternal; 81 import com.android.server.pm.pkg.PackageUserStateUtils; 82 import com.android.server.pm.pkg.SELinuxUtil; 83 84 import java.io.File; 85 import java.util.ArrayList; 86 import java.util.List; 87 import java.util.Map; 88 import java.util.Set; 89 90 91 /** 92 * Methods that use a {@link PackageStateInternal} use it to override information provided from the 93 * raw package, or to provide information that would otherwise be missing. Null can be passed if 94 * none of the state values should be applied. 95 * 96 * @hide 97 **/ 98 public class PackageInfoUtils { 99 private static final String TAG = ParsingUtils.TAG; 100 101 private static final String SYSTEM_DATA_PATH = 102 Environment.getDataDirectoryPath() + File.separator + "system"; 103 104 /** 105 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 106 */ 107 @Nullable generate(AndroidPackage pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> installedPermissions, Set<String> grantedPermissions, PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)108 public static PackageInfo generate(AndroidPackage pkg, int[] gids, 109 @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, 110 long lastUpdateTime, Set<String> installedPermissions, Set<String> grantedPermissions, 111 PackageUserStateInternal state, @UserIdInt int userId, 112 @NonNull PackageStateInternal pkgSetting) { 113 return generateWithComponents(pkg, gids, flags, firstInstallTime, lastUpdateTime, 114 installedPermissions, grantedPermissions, state, userId, pkgSetting); 115 } 116 117 /** 118 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 119 */ generateWithComponents(AndroidPackage pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> installedPermissions, Set<String> grantedPermissions, PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)120 private static PackageInfo generateWithComponents(AndroidPackage pkg, int[] gids, 121 @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, 122 long lastUpdateTime, Set<String> installedPermissions, Set<String> grantedPermissions, 123 PackageUserStateInternal state, @UserIdInt int userId, 124 @NonNull PackageStateInternal pkgSetting) { 125 ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId, 126 pkgSetting); 127 if (applicationInfo == null) { 128 return null; 129 } 130 131 PackageInfo info = new PackageInfo(); 132 info.packageName = pkg.getPackageName(); 133 info.splitNames = pkg.getSplitNames(); 134 AndroidPackageUtils.fillVersionCodes(pkg, info); 135 info.baseRevisionCode = pkg.getBaseRevisionCode(); 136 info.splitRevisionCodes = pkg.getSplitRevisionCodes(); 137 info.versionName = pkg.getVersionName(); 138 info.sharedUserId = pkg.getSharedUserId(); 139 info.sharedUserLabel = pkg.getSharedUserLabelResourceId(); 140 info.applicationInfo = applicationInfo; 141 info.installLocation = pkg.getInstallLocation(); 142 if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 143 || (info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { 144 info.requiredForAllUsers = pkg.isRequiredForAllUsers(); 145 } 146 info.restrictedAccountType = pkg.getRestrictedAccountType(); 147 info.requiredAccountType = pkg.getRequiredAccountType(); 148 info.overlayTarget = pkg.getOverlayTarget(); 149 info.targetOverlayableName = pkg.getOverlayTargetOverlayableName(); 150 info.overlayCategory = pkg.getOverlayCategory(); 151 info.overlayPriority = pkg.getOverlayPriority(); 152 info.mOverlayIsStatic = pkg.isOverlayIsStatic(); 153 info.compileSdkVersion = pkg.getCompileSdkVersion(); 154 info.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName(); 155 info.firstInstallTime = firstInstallTime; 156 info.lastUpdateTime = lastUpdateTime; 157 if (state.getArchiveState() != null) { 158 info.setArchiveTimeMillis(state.getArchiveState().getArchiveTimeMillis()); 159 } 160 if ((flags & PackageManager.GET_GIDS) != 0) { 161 info.gids = gids; 162 } 163 if ((flags & PackageManager.GET_CONFIGURATIONS) != 0) { 164 int size = pkg.getConfigPreferences().size(); 165 if (size > 0) { 166 info.configPreferences = new ConfigurationInfo[size]; 167 pkg.getConfigPreferences().toArray(info.configPreferences); 168 } 169 size = pkg.getRequestedFeatures().size(); 170 if (size > 0) { 171 info.reqFeatures = new FeatureInfo[size]; 172 pkg.getRequestedFeatures().toArray(info.reqFeatures); 173 } 174 size = pkg.getFeatureGroups().size(); 175 if (size > 0) { 176 info.featureGroups = new FeatureGroupInfo[size]; 177 pkg.getFeatureGroups().toArray(info.featureGroups); 178 } 179 } 180 if ((flags & PackageManager.GET_PERMISSIONS) != 0) { 181 int size = ArrayUtils.size(pkg.getPermissions()); 182 if (size > 0) { 183 info.permissions = new PermissionInfo[size]; 184 for (int i = 0; i < size; i++) { 185 final var permission = pkg.getPermissions().get(i); 186 final var permissionInfo = generatePermissionInfo(permission, flags); 187 if (installedPermissions.contains(permission.getName())) { 188 permissionInfo.flags |= PermissionInfo.FLAG_INSTALLED; 189 } 190 info.permissions[i] = permissionInfo; 191 } 192 } 193 final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions(); 194 size = usesPermissions.size(); 195 if (size > 0) { 196 info.requestedPermissions = new String[size]; 197 info.requestedPermissionsFlags = new int[size]; 198 for (int i = 0; i < size; i++) { 199 final ParsedUsesPermission usesPermission = usesPermissions.get(i); 200 info.requestedPermissions[i] = usesPermission.getName(); 201 // The notion of required permissions is deprecated but for compatibility. 202 info.requestedPermissionsFlags[i] |= 203 PackageInfo.REQUESTED_PERMISSION_REQUIRED; 204 if (grantedPermissions != null 205 && grantedPermissions.contains(usesPermission.getName())) { 206 info.requestedPermissionsFlags[i] |= 207 PackageInfo.REQUESTED_PERMISSION_GRANTED; 208 } 209 if ((usesPermission.getUsesPermissionFlags() 210 & ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0) { 211 info.requestedPermissionsFlags[i] |= 212 PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION; 213 } 214 if (pkg.getImplicitPermissions().contains(info.requestedPermissions[i])) { 215 info.requestedPermissionsFlags[i] |= 216 PackageInfo.REQUESTED_PERMISSION_IMPLICIT; 217 } 218 } 219 } 220 } 221 if ((flags & PackageManager.GET_ATTRIBUTIONS_LONG) != 0) { 222 int size = ArrayUtils.size(pkg.getAttributions()); 223 if (size > 0) { 224 info.attributions = new Attribution[size]; 225 for (int i = 0; i < size; i++) { 226 ParsedAttribution parsedAttribution = pkg.getAttributions().get(i); 227 if (parsedAttribution != null) { 228 info.attributions[i] = new Attribution(parsedAttribution.getTag(), 229 parsedAttribution.getLabel()); 230 } 231 } 232 } 233 if (pkg.isAttributionsUserVisible()) { 234 info.applicationInfo.privateFlagsExt 235 |= ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE; 236 } else { 237 info.applicationInfo.privateFlagsExt 238 &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE; 239 } 240 } else { 241 info.applicationInfo.privateFlagsExt 242 &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE; 243 } 244 245 final SigningDetails signingDetails = pkg.getSigningDetails(); 246 info.signatures = getDeprecatedSignatures(signingDetails, flags); 247 248 // replacement for GET_SIGNATURES 249 if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) { 250 if (signingDetails != SigningDetails.UNKNOWN) { 251 // only return a valid SigningInfo if there is signing information to report 252 info.signingInfo = new SigningInfo(signingDetails); 253 } else { 254 info.signingInfo = null; 255 } 256 } 257 258 info.isStub = pkg.isStub(); 259 info.coreApp = pkg.isCoreApp(); 260 info.isApex = pkg.isApex(); 261 262 if (!pkgSetting.hasSharedUser()) { 263 // It is possible that this shared UID app has left 264 info.sharedUserId = null; 265 info.sharedUserLabel = 0; 266 } 267 268 if ((flags & PackageManager.GET_ACTIVITIES) != 0) { 269 final int N = pkg.getActivities().size(); 270 if (N > 0) { 271 // Allow to match activities of quarantined packages. 272 long aflags = flags | PackageManager.MATCH_QUARANTINED_COMPONENTS; 273 274 int num = 0; 275 final ActivityInfo[] res = new ActivityInfo[N]; 276 for (int i = 0; i < N; i++) { 277 final ParsedActivity a = pkg.getActivities().get(i); 278 if (PackageUserStateUtils.isMatch(state, pkgSetting.isSystem(), pkg.isEnabled(), 279 a.isEnabled(), a.isDirectBootAware(), a.getName(), aflags)) { 280 if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals( 281 a.getName())) { 282 continue; 283 } 284 res[num++] = generateActivityInfo(pkg, a, aflags, state, 285 applicationInfo, userId, pkgSetting); 286 } 287 } 288 info.activities = ArrayUtils.trimToSize(res, num); 289 } 290 } 291 if ((flags & PackageManager.GET_RECEIVERS) != 0) { 292 final int size = pkg.getReceivers().size(); 293 if (size > 0) { 294 int num = 0; 295 final ActivityInfo[] res = new ActivityInfo[size]; 296 for (int i = 0; i < size; i++) { 297 final ParsedActivity a = pkg.getReceivers().get(i); 298 if (PackageUserStateUtils.isMatch(state, pkgSetting.isSystem(), pkg.isEnabled(), 299 a.isEnabled(), a.isDirectBootAware(), a.getName(), flags)) { 300 res[num++] = generateActivityInfo(pkg, a, flags, state, applicationInfo, 301 userId, pkgSetting); 302 } 303 } 304 info.receivers = ArrayUtils.trimToSize(res, num); 305 } 306 } 307 if ((flags & PackageManager.GET_SERVICES) != 0) { 308 final int size = pkg.getServices().size(); 309 if (size > 0) { 310 int num = 0; 311 final ServiceInfo[] res = new ServiceInfo[size]; 312 for (int i = 0; i < size; i++) { 313 final ParsedService s = pkg.getServices().get(i); 314 if (PackageUserStateUtils.isMatch(state, pkgSetting.isSystem(), pkg.isEnabled(), 315 s.isEnabled(), s.isDirectBootAware(), s.getName(), flags)) { 316 res[num++] = generateServiceInfo(pkg, s, flags, state, applicationInfo, 317 userId, pkgSetting); 318 } 319 } 320 info.services = ArrayUtils.trimToSize(res, num); 321 } 322 } 323 if ((flags & PackageManager.GET_PROVIDERS) != 0) { 324 final int size = pkg.getProviders().size(); 325 if (size > 0) { 326 int num = 0; 327 final ProviderInfo[] res = new ProviderInfo[size]; 328 for (int i = 0; i < size; i++) { 329 final ParsedProvider pr = pkg.getProviders() 330 .get(i); 331 if (PackageUserStateUtils.isMatch(state, pkgSetting.isSystem(), pkg.isEnabled(), 332 pr.isEnabled(), pr.isDirectBootAware(), pr.getName(), flags)) { 333 res[num++] = generateProviderInfo(pkg, pr, flags, state, applicationInfo, 334 userId, pkgSetting); 335 } 336 } 337 info.providers = ArrayUtils.trimToSize(res, num); 338 } 339 } 340 if ((flags & PackageManager.GET_INSTRUMENTATION) != 0) { 341 int N = pkg.getInstrumentations().size(); 342 if (N > 0) { 343 info.instrumentation = new InstrumentationInfo[N]; 344 for (int i = 0; i < N; i++) { 345 info.instrumentation[i] = generateInstrumentationInfo( 346 pkg.getInstrumentations().get(i), pkg, flags, state, 347 userId, pkgSetting); 348 } 349 } 350 } 351 352 return info; 353 } 354 355 /** 356 * Retrieve the deprecated {@link PackageInfo.signatures} field of signing certificates 357 */ getDeprecatedSignatures(SigningDetails signingDetails, long flags)358 public static Signature[] getDeprecatedSignatures(SigningDetails signingDetails, long flags) { 359 if ((flags & PackageManager.GET_SIGNATURES) == 0) { 360 return null; 361 } 362 if (signingDetails.hasPastSigningCertificates()) { 363 // Package has included signing certificate rotation information. Return the oldest 364 // cert so that programmatic checks keep working even if unaware of key rotation. 365 Signature[] signatures = new Signature[1]; 366 signatures[0] = signingDetails.getPastSigningCertificates()[0]; 367 return signatures; 368 } else if (signingDetails.hasSignatures()) { 369 // otherwise keep old behavior 370 int numberOfSigs = signingDetails.getSignatures().length; 371 Signature[] signatures = new Signature[numberOfSigs]; 372 System.arraycopy(signingDetails.getSignatures(), 0, signatures, 0, 373 numberOfSigs); 374 return signatures; 375 } 376 return null; 377 } 378 updateApplicationInfo(ApplicationInfo ai, long flags, PackageUserState state)379 private static void updateApplicationInfo(ApplicationInfo ai, long flags, 380 PackageUserState state) { 381 if ((flags & PackageManager.GET_META_DATA) == 0) { 382 ai.metaData = null; 383 } 384 if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) == 0) { 385 ai.sharedLibraryFiles = null; 386 ai.sharedLibraryInfos = null; 387 } 388 389 // CompatibilityMode is global state. 390 if (!ParsingPackageUtils.sCompatibilityModeEnabled) { 391 ai.disableCompatibilityMode(); 392 } 393 394 ai.flags |= flag(state.isStopped(), ApplicationInfo.FLAG_STOPPED) 395 | flag(state.isInstalled(), ApplicationInfo.FLAG_INSTALLED) 396 | flag(state.isSuspended(), ApplicationInfo.FLAG_SUSPENDED); 397 ai.privateFlags |= flag(state.isInstantApp(), ApplicationInfo.PRIVATE_FLAG_INSTANT) 398 | flag(state.isVirtualPreload(), ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD) 399 | flag(state.isHidden(), ApplicationInfo.PRIVATE_FLAG_HIDDEN); 400 if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 401 ai.enabled = true; 402 } else if (state.getEnabledState() 403 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) { 404 ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0; 405 } else if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_DISABLED 406 || state.getEnabledState() 407 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { 408 ai.enabled = false; 409 } 410 ai.enabledSetting = state.getEnabledState(); 411 if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) { 412 ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName); 413 } 414 ai.seInfoUser = SELinuxUtil.getSeinfoUser(state); 415 final OverlayPaths overlayPaths = state.getAllOverlayPaths(); 416 if (overlayPaths != null) { 417 ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]); 418 ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]); 419 } 420 ai.isArchived = PackageArchiver.isArchived(state); 421 if (ai.isArchived) { 422 ai.nonLocalizedLabel = state.getArchiveState().getActivityInfos().get(0).getTitle(); 423 } 424 if (!state.isInstalled() && !state.dataExists() 425 && android.content.pm.Flags.nullableDataDir()) { 426 // The data dir has been deleted 427 ai.dataDir = null; 428 } 429 } 430 431 @Nullable generateDelegateApplicationInfo(@ullable ApplicationInfo ai, @PackageManager.ApplicationInfoFlagsBits long flags, @NonNull PackageUserState state, int userId)432 public static ApplicationInfo generateDelegateApplicationInfo(@Nullable ApplicationInfo ai, 433 @PackageManager.ApplicationInfoFlagsBits long flags, 434 @NonNull PackageUserState state, int userId) { 435 if (ai == null || !checkUseInstalledOrHidden(flags, state, ai)) { 436 return null; 437 } 438 439 ai = new ApplicationInfo(ai); 440 ai.initForUser(userId); 441 ai.icon = (ParsingPackageUtils.sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes 442 : ai.iconRes; 443 updateApplicationInfo(ai, flags, state); 444 return ai; 445 } 446 447 /** 448 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 449 */ 450 @VisibleForTesting 451 @Nullable generateApplicationInfo(AndroidPackage pkg, @PackageManager.ApplicationInfoFlagsBits long flags, @NonNull PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)452 public static ApplicationInfo generateApplicationInfo(AndroidPackage pkg, 453 @PackageManager.ApplicationInfoFlagsBits long flags, 454 @NonNull PackageUserStateInternal state, @UserIdInt int userId, 455 @NonNull PackageStateInternal pkgSetting) { 456 if (pkg == null) { 457 return null; 458 } 459 460 if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags) 461 || !AndroidPackageUtils.isMatchForSystemOnly(pkgSetting, flags)) { 462 return null; 463 } 464 465 // Make shallow copy so we can store the metadata/libraries safely 466 ApplicationInfo info = AndroidPackageUtils.generateAppInfoWithoutState(pkg); 467 468 updateApplicationInfo(info, flags, state); 469 470 initForUser(info, pkg, userId, state); 471 472 // TODO(b/135203078): Remove PackageParser1/toAppInfoWithoutState and clean all this up 473 PackageStateUnserialized pkgState = pkgSetting.getTransientState(); 474 info.hiddenUntilInstalled = pkgState.isHiddenUntilInstalled(); 475 List<String> usesLibraryFiles = pkgState.getUsesLibraryFiles(); 476 var usesLibraries = pkgState.getUsesLibraryInfos(); 477 var usesLibraryInfos = new ArrayList<SharedLibraryInfo>(); 478 for (int index = 0; index < usesLibraries.size(); index++) { 479 usesLibraryInfos.add(usesLibraries.get(index).getInfo()); 480 } 481 info.sharedLibraryFiles = usesLibraryFiles.isEmpty() 482 ? null : usesLibraryFiles.toArray(new String[0]); 483 484 485 if (!Flags.sdkLibIndependence()) { 486 info.sharedLibraryInfos = usesLibraryInfos.isEmpty() ? null : usesLibraryInfos; 487 info.optionalSharedLibraryInfos = null; 488 } else { 489 // sharedLibraryInfos contains all shared libraries that the app depends on (including 490 // the optional sdk libraries) 491 info.sharedLibraryInfos = usesLibraryInfos.isEmpty() ? null : usesLibraryInfos; 492 String[] libsNames = pkgSetting.getUsesSdkLibraries(); 493 boolean[] libsOptional = pkgSetting.getUsesSdkLibrariesOptional(); 494 List<SharedLibraryInfo> optionalSdkLibraries = null; 495 if (!ArrayUtils.isEmpty(libsOptional) && !ArrayUtils.isEmpty(libsNames) 496 && libsNames.length == libsOptional.length) { 497 for (SharedLibraryInfo info1 : usesLibraryInfos) { 498 if (info1.getType() == SharedLibraryInfo.TYPE_SDK_PACKAGE) { 499 int index = ArrayUtils.indexOf(libsNames, info1.getName()); 500 if (index >= 0 && libsOptional[index]) { 501 if (optionalSdkLibraries == null) { 502 optionalSdkLibraries = new ArrayList<>(); 503 } 504 optionalSdkLibraries.add(info1); 505 } 506 } 507 } 508 } 509 info.optionalSharedLibraryInfos = optionalSdkLibraries; 510 } 511 if (info.category == ApplicationInfo.CATEGORY_UNDEFINED) { 512 info.category = pkgSetting.getCategoryOverride(); 513 } 514 515 info.seInfo = pkgSetting.getSeInfo(); 516 info.primaryCpuAbi = pkgSetting.getPrimaryCpuAbi(); 517 info.secondaryCpuAbi = pkgSetting.getSecondaryCpuAbi(); 518 519 info.flags |= appInfoFlags(info.flags, pkgSetting); 520 info.privateFlags |= appInfoPrivateFlags(info.privateFlags, pkgSetting); 521 info.privateFlagsExt |= appInfoPrivateFlagsExt(info.privateFlagsExt, pkgSetting); 522 523 return info; 524 } 525 526 /** 527 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 528 */ 529 @VisibleForTesting 530 @Nullable generateActivityInfo(AndroidPackage pkg, ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)531 public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a, 532 @PackageManager.ComponentInfoFlagsBits long flags, 533 @NonNull PackageUserStateInternal state, @UserIdInt int userId, 534 @NonNull PackageStateInternal pkgSetting) { 535 return generateActivityInfo(pkg, a, flags, state, null, userId, pkgSetting); 536 } 537 538 /** 539 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 540 */ 541 @VisibleForTesting 542 @Nullable generateActivityInfo(AndroidPackage pkg, ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserStateInternal state, @Nullable ApplicationInfo applicationInfo, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)543 public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a, 544 @PackageManager.ComponentInfoFlagsBits long flags, 545 @NonNull PackageUserStateInternal state, @Nullable ApplicationInfo applicationInfo, 546 @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting) { 547 if (a == null) return null; 548 if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { 549 return null; 550 } 551 if (applicationInfo == null) { 552 applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting); 553 } 554 555 if (applicationInfo == null) { 556 return null; 557 } 558 559 // Make shallow copies so we can store the metadata safely 560 ActivityInfo ai = new ActivityInfo(); 561 ai.targetActivity = a.getTargetActivity(); 562 ai.processName = a.getProcessName(); 563 ai.exported = a.isExported(); 564 ai.theme = a.getTheme(); 565 ai.uiOptions = a.getUiOptions(); 566 ai.parentActivityName = a.getParentActivityName(); 567 ai.permission = a.getPermission(); 568 ai.taskAffinity = a.getTaskAffinity(); 569 ai.flags = a.getFlags(); 570 ai.privateFlags = a.getPrivateFlags(); 571 ai.launchMode = a.getLaunchMode(); 572 ai.documentLaunchMode = a.getDocumentLaunchMode(); 573 ai.maxRecents = a.getMaxRecents(); 574 ai.configChanges = a.getConfigChanges(); 575 ai.softInputMode = a.getSoftInputMode(); 576 ai.persistableMode = a.getPersistableMode(); 577 ai.lockTaskLaunchMode = a.getLockTaskLaunchMode(); 578 ai.screenOrientation = a.getScreenOrientation(); 579 ai.resizeMode = a.getResizeMode(); 580 ai.setMaxAspectRatio(a.getMaxAspectRatio()); 581 ai.setMinAspectRatio(a.getMinAspectRatio()); 582 ai.supportsSizeChanges = a.isSupportsSizeChanges(); 583 ai.requestedVrComponent = a.getRequestedVrComponent(); 584 ai.rotationAnimation = a.getRotationAnimation(); 585 ai.colorMode = a.getColorMode(); 586 ai.windowLayout = a.getWindowLayout(); 587 ai.attributionTags = a.getAttributionTags(); 588 if ((flags & PackageManager.GET_META_DATA) != 0) { 589 var metaData = a.getMetaData(); 590 // Backwards compatibility, coerce to null if empty 591 ai.metaData = metaData.isEmpty() ? null : metaData; 592 } else { 593 ai.metaData = null; 594 } 595 ai.applicationInfo = applicationInfo; 596 ai.requiredDisplayCategory = a.getRequiredDisplayCategory(); 597 ai.requireContentUriPermissionFromCaller = a.getRequireContentUriPermissionFromCaller(); 598 ai.setKnownActivityEmbeddingCerts(a.getKnownActivityEmbeddingCerts()); 599 assignFieldsComponentInfoParsedMainComponent(ai, a, pkgSetting, userId); 600 return ai; 601 } 602 603 @Nullable generateDelegateActivityInfo(@ullable ActivityInfo a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserState state, int userId)604 public static ActivityInfo generateDelegateActivityInfo(@Nullable ActivityInfo a, 605 @PackageManager.ComponentInfoFlagsBits long flags, 606 @NonNull PackageUserState state, int userId) { 607 if (a == null || !checkUseInstalledOrHidden(flags, state, a.applicationInfo)) { 608 return null; 609 } 610 // This is used to return the ResolverActivity or instantAppInstallerActivity; 611 // we will just always make a copy. 612 final ActivityInfo ai = new ActivityInfo(a); 613 ai.applicationInfo = 614 generateDelegateApplicationInfo(ai.applicationInfo, flags, state, userId); 615 return ai; 616 } 617 618 /** 619 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 620 */ 621 @Nullable generateServiceInfo(AndroidPackage pkg, ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)622 public static ServiceInfo generateServiceInfo(AndroidPackage pkg, ParsedService s, 623 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, 624 @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting) { 625 return generateServiceInfo(pkg, s, flags, state, null, userId, pkgSetting); 626 } 627 628 /** 629 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 630 */ 631 @VisibleForTesting 632 @Nullable generateServiceInfo(AndroidPackage pkg, ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, @Nullable ApplicationInfo applicationInfo, int userId, @NonNull PackageStateInternal pkgSetting)633 public static ServiceInfo generateServiceInfo(AndroidPackage pkg, ParsedService s, 634 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, 635 @Nullable ApplicationInfo applicationInfo, int userId, 636 @NonNull PackageStateInternal pkgSetting) { 637 if (s == null) return null; 638 if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { 639 return null; 640 } 641 if (applicationInfo == null) { 642 applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting); 643 } 644 if (applicationInfo == null) { 645 return null; 646 } 647 648 649 // Make shallow copies so we can store the metadata safely 650 ServiceInfo si = new ServiceInfo(); 651 si.exported = s.isExported(); 652 si.flags = s.getFlags(); 653 si.permission = s.getPermission(); 654 si.processName = s.getProcessName(); 655 si.mForegroundServiceType = s.getForegroundServiceType(); 656 si.applicationInfo = applicationInfo; 657 if ((flags & PackageManager.GET_META_DATA) != 0) { 658 var metaData = s.getMetaData(); 659 // Backwards compatibility, coerce to null if empty 660 si.metaData = metaData.isEmpty() ? null : metaData; 661 } 662 assignFieldsComponentInfoParsedMainComponent(si, s, pkgSetting, userId); 663 return si; 664 } 665 666 /** 667 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 668 */ 669 @VisibleForTesting 670 @Nullable generateProviderInfo(AndroidPackage pkg, ParsedProvider p, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, @NonNull ApplicationInfo applicationInfo, int userId, @NonNull PackageStateInternal pkgSetting)671 public static ProviderInfo generateProviderInfo(AndroidPackage pkg, ParsedProvider p, 672 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, 673 @NonNull ApplicationInfo applicationInfo, int userId, 674 @NonNull PackageStateInternal pkgSetting) { 675 if (p == null) return null; 676 if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { 677 return null; 678 } 679 if (applicationInfo == null || !pkg.getPackageName().equals(applicationInfo.packageName)) { 680 Slog.wtf(TAG, "AppInfo's package name is different. Expected=" + pkg.getPackageName() 681 + " actual=" + (applicationInfo == null ? "(null AppInfo)" 682 : applicationInfo.packageName)); 683 applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting); 684 } 685 if (applicationInfo == null) { 686 return null; 687 } 688 689 // Make shallow copies so we can store the metadata safely 690 ProviderInfo pi = new ProviderInfo(); 691 pi.exported = p.isExported(); 692 pi.flags = p.getFlags(); 693 pi.processName = p.getProcessName(); 694 pi.authority = p.getAuthority(); 695 pi.isSyncable = p.isSyncable(); 696 pi.readPermission = p.getReadPermission(); 697 pi.writePermission = p.getWritePermission(); 698 pi.grantUriPermissions = p.isGrantUriPermissions(); 699 pi.forceUriPermissions = p.isForceUriPermissions(); 700 pi.multiprocess = p.isMultiProcess(); 701 pi.initOrder = p.getInitOrder(); 702 pi.uriPermissionPatterns = p.getUriPermissionPatterns().toArray(new PatternMatcher[0]); 703 pi.pathPermissions = p.getPathPermissions().toArray(new PathPermission[0]); 704 if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) { 705 pi.uriPermissionPatterns = null; 706 } 707 if ((flags & PackageManager.GET_META_DATA) != 0) { 708 var metaData = p.getMetaData(); 709 // Backwards compatibility, coerce to null if empty 710 pi.metaData = metaData.isEmpty() ? null : metaData; 711 } 712 pi.applicationInfo = applicationInfo; 713 assignFieldsComponentInfoParsedMainComponent(pi, p, pkgSetting, userId); 714 return pi; 715 } 716 717 /** 718 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 719 */ 720 @Nullable generateInstrumentationInfo(ParsedInstrumentation i, AndroidPackage pkg, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, int userId, @NonNull PackageStateInternal pkgSetting)721 public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i, 722 AndroidPackage pkg, @PackageManager.ComponentInfoFlagsBits long flags, 723 PackageUserStateInternal state, int userId, @NonNull PackageStateInternal pkgSetting) { 724 if (i == null) return null; 725 if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { 726 return null; 727 } 728 729 InstrumentationInfo info = new InstrumentationInfo(); 730 info.targetPackage = i.getTargetPackage(); 731 info.targetProcesses = i.getTargetProcesses(); 732 info.handleProfiling = i.isHandleProfiling(); 733 info.functionalTest = i.isFunctionalTest(); 734 735 info.sourceDir = pkg.getBaseApkPath(); 736 info.publicSourceDir = pkg.getBaseApkPath(); 737 info.splitNames = pkg.getSplitNames(); 738 info.splitSourceDirs = pkg.getSplitCodePaths().length == 0 ? null : pkg.getSplitCodePaths(); 739 info.splitPublicSourceDirs = pkg.getSplitCodePaths().length == 0 740 ? null : pkg.getSplitCodePaths(); 741 info.splitDependencies = pkg.getSplitDependencies().size() == 0 742 ? null : pkg.getSplitDependencies(); 743 744 initForUser(info, pkg, userId, state); 745 746 info.primaryCpuAbi = pkgSetting.getPrimaryCpuAbi(); 747 info.secondaryCpuAbi = pkgSetting.getSecondaryCpuAbi(); 748 info.nativeLibraryDir = pkg.getNativeLibraryDir(); 749 info.secondaryNativeLibraryDir = pkg.getSecondaryNativeLibraryDir(); 750 751 assignFieldsPackageItemInfoParsedComponent(info, i, pkgSetting, userId); 752 753 if ((flags & PackageManager.GET_META_DATA) == 0) { 754 info.metaData = null; 755 } else { 756 var metaData = i.getMetaData(); 757 // Backwards compatibility, coerce to null if empty 758 info.metaData = metaData.isEmpty() ? null : metaData; 759 } 760 761 return info; 762 } 763 764 // TODO(b/135203078): Determine if permission methods need to pass in a non-null 765 // PackageStateInternal os that checkUseInstalledOrHidden filter can apply 766 @Nullable generatePermissionInfo(ParsedPermission p, @PackageManager.ComponentInfoFlagsBits long flags)767 public static PermissionInfo generatePermissionInfo(ParsedPermission p, 768 @PackageManager.ComponentInfoFlagsBits long flags) { 769 // TODO(b/135203078): Remove null checks and make all usages @NonNull 770 if (p == null) return null; 771 772 PermissionInfo pi = new PermissionInfo(p.getBackgroundPermission()); 773 774 assignFieldsPackageItemInfoParsedComponent(pi, p); 775 776 pi.group = p.getGroup(); 777 pi.requestRes = p.getRequestRes(); 778 pi.protectionLevel = p.getProtectionLevel(); 779 pi.descriptionRes = p.getDescriptionRes(); 780 pi.flags = p.getFlags(); 781 pi.knownCerts = p.getKnownCerts(); 782 783 if ((flags & PackageManager.GET_META_DATA) == 0) { 784 pi.metaData = null; 785 } else { 786 var metaData = p.getMetaData(); 787 // Backwards compatibility, coerce to null if empty 788 pi.metaData = metaData.isEmpty() ? null : metaData; 789 } 790 return pi; 791 } 792 793 @Nullable generatePermissionGroupInfo(ParsedPermissionGroup pg, @PackageManager.ComponentInfoFlagsBits long flags)794 public static PermissionGroupInfo generatePermissionGroupInfo(ParsedPermissionGroup pg, 795 @PackageManager.ComponentInfoFlagsBits long flags) { 796 if (pg == null) return null; 797 798 PermissionGroupInfo pgi = new PermissionGroupInfo( 799 pg.getRequestDetailRes(), 800 pg.getBackgroundRequestRes(), 801 pg.getBackgroundRequestDetailRes() 802 ); 803 804 assignFieldsPackageItemInfoParsedComponent(pgi, pg); 805 pgi.descriptionRes = pg.getDescriptionRes(); 806 pgi.priority = pg.getPriority(); 807 pgi.requestRes = pg.getRequestRes(); 808 pgi.flags = pg.getFlags(); 809 810 if ((flags & PackageManager.GET_META_DATA) == 0) { 811 pgi.metaData = null; 812 } else { 813 var metaData = pg.getMetaData(); 814 // Backwards compatibility, coerce to null if empty 815 pgi.metaData = metaData.isEmpty() ? null : metaData; 816 } 817 818 return pgi; 819 } 820 821 @Nullable generateProcessInfo( Map<String, ParsedProcess> procs, @PackageManager.ComponentInfoFlagsBits long flags)822 public static ArrayMap<String, ProcessInfo> generateProcessInfo( 823 Map<String, ParsedProcess> procs, @PackageManager.ComponentInfoFlagsBits long flags) { 824 if (procs == null) { 825 return null; 826 } 827 828 final int numProcs = procs.size(); 829 ArrayMap<String, ProcessInfo> retProcs = new ArrayMap<>(numProcs); 830 for (String key : procs.keySet()) { 831 ParsedProcess proc = procs.get(key); 832 retProcs.put(proc.getName(), 833 new ProcessInfo(proc.getName(), new ArraySet<>(proc.getDeniedPermissions()), 834 proc.getGwpAsanMode(), proc.getMemtagMode(), 835 proc.getNativeHeapZeroInitialized(), proc.isUseEmbeddedDex())); 836 } 837 return retProcs; 838 } 839 840 /** 841 * Returns true if the package is installed and not hidden, or if the caller explicitly wanted 842 * all uninstalled and hidden packages as well. 843 */ checkUseInstalledOrHidden(AndroidPackage pkg, @NonNull PackageStateInternal pkgSetting, PackageUserStateInternal state, @PackageManager.PackageInfoFlagsBits long flags)844 public static boolean checkUseInstalledOrHidden(AndroidPackage pkg, 845 @NonNull PackageStateInternal pkgSetting, PackageUserStateInternal state, 846 @PackageManager.PackageInfoFlagsBits long flags) { 847 // Returns false if the package is hidden system app until installed. 848 if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0 849 && !state.isInstalled() 850 && pkgSetting.getTransientState().isHiddenUntilInstalled()) { 851 return false; 852 } 853 854 // If available for the target user, or trying to match uninstalled packages and it's 855 // a system app. 856 return PackageUserStateUtils.isAvailable(state, flags) 857 || (pkgSetting.isSystem() && matchUninstalledOrHidden(flags)); 858 } 859 checkUseInstalledOrHidden(long flags, @NonNull PackageUserState state, @Nullable ApplicationInfo appInfo)860 private static boolean checkUseInstalledOrHidden(long flags, 861 @NonNull PackageUserState state, @Nullable ApplicationInfo appInfo) { 862 // Returns false if the package is hidden system app until installed. 863 if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0 864 && !state.isInstalled() 865 && appInfo != null && appInfo.hiddenUntilInstalled) { 866 return false; 867 } 868 869 // If available for the target user, or trying to match uninstalled packages and it's 870 // a system app. 871 return PackageUserStateUtils.isAvailable(state, flags) 872 || (appInfo != null && appInfo.isSystemApp() && matchUninstalledOrHidden(flags)); 873 } 874 matchUninstalledOrHidden(long flags)875 private static boolean matchUninstalledOrHidden(long flags) { 876 return (flags 877 & (PackageManager.MATCH_KNOWN_PACKAGES 878 | PackageManager.MATCH_ARCHIVED_PACKAGES 879 | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS)) 880 != 0; 881 } 882 assignFieldsComponentInfoParsedMainComponent( @onNull ComponentInfo info, @NonNull ParsedMainComponent component)883 private static void assignFieldsComponentInfoParsedMainComponent( 884 @NonNull ComponentInfo info, @NonNull ParsedMainComponent component) { 885 assignFieldsPackageItemInfoParsedComponent(info, component); 886 info.descriptionRes = component.getDescriptionRes(); 887 info.directBootAware = component.isDirectBootAware(); 888 info.enabled = component.isEnabled(); 889 info.splitName = component.getSplitName(); 890 info.attributionTags = component.getAttributionTags(); 891 } 892 assignFieldsPackageItemInfoParsedComponent( @onNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component)893 private static void assignFieldsPackageItemInfoParsedComponent( 894 @NonNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component) { 895 packageItemInfo.nonLocalizedLabel = ComponentParseUtils.getNonLocalizedLabel(component); 896 packageItemInfo.icon = ComponentParseUtils.getIcon(component); 897 packageItemInfo.banner = component.getBanner(); 898 packageItemInfo.labelRes = component.getLabelRes(); 899 packageItemInfo.logo = component.getLogo(); 900 packageItemInfo.name = component.getName(); 901 packageItemInfo.packageName = component.getPackageName(); 902 } 903 assignFieldsComponentInfoParsedMainComponent( @onNull ComponentInfo info, @NonNull ParsedMainComponent component, @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId)904 private static void assignFieldsComponentInfoParsedMainComponent( 905 @NonNull ComponentInfo info, @NonNull ParsedMainComponent component, 906 @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId) { 907 assignFieldsComponentInfoParsedMainComponent(info, component); 908 Pair<CharSequence, Integer> labelAndIcon = 909 ParsedComponentStateUtils.getNonLocalizedLabelAndIcon(component, pkgSetting, 910 userId); 911 info.nonLocalizedLabel = labelAndIcon.first; 912 info.icon = labelAndIcon.second; 913 } 914 assignFieldsPackageItemInfoParsedComponent( @onNull PackageItemInfo info, @NonNull ParsedComponent component, @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId)915 private static void assignFieldsPackageItemInfoParsedComponent( 916 @NonNull PackageItemInfo info, @NonNull ParsedComponent component, 917 @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId) { 918 assignFieldsPackageItemInfoParsedComponent(info, component); 919 Pair<CharSequence, Integer> labelAndIcon = 920 ParsedComponentStateUtils.getNonLocalizedLabelAndIcon(component, pkgSetting, 921 userId); 922 info.nonLocalizedLabel = labelAndIcon.first; 923 info.icon = labelAndIcon.second; 924 } 925 926 @CheckResult flag(boolean hasFlag, int flag)927 private static int flag(boolean hasFlag, int flag) { 928 return hasFlag ? flag : 0; 929 } 930 931 /** 932 * @see ApplicationInfo#flags 933 */ appInfoFlags(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting)934 public static int appInfoFlags(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting) { 935 // @formatter:off 936 int pkgWithoutStateFlags = flag(pkg.isExternalStorage(), ApplicationInfo.FLAG_EXTERNAL_STORAGE) 937 | flag(pkg.isHardwareAccelerated(), ApplicationInfo.FLAG_HARDWARE_ACCELERATED) 938 | flag(pkg.isBackupAllowed(), ApplicationInfo.FLAG_ALLOW_BACKUP) 939 | flag(pkg.isKillAfterRestoreAllowed(), ApplicationInfo.FLAG_KILL_AFTER_RESTORE) 940 | flag(pkg.isRestoreAnyVersion(), ApplicationInfo.FLAG_RESTORE_ANY_VERSION) 941 | flag(pkg.isFullBackupOnly(), ApplicationInfo.FLAG_FULL_BACKUP_ONLY) 942 | flag(pkg.isPersistent(), ApplicationInfo.FLAG_PERSISTENT) 943 | flag(pkg.isDebuggable(), ApplicationInfo.FLAG_DEBUGGABLE) 944 | flag(pkg.isVmSafeMode(), ApplicationInfo.FLAG_VM_SAFE_MODE) 945 | flag(pkg.isDeclaredHavingCode(), ApplicationInfo.FLAG_HAS_CODE) 946 | flag(pkg.isTaskReparentingAllowed(), ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING) 947 | flag(pkg.isClearUserDataAllowed(), ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) 948 | flag(pkg.isLargeHeap(), ApplicationInfo.FLAG_LARGE_HEAP) 949 | flag(pkg.isCleartextTrafficAllowed(), ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) 950 | flag(pkg.isRtlSupported(), ApplicationInfo.FLAG_SUPPORTS_RTL) 951 | flag(pkg.isTestOnly(), ApplicationInfo.FLAG_TEST_ONLY) 952 | flag(pkg.isMultiArch(), ApplicationInfo.FLAG_MULTIARCH) 953 | flag(pkg.isExtractNativeLibrariesRequested(), ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) 954 | flag(pkg.isGame(), ApplicationInfo.FLAG_IS_GAME) 955 | flag(pkg.isSmallScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) 956 | flag(pkg.isNormalScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) 957 | flag(pkg.isLargeScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) 958 | flag(pkg.isExtraLargeScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) 959 | flag(pkg.isResizeable(), ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) 960 | flag(pkg.isAnyDensity(), ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 961 | flag(AndroidPackageLegacyUtils.isSystem(pkg), ApplicationInfo.FLAG_SYSTEM) 962 | flag(pkg.isFactoryTest(), ApplicationInfo.FLAG_FACTORY_TEST); 963 964 return appInfoFlags(pkgWithoutStateFlags, pkgSetting); 965 // @formatter:on 966 } 967 968 /** @see ApplicationInfo#flags */ appInfoFlags(int pkgWithoutStateFlags, @NonNull PackageStateInternal pkgSetting)969 public static int appInfoFlags(int pkgWithoutStateFlags, 970 @NonNull PackageStateInternal pkgSetting) { 971 // @formatter:off 972 int flags = pkgWithoutStateFlags; 973 if (pkgSetting != null) { 974 flags |= flag(pkgSetting.isUpdatedSystemApp(), ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 975 } 976 return flags; 977 // @formatter:on 978 } 979 980 /** @see ApplicationInfo#privateFlags */ appInfoPrivateFlags(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting)981 public static int appInfoPrivateFlags(AndroidPackage pkg, 982 @Nullable PackageStateInternal pkgSetting) { 983 // @formatter:off 984 int pkgWithoutStateFlags = flag(pkg.isStaticSharedLibrary(), ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY) 985 | flag(pkg.isResourceOverlay(), ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY) 986 | flag(pkg.isIsolatedSplitLoading(), ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING) 987 | flag(pkg.isHasDomainUrls(), ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) 988 | flag(pkg.isProfileableByShell(), ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) 989 | flag(pkg.isBackupInForeground(), ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND) 990 | flag(pkg.isUseEmbeddedDex(), ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX) 991 | flag(pkg.isDefaultToDeviceProtectedStorage(), ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) 992 | flag(pkg.isDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE) 993 | flag(pkg.isPartiallyDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE) 994 | flag(pkg.isClearUserDataOnFailedRestoreAllowed(), ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE) 995 | flag(pkg.isAllowAudioPlaybackCapture(), ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE) 996 | flag(pkg.isRequestLegacyExternalStorage(), ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE) 997 | flag(pkg.isNonSdkApiRequested(), ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API) 998 | flag(pkg.isUserDataFragile(), ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA) 999 | flag(pkg.isSaveStateDisallowed(), ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) 1000 | flag(pkg.isResizeableActivityViaSdkVersion(), ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) 1001 | flag(pkg.isAllowNativeHeapPointerTagging(), ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING) 1002 | flag(AndroidPackageLegacyUtils.isSystemExt(pkg), ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) 1003 | flag(AndroidPackageLegacyUtils.isPrivileged(pkg), ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 1004 | flag(AndroidPackageLegacyUtils.isOem(pkg), ApplicationInfo.PRIVATE_FLAG_OEM) 1005 | flag(AndroidPackageLegacyUtils.isVendor(pkg), ApplicationInfo.PRIVATE_FLAG_VENDOR) 1006 | flag(AndroidPackageLegacyUtils.isProduct(pkg), ApplicationInfo.PRIVATE_FLAG_PRODUCT) 1007 | flag(AndroidPackageLegacyUtils.isOdm(pkg), ApplicationInfo.PRIVATE_FLAG_ODM) 1008 | flag(pkg.isSignedWithPlatformKey(), ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY); 1009 1010 Boolean resizeableActivity = pkg.getResizeableActivity(); 1011 if (resizeableActivity != null) { 1012 if (resizeableActivity) { 1013 pkgWithoutStateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE; 1014 } else { 1015 pkgWithoutStateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE; 1016 } 1017 } 1018 1019 return appInfoPrivateFlags(pkgWithoutStateFlags, pkgSetting); 1020 // @formatter:on 1021 } 1022 1023 /** @see ApplicationInfo#privateFlags */ appInfoPrivateFlags(int pkgWithoutStateFlags, @Nullable PackageStateInternal pkgSetting)1024 public static int appInfoPrivateFlags(int pkgWithoutStateFlags, 1025 @Nullable PackageStateInternal pkgSetting) { 1026 // @formatter:off 1027 // TODO: Add state specific flags 1028 return pkgWithoutStateFlags; 1029 // @formatter:on 1030 } 1031 1032 /** @see ApplicationInfo#privateFlagsExt */ appInfoPrivateFlagsExt(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting)1033 public static int appInfoPrivateFlagsExt(AndroidPackage pkg, 1034 @Nullable PackageStateInternal pkgSetting) { 1035 var isAllowlistedForHiddenApis = SystemConfig.getInstance().getHiddenApiWhitelistedApps() 1036 .contains(pkg.getPackageName()); 1037 // @formatter:off 1038 int pkgWithoutStateFlags = flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE) 1039 | flag(pkg.hasRequestForegroundServiceExemption(), ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION) 1040 | flag(pkg.isAttributionsUserVisible(), ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE) 1041 | flag(pkg.isOnBackInvokedCallbackEnabled(), ApplicationInfo.PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK) 1042 | flag(isAllowlistedForHiddenApis, ApplicationInfo.PRIVATE_FLAG_EXT_ALLOWLISTED_FOR_HIDDEN_APIS); 1043 return appInfoPrivateFlagsExt(pkgWithoutStateFlags, pkgSetting); 1044 // @formatter:on 1045 } 1046 1047 /** @see ApplicationInfo#privateFlagsExt */ appInfoPrivateFlagsExt(int pkgWithoutStateFlags, @Nullable PackageStateInternal pkgSetting)1048 private static int appInfoPrivateFlagsExt(int pkgWithoutStateFlags, 1049 @Nullable PackageStateInternal pkgSetting) { 1050 // @formatter:off 1051 int flags = pkgWithoutStateFlags; 1052 if (pkgSetting != null) { 1053 flags |= flag(pkgSetting.getCpuAbiOverride() != null, ApplicationInfo.PRIVATE_FLAG_EXT_CPU_OVERRIDE); 1054 } 1055 return flags; 1056 // @formatter:on 1057 } 1058 initForUser(ApplicationInfo output, AndroidPackage input, @UserIdInt int userId, PackageUserStateInternal state)1059 private static void initForUser(ApplicationInfo output, AndroidPackage input, 1060 @UserIdInt int userId, PackageUserStateInternal state) { 1061 PackageImpl pkg = ((PackageImpl) input); 1062 String packageName = input.getPackageName(); 1063 output.uid = UserHandle.getUid(userId, UserHandle.getAppId(input.getUid())); 1064 1065 if ("android".equals(packageName)) { 1066 output.dataDir = SYSTEM_DATA_PATH; 1067 return; 1068 } 1069 1070 if (!state.isInstalled() && !state.dataExists() 1071 && android.content.pm.Flags.nullableDataDir()) { 1072 // The data dir has been deleted 1073 output.dataDir = null; 1074 return; 1075 } 1076 1077 // For performance reasons, all these paths are built as strings 1078 if (userId == UserHandle.USER_SYSTEM) { 1079 output.credentialProtectedDataDir = 1080 pkg.getBaseAppDataCredentialProtectedDirForSystemUser() + packageName; 1081 output.deviceProtectedDataDir = 1082 pkg.getBaseAppDataDeviceProtectedDirForSystemUser() + packageName; 1083 } else { 1084 // Convert /data/user/0/ -> /data/user/1/com.example.app 1085 String userIdString = String.valueOf(userId); 1086 int credentialLength = pkg.getBaseAppDataCredentialProtectedDirForSystemUser().length(); 1087 output.credentialProtectedDataDir = 1088 new StringBuilder(pkg.getBaseAppDataCredentialProtectedDirForSystemUser()) 1089 .replace(credentialLength - 2, credentialLength - 1, userIdString) 1090 .append(packageName) 1091 .toString(); 1092 int deviceLength = pkg.getBaseAppDataDeviceProtectedDirForSystemUser().length(); 1093 output.deviceProtectedDataDir = 1094 new StringBuilder(pkg.getBaseAppDataDeviceProtectedDirForSystemUser()) 1095 .replace(deviceLength - 2, deviceLength - 1, userIdString) 1096 .append(packageName) 1097 .toString(); 1098 } 1099 1100 if (input.isDefaultToDeviceProtectedStorage() 1101 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 1102 output.dataDir = output.deviceProtectedDataDir; 1103 } else { 1104 output.dataDir = output.credentialProtectedDataDir; 1105 } 1106 } 1107 1108 // This duplicates the ApplicationInfo variant because it uses field assignment and the classes 1109 // don't inherit from each other, unfortunately. Consolidating logic would introduce overhead. initForUser(InstrumentationInfo output, AndroidPackage input, @UserIdInt int userId, PackageUserStateInternal state)1110 private static void initForUser(InstrumentationInfo output, AndroidPackage input, 1111 @UserIdInt int userId, PackageUserStateInternal state) { 1112 PackageImpl pkg = ((PackageImpl) input); 1113 String packageName = input.getPackageName(); 1114 if ("android".equals(packageName)) { 1115 output.dataDir = SYSTEM_DATA_PATH; 1116 return; 1117 } 1118 1119 if (!state.isInstalled() && !state.dataExists() 1120 && android.content.pm.Flags.nullableDataDir()) { 1121 // The data dir has been deleted 1122 output.dataDir = null; 1123 return; 1124 } 1125 1126 // For performance reasons, all these paths are built as strings 1127 if (userId == UserHandle.USER_SYSTEM) { 1128 output.credentialProtectedDataDir = 1129 pkg.getBaseAppDataCredentialProtectedDirForSystemUser() + packageName; 1130 output.deviceProtectedDataDir = 1131 pkg.getBaseAppDataDeviceProtectedDirForSystemUser() + packageName; 1132 } else { 1133 // Convert /data/user/0/ -> /data/user/1/com.example.app 1134 String userIdString = String.valueOf(userId); 1135 int credentialLength = pkg.getBaseAppDataCredentialProtectedDirForSystemUser().length(); 1136 output.credentialProtectedDataDir = 1137 new StringBuilder(pkg.getBaseAppDataCredentialProtectedDirForSystemUser()) 1138 .replace(credentialLength - 2, credentialLength - 1, userIdString) 1139 .append(packageName) 1140 .toString(); 1141 int deviceLength = pkg.getBaseAppDataDeviceProtectedDirForSystemUser().length(); 1142 output.deviceProtectedDataDir = 1143 new StringBuilder(pkg.getBaseAppDataDeviceProtectedDirForSystemUser()) 1144 .replace(deviceLength - 2, deviceLength - 1, userIdString) 1145 .append(packageName) 1146 .toString(); 1147 } 1148 1149 if (input.isDefaultToDeviceProtectedStorage() 1150 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 1151 output.dataDir = output.deviceProtectedDataDir; 1152 } else { 1153 output.dataDir = output.credentialProtectedDataDir; 1154 } 1155 } 1156 1157 /** 1158 * Returns the data dir of the app for the target user. Return null if the app isn't installed 1159 * on the target user and doesn't have a data dir on the target user. 1160 */ 1161 @Nullable getDataDir(PackageStateInternal ps, int userId)1162 public static File getDataDir(PackageStateInternal ps, int userId) { 1163 if ("android".equals(ps.getPackageName())) { 1164 return Environment.getDataSystemDirectory(); 1165 } 1166 1167 if (!ps.getUserStateOrDefault(userId).isInstalled() 1168 && !ps.getUserStateOrDefault(userId).dataExists() 1169 && android.content.pm.Flags.nullableDataDir()) { 1170 // The app has been uninstalled for the user and the data dir has been deleted 1171 return null; 1172 } 1173 1174 if (ps.isDefaultToDeviceProtectedStorage() 1175 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 1176 return Environment.getDataUserDePackageDirectory(ps.getVolumeUuid(), userId, 1177 ps.getPackageName()); 1178 } else { 1179 return Environment.getDataUserCePackageDirectory(ps.getVolumeUuid(), userId, 1180 ps.getPackageName()); 1181 } 1182 } 1183 1184 /** 1185 * Wraps {@link PackageInfoUtils#generateApplicationInfo} with a cache. 1186 */ 1187 public static class CachedApplicationInfoGenerator { 1188 // Map from a package name to the corresponding app info. 1189 private final ArrayMap<String, ApplicationInfo> mCache = new ArrayMap<>(); 1190 1191 /** 1192 * {@link PackageInfoUtils#generateApplicationInfo} with a cache. 1193 */ 1194 @Nullable generate(AndroidPackage pkg, @PackageManager.ApplicationInfoFlagsBits long flags, PackageUserStateInternal state, int userId, @NonNull PackageStateInternal pkgSetting)1195 public ApplicationInfo generate(AndroidPackage pkg, 1196 @PackageManager.ApplicationInfoFlagsBits long flags, PackageUserStateInternal state, 1197 int userId, @NonNull PackageStateInternal pkgSetting) { 1198 ApplicationInfo appInfo = mCache.get(pkg.getPackageName()); 1199 if (appInfo != null) { 1200 return appInfo; 1201 } 1202 appInfo = PackageInfoUtils.generateApplicationInfo( 1203 pkg, flags, state, userId, pkgSetting); 1204 mCache.put(pkg.getPackageName(), appInfo); 1205 return appInfo; 1206 } 1207 } 1208 } 1209