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 "path/filepath" 22 "strings" 23 24 "github.com/google/blueprint" 25 "github.com/google/blueprint/proptools" 26 27 "android/soong/android" 28 "android/soong/bazel" 29 "android/soong/cc" 30 "android/soong/dexpreopt" 31 "android/soong/tradefed" 32) 33 34func init() { 35 RegisterAppBuildComponents(android.InitRegistrationContext) 36} 37 38func RegisterAppBuildComponents(ctx android.RegistrationContext) { 39 ctx.RegisterModuleType("android_app", AndroidAppFactory) 40 ctx.RegisterModuleType("android_test", AndroidTestFactory) 41 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory) 42 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory) 43 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory) 44 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory) 45} 46 47// AndroidManifest.xml merging 48// package splits 49 50type appProperties struct { 51 // Names of extra android_app_certificate modules to sign the apk with in the form ":module". 52 Additional_certificates []string 53 54 // If set, create package-export.apk, which other packages can 55 // use to get PRODUCT-agnostic resource data like IDs and type definitions. 56 Export_package_resources *bool 57 58 // Specifies that this app should be installed to the priv-app directory, 59 // where the system will grant it additional privileges not available to 60 // normal apps. 61 Privileged *bool 62 63 // list of resource labels to generate individual resource packages 64 Package_splits []string 65 66 // list of native libraries that will be provided in or alongside the resulting jar 67 Jni_libs []string `android:"arch_variant"` 68 69 // if true, use JNI libraries that link against platform APIs even if this module sets 70 // sdk_version. 71 Jni_uses_platform_apis *bool 72 73 // if true, use JNI libraries that link against SDK APIs even if this module does not set 74 // sdk_version. 75 Jni_uses_sdk_apis *bool 76 77 // STL library to use for JNI libraries. 78 Stl *string `android:"arch_variant"` 79 80 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest 81 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless 82 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for 83 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native 84 // libraries are generally preinstalled outside the APK. 85 Use_embedded_native_libs *bool 86 87 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that 88 // they are used from inside the APK at runtime. 89 Use_embedded_dex *bool 90 91 // Forces native libraries to always be packaged into the APK, 92 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed. 93 // True for android_test* modules. 94 AlwaysPackageNativeLibs bool `blueprint:"mutated"` 95 96 // If set, find and merge all NOTICE files that this module and its dependencies have and store 97 // it in the APK as an asset. 98 Embed_notices *bool 99 100 // cc.Coverage related properties 101 PreventInstall bool `blueprint:"mutated"` 102 IsCoverageVariant bool `blueprint:"mutated"` 103 104 // It can be set to test the behaviour of default target sdk version. 105 // Only required when updatable: false. It is an error if updatable: true and this is false. 106 Enforce_default_target_sdk_version *bool 107 108 // If set, the targetSdkVersion for the target is set to the latest default API level. 109 // This would be by default false, unless updatable: true or 110 // enforce_default_target_sdk_version: true in which case this defaults to true. 111 EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"` 112 113 // Whether this app is considered mainline updatable or not. When set to true, this will enforce 114 // additional rules to make sure an app can safely be updated. Default is false. 115 // Prefer using other specific properties if build behaviour must be changed; avoid using this 116 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners). 117 Updatable *bool 118} 119 120// android_app properties that can be overridden by override_android_app 121type overridableAppProperties struct { 122 // The name of a certificate in the default certificate directory, blank to use the default product certificate, 123 // or an android_app_certificate module name in the form ":module". 124 Certificate *string 125 126 // Name of the signing certificate lineage file or filegroup module. 127 Lineage *string `android:"path"` 128 129 // For overriding the --rotation-min-sdk-version property of apksig 130 RotationMinSdkVersion *string 131 132 // the package name of this app. The package name in the manifest file is used if one was not given. 133 Package_name *string 134 135 // the logging parent of this app. 136 Logging_parent *string 137 138 // Whether to rename the package in resources to the override name rather than the base name. Defaults to true. 139 Rename_resources_package *bool 140 141 // Names of modules to be overridden. Listed modules can only be other binaries 142 // (in Make or Soong). 143 // This does not completely prevent installation of the overridden binaries, but if both 144 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed 145 // from PRODUCT_PACKAGES. 146 Overrides []string 147} 148 149type AndroidApp struct { 150 android.BazelModuleBase 151 Library 152 aapt 153 android.OverridableModuleBase 154 155 certificate Certificate 156 157 appProperties appProperties 158 159 overridableAppProperties overridableAppProperties 160 161 jniLibs []jniLib 162 installPathForJNISymbols android.Path 163 embeddedJniLibs bool 164 jniCoverageOutputs android.Paths 165 166 bundleFile android.Path 167 168 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES. 169 installApkName string 170 171 installDir android.InstallPath 172 173 onDeviceDir string 174 175 additionalAaptFlags []string 176 177 overriddenManifestPackageName string 178 179 android.ApexBundleDepsInfo 180 181 javaApiUsedByOutputFile android.ModuleOutPath 182} 183 184func (a *AndroidApp) IsInstallable() bool { 185 return Bool(a.properties.Installable) 186} 187 188func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths { 189 return nil 190} 191 192func (a *AndroidApp) ExportedStaticPackages() android.Paths { 193 return nil 194} 195 196func (a *AndroidApp) OutputFile() android.Path { 197 return a.outputFile 198} 199 200func (a *AndroidApp) Certificate() Certificate { 201 return a.certificate 202} 203 204func (a *AndroidApp) JniCoverageOutputs() android.Paths { 205 return a.jniCoverageOutputs 206} 207 208var _ AndroidLibraryDependency = (*AndroidApp)(nil) 209 210type Certificate struct { 211 Pem, Key android.Path 212 presigned bool 213} 214 215var PresignedCertificate = Certificate{presigned: true} 216 217func (c Certificate) AndroidMkString() string { 218 if c.presigned { 219 return "PRESIGNED" 220 } else { 221 return c.Pem.String() 222 } 223} 224 225func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { 226 a.Module.deps(ctx) 227 228 if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() { 229 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared") 230 } 231 232 sdkDep := decodeSdkDep(ctx, android.SdkContext(a)) 233 if sdkDep.hasFrameworkLibs() { 234 a.aapt.deps(ctx, sdkDep) 235 } 236 237 usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform 238 239 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) { 240 ctx.PropertyErrorf("jni_uses_sdk_apis", 241 "can only be set for modules that do not set sdk_version") 242 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) { 243 ctx.PropertyErrorf("jni_uses_platform_apis", 244 "can only be set for modules that set sdk_version") 245 } 246 247 for _, jniTarget := range ctx.MultiTargets() { 248 variation := append(jniTarget.Variations(), 249 blueprint.Variation{Mutator: "link", Variation: "shared"}) 250 251 // If the app builds against an Android SDK use the SDK variant of JNI dependencies 252 // unless jni_uses_platform_apis is set. 253 // Don't require the SDK variant for apps that are shipped on vendor, etc., as they already 254 // have stable APIs through the VNDK. 255 if (usesSDK && !a.RequiresStableAPIs(ctx) && 256 !Bool(a.appProperties.Jni_uses_platform_apis)) || 257 Bool(a.appProperties.Jni_uses_sdk_apis) { 258 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"}) 259 } 260 ctx.AddFarVariationDependencies(variation, jniLibTag, a.appProperties.Jni_libs...) 261 } 262 263 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs()) 264} 265 266func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) { 267 cert := android.SrcIsModule(a.getCertString(ctx)) 268 if cert != "" { 269 ctx.AddDependency(ctx.Module(), certificateTag, cert) 270 } 271 272 for _, cert := range a.appProperties.Additional_certificates { 273 cert = android.SrcIsModule(cert) 274 if cert != "" { 275 ctx.AddDependency(ctx.Module(), certificateTag, cert) 276 } else { 277 ctx.PropertyErrorf("additional_certificates", 278 `must be names of android_app_certificate modules in the form ":module"`) 279 } 280 } 281} 282 283func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { 284 a.generateAndroidBuildActions(ctx) 285} 286 287func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { 288 a.checkAppSdkVersions(ctx) 289 a.generateAndroidBuildActions(ctx) 290 a.generateJavaUsedByApex(ctx) 291} 292 293func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) { 294 if a.Updatable() { 295 if !a.SdkVersion(ctx).Stable() { 296 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx)) 297 } 298 if String(a.deviceProperties.Min_sdk_version) == "" { 299 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.") 300 } 301 302 if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil { 303 a.checkJniLibsSdkVersion(ctx, minSdkVersion) 304 android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps) 305 } else { 306 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) 307 } 308 309 if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) { 310 ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version") 311 } 312 // TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set. 313 if a.deviceProperties.Target_sdk_version == nil { 314 a.SetEnforceDefaultTargetSdkVersion(true) 315 } 316 } 317 318 a.checkPlatformAPI(ctx) 319 a.checkSdkVersions(ctx) 320} 321 322// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it. 323// This check is enforced for "updatable" APKs (including APK-in-APEX). 324func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) { 325 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType() 326 ctx.VisitDirectDeps(func(m android.Module) { 327 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) { 328 return 329 } 330 dep, _ := m.(*cc.Module) 331 // The domain of cc.sdk_version is "current" and <number> 332 // We can rely on android.SdkSpec to convert it to <number> so that "current" is 333 // handled properly regardless of sdk finalization. 334 jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx) 335 if err != nil || minSdkVersion.LessThan(jniSdkVersion) { 336 ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)", 337 dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName()) 338 return 339 } 340 341 }) 342} 343 344// Returns true if the native libraries should be stored in the APK uncompressed and the 345// extractNativeLibs application flag should be set to false in the manifest. 346func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool { 347 minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx) 348 if err != nil { 349 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err) 350 } 351 352 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 353 return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) || 354 !apexInfo.IsForPlatform() 355} 356 357// Returns whether this module should have the dex file stored uncompressed in the APK. 358func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool { 359 if Bool(a.appProperties.Use_embedded_dex) { 360 return true 361 } 362 363 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may 364 // be preinstalled as prebuilts). 365 if ctx.Config().UncompressPrivAppDex() && a.Privileged() { 366 return true 367 } 368 369 if ctx.Config().UnbundledBuild() { 370 return false 371 } 372 373 return shouldUncompressDex(ctx, &a.dexpreopter) 374} 375 376func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool { 377 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 378 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) || 379 !apexInfo.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs 380} 381 382func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string { 383 aaptFlags := []string{"--rename-manifest-package " + packageName} 384 if renameResourcesPackage { 385 // Required to rename the package name in the resources table. 386 aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName) 387 } 388 return aaptFlags 389} 390 391func (a *AndroidApp) OverriddenManifestPackageName() string { 392 return a.overriddenManifestPackageName 393} 394 395func (a *AndroidApp) renameResourcesPackage() bool { 396 return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true) 397} 398 399func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { 400 usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis) 401 if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule { 402 usePlatformAPI = true 403 } 404 a.aapt.usesNonSdkApis = usePlatformAPI 405 406 // Ask manifest_fixer to add or update the application element indicating this app has no code. 407 a.aapt.hasNoCode = !a.hasCode(ctx) 408 409 aaptLinkFlags := []string{} 410 411 // Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided. 412 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product") 413 if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 { 414 aaptLinkFlags = append(aaptLinkFlags, "--product", ctx.Config().ProductAAPTCharacteristics()) 415 } 416 417 if !Bool(a.aaptProperties.Aapt_include_all_resources) { 418 // Product AAPT config 419 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() { 420 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig) 421 } 422 423 // Product AAPT preferred config 424 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 { 425 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig()) 426 } 427 } 428 429 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName()) 430 if overridden || a.overridableAppProperties.Package_name != nil { 431 // The product override variable has a priority over the package_name property. 432 if !overridden { 433 manifestPackageName = *a.overridableAppProperties.Package_name 434 } 435 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...) 436 a.overriddenManifestPackageName = manifestPackageName 437 } 438 439 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...) 440 441 a.aapt.splitNames = a.appProperties.Package_splits 442 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent) 443 if a.Updatable() { 444 a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion 445 } 446 a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, 447 a.usesLibraryProperties.Exclude_uses_libs, a.enforceDefaultTargetSdkVersion(), aaptLinkFlags...) 448 449 // apps manifests are handled by aapt, don't let Module see them 450 a.properties.Manifest = nil 451} 452 453func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) { 454 var staticLibProguardFlagFiles android.Paths 455 ctx.VisitDirectDeps(func(m android.Module) { 456 if lib, ok := m.(LibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag { 457 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, lib.ExportedProguardFlagFiles()...) 458 } 459 }) 460 461 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles) 462 463 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, staticLibProguardFlagFiles...) 464 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile) 465} 466 467func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath { 468 var installDir string 469 if ctx.ModuleName() == "framework-res" { 470 // framework-res.apk is installed as system/framework/framework-res.apk 471 installDir = "framework" 472 } else if a.Privileged() { 473 installDir = filepath.Join("priv-app", a.installApkName) 474 } else { 475 installDir = filepath.Join("app", a.installApkName) 476 } 477 478 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk") 479} 480 481func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { 482 a.dexpreopter.installPath = a.installPath(ctx) 483 a.dexpreopter.isApp = true 484 if a.dexProperties.Uncompress_dex == nil { 485 // If the value was not force-set by the user, use reasonable default based on the module. 486 a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx)) 487 } 488 a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex 489 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries() 490 a.dexpreopter.classLoaderContexts = a.classLoaderContexts 491 a.dexpreopter.manifestFile = a.mergedManifestFile 492 a.dexpreopter.preventInstall = a.appProperties.PreventInstall 493 494 if ctx.ModuleName() != "framework-res" { 495 a.Module.compile(ctx, a.aaptSrcJar) 496 } 497 498 return a.dexJarFile.PathOrNil() 499} 500 501func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath { 502 var jniJarFile android.WritablePath 503 if len(jniLibs) > 0 || len(prebuiltJniPackages) > 0 { 504 a.jniLibs = jniLibs 505 if a.shouldEmbedJnis(ctx) { 506 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip") 507 a.installPathForJNISymbols = a.installPath(ctx) 508 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, prebuiltJniPackages, a.useEmbeddedNativeLibs(ctx)) 509 for _, jni := range jniLibs { 510 if jni.coverageFile.Valid() { 511 // Only collect coverage for the first target arch if this is a multilib target. 512 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage 513 // data file path collisions since the current coverage file path format doesn't contain 514 // arch-related strings. This is fine for now though; the code coverage team doesn't use 515 // multi-arch targets such as test_suite_* for coverage collections yet. 516 // 517 // Work with the team to come up with a new format that handles multilib modules properly 518 // and change this. 519 if len(ctx.Config().Targets[android.Android]) == 1 || 520 ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType { 521 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path()) 522 } 523 } 524 } 525 a.embeddedJniLibs = true 526 } 527 } 528 return jniJarFile 529} 530 531func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls { 532 var jniSymbols android.RuleBuilderInstalls 533 for _, jniLib := range a.jniLibs { 534 if jniLib.unstrippedFile != nil { 535 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{ 536 From: jniLib.unstrippedFile, 537 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()), 538 }) 539 } 540 } 541 return jniSymbols 542} 543 544// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it 545// isn't a cert module reference. Also checks and enforces system cert restriction if applicable. 546func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate, 547 ctx android.ModuleContext) (mainCertificate Certificate, allCertificates []Certificate) { 548 if android.SrcIsModule(certPropValue) == "" { 549 var mainCert Certificate 550 if certPropValue != "" { 551 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx) 552 mainCert = Certificate{ 553 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"), 554 Key: defaultDir.Join(ctx, certPropValue+".pk8"), 555 } 556 } else { 557 pem, key := ctx.Config().DefaultAppCertificate(ctx) 558 mainCert = Certificate{ 559 Pem: pem, 560 Key: key, 561 } 562 } 563 certificates = append([]Certificate{mainCert}, certificates...) 564 } 565 566 if len(certificates) > 0 { 567 mainCertificate = certificates[0] 568 } else { 569 // This can be reached with an empty certificate list if AllowMissingDependencies is set 570 // and the certificate property for this module is a module reference to a missing module. 571 if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 { 572 panic("Should only get here if AllowMissingDependencies set and there are missing dependencies") 573 } 574 // Set a certificate to avoid panics later when accessing it. 575 mainCertificate = Certificate{ 576 Key: android.PathForModuleOut(ctx, "missing.pk8"), 577 Pem: android.PathForModuleOut(ctx, "missing.x509.pem"), 578 } 579 } 580 581 if !m.Platform() { 582 certPath := mainCertificate.Pem.String() 583 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String() 584 if strings.HasPrefix(certPath, systemCertPath) { 585 enforceSystemCert := ctx.Config().EnforceSystemCertificate() 586 allowed := ctx.Config().EnforceSystemCertificateAllowList() 587 588 if enforceSystemCert && !inList(m.Name(), allowed) { 589 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.") 590 } 591 } 592 } 593 594 595 return mainCertificate, certificates 596} 597 598func (a *AndroidApp) InstallApkName() string { 599 return a.installApkName 600} 601 602func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { 603 var apkDeps android.Paths 604 605 if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() { 606 a.hideApexVariantFromMake = true 607 } 608 609 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) 610 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) 611 612 // Check if the install APK name needs to be overridden. 613 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Stem()) 614 615 if ctx.ModuleName() == "framework-res" { 616 // framework-res.apk is installed as system/framework/framework-res.apk 617 a.installDir = android.PathForModuleInstall(ctx, "framework") 618 } else if a.Privileged() { 619 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName) 620 } else if ctx.InstallInTestcases() { 621 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch()) 622 } else { 623 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName) 624 } 625 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir) 626 627 a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx) 628 629 var noticeAssetPath android.WritablePath 630 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") { 631 // The rule to create the notice file can't be generated yet, as the final output path 632 // for the apk isn't known yet. Add the path where the notice file will be generated to the 633 // aapt rules now before calling aaptBuildActions, the rule to create the notice file will 634 // be generated later. 635 noticeAssetPath = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz") 636 a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath) 637 } 638 639 // For apps targeting latest target_sdk_version 640 if Bool(a.appProperties.Enforce_default_target_sdk_version) { 641 a.SetEnforceDefaultTargetSdkVersion(true) 642 } 643 644 // Process all building blocks, from AAPT to certificates. 645 a.aaptBuildActions(ctx) 646 647 // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries. 648 a.usesLibrary.freezeEnforceUsesLibraries() 649 650 // Add implicit SDK libraries to <uses-library> list. 651 requiredUsesLibs, optionalUsesLibs := a.classLoaderContexts.UsesLibs() 652 for _, usesLib := range requiredUsesLibs { 653 a.usesLibrary.addLib(usesLib, false) 654 } 655 for _, usesLib := range optionalUsesLibs { 656 a.usesLibrary.addLib(usesLib, true) 657 } 658 659 // Check that the <uses-library> list is coherent with the manifest. 660 if a.usesLibrary.enforceUsesLibraries() { 661 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile) 662 apkDeps = append(apkDeps, manifestCheckFile) 663 } 664 665 a.proguardBuildActions(ctx) 666 667 a.linter.mergedManifest = a.aapt.mergedManifestFile 668 a.linter.manifest = a.aapt.manifestPath 669 a.linter.resources = a.aapt.resourceFiles 670 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps() 671 672 dexJarFile := a.dexBuildActions(ctx) 673 674 jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis)) 675 jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx) 676 677 if ctx.Failed() { 678 return 679 } 680 681 a.certificate, certificates = processMainCert(a.ModuleBase, a.getCertString(ctx), certificates, ctx) 682 683 // Build a final signed app package. 684 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk") 685 v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature) 686 var v4SignatureFile android.WritablePath = nil 687 if v4SigningRequested { 688 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig") 689 } 690 var lineageFile android.Path 691 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" { 692 lineageFile = android.PathForModuleSrc(ctx, lineage) 693 } 694 rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion) 695 696 CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, Bool(a.dexProperties.Optimize.Shrink_resources)) 697 a.outputFile = packageFile 698 if v4SigningRequested { 699 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile) 700 } 701 702 if a.aapt.noticeFile.Valid() { 703 // Generating the notice file rule has to be here after a.outputFile is known. 704 noticeFile := android.PathForModuleOut(ctx, "NOTICE.html.gz") 705 android.BuildNoticeHtmlOutputFromLicenseMetadata( 706 ctx, noticeFile, "", "", 707 []string{ 708 a.installDir.String() + "/", 709 android.PathForModuleInstall(ctx).String() + "/", 710 a.outputFile.String(), 711 }) 712 builder := android.NewRuleBuilder(pctx, ctx) 713 builder.Command().Text("cp"). 714 Input(noticeFile). 715 Output(noticeAssetPath) 716 builder.Build("notice_dir", "Building notice dir") 717 } 718 719 for _, split := range a.aapt.splits { 720 // Sign the split APKs 721 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk") 722 if v4SigningRequested { 723 v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig") 724 } 725 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, false) 726 a.extraOutputFiles = append(a.extraOutputFiles, packageFile) 727 if v4SigningRequested { 728 a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile) 729 } 730 } 731 732 // Build an app bundle. 733 bundleFile := android.PathForModuleOut(ctx, "base.zip") 734 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile) 735 a.bundleFile = bundleFile 736 737 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 738 739 // Install the app package. 740 if (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && 741 !a.appProperties.PreventInstall { 742 743 var extraInstalledPaths android.Paths 744 for _, extra := range a.extraOutputFiles { 745 installed := ctx.InstallFile(a.installDir, extra.Base(), extra) 746 extraInstalledPaths = append(extraInstalledPaths, installed) 747 } 748 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) 749 } 750 751 a.buildAppDependencyInfo(ctx) 752} 753 754type appDepsInterface interface { 755 SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec 756 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel 757 RequiresStableAPIs(ctx android.BaseModuleContext) bool 758} 759 760func collectAppDeps(ctx android.ModuleContext, app appDepsInterface, 761 shouldCollectRecursiveNativeDeps bool, 762 checkNativeSdkVersion bool) ([]jniLib, android.Paths, []Certificate) { 763 764 var jniLibs []jniLib 765 var prebuiltJniPackages android.Paths 766 var certificates []Certificate 767 seenModulePaths := make(map[string]bool) 768 769 if checkNativeSdkVersion { 770 checkNativeSdkVersion = app.SdkVersion(ctx).Specified() && 771 app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx) 772 } 773 774 ctx.WalkDeps(func(module android.Module, parent android.Module) bool { 775 otherName := ctx.OtherModuleName(module) 776 tag := ctx.OtherModuleDependencyTag(module) 777 778 if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) { 779 if dep, ok := module.(cc.LinkableInterface); ok { 780 if dep.IsNdk(ctx.Config()) || dep.IsStubs() { 781 return false 782 } 783 784 lib := dep.OutputFile() 785 if lib.Valid() { 786 path := lib.Path() 787 if seenModulePaths[path.String()] { 788 return false 789 } 790 seenModulePaths[path.String()] = true 791 792 if checkNativeSdkVersion && dep.SdkVersion() == "" { 793 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not", 794 otherName) 795 } 796 797 jniLibs = append(jniLibs, jniLib{ 798 name: ctx.OtherModuleName(module), 799 path: path, 800 target: module.Target(), 801 coverageFile: dep.CoverageOutputFile(), 802 unstrippedFile: dep.UnstrippedOutputFile(), 803 partition: dep.Partition(), 804 }) 805 } else if ctx.Config().AllowMissingDependencies() { 806 ctx.AddMissingDependencies([]string{otherName}) 807 } else { 808 ctx.ModuleErrorf("dependency %q missing output file", otherName) 809 } 810 } else { 811 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName) 812 } 813 814 return shouldCollectRecursiveNativeDeps 815 } 816 817 if info, ok := ctx.OtherModuleProvider(module, JniPackageProvider).(JniPackageInfo); ok { 818 prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...) 819 } 820 821 if tag == certificateTag { 822 if dep, ok := module.(*AndroidAppCertificate); ok { 823 certificates = append(certificates, dep.Certificate) 824 } else { 825 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName) 826 } 827 } 828 829 return false 830 }) 831 832 return jniLibs, prebuiltJniPackages, certificates 833} 834 835func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) { 836 ctx.WalkDeps(func(child, parent android.Module) bool { 837 isExternal := !a.DepIsInSameApex(ctx, child) 838 if am, ok := child.(android.ApexModule); ok { 839 if !do(ctx, parent, am, isExternal) { 840 return false 841 } 842 } 843 return !isExternal 844 }) 845} 846 847func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { 848 if ctx.Host() { 849 return 850 } 851 852 depsInfo := android.DepNameToDepInfoMap{} 853 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { 854 depName := to.Name() 855 856 // Skip dependencies that are only available to APEXes; they are developed with updatability 857 // in mind and don't need manual approval. 858 if to.(android.ApexModule).NotAvailableForPlatform() { 859 return true 860 } 861 862 if info, exist := depsInfo[depName]; exist { 863 info.From = append(info.From, from.Name()) 864 info.IsExternal = info.IsExternal && externalDep 865 depsInfo[depName] = info 866 } else { 867 toMinSdkVersion := "(no version)" 868 if m, ok := to.(interface { 869 MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel 870 }); ok { 871 if v := m.MinSdkVersion(ctx); !v.IsNone() { 872 toMinSdkVersion = v.String() 873 } 874 } else if m, ok := to.(interface{ MinSdkVersion() string }); ok { 875 // TODO(b/175678607) eliminate the use of MinSdkVersion returning 876 // string 877 if v := m.MinSdkVersion(); v != "" { 878 toMinSdkVersion = v 879 } 880 } 881 depsInfo[depName] = android.ApexModuleDepInfo{ 882 To: depName, 883 From: []string{from.Name()}, 884 IsExternal: externalDep, 885 MinSdkVersion: toMinSdkVersion, 886 } 887 } 888 return true 889 }) 890 891 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo) 892} 893 894func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool { 895 return a.appProperties.EnforceDefaultTargetSdkVersion 896} 897 898func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) { 899 a.appProperties.EnforceDefaultTargetSdkVersion = val 900} 901 902func (a *AndroidApp) Updatable() bool { 903 return Bool(a.appProperties.Updatable) 904} 905 906func (a *AndroidApp) SetUpdatable(val bool) { 907 a.appProperties.Updatable = &val 908} 909 910func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string { 911 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName()) 912 if overridden { 913 return ":" + certificate 914 } 915 return String(a.overridableAppProperties.Certificate) 916} 917 918func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 919 if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) { 920 return true 921 } 922 return a.Library.DepIsInSameApex(ctx, dep) 923} 924 925// For OutputFileProducer interface 926func (a *AndroidApp) OutputFiles(tag string) (android.Paths, error) { 927 switch tag { 928 case ".aapt.srcjar": 929 return []android.Path{a.aaptSrcJar}, nil 930 case ".export-package.apk": 931 return []android.Path{a.exportPackage}, nil 932 } 933 return a.Library.OutputFiles(tag) 934} 935 936func (a *AndroidApp) Privileged() bool { 937 return Bool(a.appProperties.Privileged) 938} 939 940func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { 941 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled() 942} 943 944func (a *AndroidApp) SetPreventInstall() { 945 a.appProperties.PreventInstall = true 946} 947 948func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) { 949 a.appProperties.IsCoverageVariant = coverage 950} 951 952func (a *AndroidApp) EnableCoverageIfNeeded() {} 953 954var _ cc.Coverage = (*AndroidApp)(nil) 955 956// android_app compiles sources and Android resources into an Android application package `.apk` file. 957func AndroidAppFactory() android.Module { 958 module := &AndroidApp{} 959 960 module.Module.dexProperties.Optimize.EnabledByDefault = true 961 module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true) 962 963 module.Module.properties.Instrument = true 964 module.Module.properties.Supports_static_instrumentation = true 965 module.Module.properties.Installable = proptools.BoolPtr(true) 966 967 module.addHostAndDeviceProperties() 968 module.AddProperties( 969 &module.aaptProperties, 970 &module.appProperties, 971 &module.overridableAppProperties) 972 973 module.usesLibrary.enforce = true 974 975 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 976 android.InitDefaultableModule(module) 977 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides) 978 android.InitApexModule(module) 979 android.InitBazelModule(module) 980 981 return module 982} 983 984type appTestProperties struct { 985 // The name of the android_app module that the tests will run against. 986 Instrumentation_for *string 987 988 // If specified, the instrumentation target package name in the manifest is overwritten by it. 989 Instrumentation_target_package *string 990 991 // If specified, the mainline module package name in the test config is overwritten by it. 992 Mainline_package_name *string 993} 994 995type AndroidTest struct { 996 AndroidApp 997 998 appTestProperties appTestProperties 999 1000 testProperties testProperties 1001 1002 testConfig android.Path 1003 extraTestConfigs android.Paths 1004 data android.Paths 1005} 1006 1007func (a *AndroidTest) InstallInTestcases() bool { 1008 return true 1009} 1010 1011type androidTestApp interface { 1012 includedInTestSuite(searchPrefix string) bool 1013} 1014 1015func (a *AndroidTest) includedInTestSuite(searchPrefix string) bool { 1016 return android.PrefixInList(a.testProperties.Test_suites, searchPrefix) 1017} 1018 1019func (a *AndroidTestHelperApp) includedInTestSuite(searchPrefix string) bool { 1020 return android.PrefixInList(a.appTestHelperAppProperties.Test_suites, searchPrefix) 1021} 1022 1023func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1024 var configs []tradefed.Config 1025 if a.appTestProperties.Instrumentation_target_package != nil { 1026 a.additionalAaptFlags = append(a.additionalAaptFlags, 1027 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package) 1028 } else if a.appTestProperties.Instrumentation_for != nil { 1029 // Check if the instrumentation target package is overridden. 1030 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for) 1031 if overridden { 1032 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName) 1033 } 1034 } 1035 a.generateAndroidBuildActions(ctx) 1036 1037 for _, module := range a.testProperties.Test_mainline_modules { 1038 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module}) 1039 } 1040 1041 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, 1042 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs) 1043 a.testConfig = a.FixTestConfig(ctx, testConfig) 1044 a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs) 1045 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) 1046} 1047 1048func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path { 1049 if testConfig == nil { 1050 return nil 1051 } 1052 1053 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml") 1054 rule := android.NewRuleBuilder(pctx, ctx) 1055 command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig) 1056 fixNeeded := false 1057 1058 // Auto-generated test config uses `ModuleName` as the APK name. So fix it if it is not the case. 1059 if ctx.ModuleName() != a.installApkName { 1060 fixNeeded = true 1061 command.FlagWithArg("--test-file-name ", a.installApkName+".apk") 1062 } 1063 1064 if a.overridableAppProperties.Package_name != nil { 1065 fixNeeded = true 1066 command.FlagWithInput("--manifest ", a.manifestPath). 1067 FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name) 1068 } 1069 1070 if a.appTestProperties.Mainline_package_name != nil { 1071 fixNeeded = true 1072 command.FlagWithArg("--mainline-package-name ", *a.appTestProperties.Mainline_package_name) 1073 } 1074 1075 if fixNeeded { 1076 rule.Build("fix_test_config", "fix test config") 1077 return fixedConfig 1078 } 1079 return testConfig 1080} 1081 1082func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) { 1083 a.AndroidApp.DepsMutator(ctx) 1084} 1085 1086func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) { 1087 a.AndroidApp.OverridablePropertiesDepsMutator(ctx) 1088 if a.appTestProperties.Instrumentation_for != nil { 1089 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac, 1090 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so 1091 // use instrumentationForTag instead of libTag. 1092 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for)) 1093 } 1094} 1095 1096// android_test compiles test sources and Android resources into an Android application package `.apk` file and 1097// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file. 1098func AndroidTestFactory() android.Module { 1099 module := &AndroidTest{} 1100 1101 module.Module.dexProperties.Optimize.EnabledByDefault = false 1102 1103 module.Module.properties.Instrument = true 1104 module.Module.properties.Supports_static_instrumentation = true 1105 module.Module.properties.Installable = proptools.BoolPtr(true) 1106 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true) 1107 module.appProperties.AlwaysPackageNativeLibs = true 1108 module.Module.dexpreopter.isTest = true 1109 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) 1110 1111 module.addHostAndDeviceProperties() 1112 module.AddProperties( 1113 &module.aaptProperties, 1114 &module.appProperties, 1115 &module.appTestProperties, 1116 &module.overridableAppProperties, 1117 &module.testProperties) 1118 1119 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1120 android.InitDefaultableModule(module) 1121 android.InitOverridableModule(module, &module.overridableAppProperties.Overrides) 1122 return module 1123} 1124 1125type appTestHelperAppProperties struct { 1126 // list of compatibility suites (for example "cts", "vts") that the module should be 1127 // installed into. 1128 Test_suites []string `android:"arch_variant"` 1129 1130 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 1131 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 1132 // explicitly. 1133 Auto_gen_config *bool 1134 1135 // Install the test into a folder named for the module in all test suites. 1136 Per_testcase_directory *bool 1137} 1138 1139type AndroidTestHelperApp struct { 1140 AndroidApp 1141 1142 appTestHelperAppProperties appTestHelperAppProperties 1143} 1144 1145func (a *AndroidTestHelperApp) InstallInTestcases() bool { 1146 return true 1147} 1148 1149// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that 1150// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a 1151// test. 1152func AndroidTestHelperAppFactory() android.Module { 1153 module := &AndroidTestHelperApp{} 1154 1155 // TODO(b/192032291): Disable by default after auditing downstream usage. 1156 module.Module.dexProperties.Optimize.EnabledByDefault = true 1157 1158 module.Module.properties.Installable = proptools.BoolPtr(true) 1159 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true) 1160 module.appProperties.AlwaysPackageNativeLibs = true 1161 module.Module.dexpreopter.isTest = true 1162 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) 1163 1164 module.addHostAndDeviceProperties() 1165 module.AddProperties( 1166 &module.aaptProperties, 1167 &module.appProperties, 1168 &module.appTestHelperAppProperties, 1169 &module.overridableAppProperties) 1170 1171 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1172 android.InitDefaultableModule(module) 1173 android.InitApexModule(module) 1174 return module 1175} 1176 1177type AndroidAppCertificate struct { 1178 android.ModuleBase 1179 android.BazelModuleBase 1180 1181 properties AndroidAppCertificateProperties 1182 Certificate Certificate 1183} 1184 1185type AndroidAppCertificateProperties struct { 1186 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name. 1187 Certificate *string 1188} 1189 1190// android_app_certificate modules can be referenced by the certificates property of android_app modules to select 1191// the signing key. 1192func AndroidAppCertificateFactory() android.Module { 1193 module := &AndroidAppCertificate{} 1194 module.AddProperties(&module.properties) 1195 android.InitAndroidModule(module) 1196 android.InitBazelModule(module) 1197 return module 1198} 1199 1200func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1201 cert := String(c.properties.Certificate) 1202 c.Certificate = Certificate{ 1203 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"), 1204 Key: android.PathForModuleSrc(ctx, cert+".pk8"), 1205 } 1206} 1207 1208type OverrideAndroidApp struct { 1209 android.ModuleBase 1210 android.OverrideModuleBase 1211} 1212 1213func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) { 1214 // All the overrides happen in the base module. 1215 // TODO(jungjw): Check the base module type. 1216} 1217 1218// override_android_app is used to create an android_app module based on another android_app by overriding 1219// some of its properties. 1220func OverrideAndroidAppModuleFactory() android.Module { 1221 m := &OverrideAndroidApp{} 1222 m.AddProperties( 1223 &OverridableDeviceProperties{}, 1224 &overridableAppProperties{}, 1225 ) 1226 1227 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) 1228 android.InitOverrideModule(m) 1229 return m 1230} 1231 1232type OverrideAndroidTest struct { 1233 android.ModuleBase 1234 android.OverrideModuleBase 1235} 1236 1237func (i *OverrideAndroidTest) GenerateAndroidBuildActions(_ android.ModuleContext) { 1238 // All the overrides happen in the base module. 1239 // TODO(jungjw): Check the base module type. 1240} 1241 1242// override_android_test is used to create an android_app module based on another android_test by overriding 1243// some of its properties. 1244func OverrideAndroidTestModuleFactory() android.Module { 1245 m := &OverrideAndroidTest{} 1246 m.AddProperties(&overridableAppProperties{}) 1247 m.AddProperties(&appTestProperties{}) 1248 1249 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) 1250 android.InitOverrideModule(m) 1251 return m 1252} 1253 1254type UsesLibraryProperties struct { 1255 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file. 1256 Uses_libs []string 1257 1258 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with 1259 // required=false. 1260 Optional_uses_libs []string 1261 1262 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults 1263 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future. 1264 Enforce_uses_libs *bool 1265 1266 // Optional name of the <uses-library> provided by this module. This is needed for non-SDK 1267 // libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name 1268 // normally is the same as the module name, but there are exceptions. 1269 Provides_uses_lib *string 1270 1271 // A list of shared library names to exclude from the classpath of the APK. Adding a library here 1272 // will prevent it from being used when precompiling the APK and prevent it from being implicitly 1273 // added to the APK's manifest's <uses-library> elements. 1274 // 1275 // Care must be taken when using this as it could result in runtime errors if the APK actually 1276 // uses classes provided by the library and which are not provided in any other way. 1277 // 1278 // This is primarily intended for use by various CTS tests that check the runtime handling of the 1279 // android.test.base shared library (and related libraries) but which depend on some common 1280 // libraries that depend on the android.test.base library. Without this those tests will end up 1281 // with a <uses-library android:name="android.test.base"/> in their manifest which would either 1282 // render the tests worthless (as they would be testing the wrong behavior), or would break the 1283 // test altogether by providing access to classes that the tests were not expecting. Those tests 1284 // provide the android.test.base statically and use jarjar to rename them so they do not collide 1285 // with the classes provided by the android.test.base library. 1286 Exclude_uses_libs []string 1287} 1288 1289// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the 1290// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the 1291// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps 1292// with knowledge of their shared libraries. 1293type usesLibrary struct { 1294 usesLibraryProperties UsesLibraryProperties 1295 1296 // Whether to enforce verify_uses_library check. 1297 enforce bool 1298} 1299 1300func (u *usesLibrary) addLib(lib string, optional bool) { 1301 if !android.InList(lib, u.usesLibraryProperties.Uses_libs) && !android.InList(lib, u.usesLibraryProperties.Optional_uses_libs) { 1302 if optional { 1303 u.usesLibraryProperties.Optional_uses_libs = append(u.usesLibraryProperties.Optional_uses_libs, lib) 1304 } else { 1305 u.usesLibraryProperties.Uses_libs = append(u.usesLibraryProperties.Uses_libs, lib) 1306 } 1307 } 1308} 1309 1310func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) { 1311 if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() { 1312 ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...) 1313 ctx.AddVariationDependencies(nil, usesLibOptTag, u.presentOptionalUsesLibs(ctx)...) 1314 // Only add these extra dependencies if the module is an app that depends on framework 1315 // libs. This avoids creating a cyclic dependency: 1316 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res. 1317 if addCompatDeps { 1318 // Dexpreopt needs paths to the dex jars of these libraries in order to construct 1319 // class loader context for dex2oat. Add them as a dependency with a special tag. 1320 ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...) 1321 ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...) 1322 ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...) 1323 } 1324 } else { 1325 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...) 1326 ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...) 1327 } 1328} 1329 1330// presentOptionalUsesLibs returns optional_uses_libs after filtering out MissingUsesLibraries, which don't exist in the 1331// build. 1332func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string { 1333 optionalUsesLibs, _ := android.FilterList(u.usesLibraryProperties.Optional_uses_libs, ctx.Config().MissingUsesLibraries()) 1334 return optionalUsesLibs 1335} 1336 1337// Helper function to replace string in a list. 1338func replaceInList(list []string, oldstr, newstr string) { 1339 for i, str := range list { 1340 if str == oldstr { 1341 list[i] = newstr 1342 } 1343 } 1344} 1345 1346// Returns a map of module names of shared library dependencies to the paths to their dex jars on 1347// host and on device. 1348func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap { 1349 clcMap := make(dexpreopt.ClassLoaderContextMap) 1350 1351 // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With 1352 // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting. 1353 if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() { 1354 return clcMap 1355 } 1356 1357 ctx.VisitDirectDeps(func(m android.Module) { 1358 tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag) 1359 if !isUsesLibTag { 1360 return 1361 } 1362 1363 dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m)) 1364 1365 // Skip stub libraries. A dependency on the implementation library has been added earlier, 1366 // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed 1367 // from implementation libraries by their name, which is different as it has a suffix. 1368 if comp, ok := m.(SdkLibraryComponentDependency); ok { 1369 if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep { 1370 return 1371 } 1372 } 1373 1374 if lib, ok := m.(UsesLibraryDependency); ok { 1375 libName := dep 1376 if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil { 1377 libName = *ulib.ProvidesUsesLib() 1378 // Replace module name with library name in `uses_libs`/`optional_uses_libs` in 1379 // order to pass verify_uses_libraries check (which compares these properties 1380 // against library names written in the manifest). 1381 replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName) 1382 replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName) 1383 } 1384 clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, 1385 lib.DexJarBuildPath().PathOrNil(), lib.DexJarInstallPath(), 1386 lib.ClassLoaderContexts()) 1387 } else if ctx.Config().AllowMissingDependencies() { 1388 ctx.AddMissingDependencies([]string{dep}) 1389 } else { 1390 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep) 1391 } 1392 }) 1393 return clcMap 1394} 1395 1396// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs 1397// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true 1398// unconditionally in the future. 1399func (u *usesLibrary) enforceUsesLibraries() bool { 1400 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 || 1401 len(u.usesLibraryProperties.Optional_uses_libs) > 0 1402 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs) 1403} 1404 1405// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`. 1406func (u *usesLibrary) freezeEnforceUsesLibraries() { 1407 enforce := u.enforceUsesLibraries() 1408 u.usesLibraryProperties.Enforce_uses_libs = &enforce 1409} 1410 1411// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified 1412// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or 1413// an APK with the manifest embedded in it (manifest_check will know which one it is by the file 1414// extension: APKs are supposed to end with '.apk'). 1415func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path, 1416 outputFile android.WritablePath) android.Path { 1417 1418 statusFile := dexpreopt.UsesLibrariesStatusFile(ctx) 1419 1420 // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the 1421 // check is not necessary, and although it is good to have, it is difficult to maintain on 1422 // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to 1423 // various unrelated reasons, such as a failure to get manifest from an APK). 1424 global := dexpreopt.GetGlobalConfig(ctx) 1425 if global.DisablePreopt || global.OnlyPreoptBootImageAndSystemServer { 1426 return inputFile 1427 } 1428 1429 rule := android.NewRuleBuilder(pctx, ctx) 1430 cmd := rule.Command().BuiltTool("manifest_check"). 1431 Flag("--enforce-uses-libraries"). 1432 Input(inputFile). 1433 FlagWithOutput("--enforce-uses-libraries-status ", statusFile). 1434 FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2")) 1435 1436 if outputFile != nil { 1437 cmd.FlagWithOutput("-o ", outputFile) 1438 } 1439 1440 if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck { 1441 cmd.Flag("--enforce-uses-libraries-relax") 1442 } 1443 1444 for _, lib := range u.usesLibraryProperties.Uses_libs { 1445 cmd.FlagWithArg("--uses-library ", lib) 1446 } 1447 1448 for _, lib := range u.usesLibraryProperties.Optional_uses_libs { 1449 cmd.FlagWithArg("--optional-uses-library ", lib) 1450 } 1451 1452 rule.Build("verify_uses_libraries", "verify <uses-library>") 1453 return outputFile 1454} 1455 1456// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against 1457// the build system and returns the path to a copy of the manifest. 1458func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path { 1459 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml") 1460 return u.verifyUsesLibraries(ctx, manifest, outputFile) 1461} 1462 1463// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build 1464// system and returns the path to a copy of the APK. 1465func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path { 1466 u.verifyUsesLibraries(ctx, apk, nil) // for APKs manifest_check does not write output file 1467 outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base()) 1468 return outputFile 1469} 1470 1471// For Bazel / bp2build 1472 1473type bazelAndroidAppCertificateAttributes struct { 1474 Certificate string 1475} 1476 1477func (m *AndroidAppCertificate) ConvertWithBp2build(ctx android.TopDownMutatorContext) { 1478 androidAppCertificateBp2Build(ctx, m) 1479} 1480 1481func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *AndroidAppCertificate) { 1482 var certificate string 1483 if module.properties.Certificate != nil { 1484 certificate = *module.properties.Certificate 1485 } 1486 1487 attrs := &bazelAndroidAppCertificateAttributes{ 1488 Certificate: certificate, 1489 } 1490 1491 props := bazel.BazelTargetModuleProperties{ 1492 Rule_class: "android_app_certificate", 1493 Bzl_load_location: "//build/bazel/rules/android:rules.bzl", 1494 } 1495 1496 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs) 1497} 1498 1499type manifestValueAttribute struct { 1500 MinSdkVersion *string 1501} 1502 1503type bazelAndroidAppAttributes struct { 1504 *javaCommonAttributes 1505 *bazelAapt 1506 Deps bazel.LabelListAttribute 1507 Custom_package *string 1508 Certificate bazel.LabelAttribute 1509 Certificate_name bazel.StringAttribute 1510 Manifest_values *manifestValueAttribute 1511} 1512 1513// ConvertWithBp2build is used to convert android_app to Bazel. 1514func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { 1515 commonAttrs, bp2BuildInfo := a.convertLibraryAttrsBp2Build(ctx) 1516 depLabels := bp2BuildInfo.DepLabels 1517 1518 deps := depLabels.Deps 1519 deps.Append(depLabels.StaticDeps) 1520 1521 aapt := a.convertAaptAttrsWithBp2Build(ctx) 1522 1523 certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableAppProperties.Certificate) 1524 1525 manifestValues := &manifestValueAttribute{} 1526 // TODO(b/274474008 ): Directly convert deviceProperties.Min_sdk_version in bp2build 1527 // MinSdkVersion(ctx) calls SdkVersion(ctx) if no value for min_sdk_version is set 1528 minSdkVersion := a.MinSdkVersion(ctx) 1529 if !minSdkVersion.IsPreview() && !minSdkVersion.IsInvalid() { 1530 minSdkStr, err := minSdkVersion.EffectiveVersionString(ctx) 1531 if err == nil { 1532 manifestValues.MinSdkVersion = &minSdkStr 1533 } 1534 } 1535 1536 appAttrs := &bazelAndroidAppAttributes{ 1537 // TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES 1538 Custom_package: a.overridableAppProperties.Package_name, 1539 Certificate: certificate, 1540 Certificate_name: certificateName, 1541 Manifest_values: manifestValues, 1542 } 1543 1544 props := bazel.BazelTargetModuleProperties{ 1545 Rule_class: "android_binary", 1546 Bzl_load_location: "//build/bazel/rules/android:rules.bzl", 1547 } 1548 1549 if !bp2BuildInfo.hasKotlin { 1550 appAttrs.javaCommonAttributes = commonAttrs 1551 appAttrs.bazelAapt = aapt 1552 appAttrs.Deps = deps 1553 } else { 1554 ktName := a.Name() + "_kt" 1555 ctx.CreateBazelTargetModule( 1556 AndroidLibraryBazelTargetModuleProperties(), 1557 android.CommonAttributes{Name: ktName}, 1558 &bazelAndroidLibrary{ 1559 javaLibraryAttributes: &javaLibraryAttributes{ 1560 javaCommonAttributes: commonAttrs, 1561 Deps: deps, 1562 }, 1563 bazelAapt: aapt, 1564 }, 1565 ) 1566 1567 appAttrs.bazelAapt = &bazelAapt{Manifest: aapt.Manifest} 1568 appAttrs.Deps = bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + ktName}) 1569 appAttrs.javaCommonAttributes = &javaCommonAttributes{ 1570 Sdk_version: commonAttrs.Sdk_version, 1571 } 1572 } 1573 1574 ctx.CreateBazelTargetModule( 1575 props, 1576 android.CommonAttributes{Name: a.Name()}, 1577 appAttrs, 1578 ) 1579 1580} 1581