diff --git a/aconfig/java_aconfig_library.go b/aconfig/java_aconfig_library.go index 4db0ef794..48cfb7695 100644 --- a/aconfig/java_aconfig_library.go +++ b/aconfig/java_aconfig_library.go @@ -15,10 +15,13 @@ package aconfig import ( - "android/soong/android" - "android/soong/java" "fmt" + + "android/soong/android" + "android/soong/bazel" + "android/soong/java" "github.com/google/blueprint" + "github.com/google/blueprint/proptools" ) type declarationsTagType struct { @@ -32,7 +35,7 @@ type JavaAconfigDeclarationsLibraryProperties struct { Aconfig_declarations string // whether to generate test mode version of the library - Test bool + Test *bool } type JavaAconfigDeclarationsLibraryCallbacks struct { @@ -68,7 +71,7 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild // Generate the action to build the srcjar srcJarPath := android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar") var mode string - if callbacks.properties.Test { + if proptools.Bool(callbacks.properties.Test) { mode = "test" } else { mode = "production" @@ -89,3 +92,39 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild return srcJarPath } + +type bazelJavaAconfigLibraryAttributes struct { + Aconfig_declarations bazel.LabelAttribute + Test *bool + Sdk_version *string +} + +func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) Bp2build(ctx android.Bp2buildMutatorContext, module *java.GeneratedJavaLibraryModule) { + if ctx.ModuleType() != "java_aconfig_library" { + return + } + + // By default, soong builds the aconfig java library with private_current, however + // bazel currently doesn't support it so we default it to system_current. One reason + // is that the dependency of all java_aconfig_library aconfig-annotations-lib is + // built with system_current. For the java aconfig library itself it doesn't really + // matter whether it uses private API or system API because the only module it uses + // is DeviceConfig which is in system, and the rdeps of the java aconfig library + // won't change its sdk version either, so this should be fine. + // Ideally we should only use the default value if it is not set by the user, but + // bazel only supports a limited sdk versions, for example, the java_aconfig_library + // modules in framework/base use core_platform which is not supported by bazel yet. + // TODO(b/302148527): change soong to default to system_current as well. + sdkVersion := "system_current" + attrs := bazelJavaAconfigLibraryAttributes{ + Aconfig_declarations: *bazel.MakeLabelAttribute(android.BazelLabelForModuleDepSingle(ctx, callbacks.properties.Aconfig_declarations).Label), + Test: callbacks.properties.Test, + Sdk_version: &sdkVersion, + } + props := bazel.BazelTargetModuleProperties{ + Rule_class: "java_aconfig_library", + Bzl_load_location: "//build/bazel/rules/java:java_aconfig_library.bzl", + } + + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: ctx.ModuleName()}, &attrs) +} diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 64cb2fa51..3d64ae316 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -523,6 +523,7 @@ var ( } Bp2buildModuleAlwaysConvertList = []string{ + "AconfigJavaHostTest", // aconfig "libonce_cell", "libanyhow", @@ -1002,6 +1003,7 @@ var ( "cc_prebuilt_library_static", "combined_apis", "droiddoc_exported_dir", + "java_aconfig_library", "java_import", "java_import_host", "java_sdk_library", diff --git a/android/bazel_paths.go b/android/bazel_paths.go index d8effaa12..ac7d34941 100644 --- a/android/bazel_paths.go +++ b/android/bazel_paths.go @@ -442,7 +442,8 @@ func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string, otherLabel := labelFromModule(ctx, m) // TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets. - if tag != "" && m.Name() == "framework-res" { + if (tag != "" && m.Name() == "framework-res") || + (tag == ".generated_srcjars" && ctx.OtherModuleType(m) == "java_aconfig_library") { otherLabel += tag } diff --git a/bp2build/aconfig_conversion_test.go b/bp2build/aconfig_conversion_test.go index 51f0b2ff3..9d73ec09c 100644 --- a/bp2build/aconfig_conversion_test.go +++ b/bp2build/aconfig_conversion_test.go @@ -20,11 +20,13 @@ import ( "android/soong/aconfig" "android/soong/android" "android/soong/cc" + "android/soong/java" ) func registerAconfigModuleTypes(ctx android.RegistrationContext) { aconfig.RegisterBuildComponents(ctx) ctx.RegisterModuleType("cc_library", cc.LibraryFactory) + ctx.RegisterModuleType("java_library", java.LibraryFactory) } func TestAconfigDeclarations(t *testing.T) { @@ -135,3 +137,101 @@ func TestCcAconfigLibrary(t *testing.T) { StubbedBuildDefinitions: []string{"server_configurable_flags"}, }) } + +func TestJavaAconfigLibrary(t *testing.T) { + bp := ` + aconfig_declarations { + name: "foo_aconfig_declarations", + srcs: [ + "foo1.aconfig", + ], + package: "com.android.foo", + } + java_aconfig_library { + name: "foo", + aconfig_declarations: "foo_aconfig_declarations", + test: true, + } + ` + expectedBazelTargets := []string{ + MakeBazelTargetNoRestrictions( + "aconfig_declarations", + "foo_aconfig_declarations", + AttrNameToString{ + "srcs": `["foo1.aconfig"]`, + "package": `"com.android.foo"`, + }, + ), + MakeBazelTargetNoRestrictions( + "java_aconfig_library", + "foo", + AttrNameToString{ + "aconfig_declarations": `":foo_aconfig_declarations"`, + "test": `True`, + "sdk_version": `"system_current"`, + "target_compatible_with": `["//build/bazel/platforms/os:android"]`, + }, + )} + RunBp2BuildTestCase(t, registerAconfigModuleTypes, Bp2buildTestCase{ + Blueprint: bp, + ExpectedBazelTargets: expectedBazelTargets, + }) +} + +func TestJavaAconfigLibraryAsTaggedOutput(t *testing.T) { + bp := ` + aconfig_declarations { + name: "foo_aconfig_declarations", + srcs: [ + "foo.aconfig", + ], + package: "com.android.foo", + } + java_library { + name: "foo_library", + srcs: [":foo_aconfig_library{.generated_srcjars}"], + sdk_version: "current", + bazel_module: { bp2build_available: true }, + } + java_aconfig_library { + name: "foo_aconfig_library", + aconfig_declarations: "foo_aconfig_declarations", + test: true, + } + ` + expectedBazelTargets := []string{ + MakeBazelTargetNoRestrictions( + "aconfig_declarations", + "foo_aconfig_declarations", + AttrNameToString{ + "srcs": `["foo.aconfig"]`, + "package": `"com.android.foo"`, + }, + ), + MakeBazelTargetNoRestrictions( + "java_aconfig_library", + "foo_aconfig_library", + AttrNameToString{ + "aconfig_declarations": `":foo_aconfig_declarations"`, + "test": `True`, + "sdk_version": `"system_current"`, + "target_compatible_with": `["//build/bazel/platforms/os:android"]`, + }, + ), + MakeBazelTargetNoRestrictions( + "java_library", + "foo_library", + AttrNameToString{ + "srcs": `[":foo_aconfig_library.generated_srcjars"]`, + "sdk_version": `"current"`, + "target_compatible_with": `["//build/bazel/platforms/os:android"]`, + }, + ), + MakeNeverlinkDuplicateTarget("java_library", "foo_library"), + } + + RunBp2BuildTestCase(t, registerAconfigModuleTypes, Bp2buildTestCase{ + Blueprint: bp, + ExpectedBazelTargets: expectedBazelTargets, + }) +} diff --git a/java/base.go b/java/base.go index db237dac0..53414d9ab 100644 --- a/java/base.go +++ b/java/base.go @@ -714,6 +714,10 @@ func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel return j.SdkVersion(ctx).ApiLevel } +func (j *Module) GetDeviceProperties() *DeviceProperties { + return &j.deviceProperties +} + func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { if j.deviceProperties.Max_sdk_version != nil { return android.ApiLevelFrom(ctx, *j.deviceProperties.Max_sdk_version) diff --git a/java/generated_java_library.go b/java/generated_java_library.go index 578237e3b..930bfd267 100644 --- a/java/generated_java_library.go +++ b/java/generated_java_library.go @@ -35,6 +35,8 @@ type GeneratedJavaLibraryCallbacks interface { // Called from inside GenerateAndroidBuildActions. Add the build rules to // make the srcjar, and return the path to it. GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path + + Bp2build(ctx android.Bp2buildMutatorContext, module *GeneratedJavaLibraryModule) } // GeneratedJavaLibraryModuleFactory provides a utility for modules that are generated @@ -108,3 +110,7 @@ func (module *GeneratedJavaLibraryModule) GenerateAndroidBuildActions(ctx androi module.Library.properties.Generated_srcjars = append(module.Library.properties.Generated_srcjars, srcJarPath) module.Library.GenerateAndroidBuildActions(ctx) } + +func (module *GeneratedJavaLibraryModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { + module.callbacks.Bp2build(ctx, module) +} diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go index 7f52fd108..7fbbfee22 100644 --- a/java/generated_java_library_test.go +++ b/java/generated_java_library_test.go @@ -41,6 +41,9 @@ func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module * return android.PathForOutput(ctx, "blah.srcjar") } +func (callbacks *JavaGenLibTestCallbacks) Bp2build(ctx android.Bp2buildMutatorContext, module *GeneratedJavaLibraryModule) { +} + func testGenLib(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult { return android.GroupFixturePreparers( PrepareForIntegrationTestWithJava,