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 ai.privateFlagsExt |= 401 flag(state.isNotLaunched(), ApplicationInfo.PRIVATE_FLAG_EXT_NOT_LAUNCHED); 402 if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 403 ai.enabled = true; 404 } else if (state.getEnabledState() 405 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) { 406 ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0; 407 } else if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_DISABLED 408 || state.getEnabledState() 409 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { 410 ai.enabled = false; 411 } 412 ai.enabledSetting = state.getEnabledState(); 413 if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) { 414 ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName); 415 } 416 ai.seInfoUser = SELinuxUtil.getSeinfoUser(state); 417 final OverlayPaths overlayPaths = state.getAllOverlayPaths(); 418 if (overlayPaths != null) { 419 ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]); 420 ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]); 421 } 422 ai.isArchived = PackageArchiver.isArchived(state); 423 if (ai.isArchived) { 424 ai.nonLocalizedLabel = state.getArchiveState().getActivityInfos().get(0).getTitle(); 425 } 426 if (!state.isInstalled() && !state.dataExists() 427 && android.content.pm.Flags.nullableDataDir()) { 428 // The data dir has been deleted 429 ai.dataDir = null; 430 } 431 } 432 433 @Nullable generateDelegateApplicationInfo(@ullable ApplicationInfo ai, @PackageManager.ApplicationInfoFlagsBits long flags, @NonNull PackageUserState state, int userId)434 public static ApplicationInfo generateDelegateApplicationInfo(@Nullable ApplicationInfo ai, 435 @PackageManager.ApplicationInfoFlagsBits long flags, 436 @NonNull PackageUserState state, int userId) { 437 if (ai == null || !checkUseInstalledOrHidden(flags, state, ai)) { 438 return null; 439 } 440 441 ai = new ApplicationInfo(ai); 442 ai.initForUser(userId); 443 ai.icon = (ParsingPackageUtils.sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes 444 : ai.iconRes; 445 updateApplicationInfo(ai, flags, state); 446 return ai; 447 } 448 449 /** 450 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 451 */ 452 @VisibleForTesting 453 @Nullable generateApplicationInfo(AndroidPackage pkg, @PackageManager.ApplicationInfoFlagsBits long flags, @NonNull PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)454 public static ApplicationInfo generateApplicationInfo(AndroidPackage pkg, 455 @PackageManager.ApplicationInfoFlagsBits long flags, 456 @NonNull PackageUserStateInternal state, @UserIdInt int userId, 457 @NonNull PackageStateInternal pkgSetting) { 458 if (pkg == null) { 459 return null; 460 } 461 462 if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags) 463 || !AndroidPackageUtils.isMatchForSystemOnly(pkgSetting, flags)) { 464 return null; 465 } 466 467 // Make shallow copy so we can store the metadata/libraries safely 468 ApplicationInfo info = AndroidPackageUtils.generateAppInfoWithoutState(pkg); 469 470 updateApplicationInfo(info, flags, state); 471 472 initForUser(info, pkg, userId, state); 473 474 // TODO(b/135203078): Remove PackageParser1/toAppInfoWithoutState and clean all this up 475 PackageStateUnserialized pkgState = pkgSetting.getTransientState(); 476 info.hiddenUntilInstalled = pkgState.isHiddenUntilInstalled(); 477 List<String> usesLibraryFiles = pkgState.getUsesLibraryFiles(); 478 var usesLibraries = pkgState.getUsesLibraryInfos(); 479 var usesLibraryInfos = new ArrayList<SharedLibraryInfo>(); 480 for (int index = 0; index < usesLibraries.size(); index++) { 481 usesLibraryInfos.add(usesLibraries.get(index).getInfo()); 482 } 483 info.sharedLibraryFiles = usesLibraryFiles.isEmpty() 484 ? null : usesLibraryFiles.toArray(new String[0]); 485 486 487 if (!Flags.sdkLibIndependence()) { 488 info.sharedLibraryInfos = usesLibraryInfos.isEmpty() ? null : usesLibraryInfos; 489 info.optionalSharedLibraryInfos = null; 490 } else { 491 // sharedLibraryInfos contains all shared libraries that the app depends on (including 492 // the optional sdk libraries) 493 info.sharedLibraryInfos = usesLibraryInfos.isEmpty() ? null : usesLibraryInfos; 494 String[] libsNames = pkgSetting.getUsesSdkLibraries(); 495 boolean[] libsOptional = pkgSetting.getUsesSdkLibrariesOptional(); 496 List<SharedLibraryInfo> optionalSdkLibraries = null; 497 if (!ArrayUtils.isEmpty(libsOptional) && !ArrayUtils.isEmpty(libsNames) 498 && libsNames.length == libsOptional.length) { 499 for (SharedLibraryInfo info1 : usesLibraryInfos) { 500 if (info1.getType() == SharedLibraryInfo.TYPE_SDK_PACKAGE) { 501 int index = ArrayUtils.indexOf(libsNames, info1.getName()); 502 if (index >= 0 && libsOptional[index]) { 503 if (optionalSdkLibraries == null) { 504 optionalSdkLibraries = new ArrayList<>(); 505 } 506 optionalSdkLibraries.add(info1); 507 } 508 } 509 } 510 } 511 info.optionalSharedLibraryInfos = optionalSdkLibraries; 512 } 513 if (info.category == ApplicationInfo.CATEGORY_UNDEFINED) { 514 info.category = pkgSetting.getCategoryOverride(); 515 } 516 517 info.seInfo = pkgSetting.getSeInfo(); 518 info.primaryCpuAbi = pkgSetting.getPrimaryCpuAbi(); 519 info.secondaryCpuAbi = pkgSetting.getSecondaryCpuAbi(); 520 521 info.flags |= appInfoFlags(info.flags, pkgSetting); 522 info.privateFlags |= appInfoPrivateFlags(info.privateFlags, pkgSetting); 523 info.privateFlagsExt |= appInfoPrivateFlagsExt(info.privateFlagsExt, pkgSetting); 524 525 return info; 526 } 527 528 /** 529 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 530 */ 531 @VisibleForTesting 532 @Nullable generateActivityInfo(AndroidPackage pkg, ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)533 public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a, 534 @PackageManager.ComponentInfoFlagsBits long flags, 535 @NonNull PackageUserStateInternal state, @UserIdInt int userId, 536 @NonNull PackageStateInternal pkgSetting) { 537 return generateActivityInfo(pkg, a, flags, state, null, userId, pkgSetting); 538 } 539 540 /** 541 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 542 */ 543 @VisibleForTesting 544 @Nullable generateActivityInfo(AndroidPackage pkg, ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserStateInternal state, @Nullable ApplicationInfo applicationInfo, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)545 public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a, 546 @PackageManager.ComponentInfoFlagsBits long flags, 547 @NonNull PackageUserStateInternal state, @Nullable ApplicationInfo applicationInfo, 548 @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting) { 549 if (a == null) return null; 550 if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { 551 return null; 552 } 553 if (applicationInfo == null) { 554 applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting); 555 } 556 557 if (applicationInfo == null) { 558 return null; 559 } 560 561 // Make shallow copies so we can store the metadata safely 562 ActivityInfo ai = new ActivityInfo(); 563 ai.targetActivity = a.getTargetActivity(); 564 ai.processName = a.getProcessName(); 565 ai.exported = a.isExported(); 566 ai.theme = a.getTheme(); 567 ai.uiOptions = a.getUiOptions(); 568 ai.parentActivityName = a.getParentActivityName(); 569 ai.permission = a.getPermission(); 570 ai.taskAffinity = a.getTaskAffinity(); 571 ai.flags = a.getFlags(); 572 ai.privateFlags = a.getPrivateFlags(); 573 ai.launchMode = a.getLaunchMode(); 574 ai.documentLaunchMode = a.getDocumentLaunchMode(); 575 ai.maxRecents = a.getMaxRecents(); 576 ai.configChanges = a.getConfigChanges(); 577 ai.softInputMode = a.getSoftInputMode(); 578 ai.persistableMode = a.getPersistableMode(); 579 ai.lockTaskLaunchMode = a.getLockTaskLaunchMode(); 580 ai.screenOrientation = a.getScreenOrientation(); 581 ai.resizeMode = a.getResizeMode(); 582 ai.setMaxAspectRatio(a.getMaxAspectRatio()); 583 ai.setMinAspectRatio(a.getMinAspectRatio()); 584 ai.supportsSizeChanges = a.isSupportsSizeChanges(); 585 ai.requestedVrComponent = a.getRequestedVrComponent(); 586 ai.rotationAnimation = a.getRotationAnimation(); 587 ai.colorMode = a.getColorMode(); 588 ai.windowLayout = a.getWindowLayout(); 589 ai.attributionTags = a.getAttributionTags(); 590 if ((flags & PackageManager.GET_META_DATA) != 0) { 591 var metaData = a.getMetaData(); 592 // Backwards compatibility, coerce to null if empty 593 ai.metaData = metaData.isEmpty() ? null : metaData; 594 } else { 595 ai.metaData = null; 596 } 597 ai.applicationInfo = applicationInfo; 598 ai.requiredDisplayCategory = a.getRequiredDisplayCategory(); 599 ai.requireContentUriPermissionFromCaller = a.getRequireContentUriPermissionFromCaller(); 600 ai.setKnownActivityEmbeddingCerts(a.getKnownActivityEmbeddingCerts()); 601 assignFieldsComponentInfoParsedMainComponent(ai, a, pkgSetting, userId); 602 return ai; 603 } 604 605 @Nullable generateDelegateActivityInfo(@ullable ActivityInfo a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserState state, int userId)606 public static ActivityInfo generateDelegateActivityInfo(@Nullable ActivityInfo a, 607 @PackageManager.ComponentInfoFlagsBits long flags, 608 @NonNull PackageUserState state, int userId) { 609 if (a == null || !checkUseInstalledOrHidden(flags, state, a.applicationInfo)) { 610 return null; 611 } 612 // This is used to return the ResolverActivity or instantAppInstallerActivity; 613 // we will just always make a copy. 614 final ActivityInfo ai = new ActivityInfo(a); 615 ai.applicationInfo = 616 generateDelegateApplicationInfo(ai.applicationInfo, flags, state, userId); 617 return ai; 618 } 619 620 /** 621 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 622 */ 623 @Nullable generateServiceInfo(AndroidPackage pkg, ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting)624 public static ServiceInfo generateServiceInfo(AndroidPackage pkg, ParsedService s, 625 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, 626 @UserIdInt int userId, @NonNull PackageStateInternal pkgSetting) { 627 return generateServiceInfo(pkg, s, flags, state, null, userId, pkgSetting); 628 } 629 630 /** 631 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 632 */ 633 @VisibleForTesting 634 @Nullable generateServiceInfo(AndroidPackage pkg, ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, @Nullable ApplicationInfo applicationInfo, int userId, @NonNull PackageStateInternal pkgSetting)635 public static ServiceInfo generateServiceInfo(AndroidPackage pkg, ParsedService s, 636 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, 637 @Nullable ApplicationInfo applicationInfo, int userId, 638 @NonNull PackageStateInternal pkgSetting) { 639 if (s == null) return null; 640 if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { 641 return null; 642 } 643 if (applicationInfo == null) { 644 applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting); 645 } 646 if (applicationInfo == null) { 647 return null; 648 } 649 650 651 // Make shallow copies so we can store the metadata safely 652 ServiceInfo si = new ServiceInfo(); 653 si.exported = s.isExported(); 654 si.flags = s.getFlags(); 655 si.permission = s.getPermission(); 656 si.processName = s.getProcessName(); 657 si.mForegroundServiceType = s.getForegroundServiceType(); 658 si.applicationInfo = applicationInfo; 659 if ((flags & PackageManager.GET_META_DATA) != 0) { 660 var metaData = s.getMetaData(); 661 // Backwards compatibility, coerce to null if empty 662 si.metaData = metaData.isEmpty() ? null : metaData; 663 } 664 assignFieldsComponentInfoParsedMainComponent(si, s, pkgSetting, userId); 665 return si; 666 } 667 668 /** 669 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 670 */ 671 @VisibleForTesting 672 @Nullable generateProviderInfo(AndroidPackage pkg, ParsedProvider p, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, @NonNull ApplicationInfo applicationInfo, int userId, @NonNull PackageStateInternal pkgSetting)673 public static ProviderInfo generateProviderInfo(AndroidPackage pkg, ParsedProvider p, 674 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, 675 @NonNull ApplicationInfo applicationInfo, int userId, 676 @NonNull PackageStateInternal pkgSetting) { 677 if (p == null) return null; 678 if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { 679 return null; 680 } 681 if (applicationInfo == null || !pkg.getPackageName().equals(applicationInfo.packageName)) { 682 Slog.wtf(TAG, "AppInfo's package name is different. Expected=" + pkg.getPackageName() 683 + " actual=" + (applicationInfo == null ? "(null AppInfo)" 684 : applicationInfo.packageName)); 685 applicationInfo = generateApplicationInfo(pkg, flags, state, userId, pkgSetting); 686 } 687 if (applicationInfo == null) { 688 return null; 689 } 690 691 // Make shallow copies so we can store the metadata safely 692 ProviderInfo pi = new ProviderInfo(); 693 pi.exported = p.isExported(); 694 pi.flags = p.getFlags(); 695 pi.processName = p.getProcessName(); 696 pi.authority = p.getAuthority(); 697 pi.isSyncable = p.isSyncable(); 698 pi.readPermission = p.getReadPermission(); 699 pi.writePermission = p.getWritePermission(); 700 pi.grantUriPermissions = p.isGrantUriPermissions(); 701 pi.forceUriPermissions = p.isForceUriPermissions(); 702 pi.multiprocess = p.isMultiProcess(); 703 pi.initOrder = p.getInitOrder(); 704 pi.uriPermissionPatterns = p.getUriPermissionPatterns().toArray(new PatternMatcher[0]); 705 pi.pathPermissions = p.getPathPermissions().toArray(new PathPermission[0]); 706 if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) { 707 pi.uriPermissionPatterns = null; 708 } 709 if ((flags & PackageManager.GET_META_DATA) != 0) { 710 var metaData = p.getMetaData(); 711 // Backwards compatibility, coerce to null if empty 712 pi.metaData = metaData.isEmpty() ? null : metaData; 713 } 714 pi.applicationInfo = applicationInfo; 715 assignFieldsComponentInfoParsedMainComponent(pi, p, pkgSetting, userId); 716 return pi; 717 } 718 719 /** 720 * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. 721 */ 722 @Nullable generateInstrumentationInfo(ParsedInstrumentation i, AndroidPackage pkg, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state, int userId, @NonNull PackageStateInternal pkgSetting)723 public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i, 724 AndroidPackage pkg, @PackageManager.ComponentInfoFlagsBits long flags, 725 PackageUserStateInternal state, int userId, @NonNull PackageStateInternal pkgSetting) { 726 if (i == null) return null; 727 if (!checkUseInstalledOrHidden(pkg, pkgSetting, state, flags)) { 728 return null; 729 } 730 731 InstrumentationInfo info = new InstrumentationInfo(); 732 info.targetPackage = i.getTargetPackage(); 733 info.targetProcesses = i.getTargetProcesses(); 734 info.handleProfiling = i.isHandleProfiling(); 735 info.functionalTest = i.isFunctionalTest(); 736 737 info.sourceDir = pkg.getBaseApkPath(); 738 info.publicSourceDir = pkg.getBaseApkPath(); 739 info.splitNames = pkg.getSplitNames(); 740 info.splitSourceDirs = pkg.getSplitCodePaths().length == 0 ? null : pkg.getSplitCodePaths(); 741 info.splitPublicSourceDirs = pkg.getSplitCodePaths().length == 0 742 ? null : pkg.getSplitCodePaths(); 743 info.splitDependencies = pkg.getSplitDependencies().size() == 0 744 ? null : pkg.getSplitDependencies(); 745 746 initForUser(info, pkg, userId, state); 747 748 info.primaryCpuAbi = pkgSetting.getPrimaryCpuAbi(); 749 info.secondaryCpuAbi = pkgSetting.getSecondaryCpuAbi(); 750 info.nativeLibraryDir = pkg.getNativeLibraryDir(); 751 info.secondaryNativeLibraryDir = pkg.getSecondaryNativeLibraryDir(); 752 753 assignFieldsPackageItemInfoParsedComponent(info, i, pkgSetting, userId); 754 755 if ((flags & PackageManager.GET_META_DATA) == 0) { 756 info.metaData = null; 757 } else { 758 var metaData = i.getMetaData(); 759 // Backwards compatibility, coerce to null if empty 760 info.metaData = metaData.isEmpty() ? null : metaData; 761 } 762 763 return info; 764 } 765 766 // TODO(b/135203078): Determine if permission methods need to pass in a non-null 767 // PackageStateInternal os that checkUseInstalledOrHidden filter can apply 768 @Nullable generatePermissionInfo(ParsedPermission p, @PackageManager.ComponentInfoFlagsBits long flags)769 public static PermissionInfo generatePermissionInfo(ParsedPermission p, 770 @PackageManager.ComponentInfoFlagsBits long flags) { 771 // TODO(b/135203078): Remove null checks and make all usages @NonNull 772 if (p == null) return null; 773 774 PermissionInfo pi = new PermissionInfo(p.getBackgroundPermission()); 775 776 assignFieldsPackageItemInfoParsedComponent(pi, p); 777 778 pi.group = p.getGroup(); 779 pi.requestRes = p.getRequestRes(); 780 pi.protectionLevel = p.getProtectionLevel(); 781 pi.descriptionRes = p.getDescriptionRes(); 782 pi.flags = p.getFlags(); 783 pi.knownCerts = p.getKnownCerts(); 784 785 if ((flags & PackageManager.GET_META_DATA) == 0) { 786 pi.metaData = null; 787 } else { 788 var metaData = p.getMetaData(); 789 // Backwards compatibility, coerce to null if empty 790 pi.metaData = metaData.isEmpty() ? null : metaData; 791 } 792 return pi; 793 } 794 795 @Nullable generatePermissionGroupInfo(ParsedPermissionGroup pg, @PackageManager.ComponentInfoFlagsBits long flags)796 public static PermissionGroupInfo generatePermissionGroupInfo(ParsedPermissionGroup pg, 797 @PackageManager.ComponentInfoFlagsBits long flags) { 798 if (pg == null) return null; 799 800 PermissionGroupInfo pgi = new PermissionGroupInfo( 801 pg.getRequestDetailRes(), 802 pg.getBackgroundRequestRes(), 803 pg.getBackgroundRequestDetailRes() 804 ); 805 806 assignFieldsPackageItemInfoParsedComponent(pgi, pg); 807 pgi.descriptionRes = pg.getDescriptionRes(); 808 pgi.priority = pg.getPriority(); 809 pgi.requestRes = pg.getRequestRes(); 810 pgi.flags = pg.getFlags(); 811 812 if ((flags & PackageManager.GET_META_DATA) == 0) { 813 pgi.metaData = null; 814 } else { 815 var metaData = pg.getMetaData(); 816 // Backwards compatibility, coerce to null if empty 817 pgi.metaData = metaData.isEmpty() ? null : metaData; 818 } 819 820 return pgi; 821 } 822 823 @Nullable generateProcessInfo( Map<String, ParsedProcess> procs, @PackageManager.ComponentInfoFlagsBits long flags)824 public static ArrayMap<String, ProcessInfo> generateProcessInfo( 825 Map<String, ParsedProcess> procs, @PackageManager.ComponentInfoFlagsBits long flags) { 826 if (procs == null) { 827 return null; 828 } 829 830 final int numProcs = procs.size(); 831 ArrayMap<String, ProcessInfo> retProcs = new ArrayMap<>(numProcs); 832 for (String key : procs.keySet()) { 833 ParsedProcess proc = procs.get(key); 834 retProcs.put(proc.getName(), 835 new ProcessInfo(proc.getName(), new ArraySet<>(proc.getDeniedPermissions()), 836 proc.getGwpAsanMode(), proc.getMemtagMode(), 837 proc.getNativeHeapZeroInitialized(), proc.isUseEmbeddedDex())); 838 } 839 return retProcs; 840 } 841 842 /** 843 * Returns true if the package is installed and not hidden, or if the caller explicitly wanted 844 * all uninstalled and hidden packages as well. 845 */ checkUseInstalledOrHidden(AndroidPackage pkg, @NonNull PackageStateInternal pkgSetting, PackageUserStateInternal state, @PackageManager.PackageInfoFlagsBits long flags)846 public static boolean checkUseInstalledOrHidden(AndroidPackage pkg, 847 @NonNull PackageStateInternal pkgSetting, PackageUserStateInternal state, 848 @PackageManager.PackageInfoFlagsBits long flags) { 849 // Returns false if the package is hidden system app until installed. 850 if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0 851 && !state.isInstalled() 852 && pkgSetting.getTransientState().isHiddenUntilInstalled()) { 853 return false; 854 } 855 856 // If available for the target user, or trying to match uninstalled packages and it's 857 // a system app. 858 return PackageUserStateUtils.isAvailable(state, flags) 859 || (pkgSetting.isSystem() && matchUninstalledOrHidden(flags)); 860 } 861 checkUseInstalledOrHidden(long flags, @NonNull PackageUserState state, @Nullable ApplicationInfo appInfo)862 private static boolean checkUseInstalledOrHidden(long flags, 863 @NonNull PackageUserState state, @Nullable ApplicationInfo appInfo) { 864 // Returns false if the package is hidden system app until installed. 865 if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0 866 && !state.isInstalled() 867 && appInfo != null && appInfo.hiddenUntilInstalled) { 868 return false; 869 } 870 871 // If available for the target user, or trying to match uninstalled packages and it's 872 // a system app. 873 return PackageUserStateUtils.isAvailable(state, flags) 874 || (appInfo != null && appInfo.isSystemApp() && matchUninstalledOrHidden(flags)); 875 } 876 matchUninstalledOrHidden(long flags)877 private static boolean matchUninstalledOrHidden(long flags) { 878 return (flags 879 & (PackageManager.MATCH_KNOWN_PACKAGES 880 | PackageManager.MATCH_ARCHIVED_PACKAGES 881 | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS)) 882 != 0; 883 } 884 assignFieldsComponentInfoParsedMainComponent( @onNull ComponentInfo info, @NonNull ParsedMainComponent component)885 private static void assignFieldsComponentInfoParsedMainComponent( 886 @NonNull ComponentInfo info, @NonNull ParsedMainComponent component) { 887 assignFieldsPackageItemInfoParsedComponent(info, component); 888 info.descriptionRes = component.getDescriptionRes(); 889 info.directBootAware = component.isDirectBootAware(); 890 info.enabled = component.isEnabled(); 891 info.splitName = component.getSplitName(); 892 info.attributionTags = component.getAttributionTags(); 893 } 894 assignFieldsPackageItemInfoParsedComponent( @onNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component)895 private static void assignFieldsPackageItemInfoParsedComponent( 896 @NonNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component) { 897 packageItemInfo.nonLocalizedLabel = ComponentParseUtils.getNonLocalizedLabel(component); 898 packageItemInfo.icon = ComponentParseUtils.getIcon(component); 899 packageItemInfo.banner = component.getBanner(); 900 packageItemInfo.labelRes = component.getLabelRes(); 901 packageItemInfo.logo = component.getLogo(); 902 packageItemInfo.name = component.getName(); 903 packageItemInfo.packageName = component.getPackageName(); 904 } 905 assignFieldsComponentInfoParsedMainComponent( @onNull ComponentInfo info, @NonNull ParsedMainComponent component, @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId)906 private static void assignFieldsComponentInfoParsedMainComponent( 907 @NonNull ComponentInfo info, @NonNull ParsedMainComponent component, 908 @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId) { 909 assignFieldsComponentInfoParsedMainComponent(info, component); 910 Pair<CharSequence, Integer> labelAndIcon = 911 ParsedComponentStateUtils.getNonLocalizedLabelAndIcon(component, pkgSetting, 912 userId); 913 info.nonLocalizedLabel = labelAndIcon.first; 914 info.icon = labelAndIcon.second; 915 } 916 assignFieldsPackageItemInfoParsedComponent( @onNull PackageItemInfo info, @NonNull ParsedComponent component, @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId)917 private static void assignFieldsPackageItemInfoParsedComponent( 918 @NonNull PackageItemInfo info, @NonNull ParsedComponent component, 919 @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId) { 920 assignFieldsPackageItemInfoParsedComponent(info, component); 921 Pair<CharSequence, Integer> labelAndIcon = 922 ParsedComponentStateUtils.getNonLocalizedLabelAndIcon(component, pkgSetting, 923 userId); 924 info.nonLocalizedLabel = labelAndIcon.first; 925 info.icon = labelAndIcon.second; 926 } 927 928 @CheckResult flag(boolean hasFlag, int flag)929 private static int flag(boolean hasFlag, int flag) { 930 return hasFlag ? flag : 0; 931 } 932 933 /** 934 * @see ApplicationInfo#flags 935 */ appInfoFlags(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting)936 public static int appInfoFlags(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting) { 937 // @formatter:off 938 int pkgWithoutStateFlags = flag(pkg.isExternalStorage(), ApplicationInfo.FLAG_EXTERNAL_STORAGE) 939 | flag(pkg.isHardwareAccelerated(), ApplicationInfo.FLAG_HARDWARE_ACCELERATED) 940 | flag(pkg.isBackupAllowed(), ApplicationInfo.FLAG_ALLOW_BACKUP) 941 | flag(pkg.isKillAfterRestoreAllowed(), ApplicationInfo.FLAG_KILL_AFTER_RESTORE) 942 | flag(pkg.isRestoreAnyVersion(), ApplicationInfo.FLAG_RESTORE_ANY_VERSION) 943 | flag(pkg.isFullBackupOnly(), ApplicationInfo.FLAG_FULL_BACKUP_ONLY) 944 | flag(pkg.isPersistent(), ApplicationInfo.FLAG_PERSISTENT) 945 | flag(pkg.isDebuggable(), ApplicationInfo.FLAG_DEBUGGABLE) 946 | flag(pkg.isVmSafeMode(), ApplicationInfo.FLAG_VM_SAFE_MODE) 947 | flag(pkg.isDeclaredHavingCode(), ApplicationInfo.FLAG_HAS_CODE) 948 | flag(pkg.isTaskReparentingAllowed(), ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING) 949 | flag(pkg.isClearUserDataAllowed(), ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) 950 | flag(pkg.isLargeHeap(), ApplicationInfo.FLAG_LARGE_HEAP) 951 | flag(pkg.isCleartextTrafficAllowed(), ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) 952 | flag(pkg.isRtlSupported(), ApplicationInfo.FLAG_SUPPORTS_RTL) 953 | flag(pkg.isTestOnly(), ApplicationInfo.FLAG_TEST_ONLY) 954 | flag(pkg.isMultiArch(), ApplicationInfo.FLAG_MULTIARCH) 955 | flag(pkg.isExtractNativeLibrariesRequested(), ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) 956 | flag(pkg.isGame(), ApplicationInfo.FLAG_IS_GAME) 957 | flag(pkg.isSmallScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) 958 | flag(pkg.isNormalScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) 959 | flag(pkg.isLargeScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) 960 | flag(pkg.isExtraLargeScreensSupported(), ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) 961 | flag(pkg.isResizeable(), ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) 962 | flag(pkg.isAnyDensity(), ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 963 | flag(AndroidPackageLegacyUtils.isSystem(pkg), ApplicationInfo.FLAG_SYSTEM) 964 | flag(pkg.isFactoryTest(), ApplicationInfo.FLAG_FACTORY_TEST); 965 966 return appInfoFlags(pkgWithoutStateFlags, pkgSetting); 967 // @formatter:on 968 } 969 970 /** @see ApplicationInfo#flags */ appInfoFlags(int pkgWithoutStateFlags, @NonNull PackageStateInternal pkgSetting)971 public static int appInfoFlags(int pkgWithoutStateFlags, 972 @NonNull PackageStateInternal pkgSetting) { 973 // @formatter:off 974 int flags = pkgWithoutStateFlags; 975 if (pkgSetting != null) { 976 flags |= flag(pkgSetting.isUpdatedSystemApp(), ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 977 } 978 return flags; 979 // @formatter:on 980 } 981 982 /** @see ApplicationInfo#privateFlags */ appInfoPrivateFlags(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting)983 public static int appInfoPrivateFlags(AndroidPackage pkg, 984 @Nullable PackageStateInternal pkgSetting) { 985 // @formatter:off 986 int pkgWithoutStateFlags = flag(pkg.isStaticSharedLibrary(), ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY) 987 | flag(pkg.isResourceOverlay(), ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY) 988 | flag(pkg.isIsolatedSplitLoading(), ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING) 989 | flag(pkg.isHasDomainUrls(), ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) 990 | flag(pkg.isProfileableByShell(), ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) 991 | flag(pkg.isBackupInForeground(), ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND) 992 | flag(pkg.isUseEmbeddedDex(), ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX) 993 | flag(pkg.isDefaultToDeviceProtectedStorage(), ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) 994 | flag(pkg.isDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE) 995 | flag(pkg.isPartiallyDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE) 996 | flag(pkg.isClearUserDataOnFailedRestoreAllowed(), ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE) 997 | flag(pkg.isAllowAudioPlaybackCapture(), ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE) 998 | flag(pkg.isRequestLegacyExternalStorage(), ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE) 999 | flag(pkg.isNonSdkApiRequested(), ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API) 1000 | flag(pkg.isUserDataFragile(), ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA) 1001 | flag(pkg.isSaveStateDisallowed(), ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) 1002 | flag(pkg.isResizeableActivityViaSdkVersion(), ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) 1003 | flag(pkg.isAllowNativeHeapPointerTagging(), ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING) 1004 | flag(AndroidPackageLegacyUtils.isSystemExt(pkg), ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) 1005 | flag(AndroidPackageLegacyUtils.isPrivileged(pkg), ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 1006 | flag(AndroidPackageLegacyUtils.isOem(pkg), ApplicationInfo.PRIVATE_FLAG_OEM) 1007 | flag(AndroidPackageLegacyUtils.isVendor(pkg), ApplicationInfo.PRIVATE_FLAG_VENDOR) 1008 | flag(AndroidPackageLegacyUtils.isProduct(pkg), ApplicationInfo.PRIVATE_FLAG_PRODUCT) 1009 | flag(AndroidPackageLegacyUtils.isOdm(pkg), ApplicationInfo.PRIVATE_FLAG_ODM) 1010 | flag(pkg.isSignedWithPlatformKey(), ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY); 1011 1012 Boolean resizeableActivity = pkg.getResizeableActivity(); 1013 if (resizeableActivity != null) { 1014 if (resizeableActivity) { 1015 pkgWithoutStateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE; 1016 } else { 1017 pkgWithoutStateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE; 1018 } 1019 } 1020 1021 return appInfoPrivateFlags(pkgWithoutStateFlags, pkgSetting); 1022 // @formatter:on 1023 } 1024 1025 /** @see ApplicationInfo#privateFlags */ appInfoPrivateFlags(int pkgWithoutStateFlags, @Nullable PackageStateInternal pkgSetting)1026 public static int appInfoPrivateFlags(int pkgWithoutStateFlags, 1027 @Nullable PackageStateInternal pkgSetting) { 1028 // @formatter:off 1029 // TODO: Add state specific flags 1030 return pkgWithoutStateFlags; 1031 // @formatter:on 1032 } 1033 1034 /** @see ApplicationInfo#privateFlagsExt */ appInfoPrivateFlagsExt(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting)1035 public static int appInfoPrivateFlagsExt(AndroidPackage pkg, 1036 @Nullable PackageStateInternal pkgSetting) { 1037 var isAllowlistedForHiddenApis = SystemConfig.getInstance().getHiddenApiWhitelistedApps() 1038 .contains(pkg.getPackageName()); 1039 // @formatter:off 1040 int pkgWithoutStateFlags = flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE) 1041 | flag(pkg.hasRequestForegroundServiceExemption(), ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION) 1042 | flag(pkg.isAttributionsUserVisible(), ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE) 1043 | flag(pkg.isOnBackInvokedCallbackEnabled(), ApplicationInfo.PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK) 1044 | flag(isAllowlistedForHiddenApis, ApplicationInfo.PRIVATE_FLAG_EXT_ALLOWLISTED_FOR_HIDDEN_APIS); 1045 return appInfoPrivateFlagsExt(pkgWithoutStateFlags, pkgSetting); 1046 // @formatter:on 1047 } 1048 1049 /** @see ApplicationInfo#privateFlagsExt */ appInfoPrivateFlagsExt(int pkgWithoutStateFlags, @Nullable PackageStateInternal pkgSetting)1050 private static int appInfoPrivateFlagsExt(int pkgWithoutStateFlags, 1051 @Nullable PackageStateInternal pkgSetting) { 1052 // @formatter:off 1053 int flags = pkgWithoutStateFlags; 1054 if (pkgSetting != null) { 1055 flags |= flag(pkgSetting.getCpuAbiOverride() != null, ApplicationInfo.PRIVATE_FLAG_EXT_CPU_OVERRIDE); 1056 } 1057 return flags; 1058 // @formatter:on 1059 } 1060 initForUser(ApplicationInfo output, AndroidPackage input, @UserIdInt int userId, PackageUserStateInternal state)1061 private static void initForUser(ApplicationInfo output, AndroidPackage input, 1062 @UserIdInt int userId, PackageUserStateInternal state) { 1063 PackageImpl pkg = ((PackageImpl) input); 1064 String packageName = input.getPackageName(); 1065 output.uid = UserHandle.getUid(userId, UserHandle.getAppId(input.getUid())); 1066 1067 if ("android".equals(packageName)) { 1068 output.dataDir = SYSTEM_DATA_PATH; 1069 return; 1070 } 1071 1072 if (!state.isInstalled() && !state.dataExists() 1073 && android.content.pm.Flags.nullableDataDir()) { 1074 // The data dir has been deleted 1075 output.dataDir = null; 1076 return; 1077 } 1078 1079 // For performance reasons, all these paths are built as strings 1080 if (userId == UserHandle.USER_SYSTEM) { 1081 output.credentialProtectedDataDir = 1082 pkg.getBaseAppDataCredentialProtectedDirForSystemUser() + packageName; 1083 output.deviceProtectedDataDir = 1084 pkg.getBaseAppDataDeviceProtectedDirForSystemUser() + packageName; 1085 } else { 1086 // Convert /data/user/0/ -> /data/user/1/com.example.app 1087 String userIdString = String.valueOf(userId); 1088 int credentialLength = pkg.getBaseAppDataCredentialProtectedDirForSystemUser().length(); 1089 output.credentialProtectedDataDir = 1090 new StringBuilder(pkg.getBaseAppDataCredentialProtectedDirForSystemUser()) 1091 .replace(credentialLength - 2, credentialLength - 1, userIdString) 1092 .append(packageName) 1093 .toString(); 1094 int deviceLength = pkg.getBaseAppDataDeviceProtectedDirForSystemUser().length(); 1095 output.deviceProtectedDataDir = 1096 new StringBuilder(pkg.getBaseAppDataDeviceProtectedDirForSystemUser()) 1097 .replace(deviceLength - 2, deviceLength - 1, userIdString) 1098 .append(packageName) 1099 .toString(); 1100 } 1101 1102 if (input.isDefaultToDeviceProtectedStorage() 1103 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 1104 output.dataDir = output.deviceProtectedDataDir; 1105 } else { 1106 output.dataDir = output.credentialProtectedDataDir; 1107 } 1108 } 1109 1110 // This duplicates the ApplicationInfo variant because it uses field assignment and the classes 1111 // don't inherit from each other, unfortunately. Consolidating logic would introduce overhead. initForUser(InstrumentationInfo output, AndroidPackage input, @UserIdInt int userId, PackageUserStateInternal state)1112 private static void initForUser(InstrumentationInfo output, AndroidPackage input, 1113 @UserIdInt int userId, PackageUserStateInternal state) { 1114 PackageImpl pkg = ((PackageImpl) input); 1115 String packageName = input.getPackageName(); 1116 if ("android".equals(packageName)) { 1117 output.dataDir = SYSTEM_DATA_PATH; 1118 return; 1119 } 1120 1121 if (!state.isInstalled() && !state.dataExists() 1122 && android.content.pm.Flags.nullableDataDir()) { 1123 // The data dir has been deleted 1124 output.dataDir = null; 1125 return; 1126 } 1127 1128 // For performance reasons, all these paths are built as strings 1129 if (userId == UserHandle.USER_SYSTEM) { 1130 output.credentialProtectedDataDir = 1131 pkg.getBaseAppDataCredentialProtectedDirForSystemUser() + packageName; 1132 output.deviceProtectedDataDir = 1133 pkg.getBaseAppDataDeviceProtectedDirForSystemUser() + packageName; 1134 } else { 1135 // Convert /data/user/0/ -> /data/user/1/com.example.app 1136 String userIdString = String.valueOf(userId); 1137 int credentialLength = pkg.getBaseAppDataCredentialProtectedDirForSystemUser().length(); 1138 output.credentialProtectedDataDir = 1139 new StringBuilder(pkg.getBaseAppDataCredentialProtectedDirForSystemUser()) 1140 .replace(credentialLength - 2, credentialLength - 1, userIdString) 1141 .append(packageName) 1142 .toString(); 1143 int deviceLength = pkg.getBaseAppDataDeviceProtectedDirForSystemUser().length(); 1144 output.deviceProtectedDataDir = 1145 new StringBuilder(pkg.getBaseAppDataDeviceProtectedDirForSystemUser()) 1146 .replace(deviceLength - 2, deviceLength - 1, userIdString) 1147 .append(packageName) 1148 .toString(); 1149 } 1150 1151 if (input.isDefaultToDeviceProtectedStorage() 1152 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 1153 output.dataDir = output.deviceProtectedDataDir; 1154 } else { 1155 output.dataDir = output.credentialProtectedDataDir; 1156 } 1157 } 1158 1159 /** 1160 * Returns the data dir of the app for the target user. Return null if the app isn't installed 1161 * on the target user and doesn't have a data dir on the target user. 1162 */ 1163 @Nullable getDataDir(PackageStateInternal ps, int userId)1164 public static File getDataDir(PackageStateInternal ps, int userId) { 1165 if ("android".equals(ps.getPackageName())) { 1166 return Environment.getDataSystemDirectory(); 1167 } 1168 1169 if (!ps.getUserStateOrDefault(userId).isInstalled() 1170 && !ps.getUserStateOrDefault(userId).dataExists() 1171 && android.content.pm.Flags.nullableDataDir()) { 1172 // The app has been uninstalled for the user and the data dir has been deleted 1173 return null; 1174 } 1175 1176 if (ps.isDefaultToDeviceProtectedStorage() 1177 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 1178 return Environment.getDataUserDePackageDirectory(ps.getVolumeUuid(), userId, 1179 ps.getPackageName()); 1180 } else { 1181 return Environment.getDataUserCePackageDirectory(ps.getVolumeUuid(), userId, 1182 ps.getPackageName()); 1183 } 1184 } 1185 1186 /** 1187 * Wraps {@link PackageInfoUtils#generateApplicationInfo} with a cache. 1188 */ 1189 public static class CachedApplicationInfoGenerator { 1190 // Map from a package name to the corresponding app info. 1191 private final ArrayMap<String, ApplicationInfo> mCache = new ArrayMap<>(); 1192 1193 /** 1194 * {@link PackageInfoUtils#generateApplicationInfo} with a cache. 1195 */ 1196 @Nullable generate(AndroidPackage pkg, @PackageManager.ApplicationInfoFlagsBits long flags, PackageUserStateInternal state, int userId, @NonNull PackageStateInternal pkgSetting)1197 public ApplicationInfo generate(AndroidPackage pkg, 1198 @PackageManager.ApplicationInfoFlagsBits long flags, PackageUserStateInternal state, 1199 int userId, @NonNull PackageStateInternal pkgSetting) { 1200 ApplicationInfo appInfo = mCache.get(pkg.getPackageName()); 1201 if (appInfo != null) { 1202 return appInfo; 1203 } 1204 appInfo = PackageInfoUtils.generateApplicationInfo( 1205 pkg, flags, state, userId, pkgSetting); 1206 mCache.put(pkg.getPackageName(), appInfo); 1207 return appInfo; 1208 } 1209 } 1210 } 1211