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