1// Copyright 2015 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package java 16 17// This file contains the module implementations for android_app, android_test, and some more 18// related module types, including their override variants. 19 20import ( 21 "fmt" 22 "path/filepath" 23 "strings" 24 25 "github.com/google/blueprint" 26 "github.com/google/blueprint/depset" 27 "github.com/google/blueprint/proptools" 28 29 "android/soong/android" 30 "android/soong/cc" 31 "android/soong/dexpreopt" 32 "android/soong/tradefed" 33) 34 35func init() { 36 RegisterAppBuildComponents(android.InitRegistrationContext) 37 pctx.HostBinToolVariable("ModifyAllowlistCmd", "modify_permissions_allowlist") 38} 39 40var ( 41 modifyAllowlist = pctx.AndroidStaticRule("modifyAllowlist", 42 blueprint.RuleParams{ 43 Command: "${ModifyAllowlistCmd} $in $packageName $out", 44 CommandDeps: []string{"${ModifyAllowlistCmd}"}, 45 }, "packageName") 46) 47 48type FlagsPackages struct { 49 // Paths to the aconfig dump output text files that are consumed by aapt2 50 AconfigTextFiles android.Paths 51} 52 53var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]() 54 55func RegisterAppBuildComponents(ctx android.RegistrationContext) { 56 ctx.RegisterModuleType("android_app", AndroidAppFactory) 57 ctx.RegisterModuleType("android_test", AndroidTestFactory) 58 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory) 59 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory) 60 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory) 61 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory) 62} 63 64type AppInfo struct { 65 // Updatable is set to the value of the updatable property 66 Updatable bool 67 68 // TestHelperApp is true if the module is a android_test_helper_app 69 TestHelperApp bool 70 71 // EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK. 72 EmbeddedJNILibs android.Paths 73 74 MergedManifestFile android.Path 75 76 Prebuilt bool 77 AppSet bool 78 Privileged bool 79 OutputFile android.Path 80 InstallApkName string 81 JacocoReportClassesFile android.Path 82 Certificate Certificate 83 PrivAppAllowlist android.OptionalPath 84 OverriddenManifestPackageName *string 85 ApkCertsFile android.Path 86} 87 88var AppInfoProvider = blueprint.NewProvider[*AppInfo]() 89 90// AndroidManifest.xml merging 91// package splits 92 93type appProperties struct { 94 // Names of extra android_app_certificate modules to sign the apk with in the form ":module". 95 Additional_certificates []string 96 97 // If set, create package-export.apk, which other packages can 98 // use to get PRODUCT-agnostic resource data like IDs and type definitions. 99 Export_package_resources *bool 100 101 // Specifies that this app should be installed to the priv-app directory, 102 // where the system will grant it additional privileges not available to 103 // normal apps. 104 Privileged *bool 105 106 // list of resource labels to generate individual resource packages 107 Package_splits []string 108 109 // list of native libraries that will be provided in or alongside the resulting jar 110 Jni_libs proptools.Configurable[[]string] `android:"arch_variant"` 111 112 // if true, use JNI libraries that link against platform APIs even if this module sets 113 // sdk_version. 114 Jni_uses_platform_apis *bool 115 116 // if true, use JNI libraries that link against SDK APIs even if this module does not set 117 // sdk_version. 118 Jni_uses_sdk_apis *bool 119 120 // STL library to use for JNI libraries. 121 Stl *string `android:"arch_variant"` 122 123 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest 124 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless 125 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for 126 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native 127 // libraries are generally preinstalled outside the APK. 128 Use_embedded_native_libs *bool 129 130 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that 131 // they are used from inside the APK at runtime. 132 Use_embedded_dex *bool 133 134 // Forces native libraries to always be packaged into the APK, 135 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed. 136 // True for android_test* modules. 137 AlwaysPackageNativeLibs bool `blueprint:"mutated"` 138 139 // If set, find and merge all NOTICE files that this module and its dependencies have and store 140 // it in the APK as an asset. 141 Embed_notices *bool 142 143 // cc.Coverage related properties 144 PreventInstall bool `blueprint:"mutated"` 145 IsCoverageVariant bool `blueprint:"mutated"` 146 147 // It can be set to test the behaviour of default target sdk version. 148 // Only required when updatable: false. It is an error if updatable: true and this is false. 149 Enforce_default_target_sdk_version *bool 150 151 // If set, the targetSdkVersion for the target is set to the latest default API level. 152 // This would be by default false, unless updatable: true or 153 // enforce_default_target_sdk_version: true in which case this defaults to true. 154 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"` 155 156 // Whether this app is considered mainline updatable or not. When set to true, this will enforce 157 // additional rules to make sure an app can safely be updated. Default is false. 158 // Prefer using other specific properties if build behaviour must be changed; avoid using this 159 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners). 160 Updatable *bool 161 162 // Specifies the file that contains the allowlist for this app. 163 Privapp_allowlist *string `android:"path"` 164 165 // If set, create an RRO package which contains only resources having PRODUCT_CHARACTERISTICS 166 // and install the RRO package to /product partition, instead of passing --product argument 167 // to aapt2. Default is false. 168 // Setting this will make this APK identical to all targets, regardless of 169 // PRODUCT_CHARACTERISTICS. 170 Generate_product_characteristics_rro *bool 171 172 ProductCharacteristicsRROPackageName *string `blueprint:"mutated"` 173 ProductCharacteristicsRROManifestModuleName *string `blueprint:"mutated"` 174} 175 176// android_app properties that can be overridden by override_android_app 177type overridableAppProperties struct { 178 // The name of a certificate in the default certificate directory, blank to use the default product certificate, 179 // or an android_app_certificate module name in the form ":module". 180 Certificate proptools.Configurable[string] `android:"replace_instead_of_append"` 181 182 // Name of the signing certificate lineage file or filegroup module. 183 Lineage *string `android:"path"` 184 185 // For overriding the --rotation-min-sdk-version property of apksig 186 RotationMinSdkVersion *string 187 188 // the package name of this app. The package name in the manifest file is used if one was not given. 189 Package_name proptools.Configurable[string] 190 191 // the logging parent of this app. 192 Logging_parent *string 193 194 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true. 195 Rename_resources_package *bool 196 197 // Names of modules to be overridden. Listed modules can only be other binaries 198 // (in Make or Soong). 199 // This does not completely prevent installation of the overridden binaries, but if both 200 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed 201 // from PRODUCT_PACKAGES. 202 Overrides []string 203} 204 205type AndroidApp struct { 206 Library 207 aapt 208 android.OverridableModuleBase 209 210 certificate Certificate 211 212 appProperties appProperties 213 214 overridableAppProperties overridableAppProperties 215 216 jniLibs []jniLib 217 installPathForJNISymbols android.Path 218 embeddedJniLibs bool 219 jniCoverageOutputs android.Paths 220 221 bundleFile android.Path 222 223 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES. 224 installApkName string 225 226 installDir android.InstallPath 227 228 onDeviceDir string 229 230 additionalAaptFlags []string 231 232 overriddenManifestPackageName string 233 234 android.ApexBundleDepsInfo 235 236 javaApiUsedByOutputFile android.ModuleOutPath 237 238 privAppAllowlist android.OptionalPath 239 240 requiredModuleNames []string 241} 242 243func (a *AndroidApp) IsInstallable() bool { 244 return Bool(a.properties.Installable) 245} 246 247func (a *AndroidApp) ResourcesNodeDepSet() depset.DepSet[*resourcesNode] { 248 return a.aapt.resourcesNodesDepSet 249} 250 251func (a *AndroidApp) OutputFile() android.Path { 252 return a.outputFile 253} 254 255func (a *AndroidApp) Certificate() Certificate { 256 return a.certificate 257} 258 259func (a *AndroidApp) JniCoverageOutputs() android.Paths { 260 return a.jniCoverageOutputs 261} 262 263func (a *AndroidApp) PrivAppAllowlist() android.OptionalPath { 264 return a.privAppAllowlist 265} 266 267var _ AndroidLibraryDependency = (*AndroidApp)(nil) 268 269type Certificate struct { 270 Pem, Key android.Path 271 presigned bool 272} 273 274var PresignedCertificate = Certificate{presigned: true} 275 276func (c Certificate) AndroidMkString() string { 277 if c.presigned { 278 return "PRESIGNED" 279 } else { 280 return c.Pem.String() 281 } 282} 283 284func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { 285 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() { 286 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared") 287 } 288 289 sdkDep := decodeSdkDep(ctx, android.SdkContext(a)) 290 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs()) 291 a.Module.deps(ctx) 292 if sdkDep.hasFrameworkLibs() { 293 a.aapt.deps(ctx, sdkDep) 294 } 295 296 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform 297 298 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) { 299 ctx.PropertyErrorf("jni_uses_sdk_apis", 300 "can only be set for modules that do not set sdk_version") 301 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) { 302 ctx.PropertyErrorf("jni_uses_platform_apis", 303 "can only be set for modules that set sdk_version") 304 } 305 306 for _, jniTarget := range ctx.MultiTargets() { 307 variation := append(jniTarget.Variations(), 308 blueprint.Variation{Mutator: "link", Variation: "shared"}) 309 310 // Test whether to use the SDK variant or the non-SDK variant of JNI dependencies. 311 // Many factors are considered here. 312 // 1. Basically, the selection follows whether the app has sdk_version set or not. 313 jniUsesSdkVariant := usesSDK 314 // 2. However, jni_uses_platform_apis and jni_uses_sdk_apis can override it 315 if Bool(a.appProperties.Jni_uses_sdk_apis) { 316 jniUsesSdkVariant = true 317 } 318 if Bool(a.appProperties.Jni_uses_platform_apis) { 319 jniUsesSdkVariant = false 320 } 321 // 3. Then the use of SDK variant is again prohibited for the following cases: 322 // 3.1. the app is shipped on unbundled partitions like vendor. Since the entire 323 // partition (not only the app) is considered unbudled, there's no need to use the 324 // SDK variant. 325 // 3.2. the app doesn't support embedding the JNI libs 326 if a.RequiresStableAPIs(ctx) || !a.shouldEmbedJnis(ctx) { 327 jniUsesSdkVariant = false 328 } 329 if jniUsesSdkVariant { 330 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"}) 331 } 332 333 // Use the installable dep tag when the JNIs are not embedded 334 var tag dependencyTag 335 if a.shouldEmbedJnis(ctx) { 336 tag = jniLibTag 337 } else { 338 tag = jniInstallTag 339 } 340 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs.GetOrDefault(ctx, nil)...) 341 } 342 for _, aconfig_declaration := range a.aaptProperties.Flags_packages { 343 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration) 344 } 345} 346 347func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) { 348 cert := android.SrcIsModule(a.getCertString(ctx)) 349 if cert != "" { 350 ctx.AddDependency(ctx.Module(), certificateTag, cert) 351 } 352 353 if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) { 354 // There are a few uids that are explicitly considered privileged regardless of their 355 // app's location. Bluetooth is one such app. It should arguably be moved to priv-app, 356 // but for now, allow it not to be in priv-app. 357 privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth" 358 if !privilegedBecauseOfUid { 359 ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)") 360 } 361 } 362 363 for _, cert := range a.appProperties.Additional_certificates { 364 cert = android.SrcIsModule(cert) 365 if cert != "" { 366 ctx.AddDependency(ctx.Module(), certificateTag, cert) 367 } else { 368 ctx.PropertyErrorf("additional_certificates", 369 `must be names of android_app_certificate modules in the form ":module"`) 370 } 371 } 372} 373 374// TODO(b/156476221): Remove this allowlist 375var ( 376 missingMinSdkVersionMtsAllowlist = []string{ 377 "CellBroadcastReceiverGoogleUnitTests", 378 "CellBroadcastReceiverUnitTests", 379 "CtsBatterySavingTestCases", 380 "CtsDeviceAndProfileOwnerApp23", 381 "CtsDeviceAndProfileOwnerApp30", 382 "CtsIntentSenderApp", 383 "CtsJobSchedulerTestCases", 384 "CtsMimeMapTestCases", 385 "CtsTareTestCases", 386 "LibStatsPullTests", 387 "MediaProviderClientTests", 388 "TeleServiceTests", 389 "TestExternalImsServiceApp", 390 "TestSmsRetrieverApp", 391 "TetheringPrivilegedTests", 392 } 393) 394 395func checkMinSdkVersionMts(ctx android.ModuleContext, minSdkVersion android.ApiLevel) { 396 if includedInMts(ctx.Module()) && !minSdkVersion.Specified() && !android.InList(ctx.ModuleName(), missingMinSdkVersionMtsAllowlist) { 397 ctx.PropertyErrorf("min_sdk_version", "min_sdk_version is a required property for tests included in MTS") 398 } 399} 400 401func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { 402 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx)) 403 applicationId := a.appTestHelperAppProperties.Manifest_values.ApplicationId 404 if applicationId != nil { 405 packageName := a.overridableAppProperties.Package_name.Get(ctx) 406 if packageName.IsPresent() { 407 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.") 408 } 409 a.aapt.manifestValues.applicationId = *applicationId 410 } 411 a.generateAndroidBuildActions(ctx) 412 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ 413 TestOnly: true, 414 }) 415 appInfo := &AppInfo{ 416 Updatable: Bool(a.appProperties.Updatable), 417 TestHelperApp: true, 418 } 419 setCommonAppInfo(appInfo, a) 420 android.SetProvider(ctx, AppInfoProvider, appInfo) 421 422 moduleInfoJSON := ctx.ModuleInfoJSON() 423 moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests") 424 if len(a.appTestHelperAppProperties.Test_suites) > 0 { 425 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.appTestHelperAppProperties.Test_suites...) 426 } else { 427 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") 428 } 429 430 android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ 431 TestSuites: a.appTestHelperAppProperties.Test_suites, 432 }) 433} 434 435func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { 436 a.checkAppSdkVersions(ctx) 437 a.checkEmbedJnis(ctx) 438 a.generateAndroidBuildActions(ctx) 439 a.generateJavaUsedByApex(ctx) 440 441 var embeddedJniLibs []android.Path 442 443 if a.embeddedJniLibs { 444 for _, jni := range a.jniLibs { 445 embeddedJniLibs = append(embeddedJniLibs, jni.path) 446 } 447 } 448 overriddenName := a.OverriddenManifestPackageName() 449 appInfo := &AppInfo{ 450 Updatable: Bool(a.appProperties.Updatable), 451 TestHelperApp: false, 452 EmbeddedJNILibs: embeddedJniLibs, 453 MergedManifestFile: a.mergedManifest, 454 OverriddenManifestPackageName: &overriddenName, 455 } 456 setCommonAppInfo(appInfo, a) 457 android.SetProvider(ctx, AppInfoProvider, appInfo) 458 459 a.requiredModuleNames = a.getRequiredModuleNames(ctx) 460 461 if a.dexer.proguardDictionary.Valid() { 462 android.SetProvider(ctx, ProguardProvider, ProguardInfo{ 463 ModuleName: ctx.ModuleName(), 464 Class: "APPS", 465 ProguardDictionary: a.dexer.proguardDictionary.Path(), 466 ProguardUsageZip: a.dexer.proguardUsageZip.Path(), 467 ClassesJar: a.implementationAndResourcesJar, 468 }) 469 } 470} 471 472func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string { 473 var required []string 474 if proptools.Bool(a.appProperties.Generate_product_characteristics_rro) { 475 required = []string{a.productCharacteristicsRROPackageName()} 476 } 477 // Install the vendor overlay variant if this app is installed. 478 if len(filterRRO(a.rroDirsDepSet, device)) > 0 { 479 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "vendor")) 480 } 481 // Install the product overlay variant if this app is installed. 482 if len(filterRRO(a.rroDirsDepSet, product)) > 0 { 483 required = append(required, AutogeneratedRroModuleName(ctx, ctx.Module().Name(), "product")) 484 } 485 return required 486} 487 488func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) { 489 if a.Updatable() { 490 if !a.SdkVersion(ctx).Stable() { 491 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx)) 492 } 493 if String(a.overridableProperties.Min_sdk_version) == "" { 494 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.") 495 } 496 497 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil { 498 a.checkJniLibsSdkVersion(ctx, minSdkVersion) 499 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps) 500 } else { 501 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) 502 } 503 504 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) { 505 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version") 506 } 507 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set. 508 if a.deviceProperties.Target_sdk_version == nil { 509 a.SetEnforceDefaultTargetSdkVersion(true) 510 } 511 } 512 513 a.checkPlatformAPI(ctx) 514 a.checkSdkVersions(ctx) 515} 516 517// Ensures that use_embedded_native_libs are set for apk-in-apex 518func (a *AndroidApp) checkEmbedJnis(ctx android.BaseModuleContext) { 519 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 520 apkInApex := !apexInfo.IsForPlatform() 521 hasJnis := len(a.appProperties.Jni_libs.GetOrDefault(ctx, nil)) > 0 522 523 if apkInApex && hasJnis && !Bool(a.appProperties.Use_embedded_native_libs) { 524 ctx.ModuleErrorf("APK in APEX should have use_embedded_native_libs: true") 525 } 526} 527 528// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it. 529// This check is enforced for "updatable" APKs (including APK-in-APEX). 530func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) { 531 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType() 532 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { 533 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) { 534 return 535 } 536 if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); !ok { 537 panic(fmt.Errorf("jni dependency is not a cc module: %v", m)) 538 } 539 commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoProvider) 540 if !ok { 541 panic(fmt.Errorf("jni dependency doesn't have CommonModuleInfo provider: %v", m)) 542 } 543 // The domain of cc.sdk_version is "current" and <number> 544 // We can rely on android.SdkSpec to convert it to <number> so that "current" is 545 // handled properly regardless of sdk finalization. 546 ver := "" 547 if !commonInfo.MinSdkVersion.IsPlatform { 548 ver = commonInfo.MinSdkVersion.ApiLevel.String() 549 } 550 jniSdkVersion, err := android.SdkSpecFrom(ctx, ver).EffectiveVersion(ctx) 551 if err != nil || minSdkVersion.LessThan(jniSdkVersion) { 552 ctx.OtherModuleErrorf(m, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)", 553 ver, minSdkVersion, ctx.ModuleName()) 554 return 555 } 556 557 }) 558} 559 560// Returns true if the native libraries should be stored in the APK uncompressed and the 561// extractNativeLibs application flag should be set to false in the manifest. 562func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool { 563 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx) 564 if err != nil { 565 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err) 566 } 567 568 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 569 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) || 570 !apexInfo.IsForPlatform() 571} 572 573// Returns whether this module should have the dex file stored uncompressed in the APK. 574func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool { 575 if Bool(a.appProperties.Use_embedded_dex) { 576 return true 577 } 578 579 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may 580 // be preinstalled as prebuilts). 581 if ctx.Config().UncompressPrivAppDex() && a.Privileged() { 582 return true 583 } 584 585 if ctx.Config().UnbundledBuild() { 586 return false 587 } 588 589 return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter) 590} 591 592func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool { 593 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) || 594 Bool(a.appProperties.Updatable) || 595 a.appProperties.AlwaysPackageNativeLibs 596} 597 598func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string { 599 aaptFlags := []string{"--rename-manifest-package " + packageName} 600 if renameResourcesPackage { 601 // Required to rename the package name in the resources table. 602 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName) 603 } 604 return aaptFlags 605} 606 607func (a *AndroidApp) OverriddenManifestPackageName() string { 608 return a.overriddenManifestPackageName 609} 610 611func (a *AndroidApp) renameResourcesPackage() bool { 612 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true) 613} 614 615func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) { 616 ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { 617 tag := ctx.OtherModuleDependencyTag(dep) 618 switch tag { 619 case staticLibTag, rroDepTag: 620 if flagPackages, ok := android.OtherModuleProvider(ctx, dep, FlagsPackagesProvider); ok { 621 aconfigTextFilePaths = append(aconfigTextFilePaths, flagPackages.AconfigTextFiles...) 622 } 623 624 case aconfigDeclarationTag: 625 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok { 626 aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath) 627 } else { 628 ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+ 629 "flags_packages property, but %s is not aconfig_declarations module type", 630 dep.Name(), 631 ) 632 } 633 } 634 }) 635 636 return android.FirstUniquePaths(aconfigTextFilePaths) 637} 638 639func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { 640 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis) 641 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule { 642 usePlatformAPI = true 643 } 644 a.aapt.usesNonSdkApis = usePlatformAPI 645 646 // Ask manifest_fixer to add or update the application element indicating this app has no code. 647 a.aapt.hasNoCode = !a.hasCode(ctx) 648 649 aaptLinkFlags := []string{} 650 651 // Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided. 652 autogenerateRRO := proptools.Bool(a.appProperties.Generate_product_characteristics_rro) 653 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product") 654 characteristics := ctx.Config().ProductAAPTCharacteristics() 655 if !autogenerateRRO && !hasProduct && len(characteristics) > 0 && characteristics != "default" { 656 aaptLinkFlags = append(aaptLinkFlags, "--product", characteristics) 657 } 658 659 if !Bool(a.aaptProperties.Aapt_include_all_resources) { 660 // Product AAPT config 661 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() { 662 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig) 663 } 664 665 // Product AAPT preferred config 666 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 { 667 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig()) 668 } 669 } 670 671 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName()) 672 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx) 673 if overridden || packageNameProp.IsPresent() { 674 // The product override variable has a priority over the package_name property. 675 if !overridden { 676 manifestPackageName = packageNameProp.Get() 677 } 678 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...) 679 a.overriddenManifestPackageName = manifestPackageName 680 } 681 682 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...) 683 684 a.aapt.splitNames = a.appProperties.Package_splits 685 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent) 686 if a.Updatable() { 687 if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" { 688 a.aapt.defaultManifestVersion = override 689 } else { 690 a.aapt.defaultManifestVersion = ctx.Config().ReleaseDefaultUpdatableModuleVersion() 691 } 692 } 693 694 // Use non final ids if we are doing optimized shrinking and are using R8. 695 nonFinalIds := a.dexProperties.optimizedResourceShrinkingEnabled(ctx) && a.dexer.effectiveOptimizeEnabled(ctx) 696 697 aconfigTextFilePaths := getAconfigFilePaths(ctx) 698 699 a.aapt.buildActions(ctx, 700 aaptBuildActionOptions{ 701 sdkContext: android.SdkContext(a), 702 classLoaderContexts: a.classLoaderContexts, 703 excludedLibs: a.usesLibraryProperties.Exclude_uses_libs, 704 enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(), 705 forceNonFinalResourceIDs: nonFinalIds, 706 extraLinkFlags: aaptLinkFlags, 707 aconfigTextFiles: aconfigTextFilePaths, 708 usesLibrary: &a.usesLibrary, 709 }, 710 ) 711 712 // apps manifests are handled by aapt, don't let Module see them 713 a.properties.Manifest = nil 714 715 android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{ 716 AconfigTextFiles: aconfigTextFilePaths, 717 }) 718} 719 720func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) { 721 var staticLibProguardFlagFiles android.Paths 722 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { 723 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider) 724 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...) 725 if ctx.OtherModuleDependencyTag(m) == staticLibTag { 726 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.ProguardFlagsFiles.ToList()...) 727 } 728 }) 729 730 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles) 731 732 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...) 733 if !(a.dexProperties.optimizedResourceShrinkingEnabled(ctx)) { 734 // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become 735 // live for code references and (transitively) mark these as live. 736 // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now 737 // dead code alive) 738 a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile) 739 } 740} 741 742func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath { 743 var installDir string 744 if ctx.ModuleName() == "framework-res" { 745 // framework-res.apk is installed as system/framework/framework-res.apk 746 installDir = "framework" 747 } else if a.Privileged() { 748 installDir = filepath.Join("priv-app", a.installApkName) 749 } else { 750 installDir = filepath.Join("app", a.installApkName) 751 } 752 753 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk") 754} 755 756func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path, *JavaInfo) { 757 a.dexpreopter.installPath = a.installPath(ctx) 758 a.dexpreopter.isApp = true 759 if a.dexProperties.Uncompress_dex == nil { 760 // If the value was not force-set by the user, use reasonable default based on the module. 761 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx)) 762 } 763 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex 764 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx) 765 a.dexpreopter.classLoaderContexts = a.classLoaderContexts 766 a.dexpreopter.manifestFile = a.mergedManifestFile 767 a.dexpreopter.preventInstall = a.appProperties.PreventInstall 768 769 var packageResources = a.exportPackage 770 771 javaInfo := &JavaInfo{} 772 if ctx.ModuleName() != "framework-res" { 773 if a.dexProperties.resourceShrinkingEnabled(ctx) { 774 protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk") 775 aapt2Convert(ctx, protoFile, packageResources, "proto") 776 a.dexer.resourcesInput = android.OptionalPathForPath(protoFile) 777 } 778 779 var extraSrcJars android.Paths 780 var extraClasspathJars android.Paths 781 var extraCombinedJars android.Paths 782 if a.useResourceProcessorBusyBox(ctx) { 783 // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already 784 // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the 785 // classpath when compiling everything else, and add it to the final classes jar. 786 extraClasspathJars = android.Paths{a.aapt.rJar} 787 extraCombinedJars = android.Paths{a.aapt.rJar} 788 } else { 789 // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing 790 // R.java files for the app's package and the packages from all transitive static android_library 791 // dependencies. Compile the srcjar alongside the rest of the sources. 792 extraSrcJars = android.Paths{a.aapt.aaptSrcJar} 793 } 794 795 javaInfo = a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil) 796 if a.dexProperties.resourceShrinkingEnabled(ctx) { 797 binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk") 798 aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary") 799 packageResources = binaryResources 800 } 801 } 802 803 return a.dexJarFile.PathOrNil(), packageResources, javaInfo 804} 805 806func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath { 807 var jniJarFile android.WritablePath 808 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 { 809 a.jniLibs = jniLibs 810 if a.shouldEmbedJnis(ctx) { 811 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip") 812 a.installPathForJNISymbols = a.installPath(ctx) 813 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx)) 814 for _, jni := range jniLibs { 815 if jni.coverageFile.Valid() { 816 // Only collect coverage for the first target arch if this is a multilib target. 817 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage 818 // data file path collisions since the current coverage file path format doesn't contain 819 // arch-related strings. This is fine for now though; the code coverage team doesn't use 820 // multi-arch targets such as test_suite_* for coverage collections yet. 821 // 822 // Work with the team to come up with a new format that handles multilib modules properly 823 // and change this. 824 if len(ctx.Config().Targets[android.Android]) == 1 || 825 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType { 826 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path()) 827 } 828 } 829 } 830 a.embeddedJniLibs = true 831 } 832 } 833 return jniJarFile 834} 835 836func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls { 837 var jniSymbols android.RuleBuilderInstalls 838 for _, jniLib := range a.jniLibs { 839 if jniLib.unstrippedFile != nil { 840 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{ 841 From: jniLib.unstrippedFile, 842 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()), 843 }) 844 } 845 } 846 return jniSymbols 847} 848 849// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it 850// isn't a cert module reference. Also checks and enforces system cert restriction if applicable. 851func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate, 852 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) { 853 if android.SrcIsModule(certPropValue) == "" { 854 var mainCert Certificate 855 if certPropValue != "" { 856 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx) 857 mainCert = Certificate{ 858 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"), 859 Key: defaultDir.Join(ctx, certPropValue+".pk8"), 860 } 861 } else { 862 pem, key := ctx.Config().DefaultAppCertificate(ctx) 863 mainCert = Certificate{ 864 Pem: pem, 865 Key: key, 866 } 867 } 868 certificates = append([]Certificate{mainCert}, certificates...) 869 } 870 871 if len(certificates) > 0 { 872 mainCertificate = certificates[0] 873 } else { 874 // This can be reached with an empty certificate list if AllowMissingDependencies is set 875 // and the certificate property for this module is a module reference to a missing module. 876 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 { 877 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies") 878 } 879 // Set a certificate to avoid panics later when accessing it. 880 mainCertificate = Certificate{ 881 Key: android.PathForModuleOut(ctx, "missing.pk8"), 882 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"), 883 } 884 } 885 886 if !m.Platform() { 887 certPath := mainCertificate.Pem.String() 888 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String() 889 if strings.HasPrefix(certPath, systemCertPath) { 890 enforceSystemCert := ctx.Config().EnforceSystemCertificate() 891 allowed := ctx.Config().EnforceSystemCertificateAllowList() 892 893 if enforceSystemCert && !inList(m.Name(), allowed) { 894 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.") 895 } 896 } 897 } 898 899 return mainCertificate, certificates 900} 901 902func (a *AndroidApp) InstallApkName() string { 903 return a.installApkName 904} 905 906func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.Path { 907 if a.appProperties.Privapp_allowlist == nil { 908 return nil 909 } 910 911 isOverrideApp := a.GetOverriddenBy() != "" 912 if !isOverrideApp { 913 // if this is not an override, we don't need to rewrite the existing privapp allowlist 914 return android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist) 915 } 916 917 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx) 918 if packageNameProp.IsEmpty() { 919 ctx.PropertyErrorf("privapp_allowlist", "package_name must be set to use privapp_allowlist") 920 } 921 922 packageName := packageNameProp.Get() 923 fileName := "privapp_allowlist_" + packageName + ".xml" 924 outPath := android.PathForModuleOut(ctx, fileName) 925 ctx.Build(pctx, android.BuildParams{ 926 Rule: modifyAllowlist, 927 Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist), 928 Output: outPath, 929 Args: map[string]string{ 930 "packageName": packageName, 931 }, 932 }) 933 return outPath 934} 935 936func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { 937 var apkDeps android.Paths 938 939 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 940 if !apexInfo.IsForPlatform() { 941 a.hideApexVariantFromMake = true 942 } 943 944 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) 945 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) 946 947 // Unlike installApkName, a.stem should respect base module name for override_android_app. 948 // Therefore, use ctx.ModuleName() instead of a.Name(). 949 a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName()) 950 951 // Check if the install APK name needs to be overridden. 952 // Both android_app and override_android_app module are expected to possess 953 // its module bound apk path. However, override_android_app inherits ctx.ModuleName() 954 // from the base module. Therefore, use a.Name() which represents 955 // the module name for both android_app and override_android_app. 956 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor( 957 proptools.StringDefault(a.overridableProperties.Stem, a.Name())) 958 959 if ctx.ModuleName() == "framework-res" { 960 // framework-res.apk is installed as system/framework/framework-res.apk 961 a.installDir = android.PathForModuleInstall(ctx, "framework") 962 } else if a.Privileged() { 963 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName) 964 } else if ctx.InstallInTestcases() { 965 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch()) 966 } else { 967 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName) 968 } 969 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir) 970 971 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx) 972 if a.usesLibrary.shouldDisableDexpreopt { 973 a.dexpreopter.disableDexpreopt() 974 } 975 976 var noticeAssetPath android.WritablePath 977 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") { 978 // The rule to create the notice file can't be generated yet, as the final output path 979 // for the apk isn't known yet. Add the path where the notice file will be generated to the 980 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will 981 // be generated later. 982 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz") 983 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath) 984 } 985 986 // For apps targeting latest target_sdk_version 987 if Bool(a.appProperties.Enforce_default_target_sdk_version) { 988 a.SetEnforceDefaultTargetSdkVersion(true) 989 } 990 991 // Process all building blocks, from AAPT to certificates. 992 a.aaptBuildActions(ctx) 993 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries. 994 a.usesLibrary.freezeEnforceUsesLibraries(ctx) 995 996 // Check that the <uses-library> list is coherent with the manifest. 997 if a.usesLibrary.enforceUsesLibraries(ctx) { 998 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest( 999 ctx, a.mergedManifestFile, &a.classLoaderContexts) 1000 apkDeps = append(apkDeps, manifestCheckFile) 1001 } 1002 1003 a.proguardBuildActions(ctx) 1004 1005 a.linter.mergedManifest = a.aapt.mergedManifestFile 1006 a.linter.manifest = a.aapt.manifestPath 1007 a.linter.resources = a.aapt.resourceFiles 1008 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps() 1009 1010 dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx) 1011 1012 // No need to check the SDK version of the JNI deps unless we embed them 1013 checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis) 1014 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), checkNativeSdkVersion) 1015 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx) 1016 1017 if ctx.Failed() { 1018 return 1019 } 1020 1021 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx) 1022 1023 // Build a final signed app package. 1024 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk") 1025 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature) 1026 var v4SignatureFile android.WritablePath = nil 1027 if v4SigningRequested { 1028 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig") 1029 } 1030 var lineageFile android.Path 1031 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" { 1032 lineageFile = android.PathForModuleSrc(ctx, lineage) 1033 } 1034 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion) 1035 1036 CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion) 1037 a.outputFile = packageFile 1038 if v4SigningRequested { 1039 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile) 1040 } 1041 1042 if a.aapt.noticeFile.Valid() { 1043 // Generating the notice file rule has to be here after a.outputFile is known. 1044 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz") 1045 android.BuildNoticeHtmlOutputFromLicenseMetadata( 1046 ctx, noticeFile, "", "", 1047 []string{ 1048 a.installDir.String() + "/", 1049 android.PathForModuleInstall(ctx).String() + "/", 1050 a.outputFile.String(), 1051 }) 1052 builder := android.NewRuleBuilder(pctx, ctx) 1053 builder.Command().Text("cp"). 1054 Input(noticeFile). 1055 Output(noticeAssetPath) 1056 builder.Build("notice_dir", "Building notice dir") 1057 } 1058 1059 for _, split := range a.aapt.splits { 1060 // Sign the split APKs 1061 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk") 1062 if v4SigningRequested { 1063 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig") 1064 } 1065 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion) 1066 a.extraOutputFiles = append(a.extraOutputFiles, packageFile) 1067 if v4SigningRequested { 1068 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile) 1069 } 1070 } 1071 1072 // Build an app bundle. 1073 bundleFile := android.PathForModuleOut(ctx, "base.zip") 1074 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile) 1075 a.bundleFile = bundleFile 1076 1077 allowlist := a.createPrivappAllowlist(ctx) 1078 if allowlist != nil { 1079 a.privAppAllowlist = android.OptionalPathForPath(allowlist) 1080 } 1081 1082 // Install the app package. 1083 shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall 1084 if shouldInstallAppPackage { 1085 if a.privAppAllowlist.Valid() { 1086 allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions") 1087 allowlistInstallFilename := a.installApkName + ".xml" 1088 ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path()) 1089 } 1090 1091 var extraInstalledPaths android.InstallPaths 1092 for _, extra := range a.extraOutputFiles { 1093 installed := ctx.InstallFile(a.installDir, extra.Base(), extra) 1094 extraInstalledPaths = append(extraInstalledPaths, installed) 1095 } 1096 // If we don't embed jni libs, make sure that those are installed along with the 1097 // app, and also place symlinks to the installed paths under the lib/<arch> 1098 // directory of the app installation directory. ex: 1099 // /system/app/MyApp/lib/arm64/libfoo.so -> /system/lib64/libfoo.so 1100 if !a.embeddedJniLibs { 1101 for _, jniLib := range jniLibs { 1102 archStr := jniLib.target.Arch.ArchType.String() 1103 symlinkDir := a.installDir.Join(ctx, "lib", archStr) 1104 for _, installedLib := range jniLib.installPaths { 1105 // install the symlink itself 1106 symlinkName := installedLib.Base() 1107 symlinkTarget := android.InstallPathToOnDevicePath(ctx, installedLib) 1108 ctx.InstallAbsoluteSymlink(symlinkDir, symlinkName, symlinkTarget) 1109 } 1110 } 1111 } 1112 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) 1113 } 1114 1115 ctx.CheckbuildFile(a.outputFile) 1116 1117 a.buildAppDependencyInfo(ctx) 1118 1119 providePrebuiltInfo(ctx, 1120 prebuiltInfoProps{ 1121 baseModuleName: a.BaseModuleName(), 1122 isPrebuilt: false, 1123 }, 1124 ) 1125 1126 if javaInfo != nil { 1127 javaInfo.OutputFile = a.outputFile 1128 setExtraJavaInfo(ctx, a, javaInfo) 1129 android.SetProvider(ctx, JavaInfoProvider, javaInfo) 1130 } 1131 1132 android.SetProvider(ctx, android.ApexBundleDepsDataProvider, android.ApexBundleDepsData{ 1133 FlatListPath: a.FlatListPath(), 1134 Updatable: a.Updatable(), 1135 }) 1136 1137 moduleInfoJSON := ctx.ModuleInfoJSON() 1138 moduleInfoJSON.Class = []string{"APPS"} 1139 if !a.embeddedJniLibs { 1140 for _, jniLib := range a.jniLibs { 1141 moduleInfoJSON.ExtraRequired = append(moduleInfoJSON.ExtraRequired, jniLib.name) 1142 } 1143 } 1144 1145 a.setOutputFiles(ctx) 1146 1147 buildComplianceMetadata(ctx) 1148} 1149 1150func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) { 1151 ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile") 1152 if a.aaptSrcJar != nil { 1153 ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar") 1154 } 1155 if a.rJar != nil { 1156 ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar") 1157 } 1158 ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk") 1159 ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk") 1160 ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml") 1161 setOutputFiles(ctx, a.Library.Module) 1162} 1163 1164type appDepsInterface interface { 1165 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec 1166 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel 1167 RequiresStableAPIs(ctx android.BaseModuleContext) bool 1168} 1169 1170func collectAppDeps(ctx android.ModuleContext, app appDepsInterface, 1171 shouldCollectRecursiveNativeDeps bool, 1172 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) { 1173 1174 if checkNativeSdkVersion { 1175 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() && 1176 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx) 1177 } 1178 jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps, 1179 checkNativeSdkVersion, func(parent, child android.ModuleProxy) bool { 1180 apkInApex := ctx.Module().(android.ApexModule).NotInPlatform() 1181 childLinkable, _ := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider) 1182 parentIsLinkable := false 1183 if android.EqualModules(ctx.Module(), parent) { 1184 parentLinkable, _ := ctx.Module().(cc.LinkableInterface) 1185 parentIsLinkable = parentLinkable != nil 1186 } else { 1187 _, parentIsLinkable = android.OtherModuleProvider(ctx, parent, cc.LinkableInfoProvider) 1188 } 1189 useStubsOfDep := childLinkable.IsStubs 1190 if apkInApex && parentIsLinkable { 1191 // APK-in-APEX 1192 // If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary. 1193 useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants && cc.ShouldUseStubForApex(ctx, parent, child)) 1194 } 1195 return !childLinkable.IsNdk && !useStubsOfDep 1196 }) 1197 1198 var certificates []Certificate 1199 1200 var directImplementationDeps android.Paths 1201 var transitiveImplementationDeps []depset.DepSet[android.Path] 1202 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { 1203 otherName := ctx.OtherModuleName(module) 1204 tag := ctx.OtherModuleDependencyTag(module) 1205 1206 if tag == certificateTag { 1207 if dep, ok := android.OtherModuleProvider(ctx, module, AndroidAppCertificateInfoProvider); ok { 1208 certificates = append(certificates, dep.Certificate) 1209 } else { 1210 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName) 1211 } 1212 } 1213 1214 if IsJniDepTag(tag) { 1215 directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, module, "")) 1216 if info, ok := android.OtherModuleProvider(ctx, module, cc.ImplementationDepInfoProvider); ok { 1217 transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps) 1218 } 1219 } 1220 }) 1221 android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{ 1222 ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps), 1223 }) 1224 1225 return jniLib, prebuiltJniPackages, certificates 1226} 1227 1228func collectJniDeps(ctx android.ModuleContext, 1229 shouldCollectRecursiveNativeDeps bool, 1230 checkNativeSdkVersion bool, 1231 filter func(parent, child android.ModuleProxy) bool) ([]jniLib, android.Paths) { 1232 var jniLibs []jniLib 1233 var prebuiltJniPackages android.Paths 1234 seenModulePaths := make(map[string]bool) 1235 1236 ctx.WalkDepsProxy(func(module, parent android.ModuleProxy) bool { 1237 if !android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled { 1238 return false 1239 } 1240 otherName := ctx.OtherModuleName(module) 1241 tag := ctx.OtherModuleDependencyTag(module) 1242 1243 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) { 1244 if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok { 1245 if filter != nil && !filter(parent, module) { 1246 return false 1247 } 1248 1249 lib := dep.OutputFile 1250 if lib.Valid() { 1251 path := lib.Path() 1252 if seenModulePaths[path.String()] { 1253 return false 1254 } 1255 seenModulePaths[path.String()] = true 1256 1257 commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) 1258 if checkNativeSdkVersion && commonInfo.SdkVersion == "" { 1259 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not", 1260 otherName) 1261 } 1262 1263 jniLibs = append(jniLibs, jniLib{ 1264 name: ctx.OtherModuleName(module), 1265 path: path, 1266 target: commonInfo.Target, 1267 coverageFile: dep.CoverageOutputFile, 1268 unstrippedFile: dep.UnstrippedOutputFile, 1269 partition: dep.Partition, 1270 installPaths: android.OtherModuleProviderOrDefault(ctx, module, android.InstallFilesProvider).InstallFiles, 1271 }) 1272 } else if ctx.Config().AllowMissingDependencies() { 1273 ctx.AddMissingDependencies([]string{otherName}) 1274 } else { 1275 ctx.ModuleErrorf("dependency %q missing output file", otherName) 1276 } 1277 } else { 1278 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName) 1279 } 1280 1281 return shouldCollectRecursiveNativeDeps 1282 } 1283 1284 if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok { 1285 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...) 1286 } 1287 1288 return false 1289 }) 1290 1291 return jniLibs, prebuiltJniPackages 1292} 1293 1294func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) { 1295 ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { 1296 // TODO(ccross): Should this use android.DepIsInSameApex? Right now it is applying the android app 1297 // heuristics to every transitive dependency, when it should probably be using the heuristics of the 1298 // immediate parent. 1299 isExternal := !a.GetDepInSameApexChecker().OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child)) 1300 if am, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); ok && am.IsApexModule { 1301 if !do(ctx, parent, child, isExternal) { 1302 return false 1303 } 1304 } 1305 return !isExternal 1306 }) 1307} 1308 1309func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { 1310 if ctx.Host() { 1311 return 1312 } 1313 1314 depsInfo := android.DepNameToDepInfoMap{} 1315 a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool { 1316 depName := to.Name() 1317 1318 // Skip dependencies that are only available to APEXes; they are developed with updatability 1319 // in mind and don't need manual approval. 1320 if android.OtherModulePointerProviderOrDefault(ctx, to, android.CommonModuleInfoProvider).NotAvailableForPlatform { 1321 return true 1322 } 1323 1324 if info, exist := depsInfo[depName]; exist { 1325 info.From = append(info.From, from.Name()) 1326 info.IsExternal = info.IsExternal && externalDep 1327 depsInfo[depName] = info 1328 } else { 1329 toMinSdkVersion := "(no version)" 1330 if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoProvider); ok && 1331 !info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil { 1332 toMinSdkVersion = info.MinSdkVersion.ApiLevel.String() 1333 } 1334 depsInfo[depName] = android.ApexModuleDepInfo{ 1335 To: depName, 1336 From: []string{from.Name()}, 1337 IsExternal: externalDep, 1338 MinSdkVersion: toMinSdkVersion, 1339 } 1340 } 1341 return true 1342 }) 1343 1344 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo) 1345} 1346 1347func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool { 1348 return a.appProperties.EnforceDefaultTargetSdkVersion 1349} 1350 1351func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) { 1352 a.appProperties.EnforceDefaultTargetSdkVersion = val 1353} 1354 1355func (a *AndroidApp) Updatable() bool { 1356 return Bool(a.appProperties.Updatable) 1357} 1358 1359func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string { 1360 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName()) 1361 if overridden { 1362 return ":" + certificate 1363 } 1364 return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "") 1365} 1366 1367func (m *AndroidApp) GetDepInSameApexChecker() android.DepInSameApexChecker { 1368 return AppDepInSameApexChecker{} 1369} 1370 1371type AppDepInSameApexChecker struct { 1372 android.BaseDepInSameApexChecker 1373} 1374 1375func (m AppDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool { 1376 if IsJniDepTag(tag) { 1377 return true 1378 } 1379 return depIsInSameApex(tag) 1380} 1381 1382func (a *AndroidApp) Privileged() bool { 1383 return Bool(a.appProperties.Privileged) 1384} 1385 1386func (a *AndroidApp) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool { 1387 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled() 1388} 1389 1390func (a *AndroidApp) SetPreventInstall() { 1391 a.appProperties.PreventInstall = true 1392} 1393 1394func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) { 1395 a.appProperties.IsCoverageVariant = coverage 1396} 1397 1398func (a *AndroidApp) EnableCoverageIfNeeded() {} 1399 1400var _ cc.Coverage = (*AndroidApp)(nil) 1401 1402func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) { 1403 a.Library.IDEInfo(ctx, dpInfo) 1404 a.aapt.IDEInfo(ctx, dpInfo) 1405} 1406 1407func (a *AndroidApp) productCharacteristicsRROPackageName() string { 1408 return proptools.String(a.appProperties.ProductCharacteristicsRROPackageName) 1409} 1410 1411func (a *AndroidApp) productCharacteristicsRROManifestModuleName() string { 1412 return proptools.String(a.appProperties.ProductCharacteristicsRROManifestModuleName) 1413} 1414 1415// android_app compiles sources and Android resources into an Android application package `.apk` file. 1416func AndroidAppFactory() android.Module { 1417 module := &AndroidApp{} 1418 1419 module.Module.dexProperties.Optimize.EnabledByDefault = true 1420 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true) 1421 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false) 1422 1423 module.Module.properties.Instrument = true 1424 module.Module.properties.Supports_static_instrumentation = true 1425 module.Module.properties.Installable = proptools.BoolPtr(true) 1426 1427 module.addHostAndDeviceProperties() 1428 module.AddProperties( 1429 &module.aaptProperties, 1430 &module.appProperties, 1431 &module.overridableAppProperties, 1432 &module.Library.sourceProperties) 1433 1434 module.usesLibrary.enforce = true 1435 1436 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1437 android.InitDefaultableModule(module) 1438 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides) 1439 android.InitApexModule(module) 1440 1441 android.AddLoadHook(module, func(ctx android.LoadHookContext) { 1442 a := ctx.Module().(*AndroidApp) 1443 1444 characteristics := ctx.Config().ProductAAPTCharacteristics() 1445 if characteristics == "default" || characteristics == "" { 1446 module.appProperties.Generate_product_characteristics_rro = nil 1447 // no need to create RRO 1448 return 1449 } 1450 1451 if !proptools.Bool(module.appProperties.Generate_product_characteristics_rro) { 1452 return 1453 } 1454 1455 rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro" 1456 rroManifestName := rroPackageName + "_manifest" 1457 1458 a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName) 1459 a.appProperties.ProductCharacteristicsRROManifestModuleName = proptools.StringPtr(rroManifestName) 1460 1461 rroManifestProperties := struct { 1462 Name *string 1463 Tools []string 1464 Out []string 1465 Srcs []string 1466 Cmd *string 1467 }{ 1468 Name: proptools.StringPtr(rroManifestName), 1469 Tools: []string{"characteristics_rro_generator", "aapt2"}, 1470 Out: []string{"AndroidManifest.xml"}, 1471 Srcs: []string{":" + a.Name() + "{.apk}"}, 1472 Cmd: proptools.StringPtr("$(location characteristics_rro_generator) $$($(location aapt2) dump packagename $(in)) $(out)"), 1473 } 1474 ctx.CreateModule(GenRuleFactory, &rroManifestProperties) 1475 1476 rroProperties := struct { 1477 Name *string 1478 Filter_product *string 1479 Aaptflags []string 1480 Manifest *string 1481 Resource_dirs proptools.Configurable[[]string] 1482 Flags_packages []string 1483 }{ 1484 Name: proptools.StringPtr(rroPackageName), 1485 Filter_product: proptools.StringPtr(characteristics), 1486 Aaptflags: []string{"--auto-add-overlay"}, 1487 Manifest: proptools.StringPtr(":" + rroManifestName), 1488 Resource_dirs: a.aaptProperties.Resource_dirs, 1489 Flags_packages: a.aaptProperties.Flags_packages, 1490 } 1491 if !Bool(a.aaptProperties.Aapt_include_all_resources) { 1492 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() { 1493 rroProperties.Aaptflags = append(rroProperties.Aaptflags, "-c", aaptConfig) 1494 } 1495 } 1496 ctx.CreateModule(RuntimeResourceOverlayFactory, &rroProperties) 1497 1498 }) 1499 1500 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) { 1501 createInternalRuntimeOverlays(ctx, module.ModuleBase) 1502 }) 1503 1504 return module 1505} 1506 1507func AutogeneratedRroModuleName(ctx android.EarlyModuleContext, moduleName, partition string) string { 1508 return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition) 1509} 1510 1511type createModuleContext interface { 1512 android.EarlyModuleContext 1513 CreateModule(android.ModuleFactory, ...interface{}) android.Module 1514} 1515 1516func createInternalRuntimeOverlays(ctx createModuleContext, a android.ModuleBase) { 1517 if !ctx.Config().HasDeviceProduct() { 1518 return 1519 } 1520 // vendor 1521 vendorOverlayProps := struct { 1522 Name *string 1523 Base *string 1524 Vendor *bool 1525 Product_specific *bool 1526 System_ext_specific *bool 1527 Manifest *string 1528 Sdk_version *string 1529 Compile_multilib *string 1530 Enabled proptools.Configurable[bool] 1531 }{ 1532 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "vendor")), 1533 Base: proptools.StringPtr(a.Name()), 1534 Vendor: proptools.BoolPtr(true), 1535 Product_specific: proptools.BoolPtr(false), 1536 System_ext_specific: proptools.BoolPtr(false), 1537 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"), 1538 Sdk_version: proptools.StringPtr("current"), 1539 Compile_multilib: proptools.StringPtr("first"), 1540 Enabled: a.EnabledProperty().Clone(), 1541 } 1542 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &vendorOverlayProps) 1543 1544 // product 1545 productOverlayProps := struct { 1546 Name *string 1547 Base *string 1548 Vendor *bool 1549 Proprietary *bool 1550 Soc_specific *bool 1551 Product_specific *bool 1552 System_ext_specific *bool 1553 Manifest *string 1554 Sdk_version *string 1555 Compile_multilib *string 1556 Enabled proptools.Configurable[bool] 1557 }{ 1558 Name: proptools.StringPtr(AutogeneratedRroModuleName(ctx, a.Name(), "product")), 1559 Base: proptools.StringPtr(a.Name()), 1560 Vendor: proptools.BoolPtr(false), 1561 Proprietary: proptools.BoolPtr(false), 1562 Soc_specific: proptools.BoolPtr(false), 1563 Product_specific: proptools.BoolPtr(true), 1564 System_ext_specific: proptools.BoolPtr(false), 1565 Manifest: proptools.StringPtr(":" + a.Name() + "{.manifest.xml}"), 1566 Sdk_version: proptools.StringPtr("current"), 1567 Compile_multilib: proptools.StringPtr("first"), 1568 Enabled: a.EnabledProperty().Clone(), 1569 } 1570 ctx.CreateModule(AutogenRuntimeResourceOverlayFactory, &productOverlayProps) 1571} 1572 1573// A dictionary of values to be overridden in the manifest. 1574type Manifest_values struct { 1575 // Overrides the value of package_name in the manifest 1576 ApplicationId *string 1577} 1578 1579type appTestProperties struct { 1580 // The name of the android_app module that the tests will run against. 1581 Instrumentation_for *string 1582 1583 // If specified, the instrumentation target package name in the manifest is overwritten by it. 1584 Instrumentation_target_package *string 1585 1586 // If specified, the mainline module package name in the test config is overwritten by it. 1587 Mainline_package_name *string 1588 1589 Manifest_values Manifest_values 1590} 1591 1592type AndroidTest struct { 1593 AndroidApp 1594 1595 appTestProperties appTestProperties 1596 1597 testProperties testProperties 1598 1599 testConfig android.Path 1600 extraTestConfigs android.Paths 1601 data android.Paths 1602} 1603 1604func (a *AndroidTest) InstallInTestcases() bool { 1605 return true 1606} 1607 1608type androidTestApp interface { 1609 includedInTestSuite(searchPrefix string) bool 1610} 1611 1612func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool { 1613 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix) 1614} 1615 1616func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool { 1617 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix) 1618} 1619 1620func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1621 checkMinSdkVersionMts(ctx, a.MinSdkVersion(ctx)) 1622 var configs []tradefed.Config 1623 if a.appTestProperties.Instrumentation_target_package != nil { 1624 a.additionalAaptFlags = append(a.additionalAaptFlags, 1625 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package) 1626 } else if a.appTestProperties.Instrumentation_for != nil { 1627 // Check if the instrumentation target package is overridden. 1628 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for) 1629 if overridden { 1630 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName) 1631 } 1632 } 1633 applicationId := a.appTestProperties.Manifest_values.ApplicationId 1634 if applicationId != nil { 1635 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx) 1636 if packageNameProp.IsPresent() { 1637 ctx.PropertyErrorf("manifest_values.applicationId", "property is not supported when property package_name is set.") 1638 } 1639 a.aapt.manifestValues.applicationId = *applicationId 1640 } 1641 a.generateAndroidBuildActions(ctx) 1642 1643 for _, c := range a.testProperties.Test_options.Tradefed_options { 1644 configs = append(configs, c) 1645 } 1646 for _, module := range a.testProperties.Test_mainline_modules { 1647 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module}) 1648 } 1649 1650 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, 1651 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, 1652 a.testProperties.Auto_gen_config, configs, a.testProperties.Test_options.Test_runner_options) 1653 a.testConfig = a.FixTestConfig(ctx, testConfig) 1654 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs) 1655 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) 1656 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...) 1657 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...) 1658 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...) 1659 a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Host_common_data)...) 1660 1661 // Install test deps 1662 if !ctx.Config().KatiEnabled() { 1663 pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name()) 1664 if a.testConfig != nil { 1665 ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig) 1666 } 1667 dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") 1668 if dynamicConfig.Valid() { 1669 ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".dynamic", dynamicConfig.Path()) 1670 } 1671 testDeps := append(a.data, a.extraTestConfigs...) 1672 for _, data := range android.SortedUniquePaths(testDeps) { 1673 dataPath := android.DataPath{SrcPath: data} 1674 ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) 1675 } 1676 } 1677 1678 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ 1679 TestcaseRelDataFiles: testcaseRel(a.data), 1680 OutputFile: a.OutputFile(), 1681 TestConfig: a.testConfig, 1682 HostRequiredModuleNames: a.HostRequiredModuleNames(), 1683 TestSuites: a.testProperties.Test_suites, 1684 IsHost: false, 1685 LocalCertificate: a.certificate.AndroidMkString(), 1686 IsUnitTest: Bool(a.testProperties.Test_options.Unit_test), 1687 MkInclude: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk", 1688 MkAppClass: "APPS", 1689 }) 1690 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ 1691 TestOnly: true, 1692 TopLevelTarget: true, 1693 }) 1694 1695 moduleInfoJSON := ctx.ModuleInfoJSON() 1696 moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests") 1697 if a.testConfig != nil { 1698 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.testConfig.String()) 1699 } 1700 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.extraTestConfigs.Strings()...) 1701 if len(a.testProperties.Test_suites) > 0 { 1702 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.testProperties.Test_suites...) 1703 } else { 1704 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") 1705 } 1706 1707 if _, ok := testConfig.(android.WritablePath); ok { 1708 moduleInfoJSON.AutoTestConfig = []string{"true"} 1709 } 1710 moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...) 1711 1712 android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ 1713 TestSuites: a.testProperties.Test_suites, 1714 }) 1715} 1716 1717func testcaseRel(paths android.Paths) []string { 1718 relPaths := []string{} 1719 for _, p := range paths { 1720 relPaths = append(relPaths, p.Rel()) 1721 } 1722 return relPaths 1723} 1724 1725func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path { 1726 if testConfig == nil { 1727 return nil 1728 } 1729 1730 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml") 1731 rule := android.NewRuleBuilder(pctx, ctx) 1732 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig) 1733 fixNeeded := false 1734 1735 // Auto-generated test config uses `ModuleName` as the APK name. So fix it if it is not the case. 1736 if ctx.ModuleName() != a.installApkName { 1737 fixNeeded = true 1738 command.FlagWithArg("--test-file-name ", a.installApkName+".apk") 1739 } 1740 1741 packageNameProp := a.overridableAppProperties.Package_name.Get(ctx) 1742 if packageNameProp.IsPresent() { 1743 fixNeeded = true 1744 command.FlagWithInput("--manifest ", a.manifestPath). 1745 FlagWithArg("--package-name ", packageNameProp.Get()) 1746 } 1747 1748 if a.appTestProperties.Mainline_package_name != nil { 1749 fixNeeded = true 1750 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name) 1751 } 1752 1753 if fixNeeded { 1754 rule.Build("fix_test_config", "fix test config") 1755 return fixedConfig 1756 } 1757 return testConfig 1758} 1759 1760func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) { 1761 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") { 1762 // Instrument the android_test_helper target to log potential API calls at the run time. 1763 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER. 1764 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib") 1765 a.setApiMapper(true) 1766 } 1767 a.AndroidApp.DepsMutator(ctx) 1768} 1769 1770func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) { 1771 if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") { 1772 // Instrument the android_test_helper target to log potential API calls at the run time. 1773 // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER. 1774 ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib") 1775 a.setApiMapper(true) 1776 } 1777 a.AndroidApp.DepsMutator(ctx) 1778} 1779 1780func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) { 1781 a.AndroidApp.OverridablePropertiesDepsMutator(ctx) 1782 if a.appTestProperties.Instrumentation_for != nil { 1783 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac, 1784 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so 1785 // use instrumentationForTag instead of libTag. 1786 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for)) 1787 } 1788} 1789 1790// android_test compiles test sources and Android resources into an Android application package `.apk` file and 1791// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file. 1792func AndroidTestFactory() android.Module { 1793 module := &AndroidTest{} 1794 1795 module.Module.dexProperties.Optimize.EnabledByDefault = false 1796 1797 module.Module.properties.Instrument = true 1798 module.Module.properties.Supports_static_instrumentation = true 1799 module.Module.properties.Installable = proptools.BoolPtr(true) 1800 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true) 1801 module.appProperties.AlwaysPackageNativeLibs = true 1802 module.Module.dexpreopter.isTest = true 1803 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true) 1804 1805 module.addHostAndDeviceProperties() 1806 module.AddProperties( 1807 &module.aaptProperties, 1808 &module.appProperties, 1809 &module.appTestProperties, 1810 &module.overridableAppProperties, 1811 &module.testProperties) 1812 1813 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1814 android.InitDefaultableModule(module) 1815 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides) 1816 1817 return module 1818} 1819 1820type appTestHelperAppProperties struct { 1821 // list of compatibility suites (for example "cts", "vts") that the module should be 1822 // installed into. 1823 Test_suites []string `android:"arch_variant"` 1824 1825 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 1826 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 1827 // explicitly. 1828 Auto_gen_config *bool 1829 1830 // Install the test into a folder named for the module in all test suites. 1831 Per_testcase_directory *bool 1832 1833 Manifest_values Manifest_values 1834} 1835 1836type AndroidTestHelperApp struct { 1837 AndroidApp 1838 1839 appTestHelperAppProperties appTestHelperAppProperties 1840} 1841 1842func (a *AndroidTestHelperApp) InstallInTestcases() bool { 1843 return true 1844} 1845 1846// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that 1847// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a 1848// test. 1849func AndroidTestHelperAppFactory() android.Module { 1850 module := &AndroidTestHelperApp{} 1851 1852 // TODO(b/192032291): Disable by default after auditing downstream usage. 1853 module.Module.dexProperties.Optimize.EnabledByDefault = true 1854 module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true) 1855 module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false) 1856 1857 module.Module.properties.Installable = proptools.BoolPtr(true) 1858 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true) 1859 module.appProperties.AlwaysPackageNativeLibs = true 1860 module.Module.dexpreopter.isTest = true 1861 module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true) 1862 1863 module.addHostAndDeviceProperties() 1864 module.AddProperties( 1865 &module.aaptProperties, 1866 &module.appProperties, 1867 &module.appTestHelperAppProperties, 1868 &module.overridableAppProperties) 1869 1870 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1871 android.InitDefaultableModule(module) 1872 android.InitApexModule(module) 1873 return module 1874} 1875 1876type AndroidAppCertificate struct { 1877 android.ModuleBase 1878 1879 properties AndroidAppCertificateProperties 1880 Certificate Certificate 1881} 1882 1883type AndroidAppCertificateProperties struct { 1884 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name. 1885 Certificate *string 1886} 1887 1888type AndroidAppCertificateInfo struct { 1889 Certificate Certificate 1890} 1891 1892var AndroidAppCertificateInfoProvider = blueprint.NewProvider[AndroidAppCertificateInfo]() 1893 1894// android_app_certificate modules can be referenced by the certificates property of android_app modules to select 1895// the signing key. 1896func AndroidAppCertificateFactory() android.Module { 1897 module := &AndroidAppCertificate{} 1898 module.AddProperties(&module.properties) 1899 android.InitAndroidModule(module) 1900 return module 1901} 1902 1903func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1904 cert := String(c.properties.Certificate) 1905 c.Certificate = Certificate{ 1906 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"), 1907 Key: android.PathForModuleSrc(ctx, cert+".pk8"), 1908 } 1909 1910 android.SetProvider(ctx, AndroidAppCertificateInfoProvider, AndroidAppCertificateInfo{ 1911 Certificate: c.Certificate, 1912 }) 1913} 1914 1915type OverrideAndroidApp struct { 1916 android.ModuleBase 1917 android.OverrideModuleBase 1918} 1919 1920func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) { 1921 // All the overrides happen in the base module. 1922 // TODO(jungjw): Check the base module type. 1923} 1924 1925// override_android_app is used to create an android_app module based on another android_app by overriding 1926// some of its properties. 1927func OverrideAndroidAppModuleFactory() android.Module { 1928 m := &OverrideAndroidApp{} 1929 m.AddProperties( 1930 &OverridableProperties{}, 1931 &overridableAppProperties{}, 1932 ) 1933 1934 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) 1935 android.InitOverrideModule(m) 1936 android.AddLoadHookWithPriority(m, func(ctx android.LoadHookContext) { 1937 createInternalRuntimeOverlays(ctx, m.ModuleBase) 1938 }, 1) // Run after soong config load hoook 1939 1940 return m 1941} 1942 1943type OverrideAndroidTest struct { 1944 android.ModuleBase 1945 android.OverrideModuleBase 1946} 1947 1948func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1949 // All the overrides happen in the base module. 1950 // TODO(jungjw): Check the base module type. 1951 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ 1952 TestOnly: true, 1953 TopLevelTarget: true, 1954 }) 1955} 1956 1957// override_android_test is used to create an android_app module based on another android_test by overriding 1958// some of its properties. 1959func OverrideAndroidTestModuleFactory() android.Module { 1960 m := &OverrideAndroidTest{} 1961 m.AddProperties(&overridableAppProperties{}) 1962 m.AddProperties(&appTestProperties{}) 1963 1964 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) 1965 android.InitOverrideModule(m) 1966 return m 1967} 1968 1969type UsesLibraryProperties struct { 1970 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file. 1971 Uses_libs proptools.Configurable[[]string] 1972 1973 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with 1974 // required=false. 1975 Optional_uses_libs proptools.Configurable[[]string] 1976 1977 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults 1978 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future. 1979 Enforce_uses_libs *bool 1980 1981 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK 1982 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name 1983 // normally is the same as the module name, but there are exceptions. 1984 Provides_uses_lib *string 1985 1986 // A list of shared library names to exclude from the classpath of the APK. Adding a library here 1987 // will prevent it from being used when precompiling the APK and prevent it from being implicitly 1988 // added to the APK's manifest's <uses-library> elements. 1989 // 1990 // Care must be taken when using this as it could result in runtime errors if the APK actually 1991 // uses classes provided by the library and which are not provided in any other way. 1992 // 1993 // This is primarily intended for use by various CTS tests that check the runtime handling of the 1994 // android.test.base shared library (and related libraries) but which depend on some common 1995 // libraries that depend on the android.test.base library. Without this those tests will end up 1996 // with a <uses-library android:name="android.test.base"/> in their manifest which would either 1997 // render the tests worthless (as they would be testing the wrong behavior), or would break the 1998 // test altogether by providing access to classes that the tests were not expecting. Those tests 1999 // provide the android.test.base statically and use jarjar to rename them so they do not collide 2000 // with the classes provided by the android.test.base library. 2001 Exclude_uses_libs []string 2002 2003 // The module names of optional uses-library libraries that are missing from the source tree. 2004 Missing_optional_uses_libs []string `blueprint:"mutated"` 2005} 2006 2007// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the 2008// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the 2009// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps 2010// with knowledge of their shared libraries. 2011type usesLibrary struct { 2012 usesLibraryProperties UsesLibraryProperties 2013 2014 // Whether to enforce verify_uses_library check. 2015 enforce bool 2016 2017 // Whether dexpreopt should be disabled 2018 shouldDisableDexpreopt bool 2019} 2020 2021func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) { 2022 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() { 2023 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...) 2024 presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx) 2025 ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...) 2026 // Only add these extra dependencies if the module is an app that depends on framework 2027 // libs. This avoids creating a cyclic dependency: 2028 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res. 2029 if addCompatDeps { 2030 // Dexpreopt needs paths to the dex jars of these libraries in order to construct 2031 // class loader context for dex2oat. Add them as a dependency with a special tag. 2032 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...) 2033 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...) 2034 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...) 2035 } 2036 _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs) 2037 u.usesLibraryProperties.Missing_optional_uses_libs = diff 2038 } else { 2039 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...) 2040 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...) 2041 } 2042} 2043 2044// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree. 2045func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string { 2046 optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool { 2047 exists := ctx.OtherModuleExists(s) 2048 if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) { 2049 fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s) 2050 } 2051 return exists 2052 }) 2053 return optionalUsesLibs 2054} 2055 2056// Returns a map of module names of shared library dependencies to the paths to their dex jars on 2057// host and on device. 2058func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap { 2059 clcMap := make(dexpreopt.ClassLoaderContextMap) 2060 2061 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With 2062 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting. 2063 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() { 2064 return clcMap 2065 } 2066 2067 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { 2068 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag) 2069 if !isUsesLibTag { 2070 return 2071 } 2072 2073 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m)) 2074 2075 javaInfo, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider) 2076 if !ok { 2077 return 2078 } 2079 // Skip stub libraries. A dependency on the implementation library has been added earlier, 2080 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed 2081 // from implementation libraries by their name, which is different as it has a suffix. 2082 if comp := javaInfo.SdkLibraryComponentDependencyInfo; comp != nil { 2083 if impl := comp.OptionalSdkLibraryImplementation; impl != nil && *impl != dep { 2084 return 2085 } 2086 } 2087 2088 if lib := javaInfo.UsesLibraryDependencyInfo; lib != nil { 2089 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok { 2090 // Skip java_sdk_library dependencies that provide stubs, but not an implementation. 2091 // This will be restricted to optional_uses_libs 2092 if tag == usesLibOptTag && javaInfo.DexJarBuildPath.PathOrNil() == nil { 2093 u.shouldDisableDexpreopt = true 2094 return 2095 } 2096 } 2097 libName := dep 2098 if ulib := javaInfo.ProvidesUsesLibInfo; ulib != nil && ulib.ProvidesUsesLib != nil { 2099 libName = *ulib.ProvidesUsesLib 2100 } 2101 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, 2102 javaInfo.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath, 2103 lib.ClassLoaderContexts) 2104 } else if ctx.Config().AllowMissingDependencies() { 2105 ctx.AddMissingDependencies([]string{dep}) 2106 } else { 2107 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep) 2108 } 2109 }) 2110 return clcMap 2111} 2112 2113// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs 2114// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true 2115// unconditionally in the future. 2116func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool { 2117 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 || 2118 len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0 2119 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs) 2120} 2121 2122// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`. 2123func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) { 2124 enforce := u.enforceUsesLibraries(ctx) 2125 u.usesLibraryProperties.Enforce_uses_libs = &enforce 2126} 2127 2128// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified 2129// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or 2130// an APK with the manifest embedded in it (manifest_check will know which one it is by the file 2131// extension: APKs are supposed to end with '.apk'). 2132func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path, 2133 outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path { 2134 2135 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx) 2136 2137 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the 2138 // check is not necessary, and although it is good to have, it is difficult to maintain on 2139 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to 2140 // various unrelated reasons, such as a failure to get manifest from an APK). 2141 global := dexpreopt.GetGlobalConfig(ctx) 2142 if global.DisablePreopt || global.OnlyPreoptArtBootImage { 2143 return inputFile 2144 } 2145 2146 rule := android.NewRuleBuilder(pctx, ctx) 2147 cmd := rule.Command().BuiltTool("manifest_check"). 2148 Flag("--enforce-uses-libraries"). 2149 Input(inputFile). 2150 FlagWithOutput("--enforce-uses-libraries-status ", statusFile). 2151 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2")) 2152 2153 if outputFile != nil { 2154 cmd.FlagWithOutput("-o ", outputFile) 2155 } 2156 2157 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck { 2158 cmd.Flag("--enforce-uses-libraries-relax") 2159 } 2160 2161 requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs() 2162 for _, lib := range requiredUsesLibs { 2163 cmd.FlagWithArg("--uses-library ", lib) 2164 } 2165 for _, lib := range optionalUsesLibs { 2166 cmd.FlagWithArg("--optional-uses-library ", lib) 2167 } 2168 2169 // Also add missing optional uses libs, as the manifest check expects them. 2170 // Note that what we add here are the module names of those missing libs, not library names, while 2171 // the manifest check actually expects library names. However, the case where a library is missing 2172 // and the module name != the library name is too rare for us to handle. 2173 for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs { 2174 cmd.FlagWithArg("--missing-optional-uses-library ", lib) 2175 } 2176 2177 rule.Build("verify_uses_libraries", "verify <uses-library>") 2178 return outputFile 2179} 2180 2181// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against 2182// the build system and returns the path to a copy of the manifest. 2183func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path, 2184 classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path { 2185 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml") 2186 return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts) 2187} 2188 2189// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build 2190// system and returns the path to a copy of the APK. 2191func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path, 2192 classLoaderContexts *dexpreopt.ClassLoaderContextMap) { 2193 u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file 2194} 2195 2196// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in 2197// the same way. 2198type androidApp interface { 2199 android.Module 2200 Privileged() bool 2201 InstallApkName() string 2202 OutputFile() android.Path 2203 JacocoReportClassesFile() android.Path 2204 Certificate() Certificate 2205 BaseModuleName() string 2206 PrivAppAllowlist() android.OptionalPath 2207} 2208 2209var _ androidApp = (*AndroidApp)(nil) 2210var _ androidApp = (*AndroidAppImport)(nil) 2211var _ androidApp = (*AndroidTestHelperApp)(nil) 2212 2213func setCommonAppInfo(appInfo *AppInfo, m androidApp) { 2214 appInfo.Privileged = m.Privileged() 2215 appInfo.OutputFile = m.OutputFile() 2216 appInfo.InstallApkName = m.InstallApkName() 2217 appInfo.JacocoReportClassesFile = m.JacocoReportClassesFile() 2218 appInfo.Certificate = m.Certificate() 2219 appInfo.PrivAppAllowlist = m.PrivAppAllowlist() 2220} 2221 2222type AppInfos []AppInfo 2223 2224var AppInfosProvider = blueprint.NewProvider[AppInfos]() 2225