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 Java for Android, and converts the properties 18// into the flags and filenames necessary to pass to the Module. The final creation of the rules 19// is handled in builder.go 20 21import ( 22 "fmt" 23 "path/filepath" 24 "slices" 25 "sort" 26 "strings" 27 28 "android/soong/remoteexec" 29 "android/soong/testing" 30 31 "github.com/google/blueprint" 32 "github.com/google/blueprint/proptools" 33 34 "android/soong/android" 35 "android/soong/cc" 36 "android/soong/dexpreopt" 37 "android/soong/java/config" 38 "android/soong/tradefed" 39) 40 41func init() { 42 registerJavaBuildComponents(android.InitRegistrationContext) 43 44 RegisterJavaSdkMemberTypes() 45} 46 47func registerJavaBuildComponents(ctx android.RegistrationContext) { 48 ctx.RegisterModuleType("java_defaults", DefaultsFactory) 49 50 ctx.RegisterModuleType("java_library", LibraryFactory) 51 ctx.RegisterModuleType("java_library_static", LibraryStaticFactory) 52 ctx.RegisterModuleType("java_library_host", LibraryHostFactory) 53 ctx.RegisterModuleType("java_binary", BinaryFactory) 54 ctx.RegisterModuleType("java_binary_host", BinaryHostFactory) 55 ctx.RegisterModuleType("java_test", TestFactory) 56 ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory) 57 ctx.RegisterModuleType("java_test_host", TestHostFactory) 58 ctx.RegisterModuleType("java_test_import", JavaTestImportFactory) 59 ctx.RegisterModuleType("java_import", ImportFactory) 60 ctx.RegisterModuleType("java_import_host", ImportFactoryHost) 61 ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory) 62 ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory) 63 ctx.RegisterModuleType("dex_import", DexImportFactory) 64 ctx.RegisterModuleType("java_api_library", ApiLibraryFactory) 65 ctx.RegisterModuleType("java_api_contribution", ApiContributionFactory) 66 ctx.RegisterModuleType("java_api_contribution_import", ApiContributionImportFactory) 67 68 // This mutator registers dependencies on dex2oat for modules that should be 69 // dexpreopted. This is done late when the final variants have been 70 // established, to not get the dependencies split into the wrong variants and 71 // to support the checks in dexpreoptDisabled(). 72 ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { 73 ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel() 74 // needs access to ApexInfoProvider which is available after variant creation 75 ctx.BottomUp("jacoco_deps", jacocoDepsMutator).Parallel() 76 }) 77 78 ctx.RegisterParallelSingletonType("kythe_java_extract", kytheExtractJavaFactory) 79} 80 81func RegisterJavaSdkMemberTypes() { 82 // Register sdk member types. 83 android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) 84 android.RegisterSdkMemberType(javaLibsSdkMemberType) 85 android.RegisterSdkMemberType(JavaBootLibsSdkMemberType) 86 android.RegisterSdkMemberType(JavaSystemserverLibsSdkMemberType) 87 android.RegisterSdkMemberType(javaTestSdkMemberType) 88} 89 90type StubsLinkType int 91 92const ( 93 Unknown StubsLinkType = iota 94 Stubs 95 Implementation 96) 97 98var ( 99 // Supports adding java header libraries to module_exports and sdk. 100 javaHeaderLibsSdkMemberType = &librarySdkMemberType{ 101 android.SdkMemberTypeBase{ 102 PropertyName: "java_header_libs", 103 SupportsSdk: true, 104 }, 105 func(_ android.SdkMemberContext, j *Library) android.Path { 106 headerJars := j.HeaderJars() 107 if len(headerJars) != 1 { 108 panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) 109 } 110 111 return headerJars[0] 112 }, 113 sdkSnapshotFilePathForJar, 114 copyEverythingToSnapshot, 115 } 116 117 // Export implementation classes jar as part of the sdk. 118 exportImplementationClassesJar = func(_ android.SdkMemberContext, j *Library) android.Path { 119 implementationJars := j.ImplementationAndResourcesJars() 120 if len(implementationJars) != 1 { 121 panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) 122 } 123 return implementationJars[0] 124 } 125 126 // Supports adding java implementation libraries to module_exports but not sdk. 127 javaLibsSdkMemberType = &librarySdkMemberType{ 128 android.SdkMemberTypeBase{ 129 PropertyName: "java_libs", 130 }, 131 exportImplementationClassesJar, 132 sdkSnapshotFilePathForJar, 133 copyEverythingToSnapshot, 134 } 135 136 snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool { 137 // In the S build the build will break if updatable-media does not provide a full implementation 138 // jar. That issue was fixed in Tiramisu by b/229932396. 139 if ctx.IsTargetBuildBeforeTiramisu() && ctx.Name() == "updatable-media" { 140 return true 141 } 142 143 return false 144 } 145 146 // Supports adding java boot libraries to module_exports and sdk. 147 // 148 // The build has some implicit dependencies (via the boot jars configuration) on a number of 149 // modules, e.g. core-oj, apache-xml, that are part of the java boot class path and which are 150 // provided by mainline modules (e.g. art, conscrypt, runtime-i18n) but which are not otherwise 151 // used outside those mainline modules. 152 // 153 // As they are not needed outside the mainline modules adding them to the sdk/module-exports as 154 // either java_libs, or java_header_libs would end up exporting more information than was strictly 155 // necessary. The java_boot_libs property to allow those modules to be exported as part of the 156 // sdk/module_exports without exposing any unnecessary information. 157 JavaBootLibsSdkMemberType = &librarySdkMemberType{ 158 android.SdkMemberTypeBase{ 159 PropertyName: "java_boot_libs", 160 SupportsSdk: true, 161 }, 162 func(ctx android.SdkMemberContext, j *Library) android.Path { 163 if snapshotRequiresImplementationJar(ctx) { 164 return exportImplementationClassesJar(ctx, j) 165 } 166 167 // Java boot libs are only provided in the SDK to provide access to their dex implementation 168 // jar for use by dexpreopting and boot jars package check. They do not need to provide an 169 // actual implementation jar but the java_import will need a file that exists so just copy an 170 // empty file. Any attempt to use that file as a jar will cause a build error. 171 return ctx.SnapshotBuilder().EmptyFile() 172 }, 173 func(ctx android.SdkMemberContext, osPrefix, name string) string { 174 if snapshotRequiresImplementationJar(ctx) { 175 return sdkSnapshotFilePathForJar(ctx, osPrefix, name) 176 } 177 178 // Create a special name for the implementation jar to try and provide some useful information 179 // to a developer that attempts to compile against this. 180 // TODO(b/175714559): Provide a proper error message in Soong not ninja. 181 return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) 182 }, 183 onlyCopyJarToSnapshot, 184 } 185 186 // Supports adding java systemserver libraries to module_exports and sdk. 187 // 188 // The build has some implicit dependencies (via the systemserver jars configuration) on a number 189 // of modules that are part of the java systemserver classpath and which are provided by mainline 190 // modules but which are not otherwise used outside those mainline modules. 191 // 192 // As they are not needed outside the mainline modules adding them to the sdk/module-exports as 193 // either java_libs, or java_header_libs would end up exporting more information than was strictly 194 // necessary. The java_systemserver_libs property to allow those modules to be exported as part of 195 // the sdk/module_exports without exposing any unnecessary information. 196 JavaSystemserverLibsSdkMemberType = &librarySdkMemberType{ 197 android.SdkMemberTypeBase{ 198 PropertyName: "java_systemserver_libs", 199 SupportsSdk: true, 200 201 // This was only added in Tiramisu. 202 SupportedBuildReleaseSpecification: "Tiramisu+", 203 }, 204 func(ctx android.SdkMemberContext, j *Library) android.Path { 205 // Java systemserver libs are only provided in the SDK to provide access to their dex 206 // implementation jar for use by dexpreopting. They do not need to provide an actual 207 // implementation jar but the java_import will need a file that exists so just copy an empty 208 // file. Any attempt to use that file as a jar will cause a build error. 209 return ctx.SnapshotBuilder().EmptyFile() 210 }, 211 func(_ android.SdkMemberContext, osPrefix, name string) string { 212 // Create a special name for the implementation jar to try and provide some useful information 213 // to a developer that attempts to compile against this. 214 // TODO(b/175714559): Provide a proper error message in Soong not ninja. 215 return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) 216 }, 217 onlyCopyJarToSnapshot, 218 } 219 220 // Supports adding java test libraries to module_exports but not sdk. 221 javaTestSdkMemberType = &testSdkMemberType{ 222 SdkMemberTypeBase: android.SdkMemberTypeBase{ 223 PropertyName: "java_tests", 224 }, 225 } 226 227 // Rule for generating device binary default wrapper 228 deviceBinaryWrapper = pctx.StaticRule("deviceBinaryWrapper", blueprint.RuleParams{ 229 Command: `echo -e '#!/system/bin/sh\n` + 230 `export CLASSPATH=/system/framework/$jar_name\n` + 231 `exec app_process /$partition/bin $main_class "$$@"'> ${out}`, 232 Description: "Generating device binary wrapper ${jar_name}", 233 }, "jar_name", "partition", "main_class") 234) 235 236type ProguardSpecInfo struct { 237 // If true, proguard flags files will be exported to reverse dependencies across libs edges 238 // If false, proguard flags files will only be exported to reverse dependencies across 239 // static_libs edges. 240 Export_proguard_flags_files bool 241 242 // TransitiveDepsProguardSpecFiles is a depset of paths to proguard flags files that are exported from 243 // all transitive deps. This list includes all proguard flags files from transitive static dependencies, 244 // and all proguard flags files from transitive libs dependencies which set `export_proguard_spec: true`. 245 ProguardFlagsFiles *android.DepSet[android.Path] 246 247 // implementation detail to store transitive proguard flags files from exporting shared deps 248 UnconditionallyExportedProguardFlags *android.DepSet[android.Path] 249} 250 251var ProguardSpecInfoProvider = blueprint.NewProvider[ProguardSpecInfo]() 252 253// JavaInfo contains information about a java module for use by modules that depend on it. 254type JavaInfo struct { 255 // HeaderJars is a list of jars that can be passed as the javac classpath in order to link 256 // against this module. If empty, ImplementationJars should be used instead. 257 HeaderJars android.Paths 258 259 RepackagedHeaderJars android.Paths 260 261 // set of header jars for all transitive libs deps 262 TransitiveLibsHeaderJars *android.DepSet[android.Path] 263 264 // set of header jars for all transitive static libs deps 265 TransitiveStaticLibsHeaderJars *android.DepSet[android.Path] 266 267 // ImplementationAndResourceJars is a list of jars that contain the implementations of classes 268 // in the module as well as any resources included in the module. 269 ImplementationAndResourcesJars android.Paths 270 271 // ImplementationJars is a list of jars that contain the implementations of classes in the 272 //module. 273 ImplementationJars android.Paths 274 275 // ResourceJars is a list of jars that contain the resources included in the module. 276 ResourceJars android.Paths 277 278 // AidlIncludeDirs is a list of directories that should be passed to the aidl tool when 279 // depending on this module. 280 AidlIncludeDirs android.Paths 281 282 // SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this 283 // module. 284 SrcJarArgs []string 285 286 // SrcJarDeps is a list of paths to depend on when packaging the sources of this module. 287 SrcJarDeps android.Paths 288 289 // The source files of this module and all its transitive static dependencies. 290 TransitiveSrcFiles *android.DepSet[android.Path] 291 292 // ExportedPlugins is a list of paths that should be used as annotation processors for any 293 // module that depends on this module. 294 ExportedPlugins android.Paths 295 296 // ExportedPluginClasses is a list of classes that should be run as annotation processors for 297 // any module that depends on this module. 298 ExportedPluginClasses []string 299 300 // ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs, 301 // requiring disbling turbine for any modules that depend on it. 302 ExportedPluginDisableTurbine bool 303 304 // JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be 305 // instrumented by jacoco. 306 JacocoReportClassesFile android.Path 307 308 // StubsLinkType provides information about whether the provided jars are stub jars or 309 // implementation jars. If the provider is set by java_sdk_library, the link type is "unknown" 310 // and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...) 311 StubsLinkType StubsLinkType 312 313 // AconfigIntermediateCacheOutputPaths is a path to the cache files collected from the 314 // java_aconfig_library modules that are statically linked to this module. 315 AconfigIntermediateCacheOutputPaths android.Paths 316} 317 318var JavaInfoProvider = blueprint.NewProvider[JavaInfo]() 319 320// SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to 321// the sysprop implementation library. 322type SyspropPublicStubInfo struct { 323 // JavaInfo is the JavaInfoProvider of the sysprop public stub library that corresponds to 324 // the sysprop implementation library. 325 JavaInfo JavaInfo 326} 327 328var SyspropPublicStubInfoProvider = blueprint.NewProvider[SyspropPublicStubInfo]() 329 330// Methods that need to be implemented for a module that is added to apex java_libs property. 331type ApexDependency interface { 332 HeaderJars() android.Paths 333 ImplementationAndResourcesJars() android.Paths 334} 335 336// Provides build path and install path to DEX jars. 337type UsesLibraryDependency interface { 338 DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath 339 DexJarInstallPath() android.Path 340 ClassLoaderContexts() dexpreopt.ClassLoaderContextMap 341} 342 343// TODO(jungjw): Move this to kythe.go once it's created. 344type xref interface { 345 XrefJavaFiles() android.Paths 346} 347 348func (j *Module) XrefJavaFiles() android.Paths { 349 return j.kytheFiles 350} 351 352func (d dependencyTag) PropagateAconfigValidation() bool { 353 return d.static 354} 355 356var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{} 357 358type dependencyTag struct { 359 blueprint.BaseDependencyTag 360 name string 361 362 // True if the dependency is relinked at runtime. 363 runtimeLinked bool 364 365 // True if the dependency is a toolchain, for example an annotation processor. 366 toolchain bool 367 368 static bool 369 370 installable bool 371} 372 373var _ android.InstallNeededDependencyTag = (*dependencyTag)(nil) 374 375func (d dependencyTag) InstallDepNeeded() bool { 376 return d.installable 377} 378 379func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation { 380 if d.runtimeLinked { 381 return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency} 382 } else if d.toolchain { 383 return []android.LicenseAnnotation{android.LicenseAnnotationToolchain} 384 } 385 return nil 386} 387 388var _ android.LicenseAnnotationsDependencyTag = dependencyTag{} 389 390type usesLibraryDependencyTag struct { 391 dependencyTag 392 sdkVersion int // SDK version in which the library appared as a standalone library. 393 optional bool // If the dependency is optional or required. 394} 395 396func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDependencyTag { 397 return usesLibraryDependencyTag{ 398 dependencyTag: dependencyTag{ 399 name: fmt.Sprintf("uses-library-%d", sdkVersion), 400 runtimeLinked: true, 401 }, 402 sdkVersion: sdkVersion, 403 optional: optional, 404 } 405} 406 407func IsJniDepTag(depTag blueprint.DependencyTag) bool { 408 return depTag == jniLibTag || depTag == jniInstallTag 409} 410 411var ( 412 dataNativeBinsTag = dependencyTag{name: "dataNativeBins"} 413 dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"} 414 staticLibTag = dependencyTag{name: "staticlib", static: true} 415 libTag = dependencyTag{name: "javalib", runtimeLinked: true} 416 sdkLibTag = dependencyTag{name: "sdklib", runtimeLinked: true} 417 java9LibTag = dependencyTag{name: "java9lib", runtimeLinked: true} 418 pluginTag = dependencyTag{name: "plugin", toolchain: true} 419 errorpronePluginTag = dependencyTag{name: "errorprone-plugin", toolchain: true} 420 exportedPluginTag = dependencyTag{name: "exported-plugin", toolchain: true} 421 bootClasspathTag = dependencyTag{name: "bootclasspath", runtimeLinked: true} 422 systemModulesTag = dependencyTag{name: "system modules", runtimeLinked: true} 423 frameworkResTag = dependencyTag{name: "framework-res"} 424 kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib", runtimeLinked: true} 425 kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations", runtimeLinked: true} 426 kotlinPluginTag = dependencyTag{name: "kotlin-plugin", toolchain: true} 427 proguardRaiseTag = dependencyTag{name: "proguard-raise"} 428 certificateTag = dependencyTag{name: "certificate"} 429 instrumentationForTag = dependencyTag{name: "instrumentation_for"} 430 extraLintCheckTag = dependencyTag{name: "extra-lint-check", toolchain: true} 431 jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true} 432 r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true} 433 syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} 434 javaApiContributionTag = dependencyTag{name: "java-api-contribution"} 435 depApiSrcsTag = dependencyTag{name: "dep-api-srcs"} 436 aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"} 437 jniInstallTag = dependencyTag{name: "jni install", runtimeLinked: true, installable: true} 438 binaryInstallTag = dependencyTag{name: "binary install", runtimeLinked: true, installable: true} 439 usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false) 440 usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true) 441 usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true) 442 usesLibCompat29ReqTag = makeUsesLibraryDependencyTag(29, false) 443 usesLibCompat30OptTag = makeUsesLibraryDependencyTag(30, true) 444) 445 446func IsLibDepTag(depTag blueprint.DependencyTag) bool { 447 return depTag == libTag || depTag == sdkLibTag 448} 449 450func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool { 451 return depTag == staticLibTag 452} 453 454type sdkDep struct { 455 useModule, useFiles, invalidVersion bool 456 457 // The modules that will be added to the bootclasspath when targeting 1.8 or lower 458 bootclasspath []string 459 460 // The default system modules to use. Will be an empty string if no system 461 // modules are to be used. 462 systemModules string 463 464 // The modules that will be added to the classpath regardless of the Java language level targeted 465 classpath []string 466 467 // The modules that will be added ot the classpath when targeting 1.9 or higher 468 // (normally these will be on the bootclasspath when targeting 1.8 or lower) 469 java9Classpath []string 470 471 frameworkResModule string 472 473 jars android.Paths 474 aidl android.OptionalPath 475 476 noStandardLibs, noFrameworksLibs bool 477} 478 479func (s sdkDep) hasStandardLibs() bool { 480 return !s.noStandardLibs 481} 482 483func (s sdkDep) hasFrameworkLibs() bool { 484 return !s.noStandardLibs && !s.noFrameworksLibs 485} 486 487type jniLib struct { 488 name string 489 path android.Path 490 target android.Target 491 coverageFile android.OptionalPath 492 unstrippedFile android.Path 493 partition string 494 installPaths android.InstallPaths 495} 496 497func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) { 498 sdkDep := decodeSdkDep(ctx, sdkContext) 499 if sdkDep.useModule { 500 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) 501 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...) 502 ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...) 503 if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() { 504 ctx.AddVariationDependencies(nil, proguardRaiseTag, 505 config.LegacyCorePlatformBootclasspathLibraries..., 506 ) 507 } 508 if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() { 509 ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...) 510 } 511 } 512 if sdkDep.systemModules != "" { 513 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) 514 } 515} 516 517type deps struct { 518 // bootClasspath is the list of jars that form the boot classpath (generally the java.* and 519 // android.* classes) for tools that still use it. javac targeting 1.9 or higher uses 520 // systemModules and java9Classpath instead. 521 bootClasspath classpath 522 523 // classpath is the list of jars that form the classpath for javac and kotlinc rules. It 524 // contains header jars for all static and non-static dependencies. 525 classpath classpath 526 527 // dexClasspath is the list of jars that form the classpath for d8 and r8 rules. It contains 528 // header jars for all non-static dependencies. Static dependencies have already been 529 // combined into the program jar. 530 dexClasspath classpath 531 532 // java9Classpath is the list of jars that will be added to the classpath when targeting 533 // 1.9 or higher. It generally contains the android.* classes, while the java.* classes 534 // are provided by systemModules. 535 java9Classpath classpath 536 537 processorPath classpath 538 errorProneProcessorPath classpath 539 processorClasses []string 540 staticJars android.Paths 541 staticHeaderJars android.Paths 542 staticResourceJars android.Paths 543 aidlIncludeDirs android.Paths 544 srcs android.Paths 545 srcJars android.Paths 546 systemModules *systemModules 547 aidlPreprocess android.OptionalPath 548 kotlinStdlib android.Paths 549 kotlinAnnotations android.Paths 550 kotlinPlugins android.Paths 551 aconfigProtoFiles android.Paths 552 553 disableTurbine bool 554} 555 556func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) { 557 for _, f := range dep.Srcs() { 558 if f.Ext() != ".jar" { 559 ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency", 560 ctx.OtherModuleName(dep.(blueprint.Module))) 561 } 562 } 563} 564 565func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext android.SdkContext) javaVersion { 566 if javaVersion != "" { 567 return normalizeJavaVersion(ctx, javaVersion) 568 } else if ctx.Device() { 569 return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx)) 570 } else if ctx.Config().TargetsJava21() { 571 // Temporary experimental flag to be able to try and build with 572 // java version 21 options. The flag, if used, just sets Java 573 // 21 as the default version, leaving any components that 574 // target an older version intact. 575 return JAVA_VERSION_21 576 } else { 577 return JAVA_VERSION_17 578 } 579} 580 581// Java version for stubs generation 582func getStubsJavaVersion() javaVersion { 583 return JAVA_VERSION_8 584} 585 586type javaVersion int 587 588const ( 589 JAVA_VERSION_UNSUPPORTED = 0 590 JAVA_VERSION_6 = 6 591 JAVA_VERSION_7 = 7 592 JAVA_VERSION_8 = 8 593 JAVA_VERSION_9 = 9 594 JAVA_VERSION_11 = 11 595 JAVA_VERSION_17 = 17 596 JAVA_VERSION_21 = 21 597) 598 599func (v javaVersion) String() string { 600 switch v { 601 case JAVA_VERSION_6: 602 // Java version 1.6 no longer supported, bumping to 1.8 603 return "1.8" 604 case JAVA_VERSION_7: 605 // Java version 1.7 no longer supported, bumping to 1.8 606 return "1.8" 607 case JAVA_VERSION_8: 608 return "1.8" 609 case JAVA_VERSION_9: 610 return "1.9" 611 case JAVA_VERSION_11: 612 return "11" 613 case JAVA_VERSION_17: 614 return "17" 615 case JAVA_VERSION_21: 616 return "21" 617 default: 618 return "unsupported" 619 } 620} 621 622func (v javaVersion) StringForKotlinc() string { 623 // $ ./external/kotlinc/bin/kotlinc -jvm-target foo 624 // error: unknown JVM target version: foo 625 // Supported versions: 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17 626 switch v { 627 case JAVA_VERSION_6: 628 return "1.8" 629 case JAVA_VERSION_7: 630 return "1.8" 631 case JAVA_VERSION_9: 632 return "9" 633 default: 634 return v.String() 635 } 636} 637 638// Returns true if javac targeting this version uses system modules instead of a bootclasspath. 639func (v javaVersion) usesJavaModules() bool { 640 return v >= 9 641} 642 643func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion { 644 switch javaVersion { 645 case "1.6", "6": 646 // Java version 1.6 no longer supported, bumping to 1.8 647 return JAVA_VERSION_8 648 case "1.7", "7": 649 // Java version 1.7 no longer supported, bumping to 1.8 650 return JAVA_VERSION_8 651 case "1.8", "8": 652 return JAVA_VERSION_8 653 case "1.9", "9": 654 return JAVA_VERSION_9 655 case "11": 656 return JAVA_VERSION_11 657 case "17": 658 return JAVA_VERSION_17 659 case "21": 660 return JAVA_VERSION_21 661 case "10", "12", "13", "14", "15", "16": 662 ctx.PropertyErrorf("java_version", "Java language level %s is not supported", javaVersion) 663 return JAVA_VERSION_UNSUPPORTED 664 default: 665 ctx.PropertyErrorf("java_version", "Unrecognized Java language level") 666 return JAVA_VERSION_UNSUPPORTED 667 } 668} 669 670// 671// Java libraries (.jar file) 672// 673 674type Library struct { 675 Module 676 677 combinedExportedProguardFlagsFile android.Path 678 679 InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.InstallPaths) 680} 681 682var _ android.ApexModule = (*Library)(nil) 683 684func (j *Library) CheckDepsMinSdkVersion(ctx android.ModuleContext) { 685 CheckMinSdkVersion(ctx, j) 686} 687 688// Provides access to the list of permitted packages from apex boot jars. 689type PermittedPackagesForUpdatableBootJars interface { 690 PermittedPackagesForUpdatableBootJars() []string 691} 692 693var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil) 694 695func (j *Library) PermittedPackagesForUpdatableBootJars() []string { 696 return j.properties.Permitted_packages 697} 698 699func shouldUncompressDex(ctx android.ModuleContext, libName string, dexpreopter *dexpreopter) bool { 700 // Store uncompressed (and aligned) any dex files from jars in APEXes. 701 if apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider); !apexInfo.IsForPlatform() { 702 return true 703 } 704 705 // Store uncompressed (and do not strip) dex files from boot class path jars. 706 if inList(ctx.ModuleName(), ctx.Config().BootJars()) { 707 return true 708 } 709 710 // Store uncompressed dex files that are preopted on /system or /system_other. 711 if !dexpreopter.dexpreoptDisabled(ctx, libName) { 712 return true 713 } 714 715 if ctx.Config().UncompressPrivAppDex() && 716 inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) { 717 return true 718 } 719 720 return false 721} 722 723// Sets `dexer.dexProperties.Uncompress_dex` to the proper value. 724func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) { 725 if dexer.dexProperties.Uncompress_dex == nil { 726 // If the value was not force-set by the user, use reasonable default based on the module. 727 dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexpreopter)) 728 } 729} 730 731// list of java_library modules that set platform_apis: true 732// this property is a no-op for java_library 733// TODO (b/215379393): Remove this allowlist 734var ( 735 aospPlatformApiAllowlist = map[string]bool{ 736 "adservices-test-scenarios": true, 737 "aidl-cpp-java-test-interface-java": true, 738 "aidl-test-extras-java": true, 739 "aidl-test-interface-java": true, 740 "aidl-test-interface-permission-java": true, 741 "aidl_test_java_client_permission": true, 742 "aidl_test_java_client_sdk1": true, 743 "aidl_test_java_client_sdk29": true, 744 "aidl_test_java_client": true, 745 "aidl_test_java_service_permission": true, 746 "aidl_test_java_service_sdk1": true, 747 "aidl_test_java_service_sdk29": true, 748 "aidl_test_java_service": true, 749 "aidl_test_loggable_interface-java": true, 750 "aidl_test_nonvintf_parcelable-V1-java": true, 751 "aidl_test_nonvintf_parcelable-V2-java": true, 752 "aidl_test_unstable_parcelable-java": true, 753 "aidl_test_vintf_parcelable-V1-java": true, 754 "aidl_test_vintf_parcelable-V2-java": true, 755 "android.aidl.test.trunk-V1-java": true, 756 "android.aidl.test.trunk-V2-java": true, 757 "android.frameworks.location.altitude-V1-java": true, 758 "android.frameworks.location.altitude-V2-java": true, 759 "android.frameworks.stats-V1-java": true, 760 "android.frameworks.stats-V2-java": true, 761 "android.frameworks.stats-V3-java": true, 762 "android.hardware.authsecret-V1-java": true, 763 "android.hardware.authsecret-V2-java": true, 764 "android.hardware.biometrics.common-V1-java": true, 765 "android.hardware.biometrics.common-V2-java": true, 766 "android.hardware.biometrics.common-V3-java": true, 767 "android.hardware.biometrics.common-V4-java": true, 768 "android.hardware.biometrics.face-V1-java": true, 769 "android.hardware.biometrics.face-V2-java": true, 770 "android.hardware.biometrics.face-V3-java": true, 771 "android.hardware.biometrics.face-V4-java": true, 772 "android.hardware.biometrics.fingerprint-V1-java": true, 773 "android.hardware.biometrics.fingerprint-V2-java": true, 774 "android.hardware.biometrics.fingerprint-V3-java": true, 775 "android.hardware.biometrics.fingerprint-V4-java": true, 776 "android.hardware.bluetooth.lmp_event-V1-java": true, 777 "android.hardware.confirmationui-V1-java": true, 778 "android.hardware.confirmationui-V2-java": true, 779 "android.hardware.gatekeeper-V1-java": true, 780 "android.hardware.gatekeeper-V2-java": true, 781 "android.hardware.gnss-V1-java": true, 782 "android.hardware.gnss-V2-java": true, 783 "android.hardware.gnss-V3-java": true, 784 "android.hardware.gnss-V4-java": true, 785 "android.hardware.graphics.common-V1-java": true, 786 "android.hardware.graphics.common-V2-java": true, 787 "android.hardware.graphics.common-V3-java": true, 788 "android.hardware.graphics.common-V4-java": true, 789 "android.hardware.graphics.common-V5-java": true, 790 "android.hardware.identity-V1-java": true, 791 "android.hardware.identity-V2-java": true, 792 "android.hardware.identity-V3-java": true, 793 "android.hardware.identity-V4-java": true, 794 "android.hardware.identity-V5-java": true, 795 "android.hardware.identity-V6-java": true, 796 "android.hardware.keymaster-V1-java": true, 797 "android.hardware.keymaster-V2-java": true, 798 "android.hardware.keymaster-V3-java": true, 799 "android.hardware.keymaster-V4-java": true, 800 "android.hardware.keymaster-V5-java": true, 801 "android.hardware.oemlock-V1-java": true, 802 "android.hardware.oemlock-V2-java": true, 803 "android.hardware.power.stats-V1-java": true, 804 "android.hardware.power.stats-V2-java": true, 805 "android.hardware.power.stats-V3-java": true, 806 "android.hardware.power-V1-java": true, 807 "android.hardware.power-V2-java": true, 808 "android.hardware.power-V3-java": true, 809 "android.hardware.power-V4-java": true, 810 "android.hardware.power-V5-java": true, 811 "android.hardware.rebootescrow-V1-java": true, 812 "android.hardware.rebootescrow-V2-java": true, 813 "android.hardware.security.authgraph-V1-java": true, 814 "android.hardware.security.keymint-V1-java": true, 815 "android.hardware.security.keymint-V2-java": true, 816 "android.hardware.security.keymint-V3-java": true, 817 "android.hardware.security.keymint-V4-java": true, 818 "android.hardware.security.secretkeeper-V1-java": true, 819 "android.hardware.security.secureclock-V1-java": true, 820 "android.hardware.security.secureclock-V2-java": true, 821 "android.hardware.thermal-V1-java": true, 822 "android.hardware.thermal-V2-java": true, 823 "android.hardware.threadnetwork-V1-java": true, 824 "android.hardware.weaver-V1-java": true, 825 "android.hardware.weaver-V2-java": true, 826 "android.hardware.weaver-V3-java": true, 827 "android.security.attestationmanager-java": true, 828 "android.security.authorization-java": true, 829 "android.security.compat-java": true, 830 "android.security.legacykeystore-java": true, 831 "android.security.maintenance-java": true, 832 "android.security.metrics-java": true, 833 "android.system.keystore2-V1-java": true, 834 "android.system.keystore2-V2-java": true, 835 "android.system.keystore2-V3-java": true, 836 "android.system.keystore2-V4-java": true, 837 "binderReadParcelIface-java": true, 838 "binderRecordReplayTestIface-java": true, 839 "car-experimental-api-static-lib": true, 840 "collector-device-lib-platform": true, 841 "com.android.car.oem": true, 842 "com.google.hardware.pixel.display-V10-java": true, 843 "com.google.hardware.pixel.display-V1-java": true, 844 "com.google.hardware.pixel.display-V2-java": true, 845 "com.google.hardware.pixel.display-V3-java": true, 846 "com.google.hardware.pixel.display-V4-java": true, 847 "com.google.hardware.pixel.display-V5-java": true, 848 "com.google.hardware.pixel.display-V6-java": true, 849 "com.google.hardware.pixel.display-V7-java": true, 850 "com.google.hardware.pixel.display-V8-java": true, 851 "com.google.hardware.pixel.display-V9-java": true, 852 "conscrypt-support": true, 853 "cts-keystore-test-util": true, 854 "cts-keystore-user-auth-helper-library": true, 855 "ctsmediautil": true, 856 "CtsNetTestsNonUpdatableLib": true, 857 "DpmWrapper": true, 858 "flickerlib-apphelpers": true, 859 "flickerlib-helpers": true, 860 "flickerlib-parsers": true, 861 "flickerlib": true, 862 "hardware.google.bluetooth.ccc-V1-java": true, 863 "hardware.google.bluetooth.sar-V1-java": true, 864 "monet": true, 865 "pixel-power-ext-V1-java": true, 866 "pixel-power-ext-V2-java": true, 867 "pixel_stateresidency_provider_aidl_interface-java": true, 868 "pixel-thermal-ext-V1-java": true, 869 "protolog-lib": true, 870 "RkpRegistrationCheck": true, 871 "rotary-service-javastream-protos": true, 872 "service_based_camera_extensions": true, 873 "statsd-helper-test": true, 874 "statsd-helper": true, 875 "test-piece-2-V1-java": true, 876 "test-piece-2-V2-java": true, 877 "test-piece-3-V1-java": true, 878 "test-piece-3-V2-java": true, 879 "test-piece-3-V3-java": true, 880 "test-piece-4-V1-java": true, 881 "test-piece-4-V2-java": true, 882 "test-root-package-V1-java": true, 883 "test-root-package-V2-java": true, 884 "test-root-package-V3-java": true, 885 "test-root-package-V4-java": true, 886 "testServiceIface-java": true, 887 "wm-flicker-common-app-helpers": true, 888 "wm-flicker-common-assertions": true, 889 "wm-shell-flicker-utils": true, 890 "wycheproof-keystore": true, 891 } 892 893 // Union of aosp and internal allowlists 894 PlatformApiAllowlist = map[string]bool{} 895) 896 897func init() { 898 for k, v := range aospPlatformApiAllowlist { 899 PlatformApiAllowlist[k] = v 900 } 901} 902 903func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { 904 if disableSourceApexVariant(ctx) { 905 // Prebuilts are active, do not create the installation rules for the source javalib. 906 // Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules. 907 // TODO (b/331665856): Implement a principled solution for this. 908 j.HideFromMake() 909 } 910 j.provideHiddenAPIPropertyInfo(ctx) 911 912 j.sdkVersion = j.SdkVersion(ctx) 913 j.minSdkVersion = j.MinSdkVersion(ctx) 914 j.maxSdkVersion = j.MaxSdkVersion(ctx) 915 916 // Check min_sdk_version of the transitive dependencies if this module is created from 917 // java_sdk_library. 918 if j.overridableProperties.Min_sdk_version != nil && j.SdkLibraryName() != nil { 919 j.CheckDepsMinSdkVersion(ctx) 920 } 921 922 // SdkLibrary.GenerateAndroidBuildActions(ctx) sets the stubsLinkType to Unknown. 923 // If the stubsLinkType has already been set to Unknown, the stubsLinkType should 924 // not be overridden. 925 if j.stubsLinkType != Unknown { 926 if proptools.Bool(j.properties.Is_stubs_module) { 927 j.stubsLinkType = Stubs 928 } else { 929 j.stubsLinkType = Implementation 930 } 931 } 932 933 j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName()) 934 935 proguardSpecInfo := j.collectProguardSpecInfo(ctx) 936 android.SetProvider(ctx, ProguardSpecInfoProvider, proguardSpecInfo) 937 exportedProguardFlagsFiles := proguardSpecInfo.ProguardFlagsFiles.ToList() 938 j.extraProguardFlagsFiles = append(j.extraProguardFlagsFiles, exportedProguardFlagsFiles...) 939 940 combinedExportedProguardFlagFile := android.PathForModuleOut(ctx, "export_proguard_flags") 941 writeCombinedProguardFlagsFile(ctx, combinedExportedProguardFlagFile, exportedProguardFlagsFiles) 942 j.combinedExportedProguardFlagsFile = combinedExportedProguardFlagFile 943 944 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 945 if !apexInfo.IsForPlatform() { 946 j.hideApexVariantFromMake = true 947 } 948 949 j.checkSdkVersions(ctx) 950 j.checkHeadersOnly(ctx) 951 if ctx.Device() { 952 libName := j.Name() 953 if j.SdkLibraryName() != nil && strings.HasSuffix(libName, ".impl") { 954 libName = proptools.String(j.SdkLibraryName()) 955 } 956 j.dexpreopter.installPath = j.dexpreopter.getInstallPath( 957 ctx, libName, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) 958 j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary 959 setUncompressDex(ctx, &j.dexpreopter, &j.dexer) 960 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 961 j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx) 962 if j.usesLibrary.shouldDisableDexpreopt { 963 j.dexpreopter.disableDexpreopt() 964 } 965 } 966 j.compile(ctx, nil, nil, nil) 967 968 // If this module is an impl library created from java_sdk_library, 969 // install the files under the java_sdk_library module outdir instead of this module outdir. 970 if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") { 971 j.setInstallRules(ctx, proptools.String(j.SdkLibraryName())) 972 } else { 973 j.setInstallRules(ctx, ctx.ModuleName()) 974 } 975 976 android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ 977 TestOnly: Bool(j.sourceProperties.Test_only), 978 TopLevelTarget: j.sourceProperties.Top_level_test_target, 979 }) 980} 981 982func (j *Library) setInstallRules(ctx android.ModuleContext, installModuleName string) { 983 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 984 985 if (Bool(j.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() { 986 var extraInstallDeps android.InstallPaths 987 if j.InstallMixin != nil { 988 extraInstallDeps = j.InstallMixin(ctx, j.outputFile) 989 } 990 hostDexNeeded := Bool(j.deviceProperties.Hostdex) && !ctx.Host() 991 if hostDexNeeded { 992 j.hostdexInstallFile = ctx.InstallFile( 993 android.PathForHostDexInstall(ctx, "framework"), 994 j.Stem()+"-hostdex.jar", j.outputFile) 995 } 996 var installDir android.InstallPath 997 if ctx.InstallInTestcases() { 998 var archDir string 999 if !ctx.Host() { 1000 archDir = ctx.DeviceConfig().DeviceArch() 1001 } 1002 installDir = android.PathForModuleInstall(ctx, installModuleName, archDir) 1003 } else { 1004 installDir = android.PathForModuleInstall(ctx, "framework") 1005 } 1006 j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...) 1007 } 1008} 1009 1010func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { 1011 j.usesLibrary.deps(ctx, false) 1012 j.deps(ctx) 1013 1014 if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") { 1015 if dexpreopt.IsDex2oatNeeded(ctx) { 1016 dexpreopt.RegisterToolDeps(ctx) 1017 } 1018 prebuiltSdkLibExists := ctx.OtherModuleExists(android.PrebuiltNameFromSource(proptools.String(j.SdkLibraryName()))) 1019 if prebuiltSdkLibExists && ctx.OtherModuleExists("all_apex_contributions") { 1020 ctx.AddDependency(ctx.Module(), android.AcDepTag, "all_apex_contributions") 1021 } 1022 } 1023} 1024 1025const ( 1026 aidlIncludeDir = "aidl" 1027 javaDir = "java" 1028 jarFileSuffix = ".jar" 1029 testConfigSuffix = "-AndroidTest.xml" 1030) 1031 1032// path to the jar file of a java library. Relative to <sdk_root>/<api_dir> 1033func sdkSnapshotFilePathForJar(_ android.SdkMemberContext, osPrefix, name string) string { 1034 return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix) 1035} 1036 1037func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string { 1038 return filepath.Join(javaDir, osPrefix, name+suffix) 1039} 1040 1041type librarySdkMemberType struct { 1042 android.SdkMemberTypeBase 1043 1044 // Function to retrieve the appropriate output jar (implementation or header) from 1045 // the library. 1046 jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path 1047 1048 // Function to compute the snapshot relative path to which the named library's 1049 // jar should be copied. 1050 snapshotPathGetter func(ctx android.SdkMemberContext, osPrefix, name string) string 1051 1052 // True if only the jar should be copied to the snapshot, false if the jar plus any additional 1053 // files like aidl files should also be copied. 1054 onlyCopyJarToSnapshot bool 1055} 1056 1057const ( 1058 onlyCopyJarToSnapshot = true 1059 copyEverythingToSnapshot = false 1060) 1061 1062func (mt *librarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { 1063 ctx.AddVariationDependencies(nil, dependencyTag, names...) 1064} 1065 1066func (mt *librarySdkMemberType) IsInstance(module android.Module) bool { 1067 _, ok := module.(*Library) 1068 return ok 1069} 1070 1071func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 1072 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import") 1073} 1074 1075func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 1076 return &librarySdkMemberProperties{} 1077} 1078 1079type librarySdkMemberProperties struct { 1080 android.SdkMemberPropertiesBase 1081 1082 JarToExport android.Path `android:"arch_variant"` 1083 AidlIncludeDirs android.Paths 1084 1085 // The list of permitted packages that need to be passed to the prebuilts as they are used to 1086 // create the updatable-bcp-packages.txt file. 1087 PermittedPackages []string 1088 1089 // The value of the min_sdk_version property, translated into a number where possible. 1090 MinSdkVersion *string `supported_build_releases:"Tiramisu+"` 1091 1092 DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"` 1093} 1094 1095func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 1096 j := variant.(*Library) 1097 1098 p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j) 1099 1100 p.AidlIncludeDirs = j.AidlIncludeDirs() 1101 1102 p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars() 1103 1104 // If the min_sdk_version was set then add the canonical representation of the API level to the 1105 // snapshot. 1106 if j.overridableProperties.Min_sdk_version != nil { 1107 canonical, err := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String()) 1108 if err != nil { 1109 ctx.ModuleErrorf("%s", err) 1110 } 1111 p.MinSdkVersion = proptools.StringPtr(canonical) 1112 } 1113 1114 if j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided { 1115 p.DexPreoptProfileGuided = proptools.BoolPtr(true) 1116 } 1117} 1118 1119func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 1120 builder := ctx.SnapshotBuilder() 1121 1122 memberType := ctx.MemberType().(*librarySdkMemberType) 1123 1124 exportedJar := p.JarToExport 1125 if exportedJar != nil { 1126 // Delegate the creation of the snapshot relative path to the member type. 1127 snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(ctx, p.OsPrefix(), ctx.Name()) 1128 1129 // Copy the exported jar to the snapshot. 1130 builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) 1131 1132 propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) 1133 } 1134 1135 if p.MinSdkVersion != nil { 1136 propertySet.AddProperty("min_sdk_version", *p.MinSdkVersion) 1137 } 1138 1139 if len(p.PermittedPackages) > 0 { 1140 propertySet.AddProperty("permitted_packages", p.PermittedPackages) 1141 } 1142 1143 dexPreoptSet := propertySet.AddPropertySet("dex_preopt") 1144 if p.DexPreoptProfileGuided != nil { 1145 dexPreoptSet.AddProperty("profile_guided", proptools.Bool(p.DexPreoptProfileGuided)) 1146 } 1147 1148 // Do not copy anything else to the snapshot. 1149 if memberType.onlyCopyJarToSnapshot { 1150 return 1151 } 1152 1153 aidlIncludeDirs := p.AidlIncludeDirs 1154 if len(aidlIncludeDirs) != 0 { 1155 sdkModuleContext := ctx.SdkModuleContext() 1156 for _, dir := range aidlIncludeDirs { 1157 // TODO(jiyong): copy parcelable declarations only 1158 aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil) 1159 for _, file := range aidlFiles { 1160 builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file)) 1161 } 1162 } 1163 1164 // TODO(b/151933053) - add aidl include dirs property 1165 } 1166} 1167 1168// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well. 1169// 1170// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were 1171// compiled against the device bootclasspath. This jar is not suitable for installing on a device, but can be used 1172// as a `static_libs` dependency of another module. 1173// 1174// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on 1175// a device. 1176// 1177// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 1178// compiled against the host bootclasspath. 1179func LibraryFactory() android.Module { 1180 module := &Library{} 1181 1182 module.addHostAndDeviceProperties() 1183 module.AddProperties(&module.sourceProperties) 1184 1185 module.initModuleAndImport(module) 1186 1187 android.InitApexModule(module) 1188 InitJavaModule(module, android.HostAndDeviceSupported) 1189 return module 1190} 1191 1192// java_library_static is an obsolete alias for java_library. 1193func LibraryStaticFactory() android.Module { 1194 return LibraryFactory() 1195} 1196 1197// java_library_host builds and links sources into a `.jar` file for the host. 1198// 1199// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were 1200// compiled against the host bootclasspath. 1201func LibraryHostFactory() android.Module { 1202 module := &Library{} 1203 1204 module.addHostProperties() 1205 1206 module.Module.properties.Installable = proptools.BoolPtr(true) 1207 1208 android.InitApexModule(module) 1209 InitJavaModule(module, android.HostSupported) 1210 return module 1211} 1212 1213// 1214// Java Tests 1215// 1216 1217// Test option struct. 1218type TestOptions struct { 1219 android.CommonTestOptions 1220 1221 // a list of extra test configuration files that should be installed with the module. 1222 Extra_test_configs []string `android:"path,arch_variant"` 1223 1224 // Extra <option> tags to add to the auto generated test xml file. The "key" 1225 // is optional in each of these. 1226 Tradefed_options []tradefed.Option 1227 1228 // Extra <option> tags to add to the auto generated test xml file under the test runner, e.g., AndroidJunitTest. 1229 // The "key" is optional in each of these. 1230 Test_runner_options []tradefed.Option 1231} 1232 1233type testProperties struct { 1234 // list of compatibility suites (for example "cts", "vts") that the module should be 1235 // installed into. 1236 Test_suites []string `android:"arch_variant"` 1237 1238 // the name of the test configuration (for example "AndroidTest.xml") that should be 1239 // installed with the module. 1240 Test_config *string `android:"path,arch_variant"` 1241 1242 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that 1243 // should be installed with the module. 1244 Test_config_template *string `android:"path,arch_variant"` 1245 1246 // list of files or filegroup modules that provide data that should be installed alongside 1247 // the test 1248 Data []string `android:"path"` 1249 1250 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 1251 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 1252 // explicitly. 1253 Auto_gen_config *bool 1254 1255 // Add parameterized mainline modules to auto generated test config. The options will be 1256 // handled by TradeFed to do downloading and installing the specified modules on the device. 1257 Test_mainline_modules []string 1258 1259 // Test options. 1260 Test_options TestOptions 1261 1262 // Names of modules containing JNI libraries that should be installed alongside the test. 1263 Jni_libs []string 1264 1265 // Install the test into a folder named for the module in all test suites. 1266 Per_testcase_directory *bool 1267} 1268 1269type hostTestProperties struct { 1270 // list of native binary modules that should be installed alongside the test 1271 Data_native_bins []string `android:"arch_variant"` 1272 1273 // list of device binary modules that should be installed alongside the test 1274 // This property only adds the first variant of the dependency 1275 Data_device_bins_first []string `android:"arch_variant"` 1276 1277 // list of device binary modules that should be installed alongside the test 1278 // This property adds 64bit AND 32bit variants of the dependency 1279 Data_device_bins_both []string `android:"arch_variant"` 1280 1281 // list of device binary modules that should be installed alongside the test 1282 // This property only adds 64bit variants of the dependency 1283 Data_device_bins_64 []string `android:"arch_variant"` 1284 1285 // list of device binary modules that should be installed alongside the test 1286 // This property adds 32bit variants of the dependency if available, or else 1287 // defaults to the 64bit variant 1288 Data_device_bins_prefer32 []string `android:"arch_variant"` 1289 1290 // list of device binary modules that should be installed alongside the test 1291 // This property only adds 32bit variants of the dependency 1292 Data_device_bins_32 []string `android:"arch_variant"` 1293} 1294 1295type testHelperLibraryProperties struct { 1296 // list of compatibility suites (for example "cts", "vts") that the module should be 1297 // installed into. 1298 Test_suites []string `android:"arch_variant"` 1299 1300 // Install the test into a folder named for the module in all test suites. 1301 Per_testcase_directory *bool 1302} 1303 1304type prebuiltTestProperties struct { 1305 // list of compatibility suites (for example "cts", "vts") that the module should be 1306 // installed into. 1307 Test_suites []string `android:"arch_variant"` 1308 1309 // the name of the test configuration (for example "AndroidTest.xml") that should be 1310 // installed with the module. 1311 Test_config *string `android:"path,arch_variant"` 1312} 1313 1314type Test struct { 1315 Library 1316 1317 testProperties testProperties 1318 1319 testConfig android.Path 1320 extraTestConfigs android.Paths 1321 data android.Paths 1322} 1323 1324type TestHost struct { 1325 Test 1326 1327 testHostProperties hostTestProperties 1328} 1329 1330type TestHelperLibrary struct { 1331 Library 1332 1333 testHelperLibraryProperties testHelperLibraryProperties 1334} 1335 1336type JavaTestImport struct { 1337 Import 1338 1339 prebuiltTestProperties prebuiltTestProperties 1340 1341 testConfig android.Path 1342 dexJarFile android.Path 1343} 1344 1345func (j *Test) InstallInTestcases() bool { 1346 // Host java tests install into $(HOST_OUT_JAVA_LIBRARIES), and then are copied into 1347 // testcases by base_rules.mk. 1348 return !j.Host() 1349} 1350 1351func (j *TestHelperLibrary) InstallInTestcases() bool { 1352 return true 1353} 1354 1355func (j *JavaTestImport) InstallInTestcases() bool { 1356 return true 1357} 1358 1359func (j *TestHost) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool { 1360 return ctx.DeviceConfig().NativeCoverageEnabled() 1361} 1362 1363func (j *TestHost) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext) { 1364 if len(j.testHostProperties.Data_device_bins_first) > 0 { 1365 deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() 1366 ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_first...) 1367 } 1368 1369 var maybeAndroid32Target *android.Target 1370 var maybeAndroid64Target *android.Target 1371 android32TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib32") 1372 android64TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib64") 1373 if len(android32TargetList) > 0 { 1374 maybeAndroid32Target = &android32TargetList[0] 1375 } 1376 if len(android64TargetList) > 0 { 1377 maybeAndroid64Target = &android64TargetList[0] 1378 } 1379 1380 if len(j.testHostProperties.Data_device_bins_both) > 0 { 1381 if maybeAndroid32Target == nil && maybeAndroid64Target == nil { 1382 ctx.PropertyErrorf("data_device_bins_both", "no device targets available. Targets: %q", ctx.Config().Targets) 1383 return 1384 } 1385 if maybeAndroid32Target != nil { 1386 ctx.AddFarVariationDependencies( 1387 maybeAndroid32Target.Variations(), 1388 dataDeviceBinsTag, 1389 j.testHostProperties.Data_device_bins_both..., 1390 ) 1391 } 1392 if maybeAndroid64Target != nil { 1393 ctx.AddFarVariationDependencies( 1394 maybeAndroid64Target.Variations(), 1395 dataDeviceBinsTag, 1396 j.testHostProperties.Data_device_bins_both..., 1397 ) 1398 } 1399 } 1400 1401 if len(j.testHostProperties.Data_device_bins_prefer32) > 0 { 1402 if maybeAndroid32Target != nil { 1403 ctx.AddFarVariationDependencies( 1404 maybeAndroid32Target.Variations(), 1405 dataDeviceBinsTag, 1406 j.testHostProperties.Data_device_bins_prefer32..., 1407 ) 1408 } else { 1409 if maybeAndroid64Target == nil { 1410 ctx.PropertyErrorf("data_device_bins_prefer32", "no device targets available. Targets: %q", ctx.Config().Targets) 1411 return 1412 } 1413 ctx.AddFarVariationDependencies( 1414 maybeAndroid64Target.Variations(), 1415 dataDeviceBinsTag, 1416 j.testHostProperties.Data_device_bins_prefer32..., 1417 ) 1418 } 1419 } 1420 1421 if len(j.testHostProperties.Data_device_bins_32) > 0 { 1422 if maybeAndroid32Target == nil { 1423 ctx.PropertyErrorf("data_device_bins_32", "cannot find 32bit device target. Targets: %q", ctx.Config().Targets) 1424 return 1425 } 1426 deviceVariations := maybeAndroid32Target.Variations() 1427 ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_32...) 1428 } 1429 1430 if len(j.testHostProperties.Data_device_bins_64) > 0 { 1431 if maybeAndroid64Target == nil { 1432 ctx.PropertyErrorf("data_device_bins_64", "cannot find 64bit device target. Targets: %q", ctx.Config().Targets) 1433 return 1434 } 1435 deviceVariations := maybeAndroid64Target.Variations() 1436 ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_64...) 1437 } 1438} 1439 1440func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { 1441 if len(j.testHostProperties.Data_native_bins) > 0 { 1442 for _, target := range ctx.MultiTargets() { 1443 ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...) 1444 } 1445 } 1446 1447 if len(j.testProperties.Jni_libs) > 0 { 1448 for _, target := range ctx.MultiTargets() { 1449 sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"}) 1450 ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...) 1451 } 1452 } 1453 1454 j.addDataDeviceBinsDeps(ctx) 1455 j.deps(ctx) 1456} 1457 1458func (j *TestHost) AddExtraResource(p android.Path) { 1459 j.extraResources = append(j.extraResources, p) 1460} 1461 1462func (j *TestHost) dataDeviceBins() []string { 1463 ret := make([]string, 0, 1464 len(j.testHostProperties.Data_device_bins_first)+ 1465 len(j.testHostProperties.Data_device_bins_both)+ 1466 len(j.testHostProperties.Data_device_bins_prefer32)+ 1467 len(j.testHostProperties.Data_device_bins_32)+ 1468 len(j.testHostProperties.Data_device_bins_64), 1469 ) 1470 1471 ret = append(ret, j.testHostProperties.Data_device_bins_first...) 1472 ret = append(ret, j.testHostProperties.Data_device_bins_both...) 1473 ret = append(ret, j.testHostProperties.Data_device_bins_prefer32...) 1474 ret = append(ret, j.testHostProperties.Data_device_bins_32...) 1475 ret = append(ret, j.testHostProperties.Data_device_bins_64...) 1476 1477 return ret 1478} 1479 1480func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1481 var configs []tradefed.Config 1482 dataDeviceBins := j.dataDeviceBins() 1483 if len(dataDeviceBins) > 0 { 1484 // add Tradefed configuration to push device bins to device for testing 1485 remoteDir := filepath.Join("/data/local/tests/unrestricted/", j.Name()) 1486 options := []tradefed.Option{{Name: "cleanup", Value: "true"}} 1487 for _, bin := range dataDeviceBins { 1488 fullPath := filepath.Join(remoteDir, bin) 1489 options = append(options, tradefed.Option{Name: "push-file", Key: bin, Value: fullPath}) 1490 } 1491 configs = append(configs, tradefed.Object{ 1492 Type: "target_preparer", 1493 Class: "com.android.tradefed.targetprep.PushFilePreparer", 1494 Options: options, 1495 }) 1496 } 1497 1498 j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) 1499 android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{}) 1500 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ 1501 InstalledFiles: j.data, 1502 OutputFile: j.outputFile, 1503 TestConfig: j.testConfig, 1504 RequiredModuleNames: j.RequiredModuleNames(), 1505 TestSuites: j.testProperties.Test_suites, 1506 IsHost: true, 1507 LocalSdkVersion: j.sdkVersion.String(), 1508 IsUnitTest: Bool(j.testProperties.Test_options.Unit_test), 1509 }) 1510} 1511 1512func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1513 j.generateAndroidBuildActionsWithConfig(ctx, nil) 1514 android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{}) 1515} 1516 1517func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) { 1518 if j.testProperties.Test_options.Unit_test == nil && ctx.Host() { 1519 // TODO(b/): Clean temporary heuristic to avoid unexpected onboarding. 1520 defaultUnitTest := !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites) 1521 j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest) 1522 } 1523 j.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ 1524 TestConfigProp: j.testProperties.Test_config, 1525 TestConfigTemplateProp: j.testProperties.Test_config_template, 1526 TestSuites: j.testProperties.Test_suites, 1527 Config: configs, 1528 OptionsForAutogenerated: j.testProperties.Test_options.Tradefed_options, 1529 TestRunnerOptions: j.testProperties.Test_options.Test_runner_options, 1530 AutoGenConfig: j.testProperties.Auto_gen_config, 1531 UnitTest: j.testProperties.Test_options.Unit_test, 1532 DeviceTemplate: "${JavaTestConfigTemplate}", 1533 HostTemplate: "${JavaHostTestConfigTemplate}", 1534 HostUnitTestTemplate: "${JavaHostUnitTestConfigTemplate}", 1535 }) 1536 1537 j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data) 1538 1539 j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs) 1540 1541 ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) { 1542 j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) 1543 }) 1544 1545 ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) { 1546 j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) 1547 }) 1548 1549 ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) { 1550 sharedLibInfo, _ := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider) 1551 if sharedLibInfo.SharedLibrary != nil { 1552 // Copy to an intermediate output directory to append "lib[64]" to the path, 1553 // so that it's compatible with the default rpath values. 1554 var relPath string 1555 if sharedLibInfo.Target.Arch.ArchType.Multilib == "lib64" { 1556 relPath = filepath.Join("lib64", sharedLibInfo.SharedLibrary.Base()) 1557 } else { 1558 relPath = filepath.Join("lib", sharedLibInfo.SharedLibrary.Base()) 1559 } 1560 relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath) 1561 ctx.Build(pctx, android.BuildParams{ 1562 Rule: android.Cp, 1563 Input: sharedLibInfo.SharedLibrary, 1564 Output: relocatedLib, 1565 }) 1566 j.data = append(j.data, relocatedLib) 1567 } else { 1568 ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep)) 1569 } 1570 }) 1571 1572 j.Library.GenerateAndroidBuildActions(ctx) 1573} 1574 1575func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1576 j.Library.GenerateAndroidBuildActions(ctx) 1577} 1578 1579func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1580 j.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ 1581 TestConfigProp: j.prebuiltTestProperties.Test_config, 1582 TestSuites: j.prebuiltTestProperties.Test_suites, 1583 DeviceTemplate: "${JavaTestConfigTemplate}", 1584 HostTemplate: "${JavaHostTestConfigTemplate}", 1585 HostUnitTestTemplate: "${JavaHostUnitTestConfigTemplate}", 1586 }) 1587 1588 j.Import.GenerateAndroidBuildActions(ctx) 1589} 1590 1591type testSdkMemberType struct { 1592 android.SdkMemberTypeBase 1593} 1594 1595func (mt *testSdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { 1596 ctx.AddVariationDependencies(nil, dependencyTag, names...) 1597} 1598 1599func (mt *testSdkMemberType) IsInstance(module android.Module) bool { 1600 _, ok := module.(*Test) 1601 return ok 1602} 1603 1604func (mt *testSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 1605 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_test_import") 1606} 1607 1608func (mt *testSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 1609 return &testSdkMemberProperties{} 1610} 1611 1612type testSdkMemberProperties struct { 1613 android.SdkMemberPropertiesBase 1614 1615 JarToExport android.Path 1616 TestConfig android.Path 1617} 1618 1619func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 1620 test := variant.(*Test) 1621 1622 implementationJars := test.ImplementationJars() 1623 if len(implementationJars) != 1 { 1624 panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name())) 1625 } 1626 1627 p.JarToExport = implementationJars[0] 1628 p.TestConfig = test.testConfig 1629} 1630 1631func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 1632 builder := ctx.SnapshotBuilder() 1633 1634 exportedJar := p.JarToExport 1635 if exportedJar != nil { 1636 snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(ctx, p.OsPrefix(), ctx.Name()) 1637 builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) 1638 1639 propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) 1640 } 1641 1642 testConfig := p.TestConfig 1643 if testConfig != nil { 1644 snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(p.OsPrefix(), ctx.Name(), testConfigSuffix) 1645 builder.CopyToSnapshot(testConfig, snapshotRelativeTestConfigPath) 1646 propertySet.AddProperty("test_config", snapshotRelativeTestConfigPath) 1647 } 1648} 1649 1650// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and 1651// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file. 1652// 1653// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were 1654// compiled against the device bootclasspath. 1655// 1656// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 1657// compiled against the host bootclasspath. 1658func TestFactory() android.Module { 1659 module := &Test{} 1660 1661 module.addHostAndDeviceProperties() 1662 module.AddProperties(&module.testProperties) 1663 1664 module.Module.properties.Installable = proptools.BoolPtr(true) 1665 module.Module.dexpreopter.isTest = true 1666 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) 1667 module.Module.sourceProperties.Test_only = proptools.BoolPtr(true) 1668 module.Module.sourceProperties.Top_level_test_target = true 1669 1670 InitJavaModule(module, android.HostAndDeviceSupported) 1671 return module 1672} 1673 1674// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite. 1675func TestHelperLibraryFactory() android.Module { 1676 module := &TestHelperLibrary{} 1677 1678 module.addHostAndDeviceProperties() 1679 module.AddProperties(&module.testHelperLibraryProperties) 1680 1681 module.Module.properties.Installable = proptools.BoolPtr(true) 1682 module.Module.dexpreopter.isTest = true 1683 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) 1684 module.Module.sourceProperties.Test_only = proptools.BoolPtr(true) 1685 1686 InitJavaModule(module, android.HostAndDeviceSupported) 1687 return module 1688} 1689 1690// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module 1691// and makes sure that it is added to the appropriate test suite. 1692// 1693// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were 1694// compiled against an Android classpath. 1695// 1696// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one 1697// for host modules. 1698func JavaTestImportFactory() android.Module { 1699 module := &JavaTestImport{} 1700 1701 module.AddProperties( 1702 &module.Import.properties, 1703 &module.prebuiltTestProperties) 1704 1705 module.Import.properties.Installable = proptools.BoolPtr(true) 1706 1707 android.InitPrebuiltModule(module, &module.properties.Jars) 1708 android.InitApexModule(module) 1709 InitJavaModule(module, android.HostAndDeviceSupported) 1710 return module 1711} 1712 1713// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to 1714// allow running the test with `atest` or a `TEST_MAPPING` file. 1715// 1716// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were 1717// compiled against the host bootclasspath. 1718func TestHostFactory() android.Module { 1719 module := &TestHost{} 1720 1721 module.addHostProperties() 1722 module.AddProperties(&module.testProperties) 1723 module.AddProperties(&module.testHostProperties) 1724 1725 InitTestHost( 1726 module, 1727 proptools.BoolPtr(true), 1728 nil, 1729 nil) 1730 1731 InitJavaModuleMultiTargets(module, android.HostSupported) 1732 1733 return module 1734} 1735 1736func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenConfig *bool) { 1737 th.properties.Installable = installable 1738 th.testProperties.Auto_gen_config = autoGenConfig 1739 th.testProperties.Test_suites = testSuites 1740 th.sourceProperties.Test_only = proptools.BoolPtr(true) 1741 th.sourceProperties.Top_level_test_target = true 1742} 1743 1744// 1745// Java Binaries (.jar file plus wrapper script) 1746// 1747 1748type binaryProperties struct { 1749 // installable script to execute the resulting jar 1750 Wrapper *string `android:"path,arch_variant"` 1751 1752 // Name of the class containing main to be inserted into the manifest as Main-Class. 1753 Main_class *string 1754 1755 // Names of modules containing JNI libraries that should be installed alongside the host 1756 // variant of the binary. 1757 Jni_libs []string `android:"arch_variant"` 1758} 1759 1760type Binary struct { 1761 Library 1762 1763 binaryProperties binaryProperties 1764 1765 isWrapperVariant bool 1766 1767 wrapperFile android.Path 1768 binaryFile android.InstallPath 1769} 1770 1771func (j *Binary) HostToolPath() android.OptionalPath { 1772 return android.OptionalPathForPath(j.binaryFile) 1773} 1774 1775func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1776 j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName()) 1777 1778 if ctx.Arch().ArchType == android.Common { 1779 // Compile the jar 1780 if j.binaryProperties.Main_class != nil { 1781 if j.properties.Manifest != nil { 1782 ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set") 1783 } 1784 manifestFile := android.PathForModuleOut(ctx, "manifest.txt") 1785 GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class)) 1786 j.overrideManifest = android.OptionalPathForPath(manifestFile) 1787 } 1788 1789 j.Library.GenerateAndroidBuildActions(ctx) 1790 } else { 1791 // Handle the binary wrapper 1792 j.isWrapperVariant = true 1793 1794 if j.binaryProperties.Wrapper != nil { 1795 j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper) 1796 } else { 1797 if ctx.Windows() { 1798 ctx.PropertyErrorf("wrapper", "wrapper is required for Windows") 1799 } 1800 1801 if ctx.Device() { 1802 // device binary should have a main_class property if it does not 1803 // have a specific wrapper, so that a default wrapper can 1804 // be generated for it. 1805 if j.binaryProperties.Main_class == nil { 1806 ctx.PropertyErrorf("main_class", "main_class property "+ 1807 "is required for device binary if no default wrapper is assigned") 1808 } else { 1809 wrapper := android.PathForModuleOut(ctx, ctx.ModuleName()+".sh") 1810 jarName := j.Stem() + ".jar" 1811 partition := j.PartitionTag(ctx.DeviceConfig()) 1812 ctx.Build(pctx, android.BuildParams{ 1813 Rule: deviceBinaryWrapper, 1814 Output: wrapper, 1815 Args: map[string]string{ 1816 "jar_name": jarName, 1817 "partition": partition, 1818 "main_class": String(j.binaryProperties.Main_class), 1819 }, 1820 }) 1821 j.wrapperFile = wrapper 1822 } 1823 } else { 1824 j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") 1825 } 1826 } 1827 1828 ext := "" 1829 if ctx.Windows() { 1830 ext = ".bat" 1831 } 1832 1833 // The host installation rules make the installed wrapper depend on all the dependencies 1834 // of the wrapper variant, which will include the common variant's jar file and any JNI 1835 // libraries. This is verified by TestBinary. 1836 j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), 1837 ctx.ModuleName()+ext, j.wrapperFile) 1838 } 1839} 1840 1841func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { 1842 if ctx.Arch().ArchType == android.Common { 1843 j.deps(ctx) 1844 } 1845 if ctx.Arch().ArchType != android.Common { 1846 // These dependencies ensure the host installation rules will install the jar file and 1847 // the jni libraries when the wrapper is installed. 1848 ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...) 1849 ctx.AddVariationDependencies( 1850 []blueprint.Variation{{Mutator: "arch", Variation: android.CommonArch.String()}}, 1851 binaryInstallTag, ctx.ModuleName()) 1852 } 1853} 1854 1855// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host 1856// as well. 1857// 1858// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were 1859// compiled against the device bootclasspath. 1860// 1861// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 1862// compiled against the host bootclasspath. 1863func BinaryFactory() android.Module { 1864 module := &Binary{} 1865 1866 module.addHostAndDeviceProperties() 1867 module.AddProperties(&module.binaryProperties, &module.sourceProperties) 1868 1869 module.Module.properties.Installable = proptools.BoolPtr(true) 1870 1871 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst) 1872 android.InitDefaultableModule(module) 1873 1874 return module 1875} 1876 1877// java_binary_host builds a `.jar` file and a shell script that executes it for the host. 1878// 1879// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were 1880// compiled against the host bootclasspath. 1881func BinaryHostFactory() android.Module { 1882 module := &Binary{} 1883 1884 module.addHostProperties() 1885 module.AddProperties(&module.binaryProperties) 1886 1887 module.Module.properties.Installable = proptools.BoolPtr(true) 1888 1889 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst) 1890 android.InitDefaultableModule(module) 1891 return module 1892} 1893 1894type JavaApiContribution struct { 1895 android.ModuleBase 1896 android.DefaultableModuleBase 1897 embeddableInModuleAndImport 1898 1899 properties struct { 1900 // name of the API surface 1901 Api_surface *string 1902 1903 // relative path to the API signature text file 1904 Api_file *string `android:"path"` 1905 } 1906} 1907 1908func ApiContributionFactory() android.Module { 1909 module := &JavaApiContribution{} 1910 android.InitAndroidModule(module) 1911 android.InitDefaultableModule(module) 1912 module.AddProperties(&module.properties) 1913 module.initModuleAndImport(module) 1914 return module 1915} 1916 1917type JavaApiImportInfo struct { 1918 ApiFile android.Path 1919 ApiSurface string 1920} 1921 1922var JavaApiImportProvider = blueprint.NewProvider[JavaApiImportInfo]() 1923 1924func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1925 var apiFile android.Path = nil 1926 if apiFileString := ap.properties.Api_file; apiFileString != nil { 1927 apiFile = android.PathForModuleSrc(ctx, String(apiFileString)) 1928 } 1929 1930 android.SetProvider(ctx, JavaApiImportProvider, JavaApiImportInfo{ 1931 ApiFile: apiFile, 1932 ApiSurface: proptools.String(ap.properties.Api_surface), 1933 }) 1934} 1935 1936type ApiLibrary struct { 1937 android.ModuleBase 1938 android.DefaultableModuleBase 1939 1940 hiddenAPI 1941 dexer 1942 embeddableInModuleAndImport 1943 1944 properties JavaApiLibraryProperties 1945 1946 stubsSrcJar android.WritablePath 1947 stubsJar android.WritablePath 1948 stubsJarWithoutStaticLibs android.WritablePath 1949 extractedSrcJar android.WritablePath 1950 // .dex of stubs, used for hiddenapi processing 1951 dexJarFile OptionalDexJarPath 1952 1953 validationPaths android.Paths 1954 1955 stubsType StubsType 1956 1957 aconfigProtoFiles android.Paths 1958} 1959 1960type JavaApiLibraryProperties struct { 1961 // name of the API surface 1962 Api_surface *string 1963 1964 // list of Java API contribution modules that consists this API surface 1965 // This is a list of Soong modules 1966 Api_contributions []string 1967 1968 // List of flags to be passed to the javac compiler to generate jar file 1969 Javacflags []string 1970 1971 // List of shared java libs that this module has dependencies to and 1972 // should be passed as classpath in javac invocation 1973 Libs []string 1974 1975 // List of java libs that this module has static dependencies to and will be 1976 // merge zipped after metalava invocation 1977 Static_libs []string 1978 1979 // Java Api library to provide the full API surface stub jar file. 1980 // If this property is set, the stub jar of this module is created by 1981 // extracting the compiled class files provided by the 1982 // full_api_surface_stub module. 1983 Full_api_surface_stub *string 1984 1985 // Version of previously released API file for compatibility check. 1986 Previous_api *string `android:"path"` 1987 1988 // java_system_modules module providing the jar to be added to the 1989 // bootclasspath when compiling the stubs. 1990 // The jar will also be passed to metalava as a classpath to 1991 // generate compilable stubs. 1992 System_modules *string 1993 1994 // If true, the module runs validation on the API signature files provided 1995 // by the modules passed via api_contributions by checking if the files are 1996 // in sync with the source Java files. However, the environment variable 1997 // DISABLE_STUB_VALIDATION has precedence over this property. 1998 Enable_validation *bool 1999 2000 // Type of stubs the module should generate. Must be one of "everything", "runtime" or 2001 // "exportable". Defaults to "everything". 2002 // - "everything" stubs include all non-flagged apis and flagged apis, regardless of the state 2003 // of the flag. 2004 // - "runtime" stubs include all non-flagged apis and flagged apis that are ENABLED or 2005 // READ_WRITE, and all other flagged apis are stripped. 2006 // - "exportable" stubs include all non-flagged apis and flagged apis that are ENABLED and 2007 // READ_ONLY, and all other flagged apis are stripped. 2008 Stubs_type *string 2009 2010 // List of aconfig_declarations module names that the stubs generated in this module 2011 // depend on. 2012 Aconfig_declarations []string 2013} 2014 2015func ApiLibraryFactory() android.Module { 2016 module := &ApiLibrary{} 2017 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) 2018 module.AddProperties(&module.properties) 2019 module.initModuleAndImport(module) 2020 android.InitDefaultableModule(module) 2021 return module 2022} 2023 2024func (al *ApiLibrary) ApiSurface() *string { 2025 return al.properties.Api_surface 2026} 2027 2028func (al *ApiLibrary) StubsJar() android.Path { 2029 return al.stubsJar 2030} 2031 2032func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, 2033 srcs android.Paths, homeDir android.WritablePath, 2034 classpath android.Paths) *android.RuleBuilderCommand { 2035 rule.Command().Text("rm -rf").Flag(homeDir.String()) 2036 rule.Command().Text("mkdir -p").Flag(homeDir.String()) 2037 2038 cmd := rule.Command() 2039 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String()) 2040 2041 if metalavaUseRbe(ctx) { 2042 rule.Remoteable(android.RemoteRuleSupports{RBE: true}) 2043 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy) 2044 labels := map[string]string{"type": "tool", "name": "metalava"} 2045 2046 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16") 2047 rule.Rewrapper(&remoteexec.REParams{ 2048 Labels: labels, 2049 ExecStrategy: execStrategy, 2050 ToolchainInputs: []string{config.JavaCmd(ctx).String()}, 2051 Platform: map[string]string{remoteexec.PoolKey: pool}, 2052 }) 2053 } 2054 2055 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")). 2056 Flag(config.JavacVmFlags). 2057 Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED"). 2058 FlagWithInputList("--source-files ", srcs, " ") 2059 2060 cmd.Flag("--color"). 2061 Flag("--quiet"). 2062 Flag("--include-annotations"). 2063 // The flag makes nullability issues as warnings rather than errors by replacing 2064 // @Nullable/@NonNull in the listed packages APIs with @RecentlyNullable/@RecentlyNonNull, 2065 // and these packages are meant to have everything annotated 2066 // @RecentlyNullable/@RecentlyNonNull. 2067 FlagWithArg("--force-convert-to-warning-nullability-annotations ", "+*:-android.*:+android.icu.*:-dalvik.*"). 2068 FlagWithArg("--repeat-errors-max ", "10"). 2069 FlagWithArg("--hide ", "UnresolvedImport"). 2070 FlagWithArg("--hide ", "InvalidNullabilityOverride"). 2071 FlagWithArg("--hide ", "ChangedDefault") 2072 2073 if len(classpath) == 0 { 2074 // The main purpose of the `--api-class-resolution api` option is to force metalava to ignore 2075 // classes on the classpath when an API file contains missing classes. However, as this command 2076 // does not specify `--classpath` this is not needed for that. However, this is also used as a 2077 // signal to the special metalava code for generating stubs from text files that it needs to add 2078 // some additional items into the API (e.g. default constructors). 2079 cmd.FlagWithArg("--api-class-resolution ", "api") 2080 } else { 2081 cmd.FlagWithArg("--api-class-resolution ", "api:classpath") 2082 cmd.FlagWithInputList("--classpath ", classpath, ":") 2083 } 2084 2085 return cmd 2086} 2087 2088func (al *ApiLibrary) HeaderJars() android.Paths { 2089 return android.Paths{al.stubsJar} 2090} 2091 2092func (al *ApiLibrary) OutputDirAndDeps() (android.Path, android.Paths) { 2093 return nil, nil 2094} 2095 2096func (al *ApiLibrary) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) { 2097 if stubsDir.Valid() { 2098 cmd.FlagWithArg("--stubs ", stubsDir.String()) 2099 } 2100} 2101 2102func (al *ApiLibrary) addValidation(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, validationPaths android.Paths) { 2103 for _, validationPath := range validationPaths { 2104 cmd.Validation(validationPath) 2105 } 2106} 2107 2108// This method extracts the stub class files from the stub jar file provided 2109// from full_api_surface_stub module instead of compiling the srcjar generated from invoking metalava. 2110// This method is used because metalava can generate compilable from-text stubs only when 2111// the codebase encompasses all classes listed in the input API text file, and a class can extend 2112// a class that is not within the same API domain. 2113func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.RuleBuilder, stubsDir android.OptionalPath, fullApiSurfaceStubJar android.Path) { 2114 classFilesList := android.PathForModuleOut(ctx, "metalava", "classes.txt") 2115 unzippedSrcJarDir := android.PathForModuleOut(ctx, "metalava", "unzipDir") 2116 2117 rule.Command(). 2118 BuiltTool("list_files"). 2119 Text(stubsDir.String()). 2120 FlagWithOutput("--out ", classFilesList). 2121 FlagWithArg("--extensions ", ".java"). 2122 FlagWithArg("--root ", unzippedSrcJarDir.String()). 2123 Flag("--classes") 2124 2125 rule.Command(). 2126 Text("unzip"). 2127 Flag("-q"). 2128 Input(fullApiSurfaceStubJar). 2129 FlagWithArg("-d ", unzippedSrcJarDir.String()) 2130 2131 rule.Command(). 2132 BuiltTool("soong_zip"). 2133 Flag("-jar"). 2134 Flag("-write_if_changed"). 2135 Flag("-ignore_missing_files"). 2136 Flag("-quiet"). 2137 FlagWithArg("-C ", unzippedSrcJarDir.String()). 2138 FlagWithInput("-l ", classFilesList). 2139 FlagWithOutput("-o ", al.stubsJarWithoutStaticLibs) 2140} 2141 2142func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { 2143 apiContributions := al.properties.Api_contributions 2144 addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") && 2145 !ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") && 2146 proptools.BoolDefault(al.properties.Enable_validation, true) 2147 for _, apiContributionName := range apiContributions { 2148 ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName) 2149 2150 // Add the java_api_contribution module generating droidstubs module 2151 // as dependency when validation adding conditions are met and 2152 // the java_api_contribution module name has ".api.contribution" suffix. 2153 // All droidstubs-generated modules possess the suffix in the name, 2154 // but there is no such guarantee for tests. 2155 if addValidations { 2156 if strings.HasSuffix(apiContributionName, ".api.contribution") { 2157 ctx.AddDependency(ctx.Module(), metalavaCurrentApiTimestampTag, strings.TrimSuffix(apiContributionName, ".api.contribution")) 2158 } else { 2159 ctx.ModuleErrorf("Validation is enabled for module %s but a "+ 2160 "current timestamp provider is not found for the api "+ 2161 "contribution %s", 2162 ctx.ModuleName(), 2163 apiContributionName, 2164 ) 2165 } 2166 } 2167 } 2168 ctx.AddVariationDependencies(nil, libTag, al.properties.Libs...) 2169 ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs...) 2170 if al.properties.Full_api_surface_stub != nil { 2171 ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Full_api_surface_stub)) 2172 } 2173 if al.properties.System_modules != nil { 2174 ctx.AddVariationDependencies(nil, systemModulesTag, String(al.properties.System_modules)) 2175 } 2176 for _, aconfigDeclarationsName := range al.properties.Aconfig_declarations { 2177 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationsName) 2178 } 2179} 2180 2181// Map where key is the api scope name and value is the int value 2182// representing the order of the api scope, narrowest to the widest 2183var scopeOrderMap = AllApiScopes.MapToIndex( 2184 func(s *apiScope) string { return s.name }) 2185 2186func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo { 2187 for _, srcFileInfo := range srcFilesInfo { 2188 if srcFileInfo.ApiSurface == "" { 2189 ctx.ModuleErrorf("Api surface not defined for the associated api file %s", srcFileInfo.ApiFile) 2190 } 2191 } 2192 sort.Slice(srcFilesInfo, func(i, j int) bool { 2193 return scopeOrderMap[srcFilesInfo[i].ApiSurface] < scopeOrderMap[srcFilesInfo[j].ApiSurface] 2194 }) 2195 2196 return srcFilesInfo 2197} 2198 2199var validstubsType = []StubsType{Everything, Runtime, Exportable} 2200 2201func (al *ApiLibrary) validateProperties(ctx android.ModuleContext) { 2202 if al.properties.Stubs_type == nil { 2203 ctx.ModuleErrorf("java_api_library module type must specify stubs_type property.") 2204 } else { 2205 al.stubsType = StringToStubsType(proptools.String(al.properties.Stubs_type)) 2206 } 2207 2208 if !android.InList(al.stubsType, validstubsType) { 2209 ctx.PropertyErrorf("stubs_type", "%s is not a valid stubs_type property value. "+ 2210 "Must be one of %s.", proptools.String(al.properties.Stubs_type), validstubsType) 2211 } 2212} 2213 2214func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2215 al.validateProperties(ctx) 2216 2217 rule := android.NewRuleBuilder(pctx, ctx) 2218 2219 rule.Sbox(android.PathForModuleOut(ctx, "metalava"), 2220 android.PathForModuleOut(ctx, "metalava.sbox.textproto")). 2221 SandboxInputs() 2222 2223 stubsDir := android.OptionalPathForPath(android.PathForModuleOut(ctx, "metalava", "stubsDir")) 2224 rule.Command().Text("rm -rf").Text(stubsDir.String()) 2225 rule.Command().Text("mkdir -p").Text(stubsDir.String()) 2226 2227 homeDir := android.PathForModuleOut(ctx, "metalava", "home") 2228 2229 var srcFilesInfo []JavaApiImportInfo 2230 var classPaths android.Paths 2231 var staticLibs android.Paths 2232 var depApiSrcsStubsJar android.Path 2233 var systemModulesPaths android.Paths 2234 ctx.VisitDirectDeps(func(dep android.Module) { 2235 tag := ctx.OtherModuleDependencyTag(dep) 2236 switch tag { 2237 case javaApiContributionTag: 2238 provider, _ := android.OtherModuleProvider(ctx, dep, JavaApiImportProvider) 2239 if provider.ApiFile == nil && !ctx.Config().AllowMissingDependencies() { 2240 ctx.ModuleErrorf("Error: %s has an empty api file.", dep.Name()) 2241 } 2242 srcFilesInfo = append(srcFilesInfo, provider) 2243 case libTag: 2244 provider, _ := android.OtherModuleProvider(ctx, dep, JavaInfoProvider) 2245 classPaths = append(classPaths, provider.HeaderJars...) 2246 case staticLibTag: 2247 provider, _ := android.OtherModuleProvider(ctx, dep, JavaInfoProvider) 2248 staticLibs = append(staticLibs, provider.HeaderJars...) 2249 case depApiSrcsTag: 2250 provider, _ := android.OtherModuleProvider(ctx, dep, JavaInfoProvider) 2251 depApiSrcsStubsJar = provider.HeaderJars[0] 2252 case systemModulesTag: 2253 module := dep.(SystemModulesProvider) 2254 systemModulesPaths = append(systemModulesPaths, module.HeaderJars()...) 2255 case metalavaCurrentApiTimestampTag: 2256 if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok { 2257 al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp()) 2258 } 2259 case aconfigDeclarationTag: 2260 if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok { 2261 al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPath) 2262 } else if provider, ok := android.OtherModuleProvider(ctx, dep, android.CodegenInfoProvider); ok { 2263 al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPaths...) 2264 } else { 2265 ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+ 2266 "module type is allowed for flags_packages property, but %s is neither "+ 2267 "of these supported module types", 2268 dep.Name(), 2269 ) 2270 } 2271 } 2272 }) 2273 2274 srcFilesInfo = al.sortApiFilesByApiScope(ctx, srcFilesInfo) 2275 var srcFiles android.Paths 2276 for _, srcFileInfo := range srcFilesInfo { 2277 srcFiles = append(srcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String())) 2278 } 2279 2280 if srcFiles == nil && !ctx.Config().AllowMissingDependencies() { 2281 ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName()) 2282 } 2283 2284 cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, systemModulesPaths) 2285 2286 al.stubsFlags(ctx, cmd, stubsDir) 2287 2288 migratingNullability := String(al.properties.Previous_api) != "" 2289 if migratingNullability { 2290 previousApi := android.PathForModuleSrc(ctx, String(al.properties.Previous_api)) 2291 cmd.FlagWithInput("--migrate-nullness ", previousApi) 2292 } 2293 2294 al.addValidation(ctx, cmd, al.validationPaths) 2295 2296 generateRevertAnnotationArgs(ctx, cmd, al.stubsType, al.aconfigProtoFiles) 2297 2298 al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar") 2299 al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar") 2300 al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName())) 2301 2302 if depApiSrcsStubsJar != nil { 2303 al.extractApiSrcs(ctx, rule, stubsDir, depApiSrcsStubsJar) 2304 } 2305 rule.Command(). 2306 BuiltTool("soong_zip"). 2307 Flag("-write_if_changed"). 2308 Flag("-jar"). 2309 FlagWithOutput("-o ", al.stubsSrcJar). 2310 FlagWithArg("-C ", stubsDir.String()). 2311 FlagWithArg("-D ", stubsDir.String()) 2312 2313 rule.Build("metalava", "metalava merged text") 2314 2315 if depApiSrcsStubsJar == nil { 2316 var flags javaBuilderFlags 2317 flags.javaVersion = getStubsJavaVersion() 2318 flags.javacFlags = strings.Join(al.properties.Javacflags, " ") 2319 flags.classpath = classpath(classPaths) 2320 flags.bootClasspath = classpath(systemModulesPaths) 2321 2322 annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar") 2323 2324 TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{}, 2325 android.Paths{al.stubsSrcJar}, annoSrcJar, flags, android.Paths{}) 2326 } 2327 2328 builder := android.NewRuleBuilder(pctx, ctx) 2329 builder.Command(). 2330 BuiltTool("merge_zips"). 2331 Output(al.stubsJar). 2332 Inputs(android.Paths{al.stubsJarWithoutStaticLibs}). 2333 Inputs(staticLibs) 2334 builder.Build("merge_zips", "merge jar files") 2335 2336 // compile stubs to .dex for hiddenapi processing 2337 dexParams := &compileDexParams{ 2338 flags: javaBuilderFlags{}, 2339 sdkVersion: al.SdkVersion(ctx), 2340 minSdkVersion: al.MinSdkVersion(ctx), 2341 classesJar: al.stubsJar, 2342 jarName: ctx.ModuleName() + ".jar", 2343 } 2344 dexOutputFile, _ := al.dexer.compileDex(ctx, dexParams) 2345 uncompressed := true 2346 al.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), al.stubsJar, &uncompressed) 2347 dexOutputFile = al.hiddenAPIEncodeDex(ctx, dexOutputFile) 2348 al.dexJarFile = makeDexJarPathFromPath(dexOutputFile) 2349 2350 ctx.Phony(ctx.ModuleName(), al.stubsJar) 2351 2352 android.SetProvider(ctx, JavaInfoProvider, JavaInfo{ 2353 HeaderJars: android.PathsIfNonNil(al.stubsJar), 2354 ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar), 2355 ImplementationJars: android.PathsIfNonNil(al.stubsJar), 2356 AidlIncludeDirs: android.Paths{}, 2357 StubsLinkType: Stubs, 2358 // No aconfig libraries on api libraries 2359 }) 2360} 2361 2362func (al *ApiLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { 2363 return al.dexJarFile 2364} 2365 2366func (al *ApiLibrary) DexJarInstallPath() android.Path { 2367 return al.dexJarFile.Path() 2368} 2369 2370func (al *ApiLibrary) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { 2371 return nil 2372} 2373 2374// java_api_library constitutes the sdk, and does not build against one 2375func (al *ApiLibrary) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 2376 return android.SdkSpecNone 2377} 2378 2379// java_api_library is always at "current". Return FutureApiLevel 2380func (al *ApiLibrary) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 2381 return android.FutureApiLevel 2382} 2383 2384// implement the following interfaces for hiddenapi processing 2385var _ hiddenAPIModule = (*ApiLibrary)(nil) 2386var _ UsesLibraryDependency = (*ApiLibrary)(nil) 2387 2388// 2389// Java prebuilts 2390// 2391 2392type ImportProperties struct { 2393 Jars []string `android:"path,arch_variant"` 2394 2395 // The version of the SDK that the source prebuilt file was built against. Defaults to the 2396 // current version if not specified. 2397 Sdk_version *string 2398 2399 // The minimum version of the SDK that this module supports. Defaults to sdk_version if not 2400 // specified. 2401 Min_sdk_version *string 2402 2403 // The max sdk version placeholder used to replace maxSdkVersion attributes on permission 2404 // and uses-permission tags in manifest_fixer. 2405 Replace_max_sdk_version_placeholder *string 2406 2407 Installable *bool 2408 2409 // If not empty, classes are restricted to the specified packages and their sub-packages. 2410 Permitted_packages []string 2411 2412 // List of shared java libs that this module has dependencies to 2413 Libs []string 2414 2415 // List of static java libs that this module has dependencies to 2416 Static_libs []string 2417 2418 // List of files to remove from the jar file(s) 2419 Exclude_files []string 2420 2421 // List of directories to remove from the jar file(s) 2422 Exclude_dirs []string 2423 2424 // if set to true, run Jetifier against .jar file. Defaults to false. 2425 Jetifier *bool 2426 2427 // set the name of the output 2428 Stem *string 2429 2430 Aidl struct { 2431 // directories that should be added as include directories for any aidl sources of modules 2432 // that depend on this module, as well as to aidl for this module. 2433 Export_include_dirs []string 2434 } 2435 2436 // Name of the source soong module that gets shadowed by this prebuilt 2437 // If unspecified, follows the naming convention that the source module of 2438 // the prebuilt is Name() without "prebuilt_" prefix 2439 Source_module_name *string 2440 2441 // Non-nil if this java_import module was dynamically created by a java_sdk_library_import 2442 // The name is the undecorated name of the java_sdk_library as it appears in the blueprint file 2443 // (without any prebuilt_ prefix) 2444 Created_by_java_sdk_library_name *string `blueprint:"mutated"` 2445 2446 // Property signifying whether the module provides stubs jar or not. 2447 Is_stubs_module *bool 2448} 2449 2450type Import struct { 2451 android.ModuleBase 2452 android.DefaultableModuleBase 2453 android.ApexModuleBase 2454 prebuilt android.Prebuilt 2455 2456 // Functionality common to Module and Import. 2457 embeddableInModuleAndImport 2458 2459 hiddenAPI 2460 dexer 2461 dexpreopter 2462 2463 properties ImportProperties 2464 2465 // output file containing classes.dex and resources 2466 dexJarFile OptionalDexJarPath 2467 dexJarFileErr error 2468 dexJarInstallFile android.Path 2469 2470 combinedImplementationFile android.Path 2471 combinedHeaderFile android.Path 2472 classLoaderContexts dexpreopt.ClassLoaderContextMap 2473 exportAidlIncludeDirs android.Paths 2474 2475 hideApexVariantFromMake bool 2476 2477 sdkVersion android.SdkSpec 2478 minSdkVersion android.ApiLevel 2479 2480 stubsLinkType StubsLinkType 2481} 2482 2483var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil) 2484 2485func (j *Import) PermittedPackagesForUpdatableBootJars() []string { 2486 return j.properties.Permitted_packages 2487} 2488 2489func (j *Import) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 2490 return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version)) 2491} 2492 2493func (j *Import) SystemModules() string { 2494 return "none" 2495} 2496 2497func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 2498 if j.properties.Min_sdk_version != nil { 2499 return android.ApiLevelFrom(ctx, *j.properties.Min_sdk_version) 2500 } 2501 return j.SdkVersion(ctx).ApiLevel 2502} 2503 2504func (j *Import) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel { 2505 if j.properties.Replace_max_sdk_version_placeholder != nil { 2506 return android.ApiLevelFrom(ctx, *j.properties.Replace_max_sdk_version_placeholder) 2507 } 2508 // Default is PrivateApiLevel 2509 return android.SdkSpecPrivate.ApiLevel 2510} 2511 2512func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 2513 return j.SdkVersion(ctx).ApiLevel 2514} 2515 2516func (j *Import) Prebuilt() *android.Prebuilt { 2517 return &j.prebuilt 2518} 2519 2520func (j *Import) PrebuiltSrcs() []string { 2521 return j.properties.Jars 2522} 2523 2524func (j *Import) BaseModuleName() string { 2525 return proptools.StringDefault(j.properties.Source_module_name, j.ModuleBase.Name()) 2526} 2527 2528func (j *Import) Name() string { 2529 return j.prebuilt.Name(j.ModuleBase.Name()) 2530} 2531 2532func (j *Import) Stem() string { 2533 return proptools.StringDefault(j.properties.Stem, j.BaseModuleName()) 2534} 2535 2536func (j *Import) CreatedByJavaSdkLibraryName() *string { 2537 return j.properties.Created_by_java_sdk_library_name 2538} 2539 2540func (a *Import) JacocoReportClassesFile() android.Path { 2541 return nil 2542} 2543 2544func (j *Import) LintDepSets() LintDepSets { 2545 return LintDepSets{} 2546} 2547 2548func (j *Import) getStrictUpdatabilityLinting() bool { 2549 return false 2550} 2551 2552func (j *Import) setStrictUpdatabilityLinting(bool) { 2553} 2554 2555func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { 2556 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) 2557 ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...) 2558 2559 if ctx.Device() && Bool(j.dexProperties.Compile_dex) { 2560 sdkDeps(ctx, android.SdkContext(j), j.dexer) 2561 } 2562} 2563 2564func (j *Import) commonBuildActions(ctx android.ModuleContext) { 2565 j.sdkVersion = j.SdkVersion(ctx) 2566 j.minSdkVersion = j.MinSdkVersion(ctx) 2567 2568 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 2569 if !apexInfo.IsForPlatform() { 2570 j.hideApexVariantFromMake = true 2571 } 2572 2573 if ctx.Windows() { 2574 j.HideFromMake() 2575 } 2576 2577 if proptools.Bool(j.properties.Is_stubs_module) { 2578 j.stubsLinkType = Stubs 2579 } else { 2580 j.stubsLinkType = Implementation 2581 } 2582} 2583 2584func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2585 j.commonBuildActions(ctx) 2586 2587 j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap) 2588 2589 var flags javaBuilderFlags 2590 2591 j.collectTransitiveHeaderJars(ctx) 2592 var staticJars android.Paths 2593 var staticHeaderJars android.Paths 2594 ctx.VisitDirectDeps(func(module android.Module) { 2595 tag := ctx.OtherModuleDependencyTag(module) 2596 if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { 2597 switch tag { 2598 case libTag, sdkLibTag: 2599 flags.classpath = append(flags.classpath, dep.HeaderJars...) 2600 flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...) 2601 case staticLibTag: 2602 flags.classpath = append(flags.classpath, dep.HeaderJars...) 2603 staticJars = append(staticJars, dep.ImplementationAndResourcesJars...) 2604 staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...) 2605 case bootClasspathTag: 2606 flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...) 2607 } 2608 } else if dep, ok := module.(SdkLibraryDependency); ok { 2609 switch tag { 2610 case libTag, sdkLibTag: 2611 flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...) 2612 } 2613 } 2614 2615 addCLCFromDep(ctx, module, j.classLoaderContexts) 2616 }) 2617 2618 jars := android.PathsForModuleSrc(ctx, j.properties.Jars) 2619 jarName := j.Stem() + ".jar" 2620 2621 // Always pass the input jars to TransformJarsToJar, even if there is only a single jar, we need the output 2622 // file of the module to be named jarName. 2623 outputFile := android.PathForModuleOut(ctx, "combined", jarName) 2624 implementationJars := append(slices.Clone(jars), staticJars...) 2625 TransformJarsToJar(ctx, outputFile, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{}, 2626 false, j.properties.Exclude_files, j.properties.Exclude_dirs) 2627 2628 // If no dependencies have separate header jars then there is no need to create a separate 2629 // header jar for this module. 2630 reuseImplementationJarAsHeaderJar := slices.Equal(staticJars, staticHeaderJars) 2631 2632 var headerOutputFile android.ModuleOutPath 2633 if reuseImplementationJarAsHeaderJar { 2634 headerOutputFile = outputFile 2635 } else { 2636 headerJars := append(slices.Clone(jars), staticHeaderJars...) 2637 headerOutputFile = android.PathForModuleOut(ctx, "turbine-combined", jarName) 2638 TransformJarsToJar(ctx, headerOutputFile, "combine prebuilt header jars", headerJars, android.OptionalPath{}, 2639 false, j.properties.Exclude_files, j.properties.Exclude_dirs) 2640 } 2641 2642 if Bool(j.properties.Jetifier) { 2643 inputFile := outputFile 2644 outputFile = android.PathForModuleOut(ctx, "jetifier", jarName) 2645 TransformJetifier(ctx, outputFile, inputFile) 2646 2647 if !reuseImplementationJarAsHeaderJar { 2648 headerInputFile := headerOutputFile 2649 headerOutputFile = android.PathForModuleOut(ctx, "jetifier-headers", jarName) 2650 TransformJetifier(ctx, headerOutputFile, headerInputFile) 2651 } else { 2652 headerOutputFile = outputFile 2653 } 2654 } 2655 2656 // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource. 2657 // Also strip the relative path from the header output file so that the reuseImplementationJarAsHeaderJar check 2658 // in a module that depends on this module considers them equal. 2659 j.combinedHeaderFile = headerOutputFile.WithoutRel() 2660 j.combinedImplementationFile = outputFile.WithoutRel() 2661 2662 j.maybeInstall(ctx, jarName, outputFile) 2663 2664 j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) 2665 2666 if ctx.Device() { 2667 // If this is a variant created for a prebuilt_apex then use the dex implementation jar 2668 // obtained from the associated deapexer module. 2669 ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 2670 if ai.ForPrebuiltApex { 2671 // Get the path of the dex implementation jar from the `deapexer` module. 2672 di, err := android.FindDeapexerProviderForModule(ctx) 2673 if err != nil { 2674 // An error was found, possibly due to multiple apexes in the tree that export this library 2675 // Defer the error till a client tries to call DexJarBuildPath 2676 j.dexJarFileErr = err 2677 j.initHiddenAPIError(err) 2678 return 2679 } 2680 dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(j.BaseModuleName()) 2681 if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil { 2682 dexJarFile := makeDexJarPathFromPath(dexOutputPath) 2683 j.dexJarFile = dexJarFile 2684 installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, ApexRootRelativePathToJavaLib(j.BaseModuleName())) 2685 j.dexJarInstallFile = installPath 2686 2687 j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), installPath) 2688 setUncompressDex(ctx, &j.dexpreopter, &j.dexer) 2689 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 2690 2691 if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil { 2692 j.dexpreopter.inputProfilePathOnHost = profilePath 2693 } 2694 2695 // Initialize the hiddenapi structure. 2696 j.initHiddenAPI(ctx, dexJarFile, outputFile, j.dexProperties.Uncompress_dex) 2697 } else { 2698 // This should never happen as a variant for a prebuilt_apex is only created if the 2699 // prebuilt_apex has been configured to export the java library dex file. 2700 ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName()) 2701 } 2702 } else if Bool(j.dexProperties.Compile_dex) { 2703 sdkDep := decodeSdkDep(ctx, android.SdkContext(j)) 2704 if sdkDep.invalidVersion { 2705 ctx.AddMissingDependencies(sdkDep.bootclasspath) 2706 ctx.AddMissingDependencies(sdkDep.java9Classpath) 2707 } else if sdkDep.useFiles { 2708 // sdkDep.jar is actually equivalent to turbine header.jar. 2709 flags.classpath = append(flags.classpath, sdkDep.jars...) 2710 } 2711 2712 // Dex compilation 2713 2714 j.dexpreopter.installPath = j.dexpreopter.getInstallPath( 2715 ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", jarName)) 2716 setUncompressDex(ctx, &j.dexpreopter, &j.dexer) 2717 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 2718 2719 var dexOutputFile android.OutputPath 2720 dexParams := &compileDexParams{ 2721 flags: flags, 2722 sdkVersion: j.SdkVersion(ctx), 2723 minSdkVersion: j.MinSdkVersion(ctx), 2724 classesJar: outputFile, 2725 jarName: jarName, 2726 } 2727 2728 dexOutputFile, _ = j.dexer.compileDex(ctx, dexParams) 2729 if ctx.Failed() { 2730 return 2731 } 2732 2733 // Initialize the hiddenapi structure. 2734 j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex) 2735 2736 // Encode hidden API flags in dex file. 2737 dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) 2738 2739 j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) 2740 j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName) 2741 } 2742 } 2743 2744 android.SetProvider(ctx, JavaInfoProvider, JavaInfo{ 2745 HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile), 2746 TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars, 2747 TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars, 2748 ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedImplementationFile), 2749 ImplementationJars: android.PathsIfNonNil(j.combinedImplementationFile), 2750 AidlIncludeDirs: j.exportAidlIncludeDirs, 2751 StubsLinkType: j.stubsLinkType, 2752 // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts 2753 }) 2754} 2755 2756func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) { 2757 if !Bool(j.properties.Installable) { 2758 return 2759 } 2760 2761 var installDir android.InstallPath 2762 if ctx.InstallInTestcases() { 2763 var archDir string 2764 if !ctx.Host() { 2765 archDir = ctx.DeviceConfig().DeviceArch() 2766 } 2767 installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir) 2768 } else { 2769 installDir = android.PathForModuleInstall(ctx, "framework") 2770 } 2771 ctx.InstallFile(installDir, jarName, outputFile) 2772} 2773 2774func (j *Import) OutputFiles(tag string) (android.Paths, error) { 2775 switch tag { 2776 case "", ".jar": 2777 return android.Paths{j.combinedImplementationFile}, nil 2778 default: 2779 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 2780 } 2781} 2782 2783var _ android.OutputFileProducer = (*Import)(nil) 2784 2785func (j *Import) HeaderJars() android.Paths { 2786 return android.PathsIfNonNil(j.combinedHeaderFile) 2787} 2788 2789func (j *Import) ImplementationAndResourcesJars() android.Paths { 2790 return android.PathsIfNonNil(j.combinedImplementationFile) 2791} 2792 2793func (j *Import) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { 2794 if j.dexJarFileErr != nil { 2795 ctx.ModuleErrorf(j.dexJarFileErr.Error()) 2796 } 2797 return j.dexJarFile 2798} 2799 2800func (j *Import) DexJarInstallPath() android.Path { 2801 return j.dexJarInstallFile 2802} 2803 2804func (j *Import) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { 2805 return j.classLoaderContexts 2806} 2807 2808var _ android.ApexModule = (*Import)(nil) 2809 2810// Implements android.ApexModule 2811func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 2812 return j.depIsInSameApex(ctx, dep) 2813} 2814 2815// Implements android.ApexModule 2816func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 2817 sdkVersion android.ApiLevel) error { 2818 sdkVersionSpec := j.SdkVersion(ctx) 2819 minSdkVersion := j.MinSdkVersion(ctx) 2820 if !minSdkVersion.Specified() { 2821 return fmt.Errorf("min_sdk_version is not specified") 2822 } 2823 // If the module is compiling against core (via sdk_version), skip comparison check. 2824 if sdkVersionSpec.Kind == android.SdkCore { 2825 return nil 2826 } 2827 if minSdkVersion.GreaterThan(sdkVersion) { 2828 return fmt.Errorf("newer SDK(%v)", minSdkVersion) 2829 } 2830 return nil 2831} 2832 2833// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or 2834// java_sdk_library_import with the specified base module name requires to be exported from a 2835// prebuilt_apex/apex_set. 2836func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []string { 2837 dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(name) 2838 // Add the dex implementation jar to the set of exported files. 2839 files := []string{ 2840 dexJarFileApexRootRelative, 2841 } 2842 if BoolDefault(d.importDexpreoptProperties.Dex_preopt.Profile_guided, false) { 2843 files = append(files, dexJarFileApexRootRelative+".prof") 2844 } 2845 return files 2846} 2847 2848// ApexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for 2849// the java library with the specified name. 2850func ApexRootRelativePathToJavaLib(name string) string { 2851 return filepath.Join("javalib", name+".jar") 2852} 2853 2854var _ android.RequiredFilesFromPrebuiltApex = (*Import)(nil) 2855 2856func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string { 2857 name := j.BaseModuleName() 2858 return requiredFilesFromPrebuiltApexForImport(name, &j.dexpreopter) 2859} 2860 2861func (j *Import) UseProfileGuidedDexpreopt() bool { 2862 return proptools.Bool(j.importDexpreoptProperties.Dex_preopt.Profile_guided) 2863} 2864 2865// Add compile time check for interface implementation 2866var _ android.IDEInfo = (*Import)(nil) 2867var _ android.IDECustomizedModuleName = (*Import)(nil) 2868 2869// Collect information for opening IDE project files in java/jdeps.go. 2870 2871func (j *Import) IDEInfo(dpInfo *android.IdeInfo) { 2872 dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...) 2873} 2874 2875func (j *Import) IDECustomizedModuleName() string { 2876 // TODO(b/113562217): Extract the base module name from the Import name, often the Import name 2877 // has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better 2878 // solution to get the Import name. 2879 return android.RemoveOptionalPrebuiltPrefix(j.Name()) 2880} 2881 2882var _ android.PrebuiltInterface = (*Import)(nil) 2883 2884func (j *Import) IsInstallable() bool { 2885 return Bool(j.properties.Installable) 2886} 2887 2888var _ DexpreopterInterface = (*Import)(nil) 2889 2890// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module. 2891// 2892// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were 2893// compiled against an Android classpath. 2894// 2895// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one 2896// for host modules. 2897func ImportFactory() android.Module { 2898 module := &Import{} 2899 2900 module.AddProperties( 2901 &module.properties, 2902 &module.dexer.dexProperties, 2903 &module.importDexpreoptProperties, 2904 ) 2905 2906 module.initModuleAndImport(module) 2907 2908 module.dexProperties.Optimize.EnabledByDefault = false 2909 2910 android.InitPrebuiltModule(module, &module.properties.Jars) 2911 android.InitApexModule(module) 2912 InitJavaModule(module, android.HostAndDeviceSupported) 2913 return module 2914} 2915 2916// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host 2917// module. 2918// 2919// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were 2920// compiled against a host bootclasspath. 2921func ImportFactoryHost() android.Module { 2922 module := &Import{} 2923 2924 module.AddProperties(&module.properties) 2925 2926 android.InitPrebuiltModule(module, &module.properties.Jars) 2927 android.InitApexModule(module) 2928 InitJavaModule(module, android.HostSupported) 2929 return module 2930} 2931 2932// dex_import module 2933 2934type DexImportProperties struct { 2935 Jars []string `android:"path"` 2936 2937 // set the name of the output 2938 Stem *string 2939} 2940 2941type DexImport struct { 2942 android.ModuleBase 2943 android.DefaultableModuleBase 2944 android.ApexModuleBase 2945 prebuilt android.Prebuilt 2946 2947 properties DexImportProperties 2948 2949 dexJarFile OptionalDexJarPath 2950 2951 dexpreopter 2952 2953 hideApexVariantFromMake bool 2954} 2955 2956func (j *DexImport) Prebuilt() *android.Prebuilt { 2957 return &j.prebuilt 2958} 2959 2960func (j *DexImport) PrebuiltSrcs() []string { 2961 return j.properties.Jars 2962} 2963 2964func (j *DexImport) Name() string { 2965 return j.prebuilt.Name(j.ModuleBase.Name()) 2966} 2967 2968func (j *DexImport) Stem() string { 2969 return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) 2970} 2971 2972func (a *DexImport) JacocoReportClassesFile() android.Path { 2973 return nil 2974} 2975 2976func (a *DexImport) LintDepSets() LintDepSets { 2977 return LintDepSets{} 2978} 2979 2980func (j *DexImport) IsInstallable() bool { 2981 return true 2982} 2983 2984func (j *DexImport) getStrictUpdatabilityLinting() bool { 2985 return false 2986} 2987 2988func (j *DexImport) setStrictUpdatabilityLinting(bool) { 2989} 2990 2991func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2992 if len(j.properties.Jars) != 1 { 2993 ctx.PropertyErrorf("jars", "exactly one jar must be provided") 2994 } 2995 2996 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 2997 if !apexInfo.IsForPlatform() { 2998 j.hideApexVariantFromMake = true 2999 } 3000 3001 j.dexpreopter.installPath = j.dexpreopter.getInstallPath( 3002 ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) 3003 j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &j.dexpreopter) 3004 3005 inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars") 3006 dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar") 3007 3008 if j.dexpreopter.uncompressedDex { 3009 rule := android.NewRuleBuilder(pctx, ctx) 3010 3011 temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned") 3012 rule.Temporary(temporary) 3013 3014 // use zip2zip to uncompress classes*.dex files 3015 rule.Command(). 3016 BuiltTool("zip2zip"). 3017 FlagWithInput("-i ", inputJar). 3018 FlagWithOutput("-o ", temporary). 3019 FlagWithArg("-0 ", "'classes*.dex'") 3020 3021 // use zipalign to align uncompressed classes*.dex files 3022 rule.Command(). 3023 BuiltTool("zipalign"). 3024 Flag("-f"). 3025 Text("4"). 3026 Input(temporary). 3027 Output(dexOutputFile) 3028 3029 rule.DeleteTemporaryFiles() 3030 3031 rule.Build("uncompress_dex", "uncompress dex") 3032 } else { 3033 ctx.Build(pctx, android.BuildParams{ 3034 Rule: android.Cp, 3035 Input: inputJar, 3036 Output: dexOutputFile, 3037 }) 3038 } 3039 3040 j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) 3041 3042 j.dexpreopt(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexOutputFile) 3043 3044 if apexInfo.IsForPlatform() { 3045 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), 3046 j.Stem()+".jar", dexOutputFile) 3047 } 3048} 3049 3050func (j *DexImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { 3051 return j.dexJarFile 3052} 3053 3054var _ android.ApexModule = (*DexImport)(nil) 3055 3056// Implements android.ApexModule 3057func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 3058 sdkVersion android.ApiLevel) error { 3059 // we don't check prebuilt modules for sdk_version 3060 return nil 3061} 3062 3063// dex_import imports a `.jar` file containing classes.dex files. 3064// 3065// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed 3066// to the device. 3067func DexImportFactory() android.Module { 3068 module := &DexImport{} 3069 3070 module.AddProperties(&module.properties) 3071 3072 android.InitPrebuiltModule(module, &module.properties.Jars) 3073 android.InitApexModule(module) 3074 InitJavaModule(module, android.DeviceSupported) 3075 return module 3076} 3077 3078// Defaults 3079type Defaults struct { 3080 android.ModuleBase 3081 android.DefaultsModuleBase 3082 android.ApexModuleBase 3083} 3084 3085// java_defaults provides a set of properties that can be inherited by other java or android modules. 3086// 3087// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`. Each 3088// property in the defaults module that exists in the depending module will be prepended to the depending module's 3089// value for that property. 3090// 3091// Example: 3092// 3093// java_defaults { 3094// name: "example_defaults", 3095// srcs: ["common/**/*.java"], 3096// javacflags: ["-Xlint:all"], 3097// aaptflags: ["--auto-add-overlay"], 3098// } 3099// 3100// java_library { 3101// name: "example", 3102// defaults: ["example_defaults"], 3103// srcs: ["example/**/*.java"], 3104// } 3105// 3106// is functionally identical to: 3107// 3108// java_library { 3109// name: "example", 3110// srcs: [ 3111// "common/**/*.java", 3112// "example/**/*.java", 3113// ], 3114// javacflags: ["-Xlint:all"], 3115// } 3116func DefaultsFactory() android.Module { 3117 module := &Defaults{} 3118 3119 module.AddProperties( 3120 &CommonProperties{}, 3121 &DeviceProperties{}, 3122 &OverridableProperties{}, 3123 &DexProperties{}, 3124 &DexpreoptProperties{}, 3125 &android.ProtoProperties{}, 3126 &aaptProperties{}, 3127 &androidLibraryProperties{}, 3128 &appProperties{}, 3129 &appTestProperties{}, 3130 &overridableAppProperties{}, 3131 &hostTestProperties{}, 3132 &testProperties{}, 3133 &ImportProperties{}, 3134 &AARImportProperties{}, 3135 &sdkLibraryProperties{}, 3136 &commonToSdkLibraryAndImportProperties{}, 3137 &DexImportProperties{}, 3138 &android.ApexProperties{}, 3139 &RuntimeResourceOverlayProperties{}, 3140 &LintProperties{}, 3141 &appTestHelperAppProperties{}, 3142 &JavaApiLibraryProperties{}, 3143 &bootclasspathFragmentProperties{}, 3144 &SourceOnlyBootclasspathProperties{}, 3145 ) 3146 3147 android.InitDefaultsModule(module) 3148 return module 3149} 3150 3151func kytheExtractJavaFactory() android.Singleton { 3152 return &kytheExtractJavaSingleton{} 3153} 3154 3155type kytheExtractJavaSingleton struct { 3156} 3157 3158func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) { 3159 var xrefTargets android.Paths 3160 ctx.VisitAllModules(func(module android.Module) { 3161 if javaModule, ok := module.(xref); ok { 3162 xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...) 3163 } 3164 }) 3165 // TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets 3166 if len(xrefTargets) > 0 { 3167 ctx.Phony("xref_java", xrefTargets...) 3168 } 3169} 3170 3171var Bool = proptools.Bool 3172var BoolDefault = proptools.BoolDefault 3173var String = proptools.String 3174var inList = android.InList[string] 3175 3176// Add class loader context (CLC) of a given dependency to the current CLC. 3177func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, 3178 clcMap dexpreopt.ClassLoaderContextMap) { 3179 3180 dep, ok := depModule.(UsesLibraryDependency) 3181 if !ok { 3182 return 3183 } 3184 3185 depName := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(depModule)) 3186 3187 var sdkLib *string 3188 if lib, ok := depModule.(SdkLibraryDependency); ok && lib.sharedLibrary() { 3189 // A shared SDK library. This should be added as a top-level CLC element. 3190 sdkLib = &depName 3191 } else if ulib, ok := depModule.(ProvidesUsesLib); ok { 3192 // A non-SDK library disguised as an SDK library by the means of `provides_uses_lib` 3193 // property. This should be handled in the same way as a shared SDK library. 3194 sdkLib = ulib.ProvidesUsesLib() 3195 } 3196 3197 depTag := ctx.OtherModuleDependencyTag(depModule) 3198 if IsLibDepTag(depTag) { 3199 // Ok, propagate <uses-library> through non-static library dependencies. 3200 } else if tag, ok := depTag.(usesLibraryDependencyTag); ok && tag.sdkVersion == dexpreopt.AnySdkVersion { 3201 // Ok, propagate <uses-library> through non-compatibility <uses-library> dependencies. 3202 } else if depTag == staticLibTag { 3203 // Propagate <uses-library> through static library dependencies, unless it is a component 3204 // library (such as stubs). Component libraries have a dependency on their SDK library, 3205 // which should not be pulled just because of a static component library. 3206 if sdkLib != nil { 3207 return 3208 } 3209 } else { 3210 // Don't propagate <uses-library> for other dependency tags. 3211 return 3212 } 3213 3214 // If this is an SDK (or SDK-like) library, then it should be added as a node in the CLC tree, 3215 // and its CLC should be added as subtree of that node. Otherwise the library is not a 3216 // <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies 3217 // from its CLC should be added to the current CLC. 3218 if sdkLib != nil { 3219 optional := false 3220 if module, ok := ctx.Module().(ModuleWithUsesLibrary); ok { 3221 if android.InList(*sdkLib, module.UsesLibrary().usesLibraryProperties.Optional_uses_libs) { 3222 optional = true 3223 } 3224 } 3225 clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional, 3226 dep.DexJarBuildPath(ctx).PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) 3227 } else { 3228 clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) 3229 } 3230} 3231 3232func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.Module, 3233 usesLibrary *usesLibrary) { 3234 3235 dep, ok := depModule.(ModuleWithUsesLibrary) 3236 if !ok { 3237 return 3238 } 3239 3240 for _, lib := range dep.UsesLibrary().usesLibraryProperties.Missing_optional_uses_libs { 3241 if !android.InList(lib, usesLibrary.usesLibraryProperties.Missing_optional_uses_libs) { 3242 usesLibrary.usesLibraryProperties.Missing_optional_uses_libs = 3243 append(usesLibrary.usesLibraryProperties.Missing_optional_uses_libs, lib) 3244 } 3245 } 3246} 3247 3248type JavaApiContributionImport struct { 3249 JavaApiContribution 3250 3251 prebuilt android.Prebuilt 3252 prebuiltProperties javaApiContributionImportProperties 3253} 3254 3255type javaApiContributionImportProperties struct { 3256 // Name of the source soong module that gets shadowed by this prebuilt 3257 // If unspecified, follows the naming convention that the source module of 3258 // the prebuilt is Name() without "prebuilt_" prefix 3259 Source_module_name *string 3260 3261 // Non-nil if this java_import module was dynamically created by a java_sdk_library_import 3262 // The name is the undecorated name of the java_sdk_library as it appears in the blueprint file 3263 // (without any prebuilt_ prefix) 3264 Created_by_java_sdk_library_name *string `blueprint:"mutated"` 3265} 3266 3267func ApiContributionImportFactory() android.Module { 3268 module := &JavaApiContributionImport{} 3269 android.InitAndroidModule(module) 3270 android.InitDefaultableModule(module) 3271 android.InitPrebuiltModule(module, &[]string{""}) 3272 module.AddProperties(&module.properties, &module.prebuiltProperties) 3273 module.AddProperties(&module.sdkLibraryComponentProperties) 3274 return module 3275} 3276 3277func (module *JavaApiContributionImport) Prebuilt() *android.Prebuilt { 3278 return &module.prebuilt 3279} 3280 3281func (module *JavaApiContributionImport) Name() string { 3282 return module.prebuilt.Name(module.ModuleBase.Name()) 3283} 3284 3285func (j *JavaApiContributionImport) BaseModuleName() string { 3286 return proptools.StringDefault(j.prebuiltProperties.Source_module_name, j.ModuleBase.Name()) 3287} 3288 3289func (j *JavaApiContributionImport) CreatedByJavaSdkLibraryName() *string { 3290 return j.prebuiltProperties.Created_by_java_sdk_library_name 3291} 3292 3293func (ap *JavaApiContributionImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 3294 ap.JavaApiContribution.GenerateAndroidBuildActions(ctx) 3295} 3296