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 types for compiling Android apps. 18 19import ( 20 "path/filepath" 21 "reflect" 22 "sort" 23 "strconv" 24 "strings" 25 26 "github.com/google/blueprint" 27 "github.com/google/blueprint/proptools" 28 29 "android/soong/android" 30 "android/soong/cc" 31 "android/soong/dexpreopt" 32 "android/soong/tradefed" 33) 34 35var supportedDpis = []string{"ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"} 36 37func init() { 38 RegisterAppBuildComponents(android.InitRegistrationContext) 39 40 initAndroidAppImportVariantGroupTypes() 41} 42 43func RegisterAppBuildComponents(ctx android.RegistrationContext) { 44 ctx.RegisterModuleType("android_app", AndroidAppFactory) 45 ctx.RegisterModuleType("android_test", AndroidTestFactory) 46 ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory) 47 ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory) 48 ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory) 49 ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory) 50 ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory) 51 ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory) 52 ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory) 53 ctx.RegisterModuleType("runtime_resource_overlay", RuntimeResourceOverlayFactory) 54 ctx.RegisterModuleType("android_app_set", AndroidApkSetFactory) 55} 56 57type AndroidAppSetProperties struct { 58 // APK Set path 59 Set *string 60 61 // Specifies that this app should be installed to the priv-app directory, 62 // where the system will grant it additional privileges not available to 63 // normal apps. 64 Privileged *bool 65 66 // APKs in this set use prerelease SDK version 67 Prerelease *bool 68 69 // Names of modules to be overridden. Listed modules can only be other apps 70 // (in Make or Soong). 71 Overrides []string 72} 73 74type AndroidAppSet struct { 75 android.ModuleBase 76 android.DefaultableModuleBase 77 prebuilt android.Prebuilt 78 79 properties AndroidAppSetProperties 80 packedOutput android.WritablePath 81 installFile string 82 apkcertsFile android.ModuleOutPath 83} 84 85func (as *AndroidAppSet) Name() string { 86 return as.prebuilt.Name(as.ModuleBase.Name()) 87} 88 89func (as *AndroidAppSet) IsInstallable() bool { 90 return true 91} 92 93func (as *AndroidAppSet) Prebuilt() *android.Prebuilt { 94 return &as.prebuilt 95} 96 97func (as *AndroidAppSet) Privileged() bool { 98 return Bool(as.properties.Privileged) 99} 100 101func (as *AndroidAppSet) OutputFile() android.Path { 102 return as.packedOutput 103} 104 105func (as *AndroidAppSet) InstallFile() string { 106 return as.installFile 107} 108 109func (as *AndroidAppSet) APKCertsFile() android.Path { 110 return as.apkcertsFile 111} 112 113var TargetCpuAbi = map[string]string{ 114 "arm": "ARMEABI_V7A", 115 "arm64": "ARM64_V8A", 116 "x86": "X86", 117 "x86_64": "X86_64", 118} 119 120func SupportedAbis(ctx android.ModuleContext) []string { 121 abiName := func(archVar string, deviceArch string) string { 122 if abi, found := TargetCpuAbi[deviceArch]; found { 123 return abi 124 } 125 ctx.ModuleErrorf("Invalid %s: %s", archVar, deviceArch) 126 return "BAD_ABI" 127 } 128 129 result := []string{abiName("TARGET_ARCH", ctx.DeviceConfig().DeviceArch())} 130 if s := ctx.DeviceConfig().DeviceSecondaryArch(); s != "" { 131 result = append(result, abiName("TARGET_2ND_ARCH", s)) 132 } 133 return result 134} 135 136func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { 137 as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip") 138 as.apkcertsFile = android.PathForModuleOut(ctx, "apkcerts.txt") 139 // We are assuming here that the install file in the APK 140 // set has `.apk` suffix. If it doesn't the build will fail. 141 // APK sets containing APEX files are handled elsewhere. 142 as.installFile = as.BaseModuleName() + ".apk" 143 screenDensities := "all" 144 if dpis := ctx.Config().ProductAAPTPrebuiltDPI(); len(dpis) > 0 { 145 screenDensities = strings.ToUpper(strings.Join(dpis, ",")) 146 } 147 // TODO(asmundak): handle locales. 148 // TODO(asmundak): do we support device features 149 ctx.Build(pctx, 150 android.BuildParams{ 151 Rule: extractMatchingApks, 152 Description: "Extract APKs from APK set", 153 Output: as.packedOutput, 154 ImplicitOutput: as.apkcertsFile, 155 Inputs: android.Paths{as.prebuilt.SingleSourcePath(ctx)}, 156 Args: map[string]string{ 157 "abis": strings.Join(SupportedAbis(ctx), ","), 158 "allow-prereleased": strconv.FormatBool(proptools.Bool(as.properties.Prerelease)), 159 "screen-densities": screenDensities, 160 "sdk-version": ctx.Config().PlatformSdkVersion(), 161 "stem": as.BaseModuleName(), 162 "apkcerts": as.apkcertsFile.String(), 163 "partition": as.PartitionTag(ctx.DeviceConfig()), 164 }, 165 }) 166} 167 168// android_app_set extracts a set of APKs based on the target device 169// configuration and installs this set as "split APKs". 170// The extracted set always contains an APK whose name is 171// _module_name_.apk and every split APK matching target device. 172// The extraction of the density-specific splits depends on 173// PRODUCT_AAPT_PREBUILT_DPI variable. If present (its value should 174// be a list density names: LDPI, MDPI, HDPI, etc.), only listed 175// splits will be extracted. Otherwise all density-specific splits 176// will be extracted. 177func AndroidApkSetFactory() android.Module { 178 module := &AndroidAppSet{} 179 module.AddProperties(&module.properties) 180 InitJavaModule(module, android.DeviceSupported) 181 android.InitSingleSourcePrebuiltModule(module, &module.properties, "Set") 182 return module 183} 184 185// AndroidManifest.xml merging 186// package splits 187 188type appProperties struct { 189 // Names of extra android_app_certificate modules to sign the apk with in the form ":module". 190 Additional_certificates []string 191 192 // If set, create package-export.apk, which other packages can 193 // use to get PRODUCT-agnostic resource data like IDs and type definitions. 194 Export_package_resources *bool 195 196 // Specifies that this app should be installed to the priv-app directory, 197 // where the system will grant it additional privileges not available to 198 // normal apps. 199 Privileged *bool 200 201 // list of resource labels to generate individual resource packages 202 Package_splits []string 203 204 // Names of modules to be overridden. Listed modules can only be other binaries 205 // (in Make or Soong). 206 // This does not completely prevent installation of the overridden binaries, but if both 207 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed 208 // from PRODUCT_PACKAGES. 209 Overrides []string 210 211 // list of native libraries that will be provided in or alongside the resulting jar 212 Jni_libs []string `android:"arch_variant"` 213 214 // if true, use JNI libraries that link against platform APIs even if this module sets 215 // sdk_version. 216 Jni_uses_platform_apis *bool 217 218 // if true, use JNI libraries that link against SDK APIs even if this module does not set 219 // sdk_version. 220 Jni_uses_sdk_apis *bool 221 222 // STL library to use for JNI libraries. 223 Stl *string `android:"arch_variant"` 224 225 // Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest 226 // flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless 227 // sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for 228 // android_app modules that are embedded to APEXes, defaults to false for other module types where the native 229 // libraries are generally preinstalled outside the APK. 230 Use_embedded_native_libs *bool 231 232 // Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that 233 // they are used from inside the APK at runtime. 234 Use_embedded_dex *bool 235 236 // Forces native libraries to always be packaged into the APK, 237 // Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed. 238 // True for android_test* modules. 239 AlwaysPackageNativeLibs bool `blueprint:"mutated"` 240 241 // If set, find and merge all NOTICE files that this module and its dependencies have and store 242 // it in the APK as an asset. 243 Embed_notices *bool 244 245 // cc.Coverage related properties 246 PreventInstall bool `blueprint:"mutated"` 247 HideFromMake bool `blueprint:"mutated"` 248 IsCoverageVariant bool `blueprint:"mutated"` 249 250 // Whether this app is considered mainline updatable or not. When set to true, this will enforce 251 // additional rules to make sure an app can safely be updated. Default is false. 252 // Prefer using other specific properties if build behaviour must be changed; avoid using this 253 // flag for anything but neverallow rules (unless the behaviour change is invisible to owners). 254 Updatable *bool 255} 256 257// android_app properties that can be overridden by override_android_app 258type overridableAppProperties struct { 259 // The name of a certificate in the default certificate directory, blank to use the default product certificate, 260 // or an android_app_certificate module name in the form ":module". 261 Certificate *string 262 263 // Name of the signing certificate lineage file. 264 Lineage *string 265 266 // the package name of this app. The package name in the manifest file is used if one was not given. 267 Package_name *string 268 269 // the logging parent of this app. 270 Logging_parent *string 271} 272 273// runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay 274type OverridableRuntimeResourceOverlayProperties struct { 275 // the package name of this app. The package name in the manifest file is used if one was not given. 276 Package_name *string 277 278 // the target package name of this overlay app. The target package name in the manifest file is used if one was not given. 279 Target_package_name *string 280} 281 282type AndroidApp struct { 283 Library 284 aapt 285 android.OverridableModuleBase 286 287 usesLibrary usesLibrary 288 289 certificate Certificate 290 291 appProperties appProperties 292 293 overridableAppProperties overridableAppProperties 294 295 jniLibs []jniLib 296 installPathForJNISymbols android.Path 297 embeddedJniLibs bool 298 jniCoverageOutputs android.Paths 299 300 bundleFile android.Path 301 302 // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES. 303 installApkName string 304 305 installDir android.InstallPath 306 307 onDeviceDir string 308 309 additionalAaptFlags []string 310 311 noticeOutputs android.NoticeOutputs 312 313 overriddenManifestPackageName string 314 315 android.ApexBundleDepsInfo 316} 317 318func (a *AndroidApp) IsInstallable() bool { 319 return Bool(a.properties.Installable) 320} 321 322func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths { 323 return nil 324} 325 326func (a *AndroidApp) ExportedStaticPackages() android.Paths { 327 return nil 328} 329 330func (a *AndroidApp) OutputFile() android.Path { 331 return a.outputFile 332} 333 334func (a *AndroidApp) Certificate() Certificate { 335 return a.certificate 336} 337 338func (a *AndroidApp) JniCoverageOutputs() android.Paths { 339 return a.jniCoverageOutputs 340} 341 342var _ AndroidLibraryDependency = (*AndroidApp)(nil) 343 344type Certificate struct { 345 Pem, Key android.Path 346 presigned bool 347} 348 349var PresignedCertificate = Certificate{presigned: true} 350 351func (c Certificate) AndroidMkString() string { 352 if c.presigned { 353 return "PRESIGNED" 354 } else { 355 return c.Pem.String() 356 } 357} 358 359func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { 360 a.Module.deps(ctx) 361 362 if String(a.appProperties.Stl) == "c++_shared" && !a.sdkVersion().specified() { 363 ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared") 364 } 365 366 sdkDep := decodeSdkDep(ctx, sdkContext(a)) 367 if sdkDep.hasFrameworkLibs() { 368 a.aapt.deps(ctx, sdkDep) 369 } 370 371 usesSDK := a.sdkVersion().specified() && a.sdkVersion().kind != sdkCorePlatform 372 373 if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) { 374 ctx.PropertyErrorf("jni_uses_sdk_apis", 375 "can only be set for modules that do not set sdk_version") 376 } else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) { 377 ctx.PropertyErrorf("jni_uses_platform_apis", 378 "can only be set for modules that set sdk_version") 379 } 380 381 tag := &jniDependencyTag{} 382 for _, jniTarget := range ctx.MultiTargets() { 383 variation := append(jniTarget.Variations(), 384 blueprint.Variation{Mutator: "link", Variation: "shared"}) 385 386 // If the app builds against an Android SDK use the SDK variant of JNI dependencies 387 // unless jni_uses_platform_apis is set. 388 // Don't require the SDK variant for apps that are shipped on vendor, etc., as they already 389 // have stable APIs through the VNDK. 390 if (usesSDK && !a.RequiresStableAPIs(ctx) && 391 !Bool(a.appProperties.Jni_uses_platform_apis)) || 392 Bool(a.appProperties.Jni_uses_sdk_apis) { 393 variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"}) 394 } 395 ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...) 396 } 397 398 a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs()) 399} 400 401func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) { 402 cert := android.SrcIsModule(a.getCertString(ctx)) 403 if cert != "" { 404 ctx.AddDependency(ctx.Module(), certificateTag, cert) 405 } 406 407 for _, cert := range a.appProperties.Additional_certificates { 408 cert = android.SrcIsModule(cert) 409 if cert != "" { 410 ctx.AddDependency(ctx.Module(), certificateTag, cert) 411 } else { 412 ctx.PropertyErrorf("additional_certificates", 413 `must be names of android_app_certificate modules in the form ":module"`) 414 } 415 } 416} 417 418func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { 419 a.generateAndroidBuildActions(ctx) 420} 421 422func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { 423 a.checkAppSdkVersions(ctx) 424 a.generateAndroidBuildActions(ctx) 425} 426 427func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) { 428 if a.Updatable() { 429 if !a.sdkVersion().stable() { 430 ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.sdkVersion()) 431 } 432 if String(a.deviceProperties.Min_sdk_version) == "" { 433 ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.") 434 } 435 436 if minSdkVersion, err := a.minSdkVersion().effectiveVersion(ctx); err == nil { 437 a.checkJniLibsSdkVersion(ctx, minSdkVersion) 438 android.CheckMinSdkVersion(a, ctx, int(minSdkVersion)) 439 } else { 440 ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) 441 } 442 } 443 444 a.checkPlatformAPI(ctx) 445 a.checkSdkVersions(ctx) 446} 447 448// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it. 449// This check is enforced for "updatable" APKs (including APK-in-APEX). 450// b/155209650: until min_sdk_version is properly supported, use sdk_version instead. 451// because, sdk_version is overridden by min_sdk_version (if set as smaller) 452// and linkType is checked with dependencies so we can be sure that the whole dependency tree 453// will meet the requirements. 454func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion sdkVersion) { 455 // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType() 456 ctx.VisitDirectDeps(func(m android.Module) { 457 if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) { 458 return 459 } 460 dep, _ := m.(*cc.Module) 461 // The domain of cc.sdk_version is "current" and <number> 462 // We can rely on sdkSpec to convert it to <number> so that "current" is handled 463 // properly regardless of sdk finalization. 464 jniSdkVersion, err := sdkSpecFrom(dep.SdkVersion()).effectiveVersion(ctx) 465 if err != nil || minSdkVersion < jniSdkVersion { 466 ctx.OtherModuleErrorf(dep, "sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)", 467 dep.SdkVersion(), minSdkVersion, ctx.ModuleName()) 468 return 469 } 470 471 }) 472} 473 474// Returns true if the native libraries should be stored in the APK uncompressed and the 475// extractNativeLibs application flag should be set to false in the manifest. 476func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool { 477 minSdkVersion, err := a.minSdkVersion().effectiveVersion(ctx) 478 if err != nil { 479 ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.minSdkVersion(), err) 480 } 481 482 return (minSdkVersion >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) || 483 !a.IsForPlatform() 484} 485 486// Returns whether this module should have the dex file stored uncompressed in the APK. 487func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool { 488 if Bool(a.appProperties.Use_embedded_dex) { 489 return true 490 } 491 492 // Uncompress dex in APKs of privileged apps (even for unbundled builds, they may 493 // be preinstalled as prebuilts). 494 if ctx.Config().UncompressPrivAppDex() && a.Privileged() { 495 return true 496 } 497 498 if ctx.Config().UnbundledBuild() { 499 return false 500 } 501 502 return shouldUncompressDex(ctx, &a.dexpreopter) 503} 504 505func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool { 506 return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) || 507 !a.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs 508} 509 510func (a *AndroidApp) OverriddenManifestPackageName() string { 511 return a.overriddenManifestPackageName 512} 513 514func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { 515 a.aapt.usesNonSdkApis = Bool(a.Module.deviceProperties.Platform_apis) 516 517 // Ask manifest_fixer to add or update the application element indicating this app has no code. 518 a.aapt.hasNoCode = !a.hasCode(ctx) 519 520 aaptLinkFlags := []string{} 521 522 // Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided. 523 hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product") 524 if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 { 525 aaptLinkFlags = append(aaptLinkFlags, "--product", ctx.Config().ProductAAPTCharacteristics()) 526 } 527 528 if !Bool(a.aaptProperties.Aapt_include_all_resources) { 529 // Product AAPT config 530 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() { 531 aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig) 532 } 533 534 // Product AAPT preferred config 535 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 { 536 aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig()) 537 } 538 } 539 540 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName()) 541 if overridden || a.overridableAppProperties.Package_name != nil { 542 // The product override variable has a priority over the package_name property. 543 if !overridden { 544 manifestPackageName = *a.overridableAppProperties.Package_name 545 } 546 aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName) 547 a.overriddenManifestPackageName = manifestPackageName 548 } 549 550 aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...) 551 552 a.aapt.splitNames = a.appProperties.Package_splits 553 a.aapt.sdkLibraries = a.exportedSdkLibs 554 a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent) 555 a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...) 556 557 // apps manifests are handled by aapt, don't let Module see them 558 a.properties.Manifest = nil 559} 560 561func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) { 562 var staticLibProguardFlagFiles android.Paths 563 ctx.VisitDirectDeps(func(m android.Module) { 564 if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag { 565 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, lib.ExportedProguardFlagFiles()...) 566 } 567 }) 568 569 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles) 570 571 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, staticLibProguardFlagFiles...) 572 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile) 573} 574 575func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath { 576 var installDir string 577 if ctx.ModuleName() == "framework-res" { 578 // framework-res.apk is installed as system/framework/framework-res.apk 579 installDir = "framework" 580 } else if a.Privileged() { 581 installDir = filepath.Join("priv-app", a.installApkName) 582 } else { 583 installDir = filepath.Join("app", a.installApkName) 584 } 585 586 return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk") 587} 588 589func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { 590 a.dexpreopter.installPath = a.installPath(ctx) 591 if a.deviceProperties.Uncompress_dex == nil { 592 // If the value was not force-set by the user, use reasonable default based on the module. 593 a.deviceProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx)) 594 } 595 a.dexpreopter.uncompressedDex = *a.deviceProperties.Uncompress_dex 596 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries() 597 a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs 598 a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx) 599 a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx) 600 a.dexpreopter.manifestFile = a.mergedManifestFile 601 602 if ctx.ModuleName() != "framework-res" { 603 a.Module.compile(ctx, a.aaptSrcJar) 604 } 605 606 return a.maybeStrippedDexJarFile 607} 608 609func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, ctx android.ModuleContext) android.WritablePath { 610 var jniJarFile android.WritablePath 611 if len(jniLibs) > 0 { 612 a.jniLibs = jniLibs 613 if a.shouldEmbedJnis(ctx) { 614 jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip") 615 a.installPathForJNISymbols = a.installPath(ctx).ToMakePath() 616 TransformJniLibsToJar(ctx, jniJarFile, jniLibs, a.useEmbeddedNativeLibs(ctx)) 617 for _, jni := range jniLibs { 618 if jni.coverageFile.Valid() { 619 // Only collect coverage for the first target arch if this is a multilib target. 620 // TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage 621 // data file path collisions since the current coverage file path format doesn't contain 622 // arch-related strings. This is fine for now though; the code coverage team doesn't use 623 // multi-arch targets such as test_suite_* for coverage collections yet. 624 // 625 // Work with the team to come up with a new format that handles multilib modules properly 626 // and change this. 627 if len(ctx.Config().Targets[android.Android]) == 1 || 628 ctx.Config().Targets[android.Android][0].Arch.ArchType == jni.target.Arch.ArchType { 629 a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path()) 630 } 631 } 632 } 633 a.embeddedJniLibs = true 634 } 635 } 636 return jniJarFile 637} 638 639func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls { 640 var jniSymbols android.RuleBuilderInstalls 641 for _, jniLib := range a.jniLibs { 642 if jniLib.unstrippedFile != nil { 643 jniSymbols = append(jniSymbols, android.RuleBuilderInstall{ 644 From: jniLib.unstrippedFile, 645 To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()), 646 }) 647 } 648 } 649 return jniSymbols 650} 651 652func (a *AndroidApp) noticeBuildActions(ctx android.ModuleContext) { 653 // Collect NOTICE files from all dependencies. 654 seenModules := make(map[android.Module]bool) 655 noticePathSet := make(map[android.Path]bool) 656 657 ctx.WalkDeps(func(child android.Module, parent android.Module) bool { 658 // Have we already seen this? 659 if _, ok := seenModules[child]; ok { 660 return false 661 } 662 seenModules[child] = true 663 664 // Skip host modules. 665 if child.Target().Os.Class == android.Host || child.Target().Os.Class == android.HostCross { 666 return false 667 } 668 669 paths := child.(android.Module).NoticeFiles() 670 if len(paths) > 0 { 671 for _, path := range paths { 672 noticePathSet[path] = true 673 } 674 } 675 return true 676 }) 677 678 // If the app has one, add it too. 679 if len(a.NoticeFiles()) > 0 { 680 for _, path := range a.NoticeFiles() { 681 noticePathSet[path] = true 682 } 683 } 684 685 if len(noticePathSet) == 0 { 686 return 687 } 688 var noticePaths []android.Path 689 for path := range noticePathSet { 690 noticePaths = append(noticePaths, path) 691 } 692 sort.Slice(noticePaths, func(i, j int) bool { 693 return noticePaths[i].String() < noticePaths[j].String() 694 }) 695 696 a.noticeOutputs = android.BuildNoticeOutput(ctx, a.installDir, a.installApkName+".apk", noticePaths) 697} 698 699// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it 700// isn't a cert module reference. Also checks and enforces system cert restriction if applicable. 701func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate, ctx android.ModuleContext) []Certificate { 702 if android.SrcIsModule(certPropValue) == "" { 703 var mainCert Certificate 704 if certPropValue != "" { 705 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx) 706 mainCert = Certificate{ 707 Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"), 708 Key: defaultDir.Join(ctx, certPropValue+".pk8"), 709 } 710 } else { 711 pem, key := ctx.Config().DefaultAppCertificate(ctx) 712 mainCert = Certificate{ 713 Pem: pem, 714 Key: key, 715 } 716 } 717 certificates = append([]Certificate{mainCert}, certificates...) 718 } 719 720 if !m.Platform() { 721 certPath := certificates[0].Pem.String() 722 systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String() 723 if strings.HasPrefix(certPath, systemCertPath) { 724 enforceSystemCert := ctx.Config().EnforceSystemCertificate() 725 allowed := ctx.Config().EnforceSystemCertificateAllowList() 726 727 if enforceSystemCert && !inList(m.Name(), allowed) { 728 ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.") 729 } 730 } 731 } 732 733 return certificates 734} 735 736func (a *AndroidApp) InstallApkName() string { 737 return a.installApkName 738} 739 740func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { 741 var apkDeps android.Paths 742 743 a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) 744 a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) 745 746 // Check if the install APK name needs to be overridden. 747 a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Name()) 748 749 if ctx.ModuleName() == "framework-res" { 750 // framework-res.apk is installed as system/framework/framework-res.apk 751 a.installDir = android.PathForModuleInstall(ctx, "framework") 752 } else if a.Privileged() { 753 a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName) 754 } else if ctx.InstallInTestcases() { 755 a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch()) 756 } else { 757 a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName) 758 } 759 a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir) 760 761 a.noticeBuildActions(ctx) 762 if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") { 763 a.aapt.noticeFile = a.noticeOutputs.HtmlGzOutput 764 } 765 766 // Process all building blocks, from AAPT to certificates. 767 a.aaptBuildActions(ctx) 768 769 if a.usesLibrary.enforceUsesLibraries() { 770 manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile) 771 apkDeps = append(apkDeps, manifestCheckFile) 772 } 773 774 a.proguardBuildActions(ctx) 775 776 a.linter.mergedManifest = a.aapt.mergedManifestFile 777 a.linter.manifest = a.aapt.manifestPath 778 a.linter.resources = a.aapt.resourceFiles 779 a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps() 780 781 dexJarFile := a.dexBuildActions(ctx) 782 783 jniLibs, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis)) 784 jniJarFile := a.jniBuildActions(jniLibs, ctx) 785 786 if ctx.Failed() { 787 return 788 } 789 790 certificates := processMainCert(a.ModuleBase, a.getCertString(ctx), certificateDeps, ctx) 791 a.certificate = certificates[0] 792 793 // Build a final signed app package. 794 packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk") 795 var lineageFile android.Path 796 if lineage := String(a.overridableAppProperties.Lineage); lineage != "" { 797 lineageFile = android.PathForModuleSrc(ctx, lineage) 798 } 799 CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, lineageFile) 800 a.outputFile = packageFile 801 802 for _, split := range a.aapt.splits { 803 // Sign the split APKs 804 packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk") 805 CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, lineageFile) 806 a.extraOutputFiles = append(a.extraOutputFiles, packageFile) 807 } 808 809 // Build an app bundle. 810 bundleFile := android.PathForModuleOut(ctx, "base.zip") 811 BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile) 812 a.bundleFile = bundleFile 813 814 // Install the app package. 815 if (Bool(a.Module.properties.Installable) || ctx.Host()) && a.IsForPlatform() { 816 ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile) 817 for _, extra := range a.extraOutputFiles { 818 ctx.InstallFile(a.installDir, extra.Base(), extra) 819 } 820 } 821 822 a.buildAppDependencyInfo(ctx) 823} 824 825type appDepsInterface interface { 826 sdkVersion() sdkSpec 827 minSdkVersion() sdkSpec 828 RequiresStableAPIs(ctx android.BaseModuleContext) bool 829} 830 831func collectAppDeps(ctx android.ModuleContext, app appDepsInterface, 832 shouldCollectRecursiveNativeDeps bool, 833 checkNativeSdkVersion bool) ([]jniLib, []Certificate) { 834 835 var jniLibs []jniLib 836 var certificates []Certificate 837 seenModulePaths := make(map[string]bool) 838 839 if checkNativeSdkVersion { 840 checkNativeSdkVersion = app.sdkVersion().specified() && 841 app.sdkVersion().kind != sdkCorePlatform && !app.RequiresStableAPIs(ctx) 842 } 843 844 ctx.WalkDeps(func(module android.Module, parent android.Module) bool { 845 otherName := ctx.OtherModuleName(module) 846 tag := ctx.OtherModuleDependencyTag(module) 847 848 if IsJniDepTag(tag) || tag == cc.SharedDepTag { 849 if dep, ok := module.(*cc.Module); ok { 850 if dep.IsNdk() || dep.IsStubs() { 851 return false 852 } 853 854 lib := dep.OutputFile() 855 path := lib.Path() 856 if seenModulePaths[path.String()] { 857 return false 858 } 859 seenModulePaths[path.String()] = true 860 861 if checkNativeSdkVersion && dep.SdkVersion() == "" { 862 ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not", 863 otherName) 864 } 865 866 if lib.Valid() { 867 jniLibs = append(jniLibs, jniLib{ 868 name: ctx.OtherModuleName(module), 869 path: path, 870 target: module.Target(), 871 coverageFile: dep.CoverageOutputFile(), 872 unstrippedFile: dep.UnstrippedOutputFile(), 873 }) 874 } else { 875 ctx.ModuleErrorf("dependency %q missing output file", otherName) 876 } 877 } else { 878 ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName) 879 } 880 881 return shouldCollectRecursiveNativeDeps 882 } 883 884 if tag == certificateTag { 885 if dep, ok := module.(*AndroidAppCertificate); ok { 886 certificates = append(certificates, dep.Certificate) 887 } else { 888 ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName) 889 } 890 } 891 892 return false 893 }) 894 895 return jniLibs, certificates 896} 897 898func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) { 899 ctx.WalkDeps(func(child, parent android.Module) bool { 900 isExternal := !a.DepIsInSameApex(ctx, child) 901 if am, ok := child.(android.ApexModule); ok { 902 if !do(ctx, parent, am, isExternal) { 903 return false 904 } 905 } 906 return !isExternal 907 }) 908} 909 910func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { 911 if ctx.Host() { 912 return 913 } 914 915 depsInfo := android.DepNameToDepInfoMap{} 916 a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { 917 depName := to.Name() 918 if info, exist := depsInfo[depName]; exist { 919 info.From = append(info.From, from.Name()) 920 info.IsExternal = info.IsExternal && externalDep 921 depsInfo[depName] = info 922 } else { 923 toMinSdkVersion := "(no version)" 924 if m, ok := to.(interface{ MinSdkVersion() string }); ok { 925 if v := m.MinSdkVersion(); v != "" { 926 toMinSdkVersion = v 927 } 928 } 929 depsInfo[depName] = android.ApexModuleDepInfo{ 930 To: depName, 931 From: []string{from.Name()}, 932 IsExternal: externalDep, 933 MinSdkVersion: toMinSdkVersion, 934 } 935 } 936 return true 937 }) 938 939 a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(), depsInfo) 940} 941 942func (a *AndroidApp) Updatable() bool { 943 return Bool(a.appProperties.Updatable) || a.ApexModuleBase.Updatable() 944} 945 946func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string { 947 certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName()) 948 if overridden { 949 return ":" + certificate 950 } 951 return String(a.overridableAppProperties.Certificate) 952} 953 954func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 955 if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) { 956 return true 957 } 958 return a.Library.DepIsInSameApex(ctx, dep) 959} 960 961// For OutputFileProducer interface 962func (a *AndroidApp) OutputFiles(tag string) (android.Paths, error) { 963 switch tag { 964 case ".aapt.srcjar": 965 return []android.Path{a.aaptSrcJar}, nil 966 } 967 return a.Library.OutputFiles(tag) 968} 969 970func (a *AndroidApp) Privileged() bool { 971 return Bool(a.appProperties.Privileged) 972} 973 974func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { 975 return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled() 976} 977 978func (a *AndroidApp) PreventInstall() { 979 a.appProperties.PreventInstall = true 980} 981 982func (a *AndroidApp) HideFromMake() { 983 a.appProperties.HideFromMake = true 984} 985 986func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) { 987 a.appProperties.IsCoverageVariant = coverage 988} 989 990func (a *AndroidApp) EnableCoverageIfNeeded() {} 991 992var _ cc.Coverage = (*AndroidApp)(nil) 993 994// android_app compiles sources and Android resources into an Android application package `.apk` file. 995func AndroidAppFactory() android.Module { 996 module := &AndroidApp{} 997 998 module.Module.deviceProperties.Optimize.EnabledByDefault = true 999 module.Module.deviceProperties.Optimize.Shrink = proptools.BoolPtr(true) 1000 1001 module.Module.properties.Instrument = true 1002 module.Module.properties.Installable = proptools.BoolPtr(true) 1003 1004 module.addHostAndDeviceProperties() 1005 module.AddProperties( 1006 &module.aaptProperties, 1007 &module.appProperties, 1008 &module.overridableAppProperties, 1009 &module.usesLibrary.usesLibraryProperties) 1010 1011 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1012 android.InitDefaultableModule(module) 1013 android.InitOverridableModule(module, &module.appProperties.Overrides) 1014 android.InitApexModule(module) 1015 1016 return module 1017} 1018 1019type appTestProperties struct { 1020 // The name of the android_app module that the tests will run against. 1021 Instrumentation_for *string 1022 1023 // if specified, the instrumentation target package name in the manifest is overwritten by it. 1024 Instrumentation_target_package *string 1025} 1026 1027type AndroidTest struct { 1028 AndroidApp 1029 1030 appTestProperties appTestProperties 1031 1032 testProperties testProperties 1033 1034 testConfig android.Path 1035 data android.Paths 1036} 1037 1038func (a *AndroidTest) InstallInTestcases() bool { 1039 return true 1040} 1041 1042func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1043 var configs []tradefed.Config 1044 if a.appTestProperties.Instrumentation_target_package != nil { 1045 a.additionalAaptFlags = append(a.additionalAaptFlags, 1046 "--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package) 1047 } else if a.appTestProperties.Instrumentation_for != nil { 1048 // Check if the instrumentation target package is overridden. 1049 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for) 1050 if overridden { 1051 a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName) 1052 } 1053 } 1054 a.generateAndroidBuildActions(ctx) 1055 1056 for _, module := range a.testProperties.Test_mainline_modules { 1057 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module}) 1058 } 1059 1060 testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, 1061 a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs) 1062 a.testConfig = a.FixTestConfig(ctx, testConfig) 1063 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) 1064} 1065 1066func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path { 1067 if testConfig == nil { 1068 return nil 1069 } 1070 1071 fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml") 1072 rule := android.NewRuleBuilder() 1073 command := rule.Command().BuiltTool(ctx, "test_config_fixer").Input(testConfig).Output(fixedConfig) 1074 fixNeeded := false 1075 1076 if ctx.ModuleName() != a.installApkName { 1077 fixNeeded = true 1078 command.FlagWithArg("--test-file-name ", a.installApkName+".apk") 1079 } 1080 1081 if a.overridableAppProperties.Package_name != nil { 1082 fixNeeded = true 1083 command.FlagWithInput("--manifest ", a.manifestPath). 1084 FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name) 1085 } 1086 1087 if fixNeeded { 1088 rule.Build(pctx, ctx, "fix_test_config", "fix test config") 1089 return fixedConfig 1090 } 1091 return testConfig 1092} 1093 1094func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) { 1095 a.AndroidApp.DepsMutator(ctx) 1096} 1097 1098func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) { 1099 a.AndroidApp.OverridablePropertiesDepsMutator(ctx) 1100 if a.appTestProperties.Instrumentation_for != nil { 1101 // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac, 1102 // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so 1103 // use instrumentationForTag instead of libTag. 1104 ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for)) 1105 } 1106} 1107 1108// android_test compiles test sources and Android resources into an Android application package `.apk` file and 1109// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file. 1110func AndroidTestFactory() android.Module { 1111 module := &AndroidTest{} 1112 1113 module.Module.deviceProperties.Optimize.EnabledByDefault = true 1114 1115 module.Module.properties.Instrument = true 1116 module.Module.properties.Installable = proptools.BoolPtr(true) 1117 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true) 1118 module.appProperties.AlwaysPackageNativeLibs = true 1119 module.Module.dexpreopter.isTest = true 1120 module.Module.linter.test = true 1121 1122 module.addHostAndDeviceProperties() 1123 module.AddProperties( 1124 &module.aaptProperties, 1125 &module.appProperties, 1126 &module.appTestProperties, 1127 &module.overridableAppProperties, 1128 &module.usesLibrary.usesLibraryProperties, 1129 &module.testProperties) 1130 1131 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1132 android.InitDefaultableModule(module) 1133 android.InitOverridableModule(module, &module.appProperties.Overrides) 1134 return module 1135} 1136 1137type appTestHelperAppProperties struct { 1138 // list of compatibility suites (for example "cts", "vts") that the module should be 1139 // installed into. 1140 Test_suites []string `android:"arch_variant"` 1141 1142 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 1143 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 1144 // explicitly. 1145 Auto_gen_config *bool 1146} 1147 1148type AndroidTestHelperApp struct { 1149 AndroidApp 1150 1151 appTestHelperAppProperties appTestHelperAppProperties 1152} 1153 1154func (a *AndroidTestHelperApp) InstallInTestcases() bool { 1155 return true 1156} 1157 1158// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that 1159// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a 1160// test. 1161func AndroidTestHelperAppFactory() android.Module { 1162 module := &AndroidTestHelperApp{} 1163 1164 module.Module.deviceProperties.Optimize.EnabledByDefault = true 1165 1166 module.Module.properties.Installable = proptools.BoolPtr(true) 1167 module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true) 1168 module.appProperties.AlwaysPackageNativeLibs = true 1169 module.Module.dexpreopter.isTest = true 1170 module.Module.linter.test = true 1171 1172 module.addHostAndDeviceProperties() 1173 module.AddProperties( 1174 &module.aaptProperties, 1175 &module.appProperties, 1176 &module.appTestHelperAppProperties, 1177 &module.overridableAppProperties, 1178 &module.usesLibrary.usesLibraryProperties) 1179 1180 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1181 android.InitDefaultableModule(module) 1182 android.InitApexModule(module) 1183 return module 1184} 1185 1186type AndroidAppCertificate struct { 1187 android.ModuleBase 1188 properties AndroidAppCertificateProperties 1189 Certificate Certificate 1190} 1191 1192type AndroidAppCertificateProperties struct { 1193 // Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name. 1194 Certificate *string 1195} 1196 1197// android_app_certificate modules can be referenced by the certificates property of android_app modules to select 1198// the signing key. 1199func AndroidAppCertificateFactory() android.Module { 1200 module := &AndroidAppCertificate{} 1201 module.AddProperties(&module.properties) 1202 android.InitAndroidModule(module) 1203 return module 1204} 1205 1206func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1207 cert := String(c.properties.Certificate) 1208 c.Certificate = Certificate{ 1209 Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"), 1210 Key: android.PathForModuleSrc(ctx, cert+".pk8"), 1211 } 1212} 1213 1214type OverrideAndroidApp struct { 1215 android.ModuleBase 1216 android.OverrideModuleBase 1217} 1218 1219func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) { 1220 // All the overrides happen in the base module. 1221 // TODO(jungjw): Check the base module type. 1222} 1223 1224// override_android_app is used to create an android_app module based on another android_app by overriding 1225// some of its properties. 1226func OverrideAndroidAppModuleFactory() android.Module { 1227 m := &OverrideAndroidApp{} 1228 m.AddProperties(&overridableAppProperties{}) 1229 1230 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) 1231 android.InitOverrideModule(m) 1232 return m 1233} 1234 1235type OverrideAndroidTest struct { 1236 android.ModuleBase 1237 android.OverrideModuleBase 1238} 1239 1240func (i *OverrideAndroidTest) GenerateAndroidBuildActions(_ android.ModuleContext) { 1241 // All the overrides happen in the base module. 1242 // TODO(jungjw): Check the base module type. 1243} 1244 1245// override_android_test is used to create an android_app module based on another android_test by overriding 1246// some of its properties. 1247func OverrideAndroidTestModuleFactory() android.Module { 1248 m := &OverrideAndroidTest{} 1249 m.AddProperties(&overridableAppProperties{}) 1250 m.AddProperties(&appTestProperties{}) 1251 1252 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) 1253 android.InitOverrideModule(m) 1254 return m 1255} 1256 1257type OverrideRuntimeResourceOverlay struct { 1258 android.ModuleBase 1259 android.OverrideModuleBase 1260} 1261 1262func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(_ android.ModuleContext) { 1263 // All the overrides happen in the base module. 1264 // TODO(jungjw): Check the base module type. 1265} 1266 1267// override_runtime_resource_overlay is used to create a module based on another 1268// runtime_resource_overlay module by overriding some of its properties. 1269func OverrideRuntimeResourceOverlayModuleFactory() android.Module { 1270 m := &OverrideRuntimeResourceOverlay{} 1271 m.AddProperties(&OverridableRuntimeResourceOverlayProperties{}) 1272 1273 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) 1274 android.InitOverrideModule(m) 1275 return m 1276} 1277 1278type AndroidAppImport struct { 1279 android.ModuleBase 1280 android.DefaultableModuleBase 1281 android.ApexModuleBase 1282 prebuilt android.Prebuilt 1283 1284 properties AndroidAppImportProperties 1285 dpiVariants interface{} 1286 archVariants interface{} 1287 1288 outputFile android.Path 1289 certificate Certificate 1290 1291 dexpreopter 1292 1293 usesLibrary usesLibrary 1294 1295 preprocessed bool 1296 1297 installPath android.InstallPath 1298} 1299 1300type AndroidAppImportProperties struct { 1301 // A prebuilt apk to import 1302 Apk *string 1303 1304 // The name of a certificate in the default certificate directory or an android_app_certificate 1305 // module name in the form ":module". Should be empty if presigned or default_dev_cert is set. 1306 Certificate *string 1307 1308 // Set this flag to true if the prebuilt apk is already signed. The certificate property must not 1309 // be set for presigned modules. 1310 Presigned *bool 1311 1312 // Name of the signing certificate lineage file. 1313 Lineage *string 1314 1315 // Sign with the default system dev certificate. Must be used judiciously. Most imported apps 1316 // need to either specify a specific certificate or be presigned. 1317 Default_dev_cert *bool 1318 1319 // Specifies that this app should be installed to the priv-app directory, 1320 // where the system will grant it additional privileges not available to 1321 // normal apps. 1322 Privileged *bool 1323 1324 // Names of modules to be overridden. Listed modules can only be other binaries 1325 // (in Make or Soong). 1326 // This does not completely prevent installation of the overridden binaries, but if both 1327 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed 1328 // from PRODUCT_PACKAGES. 1329 Overrides []string 1330 1331 // Optional name for the installed app. If unspecified, it is derived from the module name. 1332 Filename *string 1333} 1334 1335func (a *AndroidAppImport) IsInstallable() bool { 1336 return true 1337} 1338 1339// Updates properties with variant-specific values. 1340func (a *AndroidAppImport) processVariants(ctx android.LoadHookContext) { 1341 config := ctx.Config() 1342 1343 dpiProps := reflect.ValueOf(a.dpiVariants).Elem().FieldByName("Dpi_variants") 1344 // Try DPI variant matches in the reverse-priority order so that the highest priority match 1345 // overwrites everything else. 1346 // TODO(jungjw): Can we optimize this by making it priority order? 1347 for i := len(config.ProductAAPTPrebuiltDPI()) - 1; i >= 0; i-- { 1348 MergePropertiesFromVariant(ctx, &a.properties, dpiProps, config.ProductAAPTPrebuiltDPI()[i]) 1349 } 1350 if config.ProductAAPTPreferredConfig() != "" { 1351 MergePropertiesFromVariant(ctx, &a.properties, dpiProps, config.ProductAAPTPreferredConfig()) 1352 } 1353 1354 archProps := reflect.ValueOf(a.archVariants).Elem().FieldByName("Arch") 1355 archType := ctx.Config().Targets[android.Android][0].Arch.ArchType 1356 MergePropertiesFromVariant(ctx, &a.properties, archProps, archType.Name) 1357} 1358 1359func MergePropertiesFromVariant(ctx android.EarlyModuleContext, 1360 dst interface{}, variantGroup reflect.Value, variant string) { 1361 src := variantGroup.FieldByName(proptools.FieldNameForProperty(variant)) 1362 if !src.IsValid() { 1363 return 1364 } 1365 1366 err := proptools.ExtendMatchingProperties([]interface{}{dst}, src.Interface(), nil, proptools.OrderAppend) 1367 if err != nil { 1368 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { 1369 ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) 1370 } else { 1371 panic(err) 1372 } 1373 } 1374} 1375 1376func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) { 1377 cert := android.SrcIsModule(String(a.properties.Certificate)) 1378 if cert != "" { 1379 ctx.AddDependency(ctx.Module(), certificateTag, cert) 1380 } 1381 1382 a.usesLibrary.deps(ctx, true) 1383} 1384 1385func (a *AndroidAppImport) uncompressEmbeddedJniLibs( 1386 ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) { 1387 // Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing 1388 // with them may invalidate pre-existing signature data. 1389 if ctx.InstallInTestcases() && (Bool(a.properties.Presigned) || a.preprocessed) { 1390 ctx.Build(pctx, android.BuildParams{ 1391 Rule: android.Cp, 1392 Output: outputPath, 1393 Input: inputPath, 1394 }) 1395 return 1396 } 1397 rule := android.NewRuleBuilder() 1398 rule.Command(). 1399 Textf(`if (zipinfo %s 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath). 1400 BuiltTool(ctx, "zip2zip"). 1401 FlagWithInput("-i ", inputPath). 1402 FlagWithOutput("-o ", outputPath). 1403 FlagWithArg("-0 ", "'lib/**/*.so'"). 1404 Textf(`; else cp -f %s %s; fi`, inputPath, outputPath) 1405 rule.Build(pctx, ctx, "uncompress-embedded-jni-libs", "Uncompress embedded JIN libs") 1406} 1407 1408// Returns whether this module should have the dex file stored uncompressed in the APK. 1409func (a *AndroidAppImport) shouldUncompressDex(ctx android.ModuleContext) bool { 1410 if ctx.Config().UnbundledBuild() || a.preprocessed { 1411 return false 1412 } 1413 1414 // Uncompress dex in APKs of privileged apps 1415 if ctx.Config().UncompressPrivAppDex() && a.Privileged() { 1416 return true 1417 } 1418 1419 return shouldUncompressDex(ctx, &a.dexpreopter) 1420} 1421 1422func (a *AndroidAppImport) uncompressDex( 1423 ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) { 1424 rule := android.NewRuleBuilder() 1425 rule.Command(). 1426 Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath). 1427 BuiltTool(ctx, "zip2zip"). 1428 FlagWithInput("-i ", inputPath). 1429 FlagWithOutput("-o ", outputPath). 1430 FlagWithArg("-0 ", "'classes*.dex'"). 1431 Textf(`; else cp -f %s %s; fi`, inputPath, outputPath) 1432 rule.Build(pctx, ctx, "uncompress-dex", "Uncompress dex files") 1433} 1434 1435func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1436 a.generateAndroidBuildActions(ctx) 1437} 1438 1439func (a *AndroidAppImport) InstallApkName() string { 1440 return a.BaseModuleName() 1441} 1442 1443func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) { 1444 numCertPropsSet := 0 1445 if String(a.properties.Certificate) != "" { 1446 numCertPropsSet++ 1447 } 1448 if Bool(a.properties.Presigned) { 1449 numCertPropsSet++ 1450 } 1451 if Bool(a.properties.Default_dev_cert) { 1452 numCertPropsSet++ 1453 } 1454 if numCertPropsSet != 1 { 1455 ctx.ModuleErrorf("One and only one of certficate, presigned, and default_dev_cert properties must be set") 1456 } 1457 1458 _, certificates := collectAppDeps(ctx, a, false, false) 1459 1460 // TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK 1461 // TODO: LOCAL_PACKAGE_SPLITS 1462 1463 srcApk := a.prebuilt.SingleSourcePath(ctx) 1464 1465 if a.usesLibrary.enforceUsesLibraries() { 1466 srcApk = a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk) 1467 } 1468 1469 // TODO: Install or embed JNI libraries 1470 1471 // Uncompress JNI libraries in the apk 1472 jnisUncompressed := android.PathForModuleOut(ctx, "jnis-uncompressed", ctx.ModuleName()+".apk") 1473 a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed.OutputPath) 1474 1475 var installDir android.InstallPath 1476 if Bool(a.properties.Privileged) { 1477 installDir = android.PathForModuleInstall(ctx, "priv-app", a.BaseModuleName()) 1478 } else if ctx.InstallInTestcases() { 1479 installDir = android.PathForModuleInstall(ctx, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch()) 1480 } else { 1481 installDir = android.PathForModuleInstall(ctx, "app", a.BaseModuleName()) 1482 } 1483 1484 a.dexpreopter.installPath = installDir.Join(ctx, a.BaseModuleName()+".apk") 1485 a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned) 1486 a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx) 1487 1488 a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries() 1489 a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs 1490 a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx) 1491 a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx) 1492 1493 dexOutput := a.dexpreopter.dexpreopt(ctx, jnisUncompressed) 1494 if a.dexpreopter.uncompressedDex { 1495 dexUncompressed := android.PathForModuleOut(ctx, "dex-uncompressed", ctx.ModuleName()+".apk") 1496 a.uncompressDex(ctx, dexOutput, dexUncompressed.OutputPath) 1497 dexOutput = dexUncompressed 1498 } 1499 1500 apkFilename := proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".apk") 1501 1502 // TODO: Handle EXTERNAL 1503 1504 // Sign or align the package if package has not been preprocessed 1505 if a.preprocessed { 1506 a.outputFile = srcApk 1507 a.certificate = PresignedCertificate 1508 } else if !Bool(a.properties.Presigned) { 1509 // If the certificate property is empty at this point, default_dev_cert must be set to true. 1510 // Which makes processMainCert's behavior for the empty cert string WAI. 1511 certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx) 1512 if len(certificates) != 1 { 1513 ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates) 1514 } 1515 a.certificate = certificates[0] 1516 signed := android.PathForModuleOut(ctx, "signed", apkFilename) 1517 var lineageFile android.Path 1518 if lineage := String(a.properties.Lineage); lineage != "" { 1519 lineageFile = android.PathForModuleSrc(ctx, lineage) 1520 } 1521 SignAppPackage(ctx, signed, dexOutput, certificates, lineageFile) 1522 a.outputFile = signed 1523 } else { 1524 alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename) 1525 TransformZipAlign(ctx, alignedApk, dexOutput) 1526 a.outputFile = alignedApk 1527 a.certificate = PresignedCertificate 1528 } 1529 1530 // TODO: Optionally compress the output apk. 1531 1532 if a.IsForPlatform() { 1533 a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile) 1534 } 1535 1536 // TODO: androidmk converter jni libs 1537} 1538 1539func (a *AndroidAppImport) Prebuilt() *android.Prebuilt { 1540 return &a.prebuilt 1541} 1542 1543func (a *AndroidAppImport) Name() string { 1544 return a.prebuilt.Name(a.ModuleBase.Name()) 1545} 1546 1547func (a *AndroidAppImport) OutputFile() android.Path { 1548 return a.outputFile 1549} 1550 1551func (a *AndroidAppImport) JacocoReportClassesFile() android.Path { 1552 return nil 1553} 1554 1555func (a *AndroidAppImport) Certificate() Certificate { 1556 return a.certificate 1557} 1558 1559var dpiVariantGroupType reflect.Type 1560var archVariantGroupType reflect.Type 1561 1562func initAndroidAppImportVariantGroupTypes() { 1563 dpiVariantGroupType = createVariantGroupType(supportedDpis, "Dpi_variants") 1564 1565 archNames := make([]string, len(android.ArchTypeList())) 1566 for i, archType := range android.ArchTypeList() { 1567 archNames[i] = archType.Name 1568 } 1569 archVariantGroupType = createVariantGroupType(archNames, "Arch") 1570} 1571 1572// Populates all variant struct properties at creation time. 1573func (a *AndroidAppImport) populateAllVariantStructs() { 1574 a.dpiVariants = reflect.New(dpiVariantGroupType).Interface() 1575 a.AddProperties(a.dpiVariants) 1576 1577 a.archVariants = reflect.New(archVariantGroupType).Interface() 1578 a.AddProperties(a.archVariants) 1579} 1580 1581func (a *AndroidAppImport) Privileged() bool { 1582 return Bool(a.properties.Privileged) 1583} 1584 1585func (a *AndroidAppImport) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool { 1586 // android_app_import might have extra dependencies via uses_libs property. 1587 // Don't track the dependency as we don't automatically add those libraries 1588 // to the classpath. It should be explicitly added to java_libs property of APEX 1589 return false 1590} 1591 1592func (a *AndroidAppImport) sdkVersion() sdkSpec { 1593 return sdkSpecFrom("") 1594} 1595 1596func (a *AndroidAppImport) minSdkVersion() sdkSpec { 1597 return sdkSpecFrom("") 1598} 1599 1600func (j *AndroidAppImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error { 1601 // Do not check for prebuilts against the min_sdk_version of enclosing APEX 1602 return nil 1603} 1604 1605func createVariantGroupType(variants []string, variantGroupName string) reflect.Type { 1606 props := reflect.TypeOf((*AndroidAppImportProperties)(nil)) 1607 1608 variantFields := make([]reflect.StructField, len(variants)) 1609 for i, variant := range variants { 1610 variantFields[i] = reflect.StructField{ 1611 Name: proptools.FieldNameForProperty(variant), 1612 Type: props, 1613 } 1614 } 1615 1616 variantGroupStruct := reflect.StructOf(variantFields) 1617 return reflect.StructOf([]reflect.StructField{ 1618 { 1619 Name: variantGroupName, 1620 Type: variantGroupStruct, 1621 }, 1622 }) 1623} 1624 1625// android_app_import imports a prebuilt apk with additional processing specified in the module. 1626// DPI-specific apk source files can be specified using dpi_variants. Example: 1627// 1628// android_app_import { 1629// name: "example_import", 1630// apk: "prebuilts/example.apk", 1631// dpi_variants: { 1632// mdpi: { 1633// apk: "prebuilts/example_mdpi.apk", 1634// }, 1635// xhdpi: { 1636// apk: "prebuilts/example_xhdpi.apk", 1637// }, 1638// }, 1639// certificate: "PRESIGNED", 1640// } 1641func AndroidAppImportFactory() android.Module { 1642 module := &AndroidAppImport{} 1643 module.AddProperties(&module.properties) 1644 module.AddProperties(&module.dexpreoptProperties) 1645 module.AddProperties(&module.usesLibrary.usesLibraryProperties) 1646 module.populateAllVariantStructs() 1647 android.AddLoadHook(module, func(ctx android.LoadHookContext) { 1648 module.processVariants(ctx) 1649 }) 1650 1651 android.InitApexModule(module) 1652 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1653 android.InitDefaultableModule(module) 1654 android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk") 1655 1656 return module 1657} 1658 1659type androidTestImportProperties struct { 1660 // Whether the prebuilt apk can be installed without additional processing. Default is false. 1661 Preprocessed *bool 1662} 1663 1664type AndroidTestImport struct { 1665 AndroidAppImport 1666 1667 testProperties testProperties 1668 1669 testImportProperties androidTestImportProperties 1670 1671 data android.Paths 1672} 1673 1674func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1675 a.preprocessed = Bool(a.testImportProperties.Preprocessed) 1676 1677 a.generateAndroidBuildActions(ctx) 1678 1679 a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) 1680} 1681 1682func (a *AndroidTestImport) InstallInTestcases() bool { 1683 return true 1684} 1685 1686// android_test_import imports a prebuilt test apk with additional processing specified in the 1687// module. DPI or arch variant configurations can be made as with android_app_import. 1688func AndroidTestImportFactory() android.Module { 1689 module := &AndroidTestImport{} 1690 module.AddProperties(&module.properties) 1691 module.AddProperties(&module.dexpreoptProperties) 1692 module.AddProperties(&module.usesLibrary.usesLibraryProperties) 1693 module.AddProperties(&module.testProperties) 1694 module.AddProperties(&module.testImportProperties) 1695 module.populateAllVariantStructs() 1696 android.AddLoadHook(module, func(ctx android.LoadHookContext) { 1697 module.processVariants(ctx) 1698 }) 1699 1700 module.dexpreopter.isTest = true 1701 1702 android.InitApexModule(module) 1703 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1704 android.InitDefaultableModule(module) 1705 android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk") 1706 1707 return module 1708} 1709 1710type RuntimeResourceOverlay struct { 1711 android.ModuleBase 1712 android.DefaultableModuleBase 1713 android.OverridableModuleBase 1714 aapt 1715 1716 properties RuntimeResourceOverlayProperties 1717 overridableProperties OverridableRuntimeResourceOverlayProperties 1718 1719 certificate Certificate 1720 1721 outputFile android.Path 1722 installDir android.InstallPath 1723} 1724 1725type RuntimeResourceOverlayProperties struct { 1726 // the name of a certificate in the default certificate directory or an android_app_certificate 1727 // module name in the form ":module". 1728 Certificate *string 1729 1730 // Name of the signing certificate lineage file. 1731 Lineage *string 1732 1733 // optional theme name. If specified, the overlay package will be applied 1734 // only when the ro.boot.vendor.overlay.theme system property is set to the same value. 1735 Theme *string 1736 1737 // if not blank, set to the version of the sdk to compile against. 1738 // Defaults to compiling against the current platform. 1739 Sdk_version *string 1740 1741 // if not blank, set the minimum version of the sdk that the compiled artifacts will run against. 1742 // Defaults to sdk_version if not set. 1743 Min_sdk_version *string 1744 1745 // list of android_library modules whose resources are extracted and linked against statically 1746 Static_libs []string 1747 1748 // list of android_app modules whose resources are extracted and linked against 1749 Resource_libs []string 1750 1751 // Names of modules to be overridden. Listed modules can only be other overlays 1752 // (in Make or Soong). 1753 // This does not completely prevent installation of the overridden overlays, but if both 1754 // overlays would be installed by default (in PRODUCT_PACKAGES) the other overlay will be removed 1755 // from PRODUCT_PACKAGES. 1756 Overrides []string 1757} 1758 1759// RuntimeResourceOverlayModule interface is used by the apex package to gather information from 1760// a RuntimeResourceOverlay module. 1761type RuntimeResourceOverlayModule interface { 1762 android.Module 1763 OutputFile() android.Path 1764 Certificate() Certificate 1765 Theme() string 1766} 1767 1768func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) { 1769 sdkDep := decodeSdkDep(ctx, sdkContext(r)) 1770 if sdkDep.hasFrameworkLibs() { 1771 r.aapt.deps(ctx, sdkDep) 1772 } 1773 1774 cert := android.SrcIsModule(String(r.properties.Certificate)) 1775 if cert != "" { 1776 ctx.AddDependency(ctx.Module(), certificateTag, cert) 1777 } 1778 1779 ctx.AddVariationDependencies(nil, staticLibTag, r.properties.Static_libs...) 1780 ctx.AddVariationDependencies(nil, libTag, r.properties.Resource_libs...) 1781} 1782 1783func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1784 // Compile and link resources 1785 r.aapt.hasNoCode = true 1786 // Do not remove resources without default values nor dedupe resource configurations with the same value 1787 aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"} 1788 // Allow the override of "package name" and "overlay target package name" 1789 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName()) 1790 if overridden || r.overridableProperties.Package_name != nil { 1791 // The product override variable has a priority over the package_name property. 1792 if !overridden { 1793 manifestPackageName = *r.overridableProperties.Package_name 1794 } 1795 aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName) 1796 } 1797 if r.overridableProperties.Target_package_name != nil { 1798 aaptLinkFlags = append(aaptLinkFlags, 1799 "--rename-overlay-target-package "+*r.overridableProperties.Target_package_name) 1800 } 1801 r.aapt.buildActions(ctx, r, aaptLinkFlags...) 1802 1803 // Sign the built package 1804 _, certificates := collectAppDeps(ctx, r, false, false) 1805 certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx) 1806 signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk") 1807 var lineageFile android.Path 1808 if lineage := String(r.properties.Lineage); lineage != "" { 1809 lineageFile = android.PathForModuleSrc(ctx, lineage) 1810 } 1811 SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, lineageFile) 1812 r.certificate = certificates[0] 1813 1814 r.outputFile = signed 1815 r.installDir = android.PathForModuleInstall(ctx, "overlay", String(r.properties.Theme)) 1816 ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile) 1817} 1818 1819func (r *RuntimeResourceOverlay) sdkVersion() sdkSpec { 1820 return sdkSpecFrom(String(r.properties.Sdk_version)) 1821} 1822 1823func (r *RuntimeResourceOverlay) systemModules() string { 1824 return "" 1825} 1826 1827func (r *RuntimeResourceOverlay) minSdkVersion() sdkSpec { 1828 if r.properties.Min_sdk_version != nil { 1829 return sdkSpecFrom(*r.properties.Min_sdk_version) 1830 } 1831 return r.sdkVersion() 1832} 1833 1834func (r *RuntimeResourceOverlay) targetSdkVersion() sdkSpec { 1835 return r.sdkVersion() 1836} 1837 1838func (r *RuntimeResourceOverlay) Certificate() Certificate { 1839 return r.certificate 1840} 1841 1842func (r *RuntimeResourceOverlay) OutputFile() android.Path { 1843 return r.outputFile 1844} 1845 1846func (r *RuntimeResourceOverlay) Theme() string { 1847 return String(r.properties.Theme) 1848} 1849 1850// runtime_resource_overlay generates a resource-only apk file that can overlay application and 1851// system resources at run time. 1852func RuntimeResourceOverlayFactory() android.Module { 1853 module := &RuntimeResourceOverlay{} 1854 module.AddProperties( 1855 &module.properties, 1856 &module.aaptProperties, 1857 &module.overridableProperties) 1858 1859 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 1860 android.InitDefaultableModule(module) 1861 android.InitOverridableModule(module, &module.properties.Overrides) 1862 return module 1863} 1864 1865type UsesLibraryProperties struct { 1866 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file. 1867 Uses_libs []string 1868 1869 // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with 1870 // required=false. 1871 Optional_uses_libs []string 1872 1873 // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults 1874 // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future. 1875 Enforce_uses_libs *bool 1876} 1877 1878// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the 1879// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the 1880// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps 1881// with knowledge of their shared libraries. 1882type usesLibrary struct { 1883 usesLibraryProperties UsesLibraryProperties 1884} 1885 1886func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) { 1887 if !ctx.Config().UnbundledBuild() { 1888 ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...) 1889 ctx.AddVariationDependencies(nil, usesLibTag, u.presentOptionalUsesLibs(ctx)...) 1890 // Only add these extra dependencies if the module depends on framework libs. This avoids 1891 // creating a cyclic dependency: 1892 // e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res. 1893 if hasFrameworkLibs { 1894 // Dexpreopt needs paths to the dex jars of these libraries in order to construct 1895 // class loader context for dex2oat. Add them as a dependency with a special tag. 1896 ctx.AddVariationDependencies(nil, usesLibTag, 1897 "org.apache.http.legacy", 1898 "android.hidl.base-V1.0-java", 1899 "android.hidl.manager-V1.0-java") 1900 ctx.AddVariationDependencies(nil, usesLibTag, optionalUsesLibs...) 1901 } 1902 } 1903} 1904 1905// presentOptionalUsesLibs returns optional_uses_libs after filtering out MissingUsesLibraries, which don't exist in the 1906// build. 1907func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string { 1908 optionalUsesLibs, _ := android.FilterList(u.usesLibraryProperties.Optional_uses_libs, ctx.Config().MissingUsesLibraries()) 1909 return optionalUsesLibs 1910} 1911 1912// usesLibraryPaths returns a map of module names of shared library dependencies to the paths 1913// to their dex jars on host and on device. 1914func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) dexpreopt.LibraryPaths { 1915 usesLibPaths := make(dexpreopt.LibraryPaths) 1916 1917 if !ctx.Config().UnbundledBuild() { 1918 ctx.VisitDirectDepsWithTag(usesLibTag, func(m android.Module) { 1919 dep := ctx.OtherModuleName(m) 1920 if lib, ok := m.(Dependency); ok { 1921 buildPath := lib.DexJarBuildPath() 1922 if buildPath == nil { 1923 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must"+ 1924 " produce a dex jar, does it have installable: true?", dep) 1925 return 1926 } 1927 1928 var devicePath string 1929 installPath := lib.DexJarInstallPath() 1930 if installPath == nil { 1931 devicePath = filepath.Join("/system/framework", dep+".jar") 1932 } else { 1933 devicePath = android.InstallPathToOnDevicePath(ctx, installPath.(android.InstallPath)) 1934 } 1935 1936 usesLibPaths[dep] = &dexpreopt.LibraryPath{buildPath, devicePath} 1937 } else if ctx.Config().AllowMissingDependencies() { 1938 ctx.AddMissingDependencies([]string{dep}) 1939 } else { 1940 ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be "+ 1941 "a java library", dep) 1942 } 1943 }) 1944 } 1945 1946 return usesLibPaths 1947} 1948 1949// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs 1950// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true 1951// unconditionally in the future. 1952func (u *usesLibrary) enforceUsesLibraries() bool { 1953 defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 || 1954 len(u.usesLibraryProperties.Optional_uses_libs) > 0 1955 return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, defaultEnforceUsesLibs) 1956} 1957 1958// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against the ones specified 1959// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the manifest. 1960func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path { 1961 outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml") 1962 1963 rule := android.NewRuleBuilder() 1964 cmd := rule.Command().BuiltTool(ctx, "manifest_check"). 1965 Flag("--enforce-uses-libraries"). 1966 Input(manifest). 1967 FlagWithOutput("-o ", outputFile) 1968 1969 for _, lib := range u.usesLibraryProperties.Uses_libs { 1970 cmd.FlagWithArg("--uses-library ", lib) 1971 } 1972 1973 for _, lib := range u.usesLibraryProperties.Optional_uses_libs { 1974 cmd.FlagWithArg("--optional-uses-library ", lib) 1975 } 1976 1977 rule.Build(pctx, ctx, "verify_uses_libraries", "verify <uses-library>") 1978 1979 return outputFile 1980} 1981 1982// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the ones specified 1983// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the APK. 1984func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path { 1985 outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base()) 1986 1987 rule := android.NewRuleBuilder() 1988 aapt := ctx.Config().HostToolPath(ctx, "aapt") 1989 rule.Command(). 1990 Textf("aapt_binary=%s", aapt.String()).Implicit(aapt). 1991 Textf(`uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Uses_libs, " ")). 1992 Textf(`optional_uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Optional_uses_libs, " ")). 1993 Tool(android.PathForSource(ctx, "build/make/core/verify_uses_libraries.sh")).Input(apk) 1994 rule.Command().Text("cp -f").Input(apk).Output(outputFile) 1995 1996 rule.Build(pctx, ctx, "verify_uses_libraries", "verify <uses-library>") 1997 1998 return outputFile 1999} 2000