diff options
Diffstat (limited to 'java/java.go')
| -rw-r--r-- | java/java.go | 1784 |
1 files changed, 849 insertions, 935 deletions
diff --git a/java/java.go b/java/java.go index bc240508b..95f4fd892 100644 --- a/java/java.go +++ b/java/java.go @@ -21,13 +21,12 @@ package java import ( "fmt" "path/filepath" + "slices" "sort" "strings" - "android/soong/bazel" - "android/soong/bazel/cquery" "android/soong/remoteexec" - "android/soong/ui/metrics/bp2build_metrics_proto" + "android/soong/testing" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -76,7 +75,6 @@ func registerJavaBuildComponents(ctx android.RegistrationContext) { ctx.BottomUp("jacoco_deps", jacocoDepsMutator).Parallel() }) - ctx.RegisterParallelSingletonType("logtags", LogtagsSingleton) ctx.RegisterParallelSingletonType("kythe_java_extract", kytheExtractJavaFactory) } @@ -84,11 +82,19 @@ func RegisterJavaSdkMemberTypes() { // Register sdk member types. android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) android.RegisterSdkMemberType(javaLibsSdkMemberType) - android.RegisterSdkMemberType(javaBootLibsSdkMemberType) - android.RegisterSdkMemberType(javaSystemserverLibsSdkMemberType) + android.RegisterSdkMemberType(JavaBootLibsSdkMemberType) + android.RegisterSdkMemberType(JavaSystemserverLibsSdkMemberType) android.RegisterSdkMemberType(javaTestSdkMemberType) } +type StubsLinkType int + +const ( + Unknown StubsLinkType = iota + Stubs + Implementation +) + var ( // Supports adding java header libraries to module_exports and sdk. javaHeaderLibsSdkMemberType = &librarySdkMemberType{ @@ -148,7 +154,7 @@ var ( // either java_libs, or java_header_libs would end up exporting more information than was strictly // necessary. The java_boot_libs property to allow those modules to be exported as part of the // sdk/module_exports without exposing any unnecessary information. - javaBootLibsSdkMemberType = &librarySdkMemberType{ + JavaBootLibsSdkMemberType = &librarySdkMemberType{ android.SdkMemberTypeBase{ PropertyName: "java_boot_libs", SupportsSdk: true, @@ -187,7 +193,7 @@ var ( // either java_libs, or java_header_libs would end up exporting more information than was strictly // necessary. The java_systemserver_libs property to allow those modules to be exported as part of // the sdk/module_exports without exposing any unnecessary information. - javaSystemserverLibsSdkMemberType = &librarySdkMemberType{ + JavaSystemserverLibsSdkMemberType = &librarySdkMemberType{ android.SdkMemberTypeBase{ PropertyName: "java_systemserver_libs", SupportsSdk: true, @@ -242,31 +248,46 @@ type ProguardSpecInfo struct { UnconditionallyExportedProguardFlags *android.DepSet[android.Path] } -var ProguardSpecInfoProvider = blueprint.NewProvider(ProguardSpecInfo{}) +var ProguardSpecInfoProvider = blueprint.NewProvider[ProguardSpecInfo]() // JavaInfo contains information about a java module for use by modules that depend on it. type JavaInfo struct { // HeaderJars is a list of jars that can be passed as the javac classpath in order to link // against this module. If empty, ImplementationJars should be used instead. + // Unlike LocalHeaderJars, HeaderJars includes classes from static dependencies. HeaderJars android.Paths + RepackagedHeaderJars android.Paths + // set of header jars for all transitive libs deps - TransitiveLibsHeaderJars *android.DepSet[android.Path] + TransitiveLibsHeaderJarsForR8 *android.DepSet[android.Path] // set of header jars for all transitive static libs deps + TransitiveStaticLibsHeaderJarsForR8 *android.DepSet[android.Path] + + // depset of header jars for this module and all transitive static dependencies TransitiveStaticLibsHeaderJars *android.DepSet[android.Path] + // depset of implementation jars for this module and all transitive static dependencies + TransitiveStaticLibsImplementationJars *android.DepSet[android.Path] + + // depset of resource jars for this module and all transitive static dependencies + TransitiveStaticLibsResourceJars *android.DepSet[android.Path] + // ImplementationAndResourceJars is a list of jars that contain the implementations of classes // in the module as well as any resources included in the module. ImplementationAndResourcesJars android.Paths // ImplementationJars is a list of jars that contain the implementations of classes in the - //module. + // module. ImplementationJars android.Paths // ResourceJars is a list of jars that contain the resources included in the module. ResourceJars android.Paths + // LocalHeaderJars is a list of jars that contain classes from this module, but not from any static dependencies. + LocalHeaderJars android.Paths + // AidlIncludeDirs is a list of directories that should be passed to the aidl tool when // depending on this module. AidlIncludeDirs android.Paths @@ -297,27 +318,27 @@ type JavaInfo struct { // instrumented by jacoco. JacocoReportClassesFile android.Path - // set of aconfig flags for all transitive libs deps - // TODO(joeo): It would be nice if this were over in the aconfig package instead of here. - // In order to do that, generated_java_library would need a way doing - // collectTransitiveAconfigFiles with one of the callbacks, and having that automatically - // propagated. If we were to clean up more of the stuff on JavaInfo that's not part of - // core java rules (e.g. AidlIncludeDirs), then maybe adding more framework to do that would be - // worth it. - TransitiveAconfigFiles *android.DepSet[android.Path] + // StubsLinkType provides information about whether the provided jars are stub jars or + // implementation jars. If the provider is set by java_sdk_library, the link type is "unknown" + // and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...) + StubsLinkType StubsLinkType + + // AconfigIntermediateCacheOutputPaths is a path to the cache files collected from the + // java_aconfig_library modules that are statically linked to this module. + AconfigIntermediateCacheOutputPaths android.Paths } -var JavaInfoProvider = blueprint.NewProvider(JavaInfo{}) +var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]() // SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to // the sysprop implementation library. type SyspropPublicStubInfo struct { // JavaInfo is the JavaInfoProvider of the sysprop public stub library that corresponds to // the sysprop implementation library. - JavaInfo JavaInfo + JavaInfo *JavaInfo } -var SyspropPublicStubInfoProvider = blueprint.NewProvider(SyspropPublicStubInfo{}) +var SyspropPublicStubInfoProvider = blueprint.NewProvider[SyspropPublicStubInfo]() // Methods that need to be implemented for a module that is added to apex java_libs property. type ApexDependency interface { @@ -327,7 +348,7 @@ type ApexDependency interface { // Provides build path and install path to DEX jars. type UsesLibraryDependency interface { - DexJarBuildPath() OptionalDexJarPath + DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath DexJarInstallPath() android.Path ClassLoaderContexts() dexpreopt.ClassLoaderContextMap } @@ -341,6 +362,12 @@ func (j *Module) XrefJavaFiles() android.Paths { return j.kytheFiles } +func (d dependencyTag) PropagateAconfigValidation() bool { + return d.static +} + +var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{} + type dependencyTag struct { blueprint.BaseDependencyTag name string @@ -350,14 +377,16 @@ type dependencyTag struct { // True if the dependency is a toolchain, for example an annotation processor. toolchain bool + + static bool + + installable bool } -// installDependencyTag is a dependency tag that is annotated to cause the installed files of the -// dependency to be installed when the parent module is installed. -type installDependencyTag struct { - blueprint.BaseDependencyTag - android.InstallAlwaysNeededDependencyTag - name string +var _ android.InstallNeededDependencyTag = (*dependencyTag)(nil) + +func (d dependencyTag) InstallDepNeeded() bool { + return d.installable } func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation { @@ -389,13 +418,13 @@ func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDepe } func IsJniDepTag(depTag blueprint.DependencyTag) bool { - return depTag == jniLibTag + return depTag == jniLibTag || depTag == jniInstallTag } var ( dataNativeBinsTag = dependencyTag{name: "dataNativeBins"} dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"} - staticLibTag = dependencyTag{name: "staticlib"} + staticLibTag = dependencyTag{name: "staticlib", static: true} libTag = dependencyTag{name: "javalib", runtimeLinked: true} sdkLibTag = dependencyTag{name: "sdklib", runtimeLinked: true} java9LibTag = dependencyTag{name: "java9lib", runtimeLinked: true} @@ -405,8 +434,6 @@ var ( bootClasspathTag = dependencyTag{name: "bootclasspath", runtimeLinked: true} systemModulesTag = dependencyTag{name: "system modules", runtimeLinked: true} frameworkResTag = dependencyTag{name: "framework-res"} - kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib", runtimeLinked: true} - kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations", runtimeLinked: true} kotlinPluginTag = dependencyTag{name: "kotlin-plugin", toolchain: true} proguardRaiseTag = dependencyTag{name: "proguard-raise"} certificateTag = dependencyTag{name: "certificate"} @@ -416,9 +443,9 @@ var ( r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true} syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} javaApiContributionTag = dependencyTag{name: "java-api-contribution"} - depApiSrcsTag = dependencyTag{name: "dep-api-srcs"} - jniInstallTag = installDependencyTag{name: "jni install"} - binaryInstallTag = installDependencyTag{name: "binary install"} + aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"} + jniInstallTag = dependencyTag{name: "jni install", runtimeLinked: true, installable: true} + binaryInstallTag = dependencyTag{name: "binary install", runtimeLinked: true, installable: true} usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false) usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true) usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true) @@ -426,6 +453,28 @@ var ( usesLibCompat30OptTag = makeUsesLibraryDependencyTag(30, true) ) +// A list of tags for deps used for compiling a module. +// Any dependency tags that modifies the following properties of `deps` in `Module.collectDeps` should be +// added to this list: +// - bootClasspath +// - classpath +// - java9Classpath +// - systemModules +// - kotlin deps... +var ( + compileDependencyTags = []blueprint.DependencyTag{ + sdkLibTag, + libTag, + staticLibTag, + bootClasspathTag, + systemModulesTag, + java9LibTag, + kotlinPluginTag, + syspropPublicStubDepTag, + instrumentationForTag, + } +) + func IsLibDepTag(depTag blueprint.DependencyTag) bool { return depTag == libTag || depTag == sdkLibTag } @@ -474,6 +523,7 @@ type jniLib struct { coverageFile android.OptionalPath unstrippedFile android.Path partition string + installPaths android.InstallPaths } func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) { @@ -516,7 +566,7 @@ type deps struct { // are provided by systemModules. java9Classpath classpath - processorPath classpath + processorPath classpath `` errorProneProcessorPath classpath processorClasses []string staticJars android.Paths @@ -527,11 +577,14 @@ type deps struct { srcJars android.Paths systemModules *systemModules aidlPreprocess android.OptionalPath - kotlinStdlib android.Paths - kotlinAnnotations android.Paths kotlinPlugins android.Paths + aconfigProtoFiles android.Paths disableTurbine bool + + transitiveStaticLibsHeaderJars []*android.DepSet[android.Path] + transitiveStaticLibsImplementationJars []*android.DepSet[android.Path] + transitiveStaticLibsResourceJars []*android.DepSet[android.Path] } func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) { @@ -548,6 +601,12 @@ func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext an return normalizeJavaVersion(ctx, javaVersion) } else if ctx.Device() { return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx)) + } else if ctx.Config().TargetsJava21() { + // Temporary experimental flag to be able to try and build with + // java version 21 options. The flag, if used, just sets Java + // 21 as the default version, leaving any components that + // target an older version intact. + return JAVA_VERSION_21 } else { return JAVA_VERSION_17 } @@ -568,14 +627,17 @@ const ( JAVA_VERSION_9 = 9 JAVA_VERSION_11 = 11 JAVA_VERSION_17 = 17 + JAVA_VERSION_21 = 21 ) func (v javaVersion) String() string { switch v { case JAVA_VERSION_6: - return "1.6" + // Java version 1.6 no longer supported, bumping to 1.8 + return "1.8" case JAVA_VERSION_7: - return "1.7" + // Java version 1.7 no longer supported, bumping to 1.8 + return "1.8" case JAVA_VERSION_8: return "1.8" case JAVA_VERSION_9: @@ -584,6 +646,8 @@ func (v javaVersion) String() string { return "11" case JAVA_VERSION_17: return "17" + case JAVA_VERSION_21: + return "21" default: return "unsupported" } @@ -592,10 +656,12 @@ func (v javaVersion) String() string { func (v javaVersion) StringForKotlinc() string { // $ ./external/kotlinc/bin/kotlinc -jvm-target foo // error: unknown JVM target version: foo - // Supported versions: 1.6, 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17 + // Supported versions: 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17 switch v { + case JAVA_VERSION_6: + return "1.8" case JAVA_VERSION_7: - return "1.6" + return "1.8" case JAVA_VERSION_9: return "9" default: @@ -611,9 +677,11 @@ func (v javaVersion) usesJavaModules() bool { func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion { switch javaVersion { case "1.6", "6": - return JAVA_VERSION_6 + // Java version 1.6 no longer supported, bumping to 1.8 + return JAVA_VERSION_8 case "1.7", "7": - return JAVA_VERSION_7 + // Java version 1.7 no longer supported, bumping to 1.8 + return JAVA_VERSION_8 case "1.8", "8": return JAVA_VERSION_8 case "1.9", "9": @@ -622,6 +690,8 @@ func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) jav return JAVA_VERSION_11 case "17": return JAVA_VERSION_17 + case "21": + return JAVA_VERSION_21 case "10", "12", "13", "14", "15", "16": ctx.PropertyErrorf("java_version", "Java language level %s is not supported", javaVersion) return JAVA_VERSION_UNSUPPORTED @@ -638,13 +708,17 @@ func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) jav type Library struct { Module - exportedProguardFlagFiles android.Paths + combinedExportedProguardFlagsFile android.Path - InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths) + InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.InstallPaths) } var _ android.ApexModule = (*Library)(nil) +func (j *Library) CheckDepsMinSdkVersion(ctx android.ModuleContext) { + CheckMinSdkVersion(ctx, j) +} + // Provides access to the list of permitted packages from apex boot jars. type PermittedPackagesForUpdatableBootJars interface { PermittedPackagesForUpdatableBootJars() []string @@ -656,9 +730,9 @@ func (j *Library) PermittedPackagesForUpdatableBootJars() []string { return j.properties.Permitted_packages } -func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool { +func shouldUncompressDex(ctx android.ModuleContext, libName string, dexpreopter *dexpreopter) bool { // Store uncompressed (and aligned) any dex files from jars in APEXes. - if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() { + if apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider); !apexInfo.IsForPlatform() { return true } @@ -667,10 +741,11 @@ func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bo return true } - // Store uncompressed dex files that are preopted on /system. - if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, dexpreopter.installPath)) { + // Store uncompressed dex files that are preopted on /system or /system_other. + if !dexpreopter.dexpreoptDisabled(ctx, libName) { return true } + if ctx.Config().UncompressPrivAppDex() && inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) { return true @@ -683,21 +758,224 @@ func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bo func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) { if dexer.dexProperties.Uncompress_dex == nil { // If the value was not force-set by the user, use reasonable default based on the module. - dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, dexpreopter)) + dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexpreopter)) } } -func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { +// list of java_library modules that set platform_apis: true +// this property is a no-op for java_library +// TODO (b/215379393): Remove this allowlist +var ( + aospPlatformApiAllowlist = map[string]bool{ + "adservices-test-scenarios": true, + "aidl-cpp-java-test-interface-java": true, + "aidl-test-extras-java": true, + "aidl-test-interface-java": true, + "aidl-test-interface-permission-java": true, + "aidl_test_java_client_permission": true, + "aidl_test_java_client_sdk1": true, + "aidl_test_java_client_sdk29": true, + "aidl_test_java_client": true, + "aidl_test_java_service_permission": true, + "aidl_test_java_service_sdk1": true, + "aidl_test_java_service_sdk29": true, + "aidl_test_java_service": true, + "aidl_test_loggable_interface-java": true, + "aidl_test_nonvintf_parcelable-V1-java": true, + "aidl_test_nonvintf_parcelable-V2-java": true, + "aidl_test_unstable_parcelable-java": true, + "aidl_test_vintf_parcelable-V1-java": true, + "aidl_test_vintf_parcelable-V2-java": true, + "android.aidl.test.trunk-V1-java": true, + "android.aidl.test.trunk-V2-java": true, + "android.frameworks.location.altitude-V1-java": true, + "android.frameworks.location.altitude-V2-java": true, + "android.frameworks.stats-V1-java": true, + "android.frameworks.stats-V2-java": true, + "android.frameworks.stats-V3-java": true, + "android.hardware.authsecret-V1-java": true, + "android.hardware.authsecret-V2-java": true, + "android.hardware.biometrics.common-V1-java": true, + "android.hardware.biometrics.common-V2-java": true, + "android.hardware.biometrics.common-V3-java": true, + "android.hardware.biometrics.common-V4-java": true, + "android.hardware.biometrics.face-V1-java": true, + "android.hardware.biometrics.face-V2-java": true, + "android.hardware.biometrics.face-V3-java": true, + "android.hardware.biometrics.face-V4-java": true, + "android.hardware.biometrics.fingerprint-V1-java": true, + "android.hardware.biometrics.fingerprint-V2-java": true, + "android.hardware.biometrics.fingerprint-V3-java": true, + "android.hardware.biometrics.fingerprint-V4-java": true, + "android.hardware.bluetooth.lmp_event-V1-java": true, + "android.hardware.confirmationui-V1-java": true, + "android.hardware.confirmationui-V2-java": true, + "android.hardware.gatekeeper-V1-java": true, + "android.hardware.gatekeeper-V2-java": true, + "android.hardware.gnss-V1-java": true, + "android.hardware.gnss-V2-java": true, + "android.hardware.gnss-V3-java": true, + "android.hardware.gnss-V4-java": true, + "android.hardware.graphics.common-V1-java": true, + "android.hardware.graphics.common-V2-java": true, + "android.hardware.graphics.common-V3-java": true, + "android.hardware.graphics.common-V4-java": true, + "android.hardware.graphics.common-V5-java": true, + "android.hardware.identity-V1-java": true, + "android.hardware.identity-V2-java": true, + "android.hardware.identity-V3-java": true, + "android.hardware.identity-V4-java": true, + "android.hardware.identity-V5-java": true, + "android.hardware.identity-V6-java": true, + "android.hardware.keymaster-V1-java": true, + "android.hardware.keymaster-V2-java": true, + "android.hardware.keymaster-V3-java": true, + "android.hardware.keymaster-V4-java": true, + "android.hardware.keymaster-V5-java": true, + "android.hardware.oemlock-V1-java": true, + "android.hardware.oemlock-V2-java": true, + "android.hardware.power.stats-V1-java": true, + "android.hardware.power.stats-V2-java": true, + "android.hardware.power.stats-V3-java": true, + "android.hardware.power-V1-java": true, + "android.hardware.power-V2-java": true, + "android.hardware.power-V3-java": true, + "android.hardware.power-V4-java": true, + "android.hardware.power-V5-java": true, + "android.hardware.rebootescrow-V1-java": true, + "android.hardware.rebootescrow-V2-java": true, + "android.hardware.security.authgraph-V1-java": true, + "android.hardware.security.keymint-V1-java": true, + "android.hardware.security.keymint-V2-java": true, + "android.hardware.security.keymint-V3-java": true, + "android.hardware.security.keymint-V4-java": true, + "android.hardware.security.secretkeeper-V1-java": true, + "android.hardware.security.secureclock-V1-java": true, + "android.hardware.security.secureclock-V2-java": true, + "android.hardware.thermal-V1-java": true, + "android.hardware.thermal-V2-java": true, + "android.hardware.threadnetwork-V1-java": true, + "android.hardware.weaver-V1-java": true, + "android.hardware.weaver-V2-java": true, + "android.hardware.weaver-V3-java": true, + "android.security.attestationmanager-java": true, + "android.security.authorization-java": true, + "android.security.compat-java": true, + "android.security.legacykeystore-java": true, + "android.security.maintenance-java": true, + "android.security.metrics-java": true, + "android.system.keystore2-V1-java": true, + "android.system.keystore2-V2-java": true, + "android.system.keystore2-V3-java": true, + "android.system.keystore2-V4-java": true, + "binderReadParcelIface-java": true, + "binderRecordReplayTestIface-java": true, + "car-experimental-api-static-lib": true, + "collector-device-lib-platform": true, + "com.android.car.oem": true, + "com.google.hardware.pixel.display-V10-java": true, + "com.google.hardware.pixel.display-V1-java": true, + "com.google.hardware.pixel.display-V2-java": true, + "com.google.hardware.pixel.display-V3-java": true, + "com.google.hardware.pixel.display-V4-java": true, + "com.google.hardware.pixel.display-V5-java": true, + "com.google.hardware.pixel.display-V6-java": true, + "com.google.hardware.pixel.display-V7-java": true, + "com.google.hardware.pixel.display-V8-java": true, + "com.google.hardware.pixel.display-V9-java": true, + "conscrypt-support": true, + "cts-keystore-test-util": true, + "cts-keystore-user-auth-helper-library": true, + "ctsmediautil": true, + "CtsNetTestsNonUpdatableLib": true, + "DpmWrapper": true, + "flickerlib-apphelpers": true, + "flickerlib-helpers": true, + "flickerlib-parsers": true, + "flickerlib": true, + "hardware.google.bluetooth.ccc-V1-java": true, + "hardware.google.bluetooth.sar-V1-java": true, + "monet": true, + "pixel-power-ext-V1-java": true, + "pixel-power-ext-V2-java": true, + "pixel_stateresidency_provider_aidl_interface-java": true, + "pixel-thermal-ext-V1-java": true, + "protolog-lib": true, + "RkpRegistrationCheck": true, + "rotary-service-javastream-protos": true, + "service_based_camera_extensions": true, + "statsd-helper-test": true, + "statsd-helper": true, + "test-piece-2-V1-java": true, + "test-piece-2-V2-java": true, + "test-piece-3-V1-java": true, + "test-piece-3-V2-java": true, + "test-piece-3-V3-java": true, + "test-piece-4-V1-java": true, + "test-piece-4-V2-java": true, + "test-root-package-V1-java": true, + "test-root-package-V2-java": true, + "test-root-package-V3-java": true, + "test-root-package-V4-java": true, + "testServiceIface-java": true, + "wm-flicker-common-app-helpers": true, + "wm-flicker-common-assertions": true, + "wm-shell-flicker-utils": true, + "wycheproof-keystore": true, + } + + // Union of aosp and internal allowlists + PlatformApiAllowlist = map[string]bool{} +) +func init() { + for k, v := range aospPlatformApiAllowlist { + PlatformApiAllowlist[k] = v + } +} + +func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { + if disableSourceApexVariant(ctx) { + // Prebuilts are active, do not create the installation rules for the source javalib. + // Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules. + // TODO (b/331665856): Implement a principled solution for this. + j.HideFromMake() + } j.provideHiddenAPIPropertyInfo(ctx) j.sdkVersion = j.SdkVersion(ctx) j.minSdkVersion = j.MinSdkVersion(ctx) j.maxSdkVersion = j.MaxSdkVersion(ctx) - j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName()) + // Check min_sdk_version of the transitive dependencies if this module is created from + // java_sdk_library. + if j.overridableProperties.Min_sdk_version != nil && j.SdkLibraryName() != nil { + j.CheckDepsMinSdkVersion(ctx) + } + + // SdkLibrary.GenerateAndroidBuildActions(ctx) sets the stubsLinkType to Unknown. + // If the stubsLinkType has already been set to Unknown, the stubsLinkType should + // not be overridden. + if j.stubsLinkType != Unknown { + if proptools.Bool(j.properties.Is_stubs_module) { + j.stubsLinkType = Stubs + } else { + j.stubsLinkType = Implementation + } + } + + j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName()) - apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + proguardSpecInfo := j.collectProguardSpecInfo(ctx) + android.SetProvider(ctx, ProguardSpecInfoProvider, proguardSpecInfo) + exportedProguardFlagsFiles := proguardSpecInfo.ProguardFlagsFiles.ToList() + j.extraProguardFlagsFiles = append(j.extraProguardFlagsFiles, exportedProguardFlagsFiles...) + + combinedExportedProguardFlagFile := android.PathForModuleOut(ctx, "export_proguard_flags") + writeCombinedProguardFlagsFile(ctx, combinedExportedProguardFlagFile, exportedProguardFlagsFiles) + j.combinedExportedProguardFlagsFile = combinedExportedProguardFlagFile + + apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if !apexInfo.IsForPlatform() { j.hideApexVariantFromMake = true } @@ -705,27 +983,49 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.checkSdkVersions(ctx) j.checkHeadersOnly(ctx) if ctx.Device() { + libName := j.Name() + if j.SdkLibraryName() != nil && strings.HasSuffix(libName, ".impl") { + libName = proptools.String(j.SdkLibraryName()) + } j.dexpreopter.installPath = j.dexpreopter.getInstallPath( - ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) + ctx, libName, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary setUncompressDex(ctx, &j.dexpreopter, &j.dexer) j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx) + if j.usesLibrary.shouldDisableDexpreopt { + j.dexpreopter.disableDexpreopt() + } } - j.compile(ctx, nil, nil, nil) + j.compile(ctx, nil, nil, nil, nil) - // Collect the module directory for IDE info in java/jdeps.go. - j.modulePaths = append(j.modulePaths, ctx.ModuleDir()) + // If this module is an impl library created from java_sdk_library, + // install the files under the java_sdk_library module outdir instead of this module outdir. + if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") { + j.setInstallRules(ctx, proptools.String(j.SdkLibraryName())) + } else { + j.setInstallRules(ctx, ctx.ModuleName()) + } - exclusivelyForApex := !apexInfo.IsForPlatform() - if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex { - var extraInstallDeps android.Paths + android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ + TestOnly: Bool(j.sourceProperties.Test_only), + TopLevelTarget: j.sourceProperties.Top_level_test_target, + }) + + setOutputFiles(ctx, j.Module) +} + +func (j *Library) setInstallRules(ctx android.ModuleContext, installModuleName string) { + apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) + + if (Bool(j.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() { + var extraInstallDeps android.InstallPaths if j.InstallMixin != nil { extraInstallDeps = j.InstallMixin(ctx, j.outputFile) } hostDexNeeded := Bool(j.deviceProperties.Hostdex) && !ctx.Host() if hostDexNeeded { - j.hostdexInstallFile = ctx.InstallFile( + j.hostdexInstallFile = ctx.InstallFileWithoutCheckbuild( android.PathForHostDexInstall(ctx, "framework"), j.Stem()+"-hostdex.jar", j.outputFile) } @@ -735,21 +1035,27 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { if !ctx.Host() { archDir = ctx.DeviceConfig().DeviceArch() } - installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir) + installDir = android.PathForModuleInstall(ctx, installModuleName, archDir) } else { installDir = android.PathForModuleInstall(ctx, "framework") } - j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...) + j.installFile = ctx.InstallFileWithoutCheckbuild(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...) } - - proguardSpecInfo := j.collectProguardSpecInfo(ctx) - ctx.SetProvider(ProguardSpecInfoProvider, proguardSpecInfo) - j.exportedProguardFlagFiles = proguardSpecInfo.ProguardFlagsFiles.ToList() } func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { - j.deps(ctx) j.usesLibrary.deps(ctx, false) + j.deps(ctx) + + if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") { + if dexpreopt.IsDex2oatNeeded(ctx) { + dexpreopt.RegisterToolDeps(ctx) + } + prebuiltSdkLibExists := ctx.OtherModuleExists(android.PrebuiltNameFromSource(proptools.String(j.SdkLibraryName()))) + if prebuiltSdkLibExists && ctx.OtherModuleExists("all_apex_contributions") { + ctx.AddDependency(ctx.Module(), android.AcDepTag, "all_apex_contributions") + } + } } const ( @@ -833,7 +1139,7 @@ func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberCo // If the min_sdk_version was set then add the canonical representation of the API level to the // snapshot. - if j.deviceProperties.Min_sdk_version != nil { + if j.overridableProperties.Min_sdk_version != nil { canonical, err := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String()) if err != nil { ctx.ModuleErrorf("%s", err) @@ -910,11 +1216,11 @@ func LibraryFactory() android.Module { module := &Library{} module.addHostAndDeviceProperties() + module.AddProperties(&module.sourceProperties) module.initModuleAndImport(module) android.InitApexModule(module) - android.InitBazelModule(module) InitJavaModule(module, android.HostAndDeviceSupported) return module } @@ -936,7 +1242,6 @@ func LibraryHostFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) android.InitApexModule(module) - android.InitBazelModule(module) InitJavaModule(module, android.HostSupported) return module } @@ -1087,7 +1392,7 @@ func (j *JavaTestImport) InstallInTestcases() bool { return true } -func (j *TestHost) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { +func (j *TestHost) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool { return ctx.DeviceConfig().NativeCoverageEnabled() } @@ -1227,10 +1532,23 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { } j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) + android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{}) + android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ + InstalledFiles: j.data, + OutputFile: j.outputFile, + TestConfig: j.testConfig, + RequiredModuleNames: j.RequiredModuleNames(ctx), + TestSuites: j.testProperties.Test_suites, + IsHost: true, + LocalSdkVersion: j.sdkVersion.String(), + IsUnitTest: Bool(j.testProperties.Test_options.Unit_test), + }) } func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { + checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) j.generateAndroidBuildActionsWithConfig(ctx, nil) + android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{}) } func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) { @@ -1266,7 +1584,7 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, }) ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) { - sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo) + sharedLibInfo, _ := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider) if sharedLibInfo.SharedLibrary != nil { // Copy to an intermediate output directory to append "lib[64]" to the path, // so that it's compatible with the default rpath values. @@ -1383,6 +1701,8 @@ func TestFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) + module.Module.sourceProperties.Test_only = proptools.BoolPtr(true) + module.Module.sourceProperties.Top_level_test_target = true InitJavaModule(module, android.HostAndDeviceSupported) return module @@ -1398,6 +1718,7 @@ func TestHelperLibraryFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) + module.Module.sourceProperties.Test_only = proptools.BoolPtr(true) InitJavaModule(module, android.HostAndDeviceSupported) return module @@ -1444,8 +1765,6 @@ func TestHostFactory() android.Module { nil, nil) - android.InitBazelModule(module) - InitJavaModuleMultiTargets(module, android.HostSupported) return module @@ -1455,6 +1774,8 @@ func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenC th.properties.Installable = installable th.testProperties.Auto_gen_config = autoGenConfig th.testProperties.Test_suites = testSuites + th.sourceProperties.Test_only = proptools.BoolPtr(true) + th.sourceProperties.Top_level_test_target = true } // @@ -1489,7 +1810,7 @@ func (j *Binary) HostToolPath() android.OptionalPath { } func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { - j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName()) + j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName()) if ctx.Arch().ArchType == android.Common { // Compile the jar @@ -1551,6 +1872,8 @@ func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { // libraries. This is verified by TestBinary. j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName()+ext, j.wrapperFile) + + setOutputFiles(ctx, j.Library.Module) } } @@ -1558,10 +1881,12 @@ func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { if ctx.Arch().ArchType == android.Common { j.deps(ctx) } - if ctx.Arch().ArchType != android.Common { - // These dependencies ensure the host installation rules will install the jar file and - // the jni libraries when the wrapper is installed. + // These dependencies ensure the installation rules will install the jar file when the + // wrapper is installed, and the jni libraries on host when the wrapper is installed. + if ctx.Arch().ArchType != android.Common && ctx.Os().Class == android.Host { ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...) + } + if ctx.Arch().ArchType != android.Common { ctx.AddVariationDependencies( []blueprint.Variation{{Mutator: "arch", Variation: android.CommonArch.String()}}, binaryInstallTag, ctx.ModuleName()) @@ -1580,13 +1905,12 @@ func BinaryFactory() android.Module { module := &Binary{} module.addHostAndDeviceProperties() - module.AddProperties(&module.binaryProperties) + module.AddProperties(&module.binaryProperties, &module.sourceProperties) module.Module.properties.Installable = proptools.BoolPtr(true) android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst) android.InitDefaultableModule(module) - android.InitBazelModule(module) return module } @@ -1605,13 +1929,13 @@ func BinaryHostFactory() android.Module { android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst) android.InitDefaultableModule(module) - android.InitBazelModule(module) return module } type JavaApiContribution struct { android.ModuleBase android.DefaultableModuleBase + embeddableInModuleAndImport properties struct { // name of the API surface @@ -1627,6 +1951,7 @@ func ApiContributionFactory() android.Module { android.InitAndroidModule(module) android.InitDefaultableModule(module) module.AddProperties(&module.properties) + module.initModuleAndImport(module) return module } @@ -1635,7 +1960,7 @@ type JavaApiImportInfo struct { ApiSurface string } -var JavaApiImportProvider = blueprint.NewProvider(JavaApiImportInfo{}) +var JavaApiImportProvider = blueprint.NewProvider[JavaApiImportInfo]() func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleContext) { var apiFile android.Path = nil @@ -1643,7 +1968,7 @@ func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleCon apiFile = android.PathForModuleSrc(ctx, String(apiFileString)) } - ctx.SetProvider(JavaApiImportProvider, JavaApiImportInfo{ + android.SetProvider(ctx, JavaApiImportProvider, JavaApiImportInfo{ ApiFile: apiFile, ApiSurface: proptools.String(ap.properties.Api_surface), }) @@ -1655,6 +1980,7 @@ type ApiLibrary struct { hiddenAPI dexer + embeddableInModuleAndImport properties JavaApiLibraryProperties @@ -1666,6 +1992,10 @@ type ApiLibrary struct { dexJarFile OptionalDexJarPath validationPaths android.Paths + + stubsType StubsType + + aconfigProtoFiles android.Paths } type JavaApiLibraryProperties struct { @@ -1681,17 +2011,11 @@ type JavaApiLibraryProperties struct { // List of shared java libs that this module has dependencies to and // should be passed as classpath in javac invocation - Libs []string + Libs proptools.Configurable[[]string] // List of java libs that this module has static dependencies to and will be // merge zipped after metalava invocation - Static_libs []string - - // Java Api library to provide the full API surface stub jar file. - // If this property is set, the stub jar of this module is created by - // extracting the compiled class files provided by the - // full_api_surface_stub module. - Full_api_surface_stub *string + Static_libs proptools.Configurable[[]string] // Version of previously released API file for compatibility check. Previous_api *string `android:"path"` @@ -1707,12 +2031,41 @@ type JavaApiLibraryProperties struct { // in sync with the source Java files. However, the environment variable // DISABLE_STUB_VALIDATION has precedence over this property. Enable_validation *bool + + // Type of stubs the module should generate. Must be one of "everything", "runtime" or + // "exportable". Defaults to "everything". + // - "everything" stubs include all non-flagged apis and flagged apis, regardless of the state + // of the flag. + // - "runtime" stubs include all non-flagged apis and flagged apis that are ENABLED or + // READ_WRITE, and all other flagged apis are stripped. + // - "exportable" stubs include all non-flagged apis and flagged apis that are ENABLED and + // READ_ONLY, and all other flagged apis are stripped. + Stubs_type *string + + // List of aconfig_declarations module names that the stubs generated in this module + // depend on. + Aconfig_declarations []string + + // List of hard coded filegroups containing Metalava config files that are passed to every + // Metalava invocation that this module performs. See addMetalavaConfigFilesToCmd. + ConfigFiles []string `android:"path" blueprint:"mutated"` + + // If not blank, set to the version of the sdk to compile against. + // Defaults to an empty string, which compiles the module against the private platform APIs. + // Values are of one of the following forms: + // 1) numerical API level, "current", "none", or "core_platform" + // 2) An SDK kind with an API level: "<sdk kind>_<API level>" + // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds. + // If the SDK kind is empty, it will be set to public. + Sdk_version *string } func ApiLibraryFactory() android.Module { module := &ApiLibrary{} - android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) module.AddProperties(&module.properties) + module.properties.ConfigFiles = getMetalavaConfigFilegroupReference() + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) + module.initModuleAndImport(module) android.InitDefaultableModule(module) return module } @@ -1727,7 +2080,7 @@ func (al *ApiLibrary) StubsJar() android.Path { func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths, homeDir android.WritablePath, - classpath android.Paths) *android.RuleBuilderCommand { + classpath android.Paths, configFiles android.Paths) *android.RuleBuilderCommand { rule.Command().Text("rm -rf").Flag(homeDir.String()) rule.Command().Text("mkdir -p").Flag(homeDir.String()) @@ -1766,6 +2119,8 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, FlagWithArg("--hide ", "InvalidNullabilityOverride"). FlagWithArg("--hide ", "ChangedDefault") + addMetalavaConfigFilesToCmd(cmd, configFiles) + if len(classpath) == 0 { // The main purpose of the `--api-class-resolution api` option is to force metalava to ignore // classes on the classpath when an API file contains missing classes. However, as this command @@ -1801,43 +2156,10 @@ func (al *ApiLibrary) addValidation(ctx android.ModuleContext, cmd *android.Rule } } -// This method extracts the stub class files from the stub jar file provided -// from full_api_surface_stub module instead of compiling the srcjar generated from invoking metalava. -// This method is used because metalava can generate compilable from-text stubs only when -// the codebase encompasses all classes listed in the input API text file, and a class can extend -// a class that is not within the same API domain. -func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.RuleBuilder, stubsDir android.OptionalPath, fullApiSurfaceStubJar android.Path) { - classFilesList := android.PathForModuleOut(ctx, "metalava", "classes.txt") - unzippedSrcJarDir := android.PathForModuleOut(ctx, "metalava", "unzipDir") - - rule.Command(). - BuiltTool("list_files"). - Text(stubsDir.String()). - FlagWithOutput("--out ", classFilesList). - FlagWithArg("--extensions ", ".java"). - FlagWithArg("--root ", unzippedSrcJarDir.String()). - Flag("--classes") - - rule.Command(). - Text("unzip"). - Flag("-q"). - Input(fullApiSurfaceStubJar). - FlagWithArg("-d ", unzippedSrcJarDir.String()) - - rule.Command(). - BuiltTool("soong_zip"). - Flag("-jar"). - Flag("-write_if_changed"). - Flag("-ignore_missing_files"). - Flag("-quiet"). - FlagWithArg("-C ", unzippedSrcJarDir.String()). - FlagWithInput("-l ", classFilesList). - FlagWithOutput("-o ", al.stubsJarWithoutStaticLibs) -} - func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { apiContributions := al.properties.Api_contributions addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") && + !ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") && proptools.BoolDefault(al.properties.Enable_validation, true) for _, apiContributionName := range apiContributions { ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName) @@ -1860,19 +2182,26 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { } } } - ctx.AddVariationDependencies(nil, libTag, al.properties.Libs...) - ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs...) - if al.properties.Full_api_surface_stub != nil { - ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Full_api_surface_stub)) + if ctx.Device() { + sdkDep := decodeSdkDep(ctx, android.SdkContext(al)) + if sdkDep.useModule { + ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) + ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...) + ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) + + } } - if al.properties.System_modules != nil { - ctx.AddVariationDependencies(nil, systemModulesTag, String(al.properties.System_modules)) + ctx.AddVariationDependencies(nil, libTag, al.properties.Libs.GetOrDefault(ctx, nil)...) + ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs.GetOrDefault(ctx, nil)...) + + for _, aconfigDeclarationsName := range al.properties.Aconfig_declarations { + ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationsName) } } // Map where key is the api scope name and value is the int value // representing the order of the api scope, narrowest to the widest -var scopeOrderMap = allApiScopes.MapToIndex( +var scopeOrderMap = AllApiScopes.MapToIndex( func(s *apiScope) string { return s.name }) func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo { @@ -1888,7 +2217,23 @@ func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFiles return srcFilesInfo } +var validstubsType = []StubsType{Everything, Runtime, Exportable} + +func (al *ApiLibrary) validateProperties(ctx android.ModuleContext) { + if al.properties.Stubs_type == nil { + ctx.ModuleErrorf("java_api_library module type must specify stubs_type property.") + } else { + al.stubsType = StringToStubsType(proptools.String(al.properties.Stubs_type)) + } + + if !android.InList(al.stubsType, validstubsType) { + ctx.PropertyErrorf("stubs_type", "%s is not a valid stubs_type property value. "+ + "Must be one of %s.", proptools.String(al.properties.Stubs_type), validstubsType) + } +} + func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { + al.validateProperties(ctx) rule := android.NewRuleBuilder(pctx, ctx) @@ -1904,34 +2249,50 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { var srcFilesInfo []JavaApiImportInfo var classPaths android.Paths + var bootclassPaths android.Paths var staticLibs android.Paths - var depApiSrcsStubsJar android.Path var systemModulesPaths android.Paths ctx.VisitDirectDeps(func(dep android.Module) { tag := ctx.OtherModuleDependencyTag(dep) switch tag { case javaApiContributionTag: - provider := ctx.OtherModuleProvider(dep, JavaApiImportProvider).(JavaApiImportInfo) + provider, _ := android.OtherModuleProvider(ctx, dep, JavaApiImportProvider) if provider.ApiFile == nil && !ctx.Config().AllowMissingDependencies() { ctx.ModuleErrorf("Error: %s has an empty api file.", dep.Name()) } srcFilesInfo = append(srcFilesInfo, provider) case libTag: - provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) - classPaths = append(classPaths, provider.HeaderJars...) + if provider, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok { + classPaths = append(classPaths, provider.HeaderJars...) + } + case bootClasspathTag: + if provider, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok { + bootclassPaths = append(bootclassPaths, provider.HeaderJars...) + } case staticLibTag: - provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) - staticLibs = append(staticLibs, provider.HeaderJars...) - case depApiSrcsTag: - provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) - depApiSrcsStubsJar = provider.HeaderJars[0] + if provider, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok { + staticLibs = append(staticLibs, provider.HeaderJars...) + } case systemModulesTag: - module := dep.(SystemModulesProvider) - systemModulesPaths = append(systemModulesPaths, module.HeaderJars()...) + if sm, ok := android.OtherModuleProvider(ctx, dep, SystemModulesProvider); ok { + systemModulesPaths = append(systemModulesPaths, sm.HeaderJars...) + } case metalavaCurrentApiTimestampTag: if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok { al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp()) } + case aconfigDeclarationTag: + if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok { + al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPath) + } else if provider, ok := android.OtherModuleProvider(ctx, dep, android.CodegenInfoProvider); ok { + al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPaths...) + } else { + ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+ + "module type is allowed for flags_packages property, but %s is neither "+ + "of these supported module types", + dep.Name(), + ) + } } }) @@ -1945,25 +2306,29 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName()) } - cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, systemModulesPaths) + configFiles := android.PathsForModuleSrc(ctx, al.properties.ConfigFiles) + + combinedPaths := append(([]android.Path)(nil), systemModulesPaths...) + combinedPaths = append(combinedPaths, classPaths...) + combinedPaths = append(combinedPaths, bootclassPaths...) + cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, combinedPaths, configFiles) al.stubsFlags(ctx, cmd, stubsDir) - migratingNullability := String(al.properties.Previous_api) != "" - if migratingNullability { - previousApi := android.PathForModuleSrc(ctx, String(al.properties.Previous_api)) - cmd.FlagWithInput("--migrate-nullness ", previousApi) + previousApi := String(al.properties.Previous_api) + if previousApi != "" { + previousApiFiles := android.PathsForModuleSrc(ctx, []string{previousApi}) + cmd.FlagForEachInput("--migrate-nullness ", previousApiFiles) } al.addValidation(ctx, cmd, al.validationPaths) + generateRevertAnnotationArgs(ctx, cmd, al.stubsType, al.aconfigProtoFiles) + al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar") al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar") al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName())) - if depApiSrcsStubsJar != nil { - al.extractApiSrcs(ctx, rule, stubsDir, depApiSrcsStubsJar) - } rule.Command(). BuiltTool("soong_zip"). Flag("-write_if_changed"). @@ -1974,18 +2339,17 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule.Build("metalava", "metalava merged text") - if depApiSrcsStubsJar == nil { - var flags javaBuilderFlags - flags.javaVersion = getStubsJavaVersion() - flags.javacFlags = strings.Join(al.properties.Javacflags, " ") - flags.classpath = classpath(classPaths) - flags.bootClasspath = classpath(systemModulesPaths) + javacFlags := javaBuilderFlags{ + javaVersion: getStubsJavaVersion(), + javacFlags: strings.Join(al.properties.Javacflags, " "), + classpath: classpath(classPaths), + bootClasspath: classpath(append(systemModulesPaths, bootclassPaths...)), + } - annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar") + annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar") - TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{}, - android.Paths{al.stubsSrcJar}, annoSrcJar, flags, android.Paths{}) - } + TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{}, + android.Paths{al.stubsSrcJar}, annoSrcJar, javacFlags, android.Paths{}) builder := android.NewRuleBuilder(pctx, ctx) builder.Command(). @@ -1997,13 +2361,13 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { // compile stubs to .dex for hiddenapi processing dexParams := &compileDexParams{ - flags: javaBuilderFlags{}, + flags: javacFlags, sdkVersion: al.SdkVersion(ctx), minSdkVersion: al.MinSdkVersion(ctx), classesJar: al.stubsJar, jarName: ctx.ModuleName() + ".jar", } - dexOutputFile := al.dexer.compileDex(ctx, dexParams) + dexOutputFile, _ := al.dexer.compileDex(ctx, dexParams) uncompressed := true al.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), al.stubsJar, &uncompressed) dexOutputFile = al.hiddenAPIEncodeDex(ctx, dexOutputFile) @@ -2011,16 +2375,20 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.Phony(ctx.ModuleName(), al.stubsJar) - ctx.SetProvider(JavaInfoProvider, JavaInfo{ - HeaderJars: android.PathsIfNonNil(al.stubsJar), - ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar), - ImplementationJars: android.PathsIfNonNil(al.stubsJar), - AidlIncludeDirs: android.Paths{}, + android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{ + HeaderJars: android.PathsIfNonNil(al.stubsJar), + LocalHeaderJars: android.PathsIfNonNil(al.stubsJar), + TransitiveStaticLibsHeaderJars: android.NewDepSet(android.PREORDER, android.PathsIfNonNil(al.stubsJar), nil), + TransitiveStaticLibsImplementationJars: android.NewDepSet(android.PREORDER, android.PathsIfNonNil(al.stubsJar), nil), + ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar), + ImplementationJars: android.PathsIfNonNil(al.stubsJar), + AidlIncludeDirs: android.Paths{}, + StubsLinkType: Stubs, // No aconfig libraries on api libraries }) } -func (al *ApiLibrary) DexJarBuildPath() OptionalDexJarPath { +func (al *ApiLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { return al.dexJarFile } @@ -2032,19 +2400,56 @@ func (al *ApiLibrary) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { return nil } -// java_api_library constitutes the sdk, and does not build against one +// Most java_api_library constitues the sdk, but there are some java_api_library that +// does not contribute to the api surface. Such modules are allowed to set sdk_version +// other than "none" func (al *ApiLibrary) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { - return android.SdkSpecNone + return android.SdkSpecFrom(ctx, proptools.String(al.properties.Sdk_version)) } // java_api_library is always at "current". Return FutureApiLevel func (al *ApiLibrary) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { - return android.FutureApiLevel + return al.SdkVersion(ctx).ApiLevel +} + +func (al *ApiLibrary) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel { + return al.SdkVersion(ctx).ApiLevel +} + +func (al *ApiLibrary) SystemModules() string { + return proptools.String(al.properties.System_modules) +} + +func (al *ApiLibrary) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + return al.SdkVersion(ctx).ApiLevel +} + +func (al *ApiLibrary) IDEInfo(ctx android.BaseModuleContext, i *android.IdeInfo) { + i.Deps = append(i.Deps, al.ideDeps(ctx)...) + i.Libs = append(i.Libs, al.properties.Libs.GetOrDefault(ctx, nil)...) + i.Static_libs = append(i.Static_libs, al.properties.Static_libs.GetOrDefault(ctx, nil)...) + i.SrcJars = append(i.SrcJars, al.stubsSrcJar.String()) +} + +// deps of java_api_library for module_bp_java_deps.json +func (al *ApiLibrary) ideDeps(ctx android.BaseModuleContext) []string { + ret := []string{} + ret = append(ret, al.properties.Libs.GetOrDefault(ctx, nil)...) + ret = append(ret, al.properties.Static_libs.GetOrDefault(ctx, nil)...) + if al.properties.System_modules != nil { + ret = append(ret, proptools.String(al.properties.System_modules)) + } + // Other non java_library dependencies like java_api_contribution are ignored for now. + return ret } // implement the following interfaces for hiddenapi processing var _ hiddenAPIModule = (*ApiLibrary)(nil) var _ UsesLibraryDependency = (*ApiLibrary)(nil) +var _ android.SdkContext = (*ApiLibrary)(nil) + +// implement the following interface for IDE completion. +var _ android.IDEInfo = (*ApiLibrary)(nil) // // Java prebuilts @@ -2073,6 +2478,9 @@ type ImportProperties struct { // List of shared java libs that this module has dependencies to Libs []string + // List of static java libs that this module has dependencies to + Static_libs proptools.Configurable[[]string] + // List of files to remove from the jar file(s) Exclude_files []string @@ -2090,13 +2498,25 @@ type ImportProperties struct { // that depend on this module, as well as to aidl for this module. Export_include_dirs []string } + + // Name of the source soong module that gets shadowed by this prebuilt + // If unspecified, follows the naming convention that the source module of + // the prebuilt is Name() without "prebuilt_" prefix + Source_module_name *string + + // Non-nil if this java_import module was dynamically created by a java_sdk_library_import + // The name is the undecorated name of the java_sdk_library as it appears in the blueprint file + // (without any prebuilt_ prefix) + Created_by_java_sdk_library_name *string `blueprint:"mutated"` + + // Property signifying whether the module provides stubs jar or not. + Is_stubs_module *bool } type Import struct { android.ModuleBase android.DefaultableModuleBase android.ApexModuleBase - android.BazelModuleBase prebuilt android.Prebuilt // Functionality common to Module and Import. @@ -2110,16 +2530,20 @@ type Import struct { // output file containing classes.dex and resources dexJarFile OptionalDexJarPath + dexJarFileErr error dexJarInstallFile android.Path - combinedClasspathFile android.Path - classLoaderContexts dexpreopt.ClassLoaderContextMap - exportAidlIncludeDirs android.Paths + combinedImplementationFile android.Path + combinedHeaderFile android.Path + classLoaderContexts dexpreopt.ClassLoaderContextMap + exportAidlIncludeDirs android.Paths hideApexVariantFromMake bool sdkVersion android.SdkSpec minSdkVersion android.ApiLevel + + stubsLinkType StubsLinkType } var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil) @@ -2163,12 +2587,20 @@ func (j *Import) PrebuiltSrcs() []string { return j.properties.Jars } +func (j *Import) BaseModuleName() string { + return proptools.StringDefault(j.properties.Source_module_name, j.ModuleBase.Name()) +} + func (j *Import) Name() string { return j.prebuilt.Name(j.ModuleBase.Name()) } func (j *Import) Stem() string { - return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) + return proptools.StringDefault(j.properties.Stem, j.BaseModuleName()) +} + +func (j *Import) CreatedByJavaSdkLibraryName() *string { + return j.properties.Created_by_java_sdk_library_name } func (a *Import) JacocoReportClassesFile() android.Path { @@ -2188,6 +2620,7 @@ func (j *Import) setStrictUpdatabilityLinting(bool) { func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) + ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs.GetOrDefault(ctx, nil)...) if ctx.Device() && Bool(j.dexProperties.Compile_dex) { sdkDeps(ctx, android.SdkContext(j), j.dexer) @@ -2195,84 +2628,212 @@ func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { } func (j *Import) commonBuildActions(ctx android.ModuleContext) { - //TODO(b/231322772) these should come from Bazel once available j.sdkVersion = j.SdkVersion(ctx) j.minSdkVersion = j.MinSdkVersion(ctx) - if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() { + apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) + if !apexInfo.IsForPlatform() { j.hideApexVariantFromMake = true } if ctx.Windows() { j.HideFromMake() } + + if proptools.Bool(j.properties.Is_stubs_module) { + j.stubsLinkType = Stubs + } else { + j.stubsLinkType = Implementation + } } func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.commonBuildActions(ctx) - jars := android.PathsForModuleSrc(ctx, j.properties.Jars) - - jarName := j.Stem() + ".jar" - outputFile := android.PathForModuleOut(ctx, "combined", jarName) - TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{}, - false, j.properties.Exclude_files, j.properties.Exclude_dirs) - if Bool(j.properties.Jetifier) { - inputFile := outputFile - outputFile = android.PathForModuleOut(ctx, "jetifier", jarName) - TransformJetifier(ctx, outputFile, inputFile) - } - j.combinedClasspathFile = outputFile j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap) var flags javaBuilderFlags - j.collectTransitiveHeaderJars(ctx) + var transitiveClasspathHeaderJars []*android.DepSet[android.Path] + var transitiveBootClasspathHeaderJars []*android.DepSet[android.Path] + var transitiveStaticLibsHeaderJars []*android.DepSet[android.Path] + var transitiveStaticLibsImplementationJars []*android.DepSet[android.Path] + var transitiveStaticLibsResourceJars []*android.DepSet[android.Path] + + j.collectTransitiveHeaderJarsForR8(ctx) + var staticJars android.Paths + var staticResourceJars android.Paths + var staticHeaderJars android.Paths ctx.VisitDirectDeps(func(module android.Module) { tag := ctx.OtherModuleDependencyTag(module) - if ctx.OtherModuleHasProvider(module, JavaInfoProvider) { - dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) + if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { switch tag { case libTag, sdkLibTag: flags.classpath = append(flags.classpath, dep.HeaderJars...) flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...) + if dep.TransitiveStaticLibsHeaderJars != nil { + transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) + } case staticLibTag: flags.classpath = append(flags.classpath, dep.HeaderJars...) + staticJars = append(staticJars, dep.ImplementationJars...) + staticResourceJars = append(staticResourceJars, dep.ResourceJars...) + staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...) + if dep.TransitiveStaticLibsHeaderJars != nil { + transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) + transitiveStaticLibsHeaderJars = append(transitiveStaticLibsHeaderJars, dep.TransitiveStaticLibsHeaderJars) + } + if dep.TransitiveStaticLibsImplementationJars != nil { + transitiveStaticLibsImplementationJars = append(transitiveStaticLibsImplementationJars, dep.TransitiveStaticLibsImplementationJars) + } + if dep.TransitiveStaticLibsResourceJars != nil { + transitiveStaticLibsResourceJars = append(transitiveStaticLibsResourceJars, dep.TransitiveStaticLibsResourceJars) + } case bootClasspathTag: flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...) + if dep.TransitiveStaticLibsHeaderJars != nil { + transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) + } } } else if dep, ok := module.(SdkLibraryDependency); ok { switch tag { case libTag, sdkLibTag: - flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...) + depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx)) + flags.classpath = append(flags.classpath, depHeaderJars...) + transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, + android.NewDepSet(android.PREORDER, depHeaderJars, nil)) } } addCLCFromDep(ctx, module, j.classLoaderContexts) }) + localJars := android.PathsForModuleSrc(ctx, j.properties.Jars) + jarName := j.Stem() + ".jar" + + // Combine only the local jars together for use in transitive classpaths. + // Always pass input jar through TransformJarsToJar to strip module-info.class from prebuilts. + localCombinedHeaderJar := android.PathForModuleOut(ctx, "local-combined", jarName) + TransformJarsToJar(ctx, localCombinedHeaderJar, "combine local prebuilt implementation jars", localJars, android.OptionalPath{}, + false, j.properties.Exclude_files, j.properties.Exclude_dirs) + localStrippedJars := android.Paths{localCombinedHeaderJar} + + completeStaticLibsHeaderJars := android.NewDepSet(android.PREORDER, localStrippedJars, transitiveStaticLibsHeaderJars) + completeStaticLibsImplementationJars := android.NewDepSet(android.PREORDER, localStrippedJars, transitiveStaticLibsImplementationJars) + completeStaticLibsResourceJars := android.NewDepSet(android.PREORDER, nil, transitiveStaticLibsResourceJars) + + // Always pass the input jars to TransformJarsToJar, even if there is only a single jar, we need the output + // file of the module to be named jarName. + var outputFile android.Path + combinedImplementationJar := android.PathForModuleOut(ctx, "combined", jarName) + var implementationJars android.Paths + if ctx.Config().UseTransitiveJarsInClasspath() { + implementationJars = completeStaticLibsImplementationJars.ToList() + } else { + implementationJars = append(slices.Clone(localJars), staticJars...) + } + TransformJarsToJar(ctx, combinedImplementationJar, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{}, + false, j.properties.Exclude_files, j.properties.Exclude_dirs) + outputFile = combinedImplementationJar + + // If no dependencies have separate header jars then there is no need to create a separate + // header jar for this module. + reuseImplementationJarAsHeaderJar := slices.Equal(staticJars, staticHeaderJars) + + var resourceJarFile android.Path + if len(staticResourceJars) > 1 { + combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName) + TransformJarsToJar(ctx, combinedJar, "for resources", staticResourceJars, android.OptionalPath{}, + false, nil, nil) + resourceJarFile = combinedJar + } else if len(staticResourceJars) == 1 { + resourceJarFile = staticResourceJars[0] + } + + var headerJar android.Path + if reuseImplementationJarAsHeaderJar { + headerJar = outputFile + } else { + var headerJars android.Paths + if ctx.Config().UseTransitiveJarsInClasspath() { + headerJars = completeStaticLibsHeaderJars.ToList() + } else { + headerJars = append(slices.Clone(localJars), staticHeaderJars...) + } + headerOutputFile := android.PathForModuleOut(ctx, "turbine-combined", jarName) + TransformJarsToJar(ctx, headerOutputFile, "combine prebuilt header jars", headerJars, android.OptionalPath{}, + false, j.properties.Exclude_files, j.properties.Exclude_dirs) + headerJar = headerOutputFile + } + + if Bool(j.properties.Jetifier) { + jetifierOutputFile := android.PathForModuleOut(ctx, "jetifier", jarName) + TransformJetifier(ctx, jetifierOutputFile, outputFile) + outputFile = jetifierOutputFile + + if !reuseImplementationJarAsHeaderJar { + jetifierHeaderJar := android.PathForModuleOut(ctx, "jetifier-headers", jarName) + TransformJetifier(ctx, jetifierHeaderJar, headerJar) + headerJar = jetifierHeaderJar + } else { + headerJar = outputFile + } + + // Enabling jetifier requires modifying classes from transitive dependencies, disable transitive + // classpath and use the combined header jar instead. + completeStaticLibsHeaderJars = android.NewDepSet(android.PREORDER, android.Paths{headerJar}, nil) + completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, android.Paths{outputFile}, nil) + } + + implementationJarFile := outputFile + + // merge implementation jar with resources if necessary + if resourceJarFile != nil { + jars := android.Paths{resourceJarFile, outputFile} + combinedJar := android.PathForModuleOut(ctx, "withres", jarName) + TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{}, + false, nil, nil) + outputFile = combinedJar + } + + // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource. + // Also strip the relative path from the header output file so that the reuseImplementationJarAsHeaderJar check + // in a module that depends on this module considers them equal. + j.combinedHeaderFile = headerJar.WithoutRel() + j.combinedImplementationFile = outputFile.WithoutRel() + j.maybeInstall(ctx, jarName, outputFile) j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) + if ctx.Config().UseTransitiveJarsInClasspath() { + ctx.CheckbuildFile(localJars...) + } else { + ctx.CheckbuildFile(outputFile) + } + if ctx.Device() { // If this is a variant created for a prebuilt_apex then use the dex implementation jar // obtained from the associated deapexer module. - ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if ai.ForPrebuiltApex { // Get the path of the dex implementation jar from the `deapexer` module. - di := android.FindDeapexerProviderForModule(ctx) - if di == nil { - return // An error has been reported by FindDeapexerProviderForModule. + di, err := android.FindDeapexerProviderForModule(ctx) + if err != nil { + // An error was found, possibly due to multiple apexes in the tree that export this library + // Defer the error till a client tries to call DexJarBuildPath + j.dexJarFileErr = err + j.initHiddenAPIError(err) + return } - dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(j.BaseModuleName()) + dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(j.BaseModuleName()) if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil { dexJarFile := makeDexJarPathFromPath(dexOutputPath) j.dexJarFile = dexJarFile - installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName())) + installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, ApexRootRelativePathToJavaLib(j.BaseModuleName())) j.dexJarInstallFile = installPath - j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath) + j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), installPath) setUncompressDex(ctx, &j.dexpreopter, &j.dexer) j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex @@ -2280,8 +2841,6 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.dexpreopter.inputProfilePathOnHost = profilePath } - j.dexpreopt(ctx, dexOutputPath) - // Initialize the hiddenapi structure. j.initHiddenAPI(ctx, dexJarFile, outputFile, j.dexProperties.Uncompress_dex) } else { @@ -2302,11 +2861,11 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Dex compilation j.dexpreopter.installPath = j.dexpreopter.getInstallPath( - ctx, android.PathForModuleInstall(ctx, "framework", jarName)) + ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", jarName)) setUncompressDex(ctx, &j.dexpreopter, &j.dexer) j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex - var dexOutputFile android.OutputPath + var dexOutputFile android.Path dexParams := &compileDexParams{ flags: flags, sdkVersion: j.SdkVersion(ctx), @@ -2315,10 +2874,11 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { jarName: jarName, } - dexOutputFile = j.dexer.compileDex(ctx, dexParams) + dexOutputFile, _ = j.dexer.compileDex(ctx, dexParams) if ctx.Failed() { return } + ctx.CheckbuildFile(dexOutputFile) // Initialize the hiddenapi structure. j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex) @@ -2331,15 +2891,24 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } - ctx.SetProvider(JavaInfoProvider, JavaInfo{ - HeaderJars: android.PathsIfNonNil(j.combinedClasspathFile), - TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars, - TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars, - ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile), - ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile), - AidlIncludeDirs: j.exportAidlIncludeDirs, + android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{ + HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile), + LocalHeaderJars: android.PathsIfNonNil(j.combinedHeaderFile), + TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8, + TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8, + TransitiveStaticLibsHeaderJars: completeStaticLibsHeaderJars, + TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars, + TransitiveStaticLibsResourceJars: completeStaticLibsResourceJars, + ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedImplementationFile), + ImplementationJars: android.PathsIfNonNil(implementationJarFile.WithoutRel()), + ResourceJars: android.PathsIfNonNil(resourceJarFile), + AidlIncludeDirs: j.exportAidlIncludeDirs, + StubsLinkType: j.stubsLinkType, // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts }) + + ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "") + ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar") } func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) { @@ -2360,32 +2929,18 @@ func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputF ctx.InstallFile(installDir, jarName, outputFile) } -func (j *Import) OutputFiles(tag string) (android.Paths, error) { - switch tag { - case "", ".jar": - return android.Paths{j.combinedClasspathFile}, nil - default: - return nil, fmt.Errorf("unsupported module reference tag %q", tag) - } -} - -var _ android.OutputFileProducer = (*Import)(nil) - func (j *Import) HeaderJars() android.Paths { - if j.combinedClasspathFile == nil { - return nil - } - return android.Paths{j.combinedClasspathFile} + return android.PathsIfNonNil(j.combinedHeaderFile) } func (j *Import) ImplementationAndResourcesJars() android.Paths { - if j.combinedClasspathFile == nil { - return nil - } - return android.Paths{j.combinedClasspathFile} + return android.PathsIfNonNil(j.combinedImplementationFile) } -func (j *Import) DexJarBuildPath() OptionalDexJarPath { +func (j *Import) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { + if j.dexJarFileErr != nil { + ctx.ModuleErrorf(j.dexJarFileErr.Error()) + } return j.dexJarFile } @@ -2426,7 +2981,7 @@ func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, // java_sdk_library_import with the specified base module name requires to be exported from a // prebuilt_apex/apex_set. func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []string { - dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(name) + dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(name) // Add the dex implementation jar to the set of exported files. files := []string{ dexJarFileApexRootRelative, @@ -2437,9 +2992,9 @@ func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []strin return files } -// apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for +// ApexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for // the java library with the specified name. -func apexRootRelativePathToJavaLib(name string) string { +func ApexRootRelativePathToJavaLib(name string) string { return filepath.Join("javalib", name+".jar") } @@ -2450,14 +3005,18 @@ func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []st return requiredFilesFromPrebuiltApexForImport(name, &j.dexpreopter) } +func (j *Import) UseProfileGuidedDexpreopt() bool { + return proptools.Bool(j.importDexpreoptProperties.Dex_preopt.Profile_guided) +} + // Add compile time check for interface implementation var _ android.IDEInfo = (*Import)(nil) var _ android.IDECustomizedModuleName = (*Import)(nil) // Collect information for opening IDE project files in java/jdeps.go. -func (j *Import) IDEInfo(dpInfo *android.IdeInfo) { - dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...) +func (j *Import) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) { + dpInfo.Jars = append(dpInfo.Jars, j.combinedHeaderFile.String()) } func (j *Import) IDECustomizedModuleName() string { @@ -2497,7 +3056,6 @@ func ImportFactory() android.Module { android.InitPrebuiltModule(module, &module.properties.Jars) android.InitApexModule(module) - android.InitBazelModule(module) InitJavaModule(module, android.HostAndDeviceSupported) return module } @@ -2514,7 +3072,6 @@ func ImportFactoryHost() android.Module { android.InitPrebuiltModule(module, &module.properties.Jars) android.InitApexModule(module) - android.InitBazelModule(module) InitJavaModule(module, android.HostSupported) return module } @@ -2583,14 +3140,14 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.PropertyErrorf("jars", "exactly one jar must be provided") } - apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if !apexInfo.IsForPlatform() { j.hideApexVariantFromMake = true } j.dexpreopter.installPath = j.dexpreopter.getInstallPath( - ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) - j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) + ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) + j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &j.dexpreopter) inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars") dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar") @@ -2629,7 +3186,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) - j.dexpreopt(ctx, dexOutputFile) + j.dexpreopt(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexOutputFile) if apexInfo.IsForPlatform() { ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), @@ -2637,7 +3194,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } -func (j *DexImport) DexJarBuildPath() OptionalDexJarPath { +func (j *DexImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { return j.dexJarFile } @@ -2709,7 +3266,7 @@ func DefaultsFactory() android.Module { module.AddProperties( &CommonProperties{}, &DeviceProperties{}, - &OverridableDeviceProperties{}, + &OverridableProperties{}, &DexProperties{}, &DexpreoptProperties{}, &android.ProtoProperties{}, @@ -2730,6 +3287,8 @@ func DefaultsFactory() android.Module { &LintProperties{}, &appTestHelperAppProperties{}, &JavaApiLibraryProperties{}, + &bootclasspathFragmentProperties{}, + &SourceOnlyBootclasspathProperties{}, ) android.InitDefaultsModule(module) @@ -2804,706 +3363,52 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, // <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies // from its CLC should be added to the current CLC. if sdkLib != nil { - clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, - dep.DexJarBuildPath().PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) - } else { - clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) - } -} - -type javaResourcesAttributes struct { - Resources bazel.LabelListAttribute - Resource_strip_prefix *string - Additional_resources bazel.LabelListAttribute `blueprint:"mutated"` -} - -func (m *Library) getResourceFilegroupStripPrefix(ctx android.Bp2buildMutatorContext, resourceFilegroup string) (*string, bool) { - if otherM, ok := ctx.ModuleFromName(resourceFilegroup); ok { - if fg, isFilegroup := otherM.(android.FileGroupPath); isFilegroup { - return proptools.StringPtr(filepath.Join(ctx.OtherModuleDir(otherM), fg.GetPath(ctx))), true - } - } - return proptools.StringPtr(""), false -} - -func (m *Library) convertJavaResourcesAttributes(ctx android.Bp2buildMutatorContext) *javaResourcesAttributes { - var resources bazel.LabelList - var resourceStripPrefix *string - - additionalJavaResourcesMap := make(map[string]*javaResourcesAttributes) - - if m.properties.Java_resources != nil { - for _, res := range m.properties.Java_resources { - if prefix, isFilegroup := m.getResourceFilegroupStripPrefix(ctx, res); isFilegroup { - otherM, _ := ctx.ModuleFromName(res) - resourcesTargetName := ctx.ModuleName() + "_filegroup_resources_" + otherM.Name() - additionalJavaResourcesMap[resourcesTargetName] = &javaResourcesAttributes{ - Resources: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, []string{res})), - Resource_strip_prefix: prefix, - } - } else { - resources.Append(android.BazelLabelForModuleSrc(ctx, []string{res})) - } - } - - if !resources.IsEmpty() { - resourceStripPrefix = proptools.StringPtr(ctx.ModuleDir()) - } - } - - //TODO(b/179889880) handle case where glob includes files outside package - resDeps := ResourceDirsToFiles( - ctx, - m.properties.Java_resource_dirs, - m.properties.Exclude_java_resource_dirs, - m.properties.Exclude_java_resources, - ) - - for _, resDep := range resDeps { - dir, files := resDep.dir, resDep.files - - // Bazel includes the relative path from the WORKSPACE root when placing the resource - // inside the JAR file, so we need to remove that prefix - prefix := proptools.StringPtr(dir.String()) - resourcesTargetName := ctx.ModuleName() + "_resource_dir_" + dir.String() - additionalJavaResourcesMap[resourcesTargetName] = &javaResourcesAttributes{ - Resources: bazel.MakeLabelListAttribute(bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, files))), - Resource_strip_prefix: prefix, - } - } - - var additionalResourceLabels bazel.LabelList - if len(additionalJavaResourcesMap) > 0 { - var additionalResources []string - for resName, _ := range additionalJavaResourcesMap { - additionalResources = append(additionalResources, resName) - } - sort.Strings(additionalResources) - - for i, resName := range additionalResources { - resAttr := additionalJavaResourcesMap[resName] - if resourceStripPrefix == nil && i == 0 { - resourceStripPrefix = resAttr.Resource_strip_prefix - resources = resAttr.Resources.Value - } else if !resAttr.Resources.IsEmpty() { - ctx.CreateBazelTargetModule( - bazel.BazelTargetModuleProperties{ - Rule_class: "java_resources", - Bzl_load_location: "//build/bazel/rules/java:java_resources.bzl", - }, - android.CommonAttributes{Name: resName}, - resAttr, - ) - additionalResourceLabels.Append(android.BazelLabelForModuleSrc(ctx, []string{resName})) - } - } - - } - - return &javaResourcesAttributes{ - Resources: bazel.MakeLabelListAttribute(resources), - Resource_strip_prefix: resourceStripPrefix, - Additional_resources: bazel.MakeLabelListAttribute(additionalResourceLabels), - } -} - -type javaCommonAttributes struct { - *javaResourcesAttributes - *kotlinAttributes - Srcs bazel.LabelListAttribute - Plugins bazel.LabelListAttribute - Javacopts bazel.StringListAttribute - Sdk_version bazel.StringAttribute - Java_version bazel.StringAttribute - Errorprone_force_enable bazel.BoolAttribute - Javac_shard_size *int64 -} - -type javaDependencyLabels struct { - // Dependencies which DO NOT contribute to the API visible to upstream dependencies. - Deps bazel.LabelListAttribute - // Dependencies which DO contribute to the API visible to upstream dependencies. - StaticDeps bazel.LabelListAttribute -} - -type eventLogTagsAttributes struct { - Srcs bazel.LabelListAttribute -} - -type aidlLibraryAttributes struct { - Srcs bazel.LabelListAttribute - Tags bazel.StringListAttribute -} - -type javaAidlLibraryAttributes struct { - Deps bazel.LabelListAttribute - Tags bazel.StringListAttribute -} - -// bp2BuildJavaInfo has information needed for the conversion of java*_modules -// that is needed bor Bp2Build conversion but that requires different handling -// depending on the module type. -type bp2BuildJavaInfo struct { - // separates dependencies into dynamic dependencies and static dependencies. - DepLabels *javaDependencyLabels - hasKotlin bool -} - -func javaXsdTargetName(xsd android.XsdConfigBp2buildTargets) string { - return xsd.JavaBp2buildTargetName() -} - -// convertLibraryAttrsBp2Build returns a javaCommonAttributes struct with -// converted attributes shared across java_* modules and a bp2BuildJavaInfo struct -// which has other non-attribute information needed for bp2build conversion -// that needs different handling depending on the module types, and thus needs -// to be returned to the calling function. -func (m *Library) convertLibraryAttrsBp2Build(ctx android.Bp2buildMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo, bool) { - var srcs bazel.LabelListAttribute - var deps bazel.LabelListAttribute - var staticDeps bazel.LabelListAttribute - - if proptools.String(m.deviceProperties.Sdk_version) == "" && m.DeviceSupported() { - // TODO(b/297356704): handle platform apis in bp2build - ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "sdk_version unset") - return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false - } else if proptools.String(m.deviceProperties.Sdk_version) == "core_platform" { - // TODO(b/297356582): handle core_platform in bp2build - ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "sdk_version core_platform") - return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false - } - - archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{}) - for axis, configToProps := range archVariantProps { - for config, p := range configToProps { - if archProps, ok := p.(*CommonProperties); ok { - archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Srcs, archProps.Exclude_srcs) - srcs.SetSelectValue(axis, config, archSrcs) - if archProps.Jarjar_rules != nil { - ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "jarjar_rules") - return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false - } - } - } - } - srcs.Append( - bazel.MakeLabelListAttribute( - android.BazelLabelForModuleSrcExcludes(ctx, - m.properties.Openjdk9.Srcs, - m.properties.Exclude_srcs))) - srcs.ResolveExcludes() - - javaSrcPartition := "java" - protoSrcPartition := "proto" - xsdSrcPartition := "xsd" - logtagSrcPartition := "logtag" - aidlSrcPartition := "aidl" - kotlinPartition := "kotlin" - srcPartitions := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{ - javaSrcPartition: bazel.LabelPartition{Extensions: []string{".java"}, Keep_remainder: true}, - logtagSrcPartition: bazel.LabelPartition{Extensions: []string{".logtags", ".logtag"}}, - protoSrcPartition: android.ProtoSrcLabelPartition, - aidlSrcPartition: android.AidlSrcLabelPartition, - xsdSrcPartition: bazel.LabelPartition{LabelMapper: android.XsdLabelMapper(javaXsdTargetName)}, - kotlinPartition: bazel.LabelPartition{Extensions: []string{".kt"}}, - }) - - javaSrcs := srcPartitions[javaSrcPartition] - kotlinSrcs := srcPartitions[kotlinPartition] - javaSrcs.Append(kotlinSrcs) - - staticDeps.Append(srcPartitions[xsdSrcPartition]) - - if !srcPartitions[logtagSrcPartition].IsEmpty() { - logtagsLibName := m.Name() + "_logtags" - ctx.CreateBazelTargetModule( - bazel.BazelTargetModuleProperties{ - Rule_class: "event_log_tags", - Bzl_load_location: "//build/bazel/rules/java:event_log_tags.bzl", - }, - android.CommonAttributes{Name: logtagsLibName}, - &eventLogTagsAttributes{ - Srcs: srcPartitions[logtagSrcPartition], - }, - ) - - logtagsSrcs := bazel.MakeLabelList([]bazel.Label{{Label: ":" + logtagsLibName}}) - javaSrcs.Append(bazel.MakeLabelListAttribute(logtagsSrcs)) - } - - if !srcPartitions[aidlSrcPartition].IsEmpty() { - aidlLibs, aidlSrcs := srcPartitions[aidlSrcPartition].Partition(func(src bazel.Label) bool { - return android.IsConvertedToAidlLibrary(ctx, src.OriginalModuleName) - }) - - apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx, ctx.Module()) - - if !aidlSrcs.IsEmpty() { - aidlLibName := m.Name() + "_aidl_library" - ctx.CreateBazelTargetModule( - bazel.BazelTargetModuleProperties{ - Rule_class: "aidl_library", - Bzl_load_location: "//build/bazel/rules/aidl:aidl_library.bzl", - }, - android.CommonAttributes{Name: aidlLibName}, - &aidlLibraryAttributes{ - Srcs: aidlSrcs, - Tags: apexAvailableTags, - }, - ) - aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}}) - } - - javaAidlLibName := m.Name() + "_java_aidl_library" - ctx.CreateBazelTargetModule( - bazel.BazelTargetModuleProperties{ - Rule_class: "java_aidl_library", - Bzl_load_location: "//build/bazel/rules/java:java_aidl_library.bzl", - }, - android.CommonAttributes{Name: javaAidlLibName}, - &javaAidlLibraryAttributes{ - Deps: aidlLibs, - Tags: apexAvailableTags, - }, - ) - - staticDeps.Append(bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + javaAidlLibName})) - } - - var javacopts bazel.StringListAttribute //[]string - plugins := bazel.MakeLabelListAttribute( - android.BazelLabelForModuleDeps(ctx, m.properties.Plugins), - ) - if m.properties.Javacflags != nil || m.properties.Openjdk9.Javacflags != nil { - javacopts = bazel.MakeStringListAttribute( - append(append([]string{}, m.properties.Javacflags...), m.properties.Openjdk9.Javacflags...)) - } - - epEnabled := m.properties.Errorprone.Enabled - epJavacflags := m.properties.Errorprone.Javacflags - var errorproneForceEnable bazel.BoolAttribute - if epEnabled == nil { - //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable - } else if *epEnabled { - plugins.Append(bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, m.properties.Errorprone.Extra_check_modules))) - javacopts.Append(bazel.MakeStringListAttribute(epJavacflags)) - errorproneForceEnable.Value = epEnabled - } else { - javacopts.Append(bazel.MakeStringListAttribute([]string{"-XepDisableAllChecks"})) - } - - resourcesAttrs := m.convertJavaResourcesAttributes(ctx) - - commonAttrs := &javaCommonAttributes{ - Srcs: javaSrcs, - javaResourcesAttributes: resourcesAttrs, - Plugins: plugins, - Javacopts: javacopts, - Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, - Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, - Errorprone_force_enable: errorproneForceEnable, - Javac_shard_size: m.properties.Javac_shard_size, - } - - for axis, configToProps := range archVariantProps { - for config, _props := range configToProps { - if archProps, ok := _props.(*CommonProperties); ok { - var libLabels []bazel.Label - for _, d := range archProps.Libs { - neverlinkLabel := android.BazelLabelForModuleDepSingle(ctx, d) - neverlinkLabel.Label = neverlinkLabel.Label + "-neverlink" - libLabels = append(libLabels, neverlinkLabel) - } - deps.SetSelectValue(axis, config, bazel.MakeLabelList(libLabels)) + optional := false + if module, ok := ctx.Module().(ModuleWithUsesLibrary); ok { + if android.InList(*sdkLib, module.UsesLibrary().usesLibraryProperties.Optional_uses_libs) { + optional = true } } - } - - depLabels := &javaDependencyLabels{} - deps.Append(resourcesAttrs.Additional_resources) - depLabels.Deps = deps - - for axis, configToProps := range archVariantProps { - for config, _props := range configToProps { - if archProps, ok := _props.(*CommonProperties); ok { - archStaticLibs := android.BazelLabelForModuleDeps( - ctx, - android.LastUniqueStrings(android.CopyOf(archProps.Static_libs))) - depLabels.StaticDeps.SetSelectValue(axis, config, archStaticLibs) - } - } - } - depLabels.StaticDeps.Append(staticDeps) - - var additionalProtoDeps bazel.LabelListAttribute - additionalProtoDeps.Append(depLabels.Deps) - additionalProtoDeps.Append(depLabels.StaticDeps) - protoDepLabel := bp2buildProto(ctx, &m.Module, srcPartitions[protoSrcPartition], additionalProtoDeps) - // Soong does not differentiate between a java_library and the Bazel equivalent of - // a java_proto_library + proto_library pair. Instead, in Soong proto sources are - // listed directly in the srcs of a java_library, and the classes produced - // by protoc are included directly in the resulting JAR. Thus upstream dependencies - // that depend on a java_library with proto sources can link directly to the protobuf API, - // and so this should be a static dependency. - if protoDepLabel != nil { - depLabels.StaticDeps.Append(bazel.MakeSingleLabelListAttribute(*protoDepLabel)) - } - - hasKotlin := !kotlinSrcs.IsEmpty() - commonAttrs.kotlinAttributes = &kotlinAttributes{ - Kotlincflags: &m.properties.Kotlincflags, - } - if len(m.properties.Common_srcs) != 0 { - hasKotlin = true - commonAttrs.kotlinAttributes.Common_srcs = bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Common_srcs)) - } - - bp2BuildInfo := &bp2BuildJavaInfo{ - DepLabels: depLabels, - hasKotlin: hasKotlin, - } - - return commonAttrs, bp2BuildInfo, true -} - -type javaLibraryAttributes struct { - *javaCommonAttributes - Deps bazel.LabelListAttribute - Exports bazel.LabelListAttribute - Neverlink bazel.BoolAttribute -} - -type kotlinAttributes struct { - Common_srcs bazel.LabelListAttribute - Kotlincflags *[]string -} - -func ktJvmLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties { - return bazel.BazelTargetModuleProperties{ - Rule_class: "kt_jvm_library", - Bzl_load_location: "//build/bazel/rules/kotlin:kt_jvm_library.bzl", - } -} - -func javaLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties { - return bazel.BazelTargetModuleProperties{ - Rule_class: "java_library", - Bzl_load_location: "//build/bazel/rules/java:library.bzl", - } -} - -func javaLibraryBp2Build(ctx android.Bp2buildMutatorContext, m *Library) { - commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx) - if !supported { - return - } - depLabels := bp2BuildInfo.DepLabels - - deps := depLabels.Deps - exports := depLabels.StaticDeps - if !commonAttrs.Srcs.IsEmpty() { - deps.Append(exports) // we should only append these if there are sources to use them - } else if !deps.IsEmpty() { - // java_library does not accept deps when there are no srcs because - // there is no compilation happening, but it accepts exports. - // The non-empty deps here are unnecessary as deps on the java_library - // since they aren't being propagated to any dependencies. - // So we can drop deps here. - deps = bazel.LabelListAttribute{} - } - var props bazel.BazelTargetModuleProperties - attrs := &javaLibraryAttributes{ - javaCommonAttributes: commonAttrs, - Deps: deps, - Exports: exports, - } - name := m.Name() - - if !bp2BuildInfo.hasKotlin { - props = javaLibraryBazelTargetModuleProperties() + clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional, + dep.DexJarBuildPath(ctx).PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) } else { - props = ktJvmLibraryBazelTargetModuleProperties() - } - - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs) - neverlinkProp := true - neverLinkAttrs := &javaLibraryAttributes{ - Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), - Neverlink: bazel.BoolAttribute{Value: &neverlinkProp}, - javaCommonAttributes: &javaCommonAttributes{ - Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, - Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, - }, - } - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name + "-neverlink"}, neverLinkAttrs) - -} - -type javaBinaryHostAttributes struct { - *javaCommonAttributes - Deps bazel.LabelListAttribute - Runtime_deps bazel.LabelListAttribute - Main_class string - Jvm_flags bazel.StringListAttribute -} - -// JavaBinaryHostBp2Build is for java_binary_host bp2build. -func javaBinaryHostBp2Build(ctx android.Bp2buildMutatorContext, m *Binary) { - commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx) - if !supported { - return - } - depLabels := bp2BuildInfo.DepLabels - - deps := depLabels.Deps - deps.Append(depLabels.StaticDeps) - if m.binaryProperties.Jni_libs != nil { - deps.Append(bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, m.binaryProperties.Jni_libs))) - } - - var runtimeDeps bazel.LabelListAttribute - if commonAttrs.Srcs.IsEmpty() { - // if there are no sources, then the dependencies can only be used at runtime - runtimeDeps = deps - deps = bazel.LabelListAttribute{} - } - - mainClass := "" - if m.binaryProperties.Main_class != nil { - mainClass = *m.binaryProperties.Main_class - } - if m.properties.Manifest != nil { - mainClassInManifest, err := android.GetMainClassInManifest(ctx.Config(), android.PathForModuleSrc(ctx, *m.properties.Manifest).String()) - if err != nil { - return - } - mainClass = mainClassInManifest - } - - // Attribute jvm_flags - var jvmFlags bazel.StringListAttribute - if m.binaryProperties.Jni_libs != nil { - jniLibPackages := []string{} - for _, jniLib := range m.binaryProperties.Jni_libs { - if jniLibModule, exists := ctx.ModuleFromName(jniLib); exists { - otherDir := ctx.OtherModuleDir(jniLibModule) - jniLibPackages = append(jniLibPackages, filepath.Join(otherDir, jniLib)) - } - } - jniLibPaths := []string{} - for _, jniLibPackage := range jniLibPackages { - // See cs/f:.*/third_party/bazel/.*java_stub_template.txt for the use of RUNPATH - jniLibPaths = append(jniLibPaths, "$${RUNPATH}"+jniLibPackage) - } - jvmFlags = bazel.MakeStringListAttribute([]string{"-Djava.library.path=" + strings.Join(jniLibPaths, ":")}) - } - - props := bazel.BazelTargetModuleProperties{ - Rule_class: "java_binary", - Bzl_load_location: "@rules_java//java:defs.bzl", - } - binAttrs := &javaBinaryHostAttributes{ - Runtime_deps: runtimeDeps, - Main_class: mainClass, - Jvm_flags: jvmFlags, - } - - if commonAttrs.Srcs.IsEmpty() { - binAttrs.javaCommonAttributes = commonAttrs - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs) - return - } - - libInfo := libraryCreationInfo{ - deps: deps, - attrs: commonAttrs, - baseName: m.Name(), - hasKotlin: bp2BuildInfo.hasKotlin, + clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) } - libName := createLibraryTarget(ctx, libInfo) - binAttrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) - - // Create the BazelTargetModule. - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs) -} - -type javaTestHostAttributes struct { - *javaCommonAttributes - Srcs bazel.LabelListAttribute - Deps bazel.LabelListAttribute - Runtime_deps bazel.LabelListAttribute } -// javaTestHostBp2Build is for java_test_host bp2build. -func javaTestHostBp2Build(ctx android.Bp2buildMutatorContext, m *TestHost) { - commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx) - if !supported { - return - } - depLabels := bp2BuildInfo.DepLabels - - deps := depLabels.Deps - deps.Append(depLabels.StaticDeps) - - var runtimeDeps bazel.LabelListAttribute - attrs := &javaTestHostAttributes{ - Runtime_deps: runtimeDeps, - } - props := bazel.BazelTargetModuleProperties{ - Rule_class: "java_test", - Bzl_load_location: "//build/bazel/rules/java:test.bzl", - } +func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.Module, + usesLibrary *usesLibrary) { - if commonAttrs.Srcs.IsEmpty() { - // if there are no sources, then the dependencies can only be used at runtime - attrs.Runtime_deps = deps - attrs.javaCommonAttributes = commonAttrs - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) + dep, ok := depModule.(ModuleWithUsesLibrary) + if !ok { return } - libInfo := libraryCreationInfo{ - deps: deps, - attrs: commonAttrs, - baseName: m.Name(), - hasKotlin: bp2BuildInfo.hasKotlin, - } - libName := createLibraryTarget(ctx, libInfo) - - attrs.Srcs = commonAttrs.Srcs - attrs.Deps = deps - attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) - // Create the BazelTargetModule. - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) -} - -// libraryCreationInfo encapsulates the info needed to create java_library target from -// java_binary_host or java_test_host. -type libraryCreationInfo struct { - deps bazel.LabelListAttribute - attrs *javaCommonAttributes - baseName string - hasKotlin bool -} - -// helper function that creates java_library target from java_binary_host or java_test_host, -// and returns the library target name, -func createLibraryTarget(ctx android.Bp2buildMutatorContext, libInfo libraryCreationInfo) string { - libName := libInfo.baseName + "_lib" - var libProps bazel.BazelTargetModuleProperties - if libInfo.hasKotlin { - libProps = ktJvmLibraryBazelTargetModuleProperties() - } else { - libProps = javaLibraryBazelTargetModuleProperties() - } - libAttrs := &javaLibraryAttributes{ - Deps: libInfo.deps, - javaCommonAttributes: libInfo.attrs, - } - - ctx.CreateBazelTargetModule(libProps, android.CommonAttributes{Name: libName}, libAttrs) - return libName -} - -type bazelJavaImportAttributes struct { - Jars bazel.LabelListAttribute - Exports bazel.LabelListAttribute -} - -// java_import bp2Build converter. -func (i *Import) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { - var jars bazel.LabelListAttribute - archVariantProps := i.GetArchVariantProperties(ctx, &ImportProperties{}) - for axis, configToProps := range archVariantProps { - for config, _props := range configToProps { - if archProps, ok := _props.(*ImportProperties); ok { - archJars := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Jars, []string(nil)) - jars.SetSelectValue(axis, config, archJars) - } + for _, lib := range dep.UsesLibrary().usesLibraryProperties.Missing_optional_uses_libs { + if !android.InList(lib, usesLibrary.usesLibraryProperties.Missing_optional_uses_libs) { + usesLibrary.usesLibraryProperties.Missing_optional_uses_libs = + append(usesLibrary.usesLibraryProperties.Missing_optional_uses_libs, lib) } } - - attrs := &bazelJavaImportAttributes{ - Jars: jars, - } - props := bazel.BazelTargetModuleProperties{ - Rule_class: "java_import", - Bzl_load_location: "//build/bazel/rules/java:import.bzl", - } - - name := android.RemoveOptionalPrebuiltPrefix(i.Name()) - - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs) - - neverlink := true - neverlinkAttrs := &javaLibraryAttributes{ - Neverlink: bazel.BoolAttribute{Value: &neverlink}, - Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), - javaCommonAttributes: &javaCommonAttributes{ - Sdk_version: bazel.StringAttribute{Value: proptools.StringPtr("none")}, - }, - } - ctx.CreateBazelTargetModule( - javaLibraryBazelTargetModuleProperties(), - android.CommonAttributes{Name: name + "-neverlink"}, - neverlinkAttrs) -} - -var _ android.MixedBuildBuildable = (*Import)(nil) - -func (i *Import) getBazelModuleLabel(ctx android.BaseModuleContext) string { - return android.RemoveOptionalPrebuiltPrefixFromBazelLabel(i.GetBazelLabel(ctx, i)) -} - -func (i *Import) ProcessBazelQueryResponse(ctx android.ModuleContext) { - i.commonBuildActions(ctx) - - bazelCtx := ctx.Config().BazelContext - filePaths, err := bazelCtx.GetOutputFiles(i.getBazelModuleLabel(ctx), android.GetConfigKey(ctx)) - if err != nil { - ctx.ModuleErrorf(err.Error()) - return - } - - bazelJars := android.Paths{} - for _, bazelOutputFile := range filePaths { - bazelJars = append(bazelJars, android.PathForBazelOut(ctx, bazelOutputFile)) - } - - jarName := android.RemoveOptionalPrebuiltPrefix(i.Name()) + ".jar" - outputFile := android.PathForModuleOut(ctx, "bazelCombined", jarName) - TransformJarsToJar(ctx, outputFile, "combine prebuilt jars", bazelJars, - android.OptionalPath{}, // manifest - false, // stripDirEntries - []string{}, // filesToStrip - []string{}, // dirsToStrip - ) - i.combinedClasspathFile = outputFile - - ctx.SetProvider(JavaInfoProvider, JavaInfo{ - HeaderJars: android.PathsIfNonNil(i.combinedClasspathFile), - ImplementationAndResourcesJars: android.PathsIfNonNil(i.combinedClasspathFile), - ImplementationJars: android.PathsIfNonNil(i.combinedClasspathFile), - // TODO(b/240308299) include AIDL information from Bazel - // TODO: aconfig files? - }) - - i.maybeInstall(ctx, jarName, outputFile) } -func (i *Import) QueueBazelCall(ctx android.BaseModuleContext) { - bazelCtx := ctx.Config().BazelContext - bazelCtx.QueueBazelRequest(i.getBazelModuleLabel(ctx), cquery.GetOutputFiles, android.GetConfigKey(ctx)) -} +type JavaApiContributionImport struct { + JavaApiContribution -func (i *Import) IsMixedBuildSupported(ctx android.BaseModuleContext) bool { - return true + prebuilt android.Prebuilt + prebuiltProperties javaApiContributionImportProperties } -type JavaApiContributionImport struct { - JavaApiContribution +type javaApiContributionImportProperties struct { + // Name of the source soong module that gets shadowed by this prebuilt + // If unspecified, follows the naming convention that the source module of + // the prebuilt is Name() without "prebuilt_" prefix + Source_module_name *string - prebuilt android.Prebuilt + // Non-nil if this java_import module was dynamically created by a java_sdk_library_import + // The name is the undecorated name of the java_sdk_library as it appears in the blueprint file + // (without any prebuilt_ prefix) + Created_by_java_sdk_library_name *string `blueprint:"mutated"` } func ApiContributionImportFactory() android.Module { @@ -3511,7 +3416,8 @@ func ApiContributionImportFactory() android.Module { android.InitAndroidModule(module) android.InitDefaultableModule(module) android.InitPrebuiltModule(module, &[]string{""}) - module.AddProperties(&module.properties) + module.AddProperties(&module.properties, &module.prebuiltProperties) + module.AddProperties(&module.sdkLibraryComponentProperties) return module } @@ -3523,6 +3429,14 @@ func (module *JavaApiContributionImport) Name() string { return module.prebuilt.Name(module.ModuleBase.Name()) } +func (j *JavaApiContributionImport) BaseModuleName() string { + return proptools.StringDefault(j.prebuiltProperties.Source_module_name, j.ModuleBase.Name()) +} + +func (j *JavaApiContributionImport) CreatedByJavaSdkLibraryName() *string { + return j.prebuiltProperties.Created_by_java_sdk_library_name +} + func (ap *JavaApiContributionImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { ap.JavaApiContribution.GenerateAndroidBuildActions(ctx) } |