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