1 /* 2 * Copyright (C) 2022 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.pkg.parsing; 18 19 import android.annotation.CheckResult; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.apex.ApexInfo; 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.ProviderInfo; 39 import android.content.pm.ServiceInfo; 40 import android.content.pm.Signature; 41 import android.content.pm.SigningDetails; 42 import android.content.pm.SigningInfo; 43 import android.content.pm.overlay.OverlayPaths; 44 import android.os.Environment; 45 import android.os.PatternMatcher; 46 import android.os.UserHandle; 47 48 import com.android.internal.util.ArrayUtils; 49 import com.android.server.pm.pkg.PackageUserState; 50 import com.android.server.pm.pkg.PackageUserStateUtils; 51 import com.android.server.pm.pkg.SELinuxUtil; 52 import com.android.server.pm.pkg.component.ComponentParseUtils; 53 import com.android.server.pm.pkg.component.ParsedActivity; 54 import com.android.server.pm.pkg.component.ParsedAttribution; 55 import com.android.server.pm.pkg.component.ParsedComponent; 56 import com.android.server.pm.pkg.component.ParsedInstrumentation; 57 import com.android.server.pm.pkg.component.ParsedMainComponent; 58 import com.android.server.pm.pkg.component.ParsedPermission; 59 import com.android.server.pm.pkg.component.ParsedPermissionGroup; 60 import com.android.server.pm.pkg.component.ParsedProvider; 61 import com.android.server.pm.pkg.component.ParsedService; 62 import com.android.server.pm.pkg.component.ParsedUsesPermission; 63 64 import libcore.util.EmptyArray; 65 66 import java.io.File; 67 import java.util.Collections; 68 import java.util.List; 69 import java.util.Set; 70 71 /** 72 * @hide 73 **/ 74 public class PackageInfoWithoutStateUtils { 75 76 public static final String SYSTEM_DATA_PATH = 77 Environment.getDataDirectoryPath() + File.separator + "system"; 78 79 @Nullable generate(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId)80 public static PackageInfo generate(ParsingPackageRead pkg, int[] gids, 81 @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, 82 long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, 83 int userId) { 84 return generateWithComponents(pkg, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions, 85 state, userId, null); 86 } 87 88 @Nullable generate(ParsingPackageRead pkg, ApexInfo apexInfo, int flags)89 public static PackageInfo generate(ParsingPackageRead pkg, ApexInfo apexInfo, int flags) { 90 return generateWithComponents(pkg, EmptyArray.INT, flags, 0, 0, Collections.emptySet(), 91 PackageUserState.DEFAULT, UserHandle.getCallingUserId(), apexInfo); 92 } 93 94 @Nullable generateWithComponents(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId, @Nullable ApexInfo apexInfo)95 private static PackageInfo generateWithComponents(ParsingPackageRead pkg, int[] gids, 96 @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, 97 long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, 98 int userId, @Nullable ApexInfo apexInfo) { 99 ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId); 100 if (applicationInfo == null) { 101 return null; 102 } 103 PackageInfo info = generateWithoutComponents(pkg, gids, flags, firstInstallTime, 104 lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo); 105 106 if (info == null) { 107 return null; 108 } 109 110 if ((flags & PackageManager.GET_ACTIVITIES) != 0) { 111 final int N = pkg.getActivities().size(); 112 if (N > 0) { 113 int num = 0; 114 final ActivityInfo[] res = new ActivityInfo[N]; 115 for (int i = 0; i < N; i++) { 116 final ParsedActivity a = pkg.getActivities().get(i); 117 if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), a, 118 flags)) { 119 if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals( 120 a.getName())) { 121 continue; 122 } 123 res[num++] = generateActivityInfo(pkg, a, flags, state, 124 applicationInfo, userId); 125 } 126 } 127 info.activities = ArrayUtils.trimToSize(res, num); 128 } 129 } 130 if ((flags & PackageManager.GET_RECEIVERS) != 0) { 131 final int size = pkg.getReceivers().size(); 132 if (size > 0) { 133 int num = 0; 134 final ActivityInfo[] res = new ActivityInfo[size]; 135 for (int i = 0; i < size; i++) { 136 final ParsedActivity a = pkg.getReceivers().get(i); 137 if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), a, 138 flags)) { 139 res[num++] = generateActivityInfo(pkg, a, flags, state, 140 applicationInfo, userId); 141 } 142 } 143 info.receivers = ArrayUtils.trimToSize(res, num); 144 } 145 } 146 if ((flags & PackageManager.GET_SERVICES) != 0) { 147 final int size = pkg.getServices().size(); 148 if (size > 0) { 149 int num = 0; 150 final ServiceInfo[] res = new ServiceInfo[size]; 151 for (int i = 0; i < size; i++) { 152 final ParsedService s = pkg.getServices().get(i); 153 if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), s, 154 flags)) { 155 res[num++] = generateServiceInfo(pkg, s, flags, state, 156 applicationInfo, userId); 157 } 158 } 159 info.services = ArrayUtils.trimToSize(res, num); 160 } 161 } 162 if ((flags & PackageManager.GET_PROVIDERS) != 0) { 163 final int size = pkg.getProviders().size(); 164 if (size > 0) { 165 int num = 0; 166 final ProviderInfo[] res = new ProviderInfo[size]; 167 for (int i = 0; i < size; i++) { 168 final ParsedProvider pr = pkg.getProviders() 169 .get(i); 170 if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), pr, 171 flags)) { 172 res[num++] = generateProviderInfo(pkg, pr, flags, state, 173 applicationInfo, userId); 174 } 175 } 176 info.providers = ArrayUtils.trimToSize(res, num); 177 } 178 } 179 if ((flags & PackageManager.GET_INSTRUMENTATION) != 0) { 180 int N = pkg.getInstrumentations().size(); 181 if (N > 0) { 182 info.instrumentation = new InstrumentationInfo[N]; 183 for (int i = 0; i < N; i++) { 184 info.instrumentation[i] = generateInstrumentationInfo( 185 pkg.getInstrumentations().get(i), pkg, flags, userId, 186 true /* assignUserFields */); 187 } 188 } 189 } 190 191 return info; 192 } 193 194 @Nullable generateWithoutComponents(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo)195 public static PackageInfo generateWithoutComponents(ParsingPackageRead pkg, int[] gids, 196 @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, 197 long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, 198 int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) { 199 if (!checkUseInstalled(pkg, state, flags)) { 200 return null; 201 } 202 203 return generateWithoutComponentsUnchecked(pkg, gids, flags, firstInstallTime, 204 lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo); 205 } 206 207 /** 208 * This bypasses critical checks that are necessary for usage with data passed outside of system 209 * server. 210 * <p> 211 * Prefer {@link #generateWithoutComponents(ParsingPackageRead, int[], int, long, long, Set, 212 * PackageUserState, int, ApexInfo, ApplicationInfo)}. 213 */ 214 @NonNull generateWithoutComponentsUnchecked(ParsingPackageRead pkg, int[] gids, @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo)215 public static PackageInfo generateWithoutComponentsUnchecked(ParsingPackageRead pkg, int[] gids, 216 @PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime, 217 long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, 218 int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) { 219 PackageInfo pi = new PackageInfo(); 220 pi.packageName = pkg.getPackageName(); 221 pi.splitNames = pkg.getSplitNames(); 222 pi.versionCode = ((ParsingPackageHidden) pkg).getVersionCode(); 223 pi.versionCodeMajor = ((ParsingPackageHidden) pkg).getVersionCodeMajor(); 224 pi.baseRevisionCode = pkg.getBaseRevisionCode(); 225 pi.splitRevisionCodes = pkg.getSplitRevisionCodes(); 226 pi.versionName = pkg.getVersionName(); 227 pi.sharedUserId = pkg.getSharedUserId(); 228 pi.sharedUserLabel = pkg.getSharedUserLabel(); 229 pi.applicationInfo = applicationInfo; 230 pi.installLocation = pkg.getInstallLocation(); 231 if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 232 || (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { 233 pi.requiredForAllUsers = pkg.isRequiredForAllUsers(); 234 } 235 pi.restrictedAccountType = pkg.getRestrictedAccountType(); 236 pi.requiredAccountType = pkg.getRequiredAccountType(); 237 pi.overlayTarget = pkg.getOverlayTarget(); 238 pi.targetOverlayableName = pkg.getOverlayTargetOverlayableName(); 239 pi.overlayCategory = pkg.getOverlayCategory(); 240 pi.overlayPriority = pkg.getOverlayPriority(); 241 pi.mOverlayIsStatic = pkg.isOverlayIsStatic(); 242 pi.compileSdkVersion = pkg.getCompileSdkVersion(); 243 pi.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName(); 244 pi.firstInstallTime = firstInstallTime; 245 pi.lastUpdateTime = lastUpdateTime; 246 if ((flags & PackageManager.GET_GIDS) != 0) { 247 pi.gids = gids; 248 } 249 if ((flags & PackageManager.GET_CONFIGURATIONS) != 0) { 250 int size = pkg.getConfigPreferences().size(); 251 if (size > 0) { 252 pi.configPreferences = new ConfigurationInfo[size]; 253 pkg.getConfigPreferences().toArray(pi.configPreferences); 254 } 255 size = pkg.getRequestedFeatures().size(); 256 if (size > 0) { 257 pi.reqFeatures = new FeatureInfo[size]; 258 pkg.getRequestedFeatures().toArray(pi.reqFeatures); 259 } 260 size = pkg.getFeatureGroups().size(); 261 if (size > 0) { 262 pi.featureGroups = new FeatureGroupInfo[size]; 263 pkg.getFeatureGroups().toArray(pi.featureGroups); 264 } 265 } 266 if ((flags & PackageManager.GET_PERMISSIONS) != 0) { 267 int size = ArrayUtils.size(pkg.getPermissions()); 268 if (size > 0) { 269 pi.permissions = new PermissionInfo[size]; 270 for (int i = 0; i < size; i++) { 271 pi.permissions[i] = generatePermissionInfo(pkg.getPermissions().get(i), 272 flags); 273 } 274 } 275 final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions(); 276 size = usesPermissions.size(); 277 if (size > 0) { 278 pi.requestedPermissions = new String[size]; 279 pi.requestedPermissionsFlags = new int[size]; 280 for (int i = 0; i < size; i++) { 281 final ParsedUsesPermission usesPermission = usesPermissions.get(i); 282 pi.requestedPermissions[i] = usesPermission.getName(); 283 // The notion of required permissions is deprecated but for compatibility. 284 pi.requestedPermissionsFlags[i] |= 285 PackageInfo.REQUESTED_PERMISSION_REQUIRED; 286 if (grantedPermissions != null 287 && grantedPermissions.contains(usesPermission.getName())) { 288 pi.requestedPermissionsFlags[i] |= 289 PackageInfo.REQUESTED_PERMISSION_GRANTED; 290 } 291 if ((usesPermission.getUsesPermissionFlags() 292 & ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0) { 293 pi.requestedPermissionsFlags[i] |= 294 PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION; 295 } 296 } 297 } 298 } 299 if ((flags & PackageManager.GET_ATTRIBUTIONS) != 0) { 300 int size = ArrayUtils.size(pkg.getAttributions()); 301 if (size > 0) { 302 pi.attributions = new Attribution[size]; 303 for (int i = 0; i < size; i++) { 304 pi.attributions[i] = generateAttribution(pkg.getAttributions().get(i)); 305 } 306 } 307 if (pkg.areAttributionsUserVisible()) { 308 pi.applicationInfo.privateFlagsExt 309 |= ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE; 310 } else { 311 pi.applicationInfo.privateFlagsExt 312 &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE; 313 } 314 } else { 315 pi.applicationInfo.privateFlagsExt 316 &= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE; 317 } 318 319 if (apexInfo != null) { 320 File apexFile = new File(apexInfo.modulePath); 321 322 pi.applicationInfo.sourceDir = apexFile.getPath(); 323 pi.applicationInfo.publicSourceDir = apexFile.getPath(); 324 if (apexInfo.isFactory) { 325 pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 326 pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 327 } else { 328 pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 329 pi.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 330 } 331 if (apexInfo.isActive) { 332 pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED; 333 } else { 334 pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED; 335 } 336 pi.isApex = true; 337 } 338 339 final SigningDetails signingDetails = pkg.getSigningDetails(); 340 // deprecated method of getting signing certificates 341 if ((flags & PackageManager.GET_SIGNATURES) != 0) { 342 if (signingDetails.hasPastSigningCertificates()) { 343 // Package has included signing certificate rotation information. Return the oldest 344 // cert so that programmatic checks keep working even if unaware of key rotation. 345 pi.signatures = new Signature[1]; 346 pi.signatures[0] = signingDetails.getPastSigningCertificates()[0]; 347 } else if (signingDetails.hasSignatures()) { 348 // otherwise keep old behavior 349 int numberOfSigs = signingDetails.getSignatures().length; 350 pi.signatures = new Signature[numberOfSigs]; 351 System.arraycopy(signingDetails.getSignatures(), 0, pi.signatures, 0, 352 numberOfSigs); 353 } 354 } 355 356 // replacement for GET_SIGNATURES 357 if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) { 358 if (signingDetails != SigningDetails.UNKNOWN) { 359 // only return a valid SigningInfo if there is signing information to report 360 pi.signingInfo = new SigningInfo(signingDetails); 361 } else { 362 pi.signingInfo = null; 363 } 364 } 365 366 return pi; 367 } 368 369 @Nullable generateApplicationInfo(ParsingPackageRead pkg, @PackageManager.ApplicationInfoFlagsBits long flags, PackageUserState state, int userId)370 public static ApplicationInfo generateApplicationInfo(ParsingPackageRead pkg, 371 @PackageManager.ApplicationInfoFlagsBits long flags, PackageUserState state, 372 int userId) { 373 if (pkg == null) { 374 return null; 375 } 376 377 if (!checkUseInstalled(pkg, state, flags)) { 378 return null; 379 } 380 381 return generateApplicationInfoUnchecked(pkg, flags, state, userId, 382 true /* assignUserFields */); 383 } 384 385 /** 386 * This bypasses critical checks that are necessary for usage with data passed outside of system 387 * server. 388 * <p> 389 * Prefer {@link #generateApplicationInfo(ParsingPackageRead, int, PackageUserState, int)}. 390 * 391 * @param assignUserFields whether to fill the returned {@link ApplicationInfo} with user 392 * specific fields. This can be skipped when building from a system 393 * server package, as there are cached strings which can be used rather 394 * than querying and concatenating the comparatively expensive {@link 395 * Environment#getDataDirectory(String)}}. 396 */ 397 @NonNull generateApplicationInfoUnchecked(@onNull ParsingPackageRead pkg, @PackageManager.ApplicationInfoFlagsBits long flags, @NonNull PackageUserState state, int userId, boolean assignUserFields)398 public static ApplicationInfo generateApplicationInfoUnchecked(@NonNull ParsingPackageRead pkg, 399 @PackageManager.ApplicationInfoFlagsBits long flags, 400 @NonNull PackageUserState state, int userId, boolean assignUserFields) { 401 // Make shallow copy so we can store the metadata/libraries safely 402 ApplicationInfo ai = ((ParsingPackageHidden) pkg).toAppInfoWithoutState(); 403 404 if (assignUserFields) { 405 assignUserFields(pkg, ai, userId); 406 } 407 408 updateApplicationInfo(ai, flags, state); 409 410 return ai; 411 } 412 updateApplicationInfo(ApplicationInfo ai, long flags, PackageUserState state)413 private static void updateApplicationInfo(ApplicationInfo ai, long flags, 414 PackageUserState state) { 415 if ((flags & PackageManager.GET_META_DATA) == 0) { 416 ai.metaData = null; 417 } 418 if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) == 0) { 419 ai.sharedLibraryFiles = null; 420 ai.sharedLibraryInfos = null; 421 } 422 423 // CompatibilityMode is global state. 424 if (!ParsingPackageUtils.sCompatibilityModeEnabled) { 425 ai.disableCompatibilityMode(); 426 } 427 428 ai.flags |= flag(state.isStopped(), ApplicationInfo.FLAG_STOPPED) 429 | flag(state.isInstalled(), ApplicationInfo.FLAG_INSTALLED) 430 | flag(state.isSuspended(), ApplicationInfo.FLAG_SUSPENDED); 431 ai.privateFlags |= flag(state.isInstantApp(), ApplicationInfo.PRIVATE_FLAG_INSTANT) 432 | flag(state.isVirtualPreload(), ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD) 433 | flag(state.isHidden(), ApplicationInfo.PRIVATE_FLAG_HIDDEN); 434 435 if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 436 ai.enabled = true; 437 } else if (state.getEnabledState() 438 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) { 439 ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0; 440 } else if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_DISABLED 441 || state.getEnabledState() 442 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { 443 ai.enabled = false; 444 } 445 ai.enabledSetting = state.getEnabledState(); 446 if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) { 447 ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName); 448 } 449 ai.seInfoUser = SELinuxUtil.getSeinfoUser(state); 450 final OverlayPaths overlayPaths = state.getAllOverlayPaths(); 451 if (overlayPaths != null) { 452 ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]); 453 ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]); 454 } 455 } 456 457 @Nullable generateDelegateApplicationInfo(@ullable ApplicationInfo ai, @PackageManager.ApplicationInfoFlagsBits long flags, @NonNull PackageUserState state, int userId)458 public static ApplicationInfo generateDelegateApplicationInfo(@Nullable ApplicationInfo ai, 459 @PackageManager.ApplicationInfoFlagsBits long flags, 460 @NonNull PackageUserState state, int userId) { 461 if (ai == null || !checkUseInstalledOrHidden(flags, state, ai)) { 462 return null; 463 } 464 // This is used to return the ResolverActivity or instantAppInstallerActivity; 465 // we will just always make a copy. 466 ai = new ApplicationInfo(ai); 467 ai.initForUser(userId); 468 ai.icon = (ParsingPackageUtils.sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes 469 : ai.iconRes; 470 updateApplicationInfo(ai, flags, state); 471 return ai; 472 } 473 474 @Nullable generateDelegateActivityInfo(@ullable ActivityInfo a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull PackageUserState state, int userId)475 public static ActivityInfo generateDelegateActivityInfo(@Nullable ActivityInfo a, 476 @PackageManager.ComponentInfoFlagsBits long flags, 477 @NonNull PackageUserState state, int userId) { 478 if (a == null || !checkUseInstalledOrHidden(flags, state, a.applicationInfo)) { 479 return null; 480 } 481 // This is used to return the ResolverActivity or instantAppInstallerActivity; 482 // we will just always make a copy. 483 final ActivityInfo ai = new ActivityInfo(a); 484 ai.applicationInfo = 485 generateDelegateApplicationInfo(ai.applicationInfo, flags, state, userId); 486 return ai; 487 } 488 489 @Nullable generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, @Nullable ApplicationInfo applicationInfo, int userId)490 public static ActivityInfo generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a, 491 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, 492 @Nullable ApplicationInfo applicationInfo, int userId) { 493 if (a == null) return null; 494 if (!checkUseInstalled(pkg, state, flags)) { 495 return null; 496 } 497 if (applicationInfo == null) { 498 applicationInfo = generateApplicationInfo(pkg, flags, state, userId); 499 } 500 if (applicationInfo == null) { 501 return null; 502 } 503 504 return generateActivityInfoUnchecked(a, flags, applicationInfo); 505 } 506 507 /** 508 * This bypasses critical checks that are necessary for usage with data passed outside of system 509 * server. 510 * <p> 511 * Prefer {@link #generateActivityInfo(ParsingPackageRead, ParsedActivity, long, 512 * PackageUserState, ApplicationInfo, int)}. 513 */ 514 @NonNull generateActivityInfoUnchecked(@onNull ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull ApplicationInfo applicationInfo)515 public static ActivityInfo generateActivityInfoUnchecked(@NonNull ParsedActivity a, 516 @PackageManager.ComponentInfoFlagsBits long flags, 517 @NonNull ApplicationInfo applicationInfo) { 518 // Make shallow copies so we can store the metadata safely 519 ActivityInfo ai = new ActivityInfo(); 520 assignSharedFieldsForComponentInfo(ai, a); 521 ai.targetActivity = a.getTargetActivity(); 522 ai.processName = a.getProcessName(); 523 ai.exported = a.isExported(); 524 ai.theme = a.getTheme(); 525 ai.uiOptions = a.getUiOptions(); 526 ai.parentActivityName = a.getParentActivityName(); 527 ai.permission = a.getPermission(); 528 ai.taskAffinity = a.getTaskAffinity(); 529 ai.flags = a.getFlags(); 530 ai.privateFlags = a.getPrivateFlags(); 531 ai.launchMode = a.getLaunchMode(); 532 ai.documentLaunchMode = a.getDocumentLaunchMode(); 533 ai.maxRecents = a.getMaxRecents(); 534 ai.configChanges = a.getConfigChanges(); 535 ai.softInputMode = a.getSoftInputMode(); 536 ai.persistableMode = a.getPersistableMode(); 537 ai.lockTaskLaunchMode = a.getLockTaskLaunchMode(); 538 ai.screenOrientation = a.getScreenOrientation(); 539 ai.resizeMode = a.getResizeMode(); 540 ai.setMaxAspectRatio(a.getMaxAspectRatio()); 541 ai.setMinAspectRatio(a.getMinAspectRatio()); 542 ai.supportsSizeChanges = a.isSupportsSizeChanges(); 543 ai.requestedVrComponent = a.getRequestedVrComponent(); 544 ai.rotationAnimation = a.getRotationAnimation(); 545 ai.colorMode = a.getColorMode(); 546 ai.windowLayout = a.getWindowLayout(); 547 ai.attributionTags = a.getAttributionTags(); 548 if ((flags & PackageManager.GET_META_DATA) != 0) { 549 var metaData = a.getMetaData(); 550 // Backwards compatibility, coerce to null if empty 551 ai.metaData = metaData.isEmpty() ? null : metaData; 552 } 553 ai.applicationInfo = applicationInfo; 554 ai.setKnownActivityEmbeddingCerts(a.getKnownActivityEmbeddingCerts()); 555 return ai; 556 } 557 558 @Nullable generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, int userId)559 public static ActivityInfo generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a, 560 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, 561 int userId) { 562 return generateActivityInfo(pkg, a, flags, state, null, userId); 563 } 564 565 @Nullable generateServiceInfo(ParsingPackageRead pkg, ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, @Nullable ApplicationInfo applicationInfo, int userId)566 public static ServiceInfo generateServiceInfo(ParsingPackageRead pkg, ParsedService s, 567 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, 568 @Nullable ApplicationInfo applicationInfo, int userId) { 569 if (s == null) return null; 570 if (!checkUseInstalled(pkg, state, flags)) { 571 return null; 572 } 573 if (applicationInfo == null) { 574 applicationInfo = generateApplicationInfo(pkg, flags, state, userId); 575 } 576 if (applicationInfo == null) { 577 return null; 578 } 579 580 return generateServiceInfoUnchecked(s, flags, applicationInfo); 581 } 582 583 /** 584 * This bypasses critical checks that are necessary for usage with data passed outside of system 585 * server. 586 * <p> 587 * Prefer {@link #generateServiceInfo(ParsingPackageRead, ParsedService, long, PackageUserState, 588 * ApplicationInfo, int)}. 589 */ 590 @NonNull generateServiceInfoUnchecked(@onNull ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull ApplicationInfo applicationInfo)591 public static ServiceInfo generateServiceInfoUnchecked(@NonNull ParsedService s, 592 @PackageManager.ComponentInfoFlagsBits long flags, 593 @NonNull ApplicationInfo applicationInfo) { 594 // Make shallow copies so we can store the metadata safely 595 ServiceInfo si = new ServiceInfo(); 596 assignSharedFieldsForComponentInfo(si, s); 597 si.exported = s.isExported(); 598 si.flags = s.getFlags(); 599 si.permission = s.getPermission(); 600 si.processName = s.getProcessName(); 601 si.mForegroundServiceType = s.getForegroundServiceType(); 602 si.applicationInfo = applicationInfo; 603 if ((flags & PackageManager.GET_META_DATA) != 0) { 604 var metaData = s.getMetaData(); 605 // Backwards compatibility, coerce to null if empty 606 si.metaData = metaData.isEmpty() ? null : metaData; 607 } 608 return si; 609 } 610 611 @Nullable generateServiceInfo(ParsingPackageRead pkg, ParsedService s, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, int userId)612 public static ServiceInfo generateServiceInfo(ParsingPackageRead pkg, ParsedService s, 613 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, 614 int userId) { 615 return generateServiceInfo(pkg, s, flags, state, null, userId); 616 } 617 618 @Nullable generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, @Nullable ApplicationInfo applicationInfo, int userId)619 public static ProviderInfo generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p, 620 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, 621 @Nullable ApplicationInfo applicationInfo, int userId) { 622 if (p == null) return null; 623 if (!checkUseInstalled(pkg, state, flags)) { 624 return null; 625 } 626 if (applicationInfo == null) { 627 applicationInfo = generateApplicationInfo(pkg, flags, state, userId); 628 } 629 if (applicationInfo == null) { 630 return null; 631 } 632 633 return generateProviderInfoUnchecked(p, flags, applicationInfo); 634 } 635 636 /** 637 * This bypasses critical checks that are necessary for usage with data passed outside of system 638 * server. 639 * <p> 640 * Prefer {@link #generateProviderInfo(ParsingPackageRead, ParsedProvider, long, 641 * PackageUserState, ApplicationInfo, int)}. 642 */ 643 @NonNull generateProviderInfoUnchecked(@onNull ParsedProvider p, @PackageManager.ComponentInfoFlagsBits long flags, @NonNull ApplicationInfo applicationInfo)644 public static ProviderInfo generateProviderInfoUnchecked(@NonNull ParsedProvider p, 645 @PackageManager.ComponentInfoFlagsBits long flags, 646 @NonNull ApplicationInfo applicationInfo) { 647 // Make shallow copies so we can store the metadata safely 648 ProviderInfo pi = new ProviderInfo(); 649 assignSharedFieldsForComponentInfo(pi, p); 650 pi.exported = p.isExported(); 651 pi.flags = p.getFlags(); 652 pi.processName = p.getProcessName(); 653 pi.authority = p.getAuthority(); 654 pi.isSyncable = p.isSyncable(); 655 pi.readPermission = p.getReadPermission(); 656 pi.writePermission = p.getWritePermission(); 657 pi.grantUriPermissions = p.isGrantUriPermissions(); 658 pi.forceUriPermissions = p.isForceUriPermissions(); 659 pi.multiprocess = p.isMultiProcess(); 660 pi.initOrder = p.getInitOrder(); 661 pi.uriPermissionPatterns = p.getUriPermissionPatterns().toArray(new PatternMatcher[0]); 662 pi.pathPermissions = p.getPathPermissions().toArray(new PathPermission[0]); 663 if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) { 664 pi.uriPermissionPatterns = null; 665 } 666 if ((flags & PackageManager.GET_META_DATA) != 0) { 667 var metaData = p.getMetaData(); 668 // Backwards compatibility, coerce to null if empty 669 pi.metaData = metaData.isEmpty() ? null : metaData; 670 } 671 pi.applicationInfo = applicationInfo; 672 return pi; 673 } 674 675 @Nullable generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p, @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, int userId)676 public static ProviderInfo generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p, 677 @PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state, 678 int userId) { 679 return generateProviderInfo(pkg, p, flags, state, null, userId); 680 } 681 682 /** 683 * @param assignUserFields see {@link #generateApplicationInfoUnchecked(ParsingPackageRead, 684 * long, PackageUserState, int, boolean)} 685 */ 686 @Nullable generateInstrumentationInfo(ParsedInstrumentation i, ParsingPackageRead pkg, @PackageManager.ComponentInfoFlagsBits long flags, int userId, boolean assignUserFields)687 public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i, 688 ParsingPackageRead pkg, @PackageManager.ComponentInfoFlagsBits long flags, int userId, 689 boolean assignUserFields) { 690 if (i == null) return null; 691 692 InstrumentationInfo ii = new InstrumentationInfo(); 693 assignSharedFieldsForPackageItemInfo(ii, i); 694 ii.targetPackage = i.getTargetPackage(); 695 ii.targetProcesses = i.getTargetProcesses(); 696 ii.handleProfiling = i.isHandleProfiling(); 697 ii.functionalTest = i.isFunctionalTest(); 698 699 ii.sourceDir = pkg.getBaseApkPath(); 700 ii.publicSourceDir = pkg.getBaseApkPath(); 701 ii.splitNames = pkg.getSplitNames(); 702 ii.splitSourceDirs = pkg.getSplitCodePaths().length == 0 ? null : pkg.getSplitCodePaths(); 703 ii.splitPublicSourceDirs = pkg.getSplitCodePaths().length == 0 704 ? null : pkg.getSplitCodePaths(); 705 ii.splitDependencies = pkg.getSplitDependencies().size() == 0 706 ? null : pkg.getSplitDependencies(); 707 708 if (assignUserFields) { 709 assignUserFields(pkg, ii, userId); 710 } 711 712 if ((flags & PackageManager.GET_META_DATA) == 0) { 713 return ii; 714 } 715 var metaData = i.getMetaData(); 716 // Backwards compatibility, coerce to null if empty 717 ii.metaData = metaData.isEmpty() ? null : metaData; 718 return ii; 719 } 720 721 @Nullable generatePermissionInfo(ParsedPermission p, @PackageManager.ComponentInfoFlagsBits long flags)722 public static PermissionInfo generatePermissionInfo(ParsedPermission p, 723 @PackageManager.ComponentInfoFlagsBits long flags) { 724 if (p == null) return null; 725 726 PermissionInfo pi = new PermissionInfo(p.getBackgroundPermission()); 727 728 assignSharedFieldsForPackageItemInfo(pi, p); 729 730 pi.group = p.getGroup(); 731 pi.requestRes = p.getRequestRes(); 732 pi.protectionLevel = p.getProtectionLevel(); 733 pi.descriptionRes = p.getDescriptionRes(); 734 pi.flags = p.getFlags(); 735 pi.knownCerts = p.getKnownCerts(); 736 737 if ((flags & PackageManager.GET_META_DATA) == 0) { 738 return pi; 739 } 740 var metaData = p.getMetaData(); 741 // Backwards compatibility, coerce to null if empty 742 pi.metaData = metaData.isEmpty() ? null : metaData; 743 return pi; 744 } 745 746 @Nullable generatePermissionGroupInfo(ParsedPermissionGroup pg, @PackageManager.ComponentInfoFlagsBits long flags)747 public static PermissionGroupInfo generatePermissionGroupInfo(ParsedPermissionGroup pg, 748 @PackageManager.ComponentInfoFlagsBits long flags) { 749 if (pg == null) return null; 750 751 PermissionGroupInfo pgi = new PermissionGroupInfo( 752 pg.getRequestDetailRes(), 753 pg.getBackgroundRequestRes(), 754 pg.getBackgroundRequestDetailRes() 755 ); 756 757 assignSharedFieldsForPackageItemInfo(pgi, pg); 758 pgi.descriptionRes = pg.getDescriptionRes(); 759 pgi.priority = pg.getPriority(); 760 pgi.requestRes = pg.getRequestRes(); 761 pgi.flags = pg.getFlags(); 762 763 if ((flags & PackageManager.GET_META_DATA) == 0) { 764 return pgi; 765 } 766 var metaData = pg.getMetaData(); 767 // Backwards compatibility, coerce to null if empty 768 pgi.metaData = metaData.isEmpty() ? null : metaData; 769 return pgi; 770 } 771 772 @Nullable generateAttribution(ParsedAttribution pa)773 public static Attribution generateAttribution(ParsedAttribution pa) { 774 if (pa == null) return null; 775 return new Attribution(pa.getTag(), pa.getLabel()); 776 } 777 checkUseInstalledOrHidden(long flags, @NonNull PackageUserState state, @Nullable ApplicationInfo appInfo)778 private static boolean checkUseInstalledOrHidden(long flags, 779 @NonNull PackageUserState state, @Nullable ApplicationInfo appInfo) { 780 // Returns false if the package is hidden system app until installed. 781 if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0 782 && !state.isInstalled() 783 && appInfo != null && appInfo.hiddenUntilInstalled) { 784 return false; 785 } 786 787 // If available for the target user, or trying to match uninstalled packages and it's 788 // a system app. 789 return PackageUserStateUtils.isAvailable(state, flags) 790 || (appInfo != null && appInfo.isSystemApp() 791 && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0 792 || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0)); 793 } 794 assignSharedFieldsForComponentInfo(@onNull ComponentInfo componentInfo, @NonNull ParsedMainComponent mainComponent)795 private static void assignSharedFieldsForComponentInfo(@NonNull ComponentInfo componentInfo, 796 @NonNull ParsedMainComponent mainComponent) { 797 assignSharedFieldsForPackageItemInfo(componentInfo, mainComponent); 798 componentInfo.descriptionRes = mainComponent.getDescriptionRes(); 799 componentInfo.directBootAware = mainComponent.isDirectBootAware(); 800 componentInfo.enabled = mainComponent.isEnabled(); 801 componentInfo.splitName = mainComponent.getSplitName(); 802 componentInfo.attributionTags = mainComponent.getAttributionTags(); 803 } 804 assignSharedFieldsForPackageItemInfo( @onNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component)805 private static void assignSharedFieldsForPackageItemInfo( 806 @NonNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component) { 807 packageItemInfo.nonLocalizedLabel = ComponentParseUtils.getNonLocalizedLabel(component); 808 packageItemInfo.icon = ComponentParseUtils.getIcon(component); 809 810 packageItemInfo.banner = component.getBanner(); 811 packageItemInfo.labelRes = component.getLabelRes(); 812 packageItemInfo.logo = component.getLogo(); 813 packageItemInfo.name = component.getName(); 814 packageItemInfo.packageName = component.getPackageName(); 815 } 816 817 @CheckResult flag(boolean hasFlag, int flag)818 private static int flag(boolean hasFlag, int flag) { 819 if (hasFlag) { 820 return flag; 821 } else { 822 return 0; 823 } 824 } 825 826 /** 827 * @see ApplicationInfo#flags 828 */ appInfoFlags(ParsingPackageRead pkg)829 public static int appInfoFlags(ParsingPackageRead pkg) { 830 // @formatter:off 831 return flag(pkg.isExternalStorage(), ApplicationInfo.FLAG_EXTERNAL_STORAGE) 832 | flag(pkg.isBaseHardwareAccelerated(), ApplicationInfo.FLAG_HARDWARE_ACCELERATED) 833 | flag(pkg.isAllowBackup(), ApplicationInfo.FLAG_ALLOW_BACKUP) 834 | flag(pkg.isKillAfterRestore(), ApplicationInfo.FLAG_KILL_AFTER_RESTORE) 835 | flag(pkg.isRestoreAnyVersion(), ApplicationInfo.FLAG_RESTORE_ANY_VERSION) 836 | flag(pkg.isFullBackupOnly(), ApplicationInfo.FLAG_FULL_BACKUP_ONLY) 837 | flag(pkg.isPersistent(), ApplicationInfo.FLAG_PERSISTENT) 838 | flag(pkg.isDebuggable(), ApplicationInfo.FLAG_DEBUGGABLE) 839 | flag(pkg.isVmSafeMode(), ApplicationInfo.FLAG_VM_SAFE_MODE) 840 | flag(pkg.isHasCode(), ApplicationInfo.FLAG_HAS_CODE) 841 | flag(pkg.isAllowTaskReparenting(), ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING) 842 | flag(pkg.isAllowClearUserData(), ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) 843 | flag(pkg.isLargeHeap(), ApplicationInfo.FLAG_LARGE_HEAP) 844 | flag(pkg.isUsesCleartextTraffic(), ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) 845 | flag(pkg.isSupportsRtl(), ApplicationInfo.FLAG_SUPPORTS_RTL) 846 | flag(pkg.isTestOnly(), ApplicationInfo.FLAG_TEST_ONLY) 847 | flag(pkg.isMultiArch(), ApplicationInfo.FLAG_MULTIARCH) 848 | flag(pkg.isExtractNativeLibs(), ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) 849 | flag(pkg.isGame(), ApplicationInfo.FLAG_IS_GAME) 850 | flag(pkg.isSupportsSmallScreens(), ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) 851 | flag(pkg.isSupportsNormalScreens(), ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) 852 | flag(pkg.isSupportsLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) 853 | flag(pkg.isSupportsExtraLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) 854 | flag(pkg.isResizeable(), ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) 855 | flag(pkg.isAnyDensity(), ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES); 856 // @formatter:on 857 } 858 859 /** @see ApplicationInfo#privateFlags */ appInfoPrivateFlags(ParsingPackageRead pkg)860 public static int appInfoPrivateFlags(ParsingPackageRead pkg) { 861 // @formatter:off 862 int privateFlags = flag(pkg.isStaticSharedLibrary(), ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY) 863 | flag(pkg.isOverlay(), ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY) 864 | flag(pkg.isIsolatedSplitLoading(), ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING) 865 | flag(pkg.isHasDomainUrls(), ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) 866 | flag(pkg.isProfileableByShell(), ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) 867 | flag(pkg.isBackupInForeground(), ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND) 868 | flag(pkg.isUseEmbeddedDex(), ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX) 869 | flag(pkg.isDefaultToDeviceProtectedStorage(), ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) 870 | flag(pkg.isDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE) 871 | flag(pkg.isPartiallyDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE) 872 | flag(pkg.isAllowClearUserDataOnFailedRestore(), ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE) 873 | flag(pkg.isAllowAudioPlaybackCapture(), ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE) 874 | flag(pkg.isRequestLegacyExternalStorage(), ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE) 875 | flag(pkg.isUsesNonSdkApi(), ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API) 876 | flag(pkg.isHasFragileUserData(), ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA) 877 | flag(pkg.isCantSaveState(), ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) 878 | flag(pkg.isResizeableActivityViaSdkVersion(), ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) 879 | flag(pkg.isAllowNativeHeapPointerTagging(), ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING); 880 // @formatter:on 881 882 Boolean resizeableActivity = pkg.getResizeableActivity(); 883 if (resizeableActivity != null) { 884 if (resizeableActivity) { 885 privateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE; 886 } else { 887 privateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE; 888 } 889 } 890 891 return privateFlags; 892 } 893 894 /** @see ApplicationInfo#privateFlagsExt */ appInfoPrivateFlagsExt(ParsingPackageRead pkg)895 public static int appInfoPrivateFlagsExt(ParsingPackageRead pkg) { 896 // @formatter:off 897 int privateFlagsExt = 898 flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE) 899 | flag(pkg.hasRequestForegroundServiceExemption(), 900 ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION) 901 | flag(pkg.areAttributionsUserVisible(), 902 ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE) 903 | flag(pkg.isOnBackInvokedCallbackEnabled(), 904 ApplicationInfo.PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK); 905 // @formatter:on 906 return privateFlagsExt; 907 } 908 checkUseInstalled(ParsingPackageRead pkg, PackageUserState state, @PackageManager.PackageInfoFlagsBits long flags)909 private static boolean checkUseInstalled(ParsingPackageRead pkg, 910 PackageUserState state, @PackageManager.PackageInfoFlagsBits long flags) { 911 // If available for the target user 912 return PackageUserStateUtils.isAvailable(state, flags); 913 } 914 915 @NonNull getDataDir(ParsingPackageRead pkg, int userId)916 public static File getDataDir(ParsingPackageRead pkg, int userId) { 917 if ("android".equals(pkg.getPackageName())) { 918 return Environment.getDataSystemDirectory(); 919 } 920 921 if (pkg.isDefaultToDeviceProtectedStorage() 922 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 923 return getDeviceProtectedDataDir(pkg, userId); 924 } else { 925 return getCredentialProtectedDataDir(pkg, userId); 926 } 927 } 928 929 @NonNull getDeviceProtectedDataDir(ParsingPackageRead pkg, int userId)930 public static File getDeviceProtectedDataDir(ParsingPackageRead pkg, int userId) { 931 return Environment.getDataUserDePackageDirectory(pkg.getVolumeUuid(), userId, 932 pkg.getPackageName()); 933 } 934 935 @NonNull getCredentialProtectedDataDir(ParsingPackageRead pkg, int userId)936 public static File getCredentialProtectedDataDir(ParsingPackageRead pkg, int userId) { 937 return Environment.getDataUserCePackageDirectory(pkg.getVolumeUuid(), userId, 938 pkg.getPackageName()); 939 } 940 assignUserFields(ParsingPackageRead pkg, ApplicationInfo info, int userId)941 private static void assignUserFields(ParsingPackageRead pkg, ApplicationInfo info, int userId) { 942 // This behavior is undefined for no-state ApplicationInfos when called by a public API, 943 // since the uid is never assigned by the system. It will always effectively be appId 0. 944 info.uid = UserHandle.getUid(userId, UserHandle.getAppId(info.uid)); 945 946 String pkgName = pkg.getPackageName(); 947 if ("android".equals(pkgName)) { 948 info.dataDir = SYSTEM_DATA_PATH; 949 return; 950 } 951 952 // For performance reasons, all these paths are built as strings 953 String baseDataDirPrefix = 954 Environment.getDataDirectoryPath(pkg.getVolumeUuid()) + File.separator; 955 String userIdPkgSuffix = File.separator + userId + File.separator + pkgName; 956 info.credentialProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_CE 957 + userIdPkgSuffix; 958 info.deviceProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_DE + userIdPkgSuffix; 959 960 if (pkg.isDefaultToDeviceProtectedStorage() 961 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 962 info.dataDir = info.deviceProtectedDataDir; 963 } else { 964 info.dataDir = info.credentialProtectedDataDir; 965 } 966 } 967 assignUserFields(ParsingPackageRead pkg, InstrumentationInfo info, int userId)968 private static void assignUserFields(ParsingPackageRead pkg, InstrumentationInfo info, 969 int userId) { 970 String pkgName = pkg.getPackageName(); 971 if ("android".equals(pkgName)) { 972 info.dataDir = SYSTEM_DATA_PATH; 973 return; 974 } 975 976 // For performance reasons, all these paths are built as strings 977 String baseDataDirPrefix = 978 Environment.getDataDirectoryPath(pkg.getVolumeUuid()) + File.separator; 979 String userIdPkgSuffix = File.separator + userId + File.separator + pkgName; 980 info.credentialProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_CE 981 + userIdPkgSuffix; 982 info.deviceProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_DE + userIdPkgSuffix; 983 984 if (pkg.isDefaultToDeviceProtectedStorage() 985 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 986 info.dataDir = info.deviceProtectedDataDir; 987 } else { 988 info.dataDir = info.credentialProtectedDataDir; 989 } 990 } 991 } 992