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