diff --git a/android/test_asserts.go b/android/test_asserts.go index 5cc7e4ac0..3a2cb1ad9 100644 --- a/android/test_asserts.go +++ b/android/test_asserts.go @@ -200,6 +200,22 @@ func AssertArrayString(t *testing.T, message string, expected, actual []string) } } +// Asserts that each of the Paths in actual end with the corresponding string +// from expected. Useful to test that output paths contain expected items without +// hard-coding where intermediate files might be located. +func AssertPathsEndWith(t *testing.T, message string, expected []string, actual []Path) { + t.Helper() + if len(expected) != len(actual) { + t.Errorf("%s (length): expected %d, actual %d", message, len(expected), len(actual)) + return + } + for i := range expected { + if !strings.HasSuffix(actual[i].String(), expected[i]) { + t.Errorf("%s (item %d): expected '%s', actual '%s'", message, i, expected[i], actual[i].String()) + } + } +} + // AssertDeepEquals checks if the expected and actual values are equal using reflect.DeepEqual and // if they are not then it reports an error prefixed with the supplied message and including a // reason for why it failed. diff --git a/device_config/Android.bp b/device_config/Android.bp index 360b3898a..6c4445499 100644 --- a/device_config/Android.bp +++ b/device_config/Android.bp @@ -12,19 +12,21 @@ bootstrap_go_package { "soong", "soong-android", "soong-bazel", - "soong-shared", + "soong-android", + "soong-java", ], srcs: [ "device_config_definitions.go", "device_config_values.go", "device_config_value_set.go", "init.go", - //"testing.go" + "java_device_config_definitions_library.go", + "testing.go", ], - /* testSrcs: [ - "device_config_test.go", + "device_config_definitions_test.go", + "device_config_values_test.go", + "device_config_value_set_test.go", ], - */ pluginFor: ["soong_build"], } diff --git a/device_config/device_config_definitions.go b/device_config/device_config_definitions.go index c5657666c..bb78695f1 100644 --- a/device_config/device_config_definitions.go +++ b/device_config/device_config_definitions.go @@ -38,7 +38,6 @@ type DefinitionsModule struct { } intermediatePath android.WritablePath - srcJarPath android.WritablePath } func DefinitionsFactory() android.Module { @@ -78,8 +77,6 @@ func (module *DefinitionsModule) DepsMutator(ctx android.BottomUpMutatorContext) func (module *DefinitionsModule) OutputFiles(tag string) (android.Paths, error) { switch tag { - case ".srcjar": - return []android.Path{module.srcJarPath}, nil case "": // The default output of this module is the intermediates format, which is // not installable and in a private format that no other rules can handle @@ -99,6 +96,14 @@ func joinAndPrefix(prefix string, values []string) string { return sb.String() } +// Provider published by device_config_value_set +type definitionsProviderData struct { + namespace string + intermediatePath android.WritablePath +} + +var definitionsProviderKey = blueprint.NewProvider(definitionsProviderData{}) + func (module *DefinitionsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Get the values that came from the global RELEASE_DEVICE_CONFIG_VALUE_SETS flag ctx.VisitDirectDeps(func(dep android.Module) { @@ -117,11 +122,11 @@ func (module *DefinitionsModule) GenerateAndroidBuildActions(ctx android.ModuleC // Intermediate format inputFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs) - module.intermediatePath = android.PathForModuleOut(ctx, "intermediate.json") + intermediatePath := android.PathForModuleOut(ctx, "intermediate.json") ctx.Build(pctx, android.BuildParams{ Rule: aconfigRule, Inputs: inputFiles, - Output: module.intermediatePath, + Output: intermediatePath, Description: "device_config_definitions", Args: map[string]string{ "release_version": ctx.Config().ReleaseVersion(), @@ -130,21 +135,9 @@ func (module *DefinitionsModule) GenerateAndroidBuildActions(ctx android.ModuleC }, }) - // Generated java inside a srcjar - module.srcJarPath = android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar") - ctx.Build(pctx, android.BuildParams{ - Rule: srcJarRule, - Input: module.intermediatePath, - Output: module.srcJarPath, - Description: "device_config.srcjar", + ctx.SetProvider(definitionsProviderKey, definitionsProviderData{ + namespace: module.properties.Namespace, + intermediatePath: intermediatePath, }) - // TODO: C++ - - // Phony target for debugging convenience - ctx.Build(pctx, android.BuildParams{ - Rule: blueprint.Phony, - Output: android.PathForPhony(ctx, ctx.ModuleName()), - Inputs: []android.Path{module.srcJarPath}, // TODO: C++ - }) } diff --git a/device_config/device_config_definitions_test.go b/device_config/device_config_definitions_test.go new file mode 100644 index 000000000..49afcc4d5 --- /dev/null +++ b/device_config/device_config_definitions_test.go @@ -0,0 +1,42 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package device_config + +import ( + "strings" + "testing" + + "android/soong/android" +) + +func TestDeviceConfigDefinitions(t *testing.T) { + bp := ` + device_config_definitions { + name: "module_name", + namespace: "com.example.package", + srcs: ["foo.aconfig"], + } + ` + result := runTest(t, android.FixtureExpectsNoErrors, bp) + + module := result.ModuleForTests("module_name", "").Module().(*DefinitionsModule) + + // Check that the provider has the right contents + depData := result.ModuleProvider(module, definitionsProviderKey).(definitionsProviderData) + android.AssertStringEquals(t, "namespace", depData.namespace, "com.example.package") + if !strings.HasSuffix(depData.intermediatePath.String(), "/intermediate.json") { + t.Errorf("Missing intermediates path in provider: %s", depData.intermediatePath.String()) + } +} diff --git a/device_config/device_config_test.go b/device_config/device_config_test.go deleted file mode 100644 index 91a06a781..000000000 --- a/device_config/device_config_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package device_config - -import ( - "os" - "testing" - - "android/soong/android" - "android/soong/java" -) - -func TestMain(m *testing.M) { - os.Exit(m.Run()) -} - -func test(t *testing.T, bp string) *android.TestResult { - t.Helper() - - mockFS := android.MockFS{ - "config.aconfig": nil, - } - - result := android.GroupFixturePreparers( - java.PrepareForTestWithJavaDefaultModules, - PrepareForTestWithSyspropBuildComponents, - // TODO: Consider values files, although maybe in its own test - // android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { - // variables.ReleaseConfigValuesBasePaths = ... - //}) - mockFS.AddToFixture(), - android.FixtureWithRootAndroidBp(bp), - ).RunTest(t) - - return result -} - -func TestOutputs(t *testing.T) { - /*result := */ test(t, ` - device_config { - name: "my_device_config", - srcs: ["config.aconfig"], - } - `) - - // TODO: Make sure it exports a .srcjar, which is used by java libraries - // TODO: Make sure it exports an intermediates file - // TODO: Make sure the intermediates file is propagated to the Android.mk file -} diff --git a/device_config/device_config_value_set_test.go b/device_config/device_config_value_set_test.go new file mode 100644 index 000000000..f9e7c38e4 --- /dev/null +++ b/device_config/device_config_value_set_test.go @@ -0,0 +1,43 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package device_config + +import ( + "testing" + + "android/soong/android" +) + +func TestDeviceConfigValueSet(t *testing.T) { + bp := ` + device_config_values { + name: "one", + srcs: [ "blah.aconfig_values" ], + namespace: "foo.namespace" + } + + device_config_value_set { + name: "module_name", + values: [ "one" ], + } + ` + result := runTest(t, android.FixtureExpectsNoErrors, bp) + + module := result.ModuleForTests("module_name", "").Module().(*ValueSetModule) + + // Check that the provider has the right contents + depData := result.ModuleProvider(module, valueSetProviderKey).(valueSetProviderData) + android.AssertStringEquals(t, "AvailableNamespaces", "blah.aconfig_values", depData.AvailableNamespaces["foo.namespace"][0].String()) +} diff --git a/device_config/device_config_values_test.go b/device_config/device_config_values_test.go new file mode 100644 index 000000000..64c57eb87 --- /dev/null +++ b/device_config/device_config_values_test.go @@ -0,0 +1,39 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package device_config + +import ( + "testing" + + "android/soong/android" +) + +func TestDeviceConfigValues(t *testing.T) { + bp := ` + device_config_values { + name: "module_name", + srcs: [ "blah.aconfig_values" ], + namespace: "foo.namespace" + } + ` + result := runTest(t, android.FixtureExpectsNoErrors, bp) + + module := result.ModuleForTests("module_name", "").Module().(*ValuesModule) + + // Check that the provider has the right contents + depData := result.ModuleProvider(module, valuesProviderKey).(valuesProviderData) + android.AssertStringEquals(t, "namespace", "foo.namespace", depData.Namespace) + android.AssertPathsEndWith(t, "srcs", []string{"blah.aconfig_values"}, depData.Values) +} diff --git a/device_config/init.go b/device_config/init.go index 6d235c484..04bbab661 100644 --- a/device_config/init.go +++ b/device_config/init.go @@ -23,7 +23,6 @@ var ( pctx = android.NewPackageContext("android/soong/device_config") // For device_config_definitions: Generate cache file - // TODO: Restat aconfigRule = pctx.AndroidStaticRule("aconfig", blueprint.RuleParams{ Command: `${aconfig} create-cache` + @@ -39,7 +38,7 @@ var ( Restat: true, }, "release_version", "namespace", "values") - // For device_config_definitions: Generate java file + // For java_device_config_definitions_library: Generate java file srcJarRule = pctx.AndroidStaticRule("aconfig_srcjar", blueprint.RuleParams{ Command: `rm -rf ${out}.tmp` + @@ -59,12 +58,13 @@ var ( func init() { registerBuildComponents(android.InitRegistrationContext) + pctx.HostBinToolVariable("aconfig", "aconfig") + pctx.HostBinToolVariable("soong_zip", "soong_zip") } func registerBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("device_config_definitions", DefinitionsFactory) ctx.RegisterModuleType("device_config_values", ValuesFactory) ctx.RegisterModuleType("device_config_value_set", ValueSetFactory) - pctx.HostBinToolVariable("aconfig", "aconfig") - pctx.HostBinToolVariable("soong_zip", "soong_zip") + ctx.RegisterModuleType("java_device_config_definitions_library", JavaDefinitionsLibraryFactory) } diff --git a/device_config/java_device_config_definitions_library.go b/device_config/java_device_config_definitions_library.go new file mode 100644 index 000000000..6e48ece16 --- /dev/null +++ b/device_config/java_device_config_definitions_library.go @@ -0,0 +1,71 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package device_config + +import ( + "android/soong/android" + "android/soong/java" + "fmt" + "github.com/google/blueprint" +) + +type definitionsTagType struct { + blueprint.BaseDependencyTag +} + +var definitionsTag = definitionsTagType{} + +type JavaDeviceConfigDefinitionsLibraryProperties struct { + // name of the device_config_definitions module to generate a library for + Device_config_definitions string +} + +type JavaDeviceConfigDefinitionsLibraryCallbacks struct { + properties JavaDeviceConfigDefinitionsLibraryProperties +} + +func JavaDefinitionsLibraryFactory() android.Module { + callbacks := &JavaDeviceConfigDefinitionsLibraryCallbacks{} + return java.GeneratedJavaLibraryModuleFactory("java_device_config_definitions_library", callbacks, &callbacks.properties) +} + +func (callbacks *JavaDeviceConfigDefinitionsLibraryCallbacks) DepsMutator(module *java.GeneratedJavaLibraryModule, ctx android.BottomUpMutatorContext) { + definitions := callbacks.properties.Device_config_definitions + if len(definitions) == 0 { + // TODO: Add test for this case + ctx.PropertyErrorf("device_config_definitions", "device_config_definitions property required") + } else { + ctx.AddDependency(ctx.Module(), definitionsTag, definitions) + } +} + +func (callbacks *JavaDeviceConfigDefinitionsLibraryCallbacks) GenerateSourceJarBuildActions(ctx android.ModuleContext) android.Path { + // Get the values that came from the global RELEASE_DEVICE_CONFIG_VALUE_SETS flag + definitionsModules := ctx.GetDirectDepsWithTag(definitionsTag) + if len(definitionsModules) != 1 { + panic(fmt.Errorf("Exactly one device_config_definitions property required")) + } + definitions := ctx.OtherModuleProvider(definitionsModules[0], definitionsProviderKey).(definitionsProviderData) + + srcJarPath := android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar") + ctx.Build(pctx, android.BuildParams{ + Rule: srcJarRule, + Input: definitions.intermediatePath, + Output: srcJarPath, + Description: "device_config.srcjar", + }) + + return srcJarPath +} diff --git a/device_config/testing.go b/device_config/testing.go index f0544766b..284a7fa55 100644 --- a/device_config/testing.go +++ b/device_config/testing.go @@ -14,6 +14,16 @@ package device_config -import "android/soong/android" +import ( + "testing" -var PrepareForTestWithSyspropBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents) + "android/soong/android" +) + +var PrepareForTestWithDeviceConfigBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents) + +func runTest(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult { + return android.GroupFixturePreparers(PrepareForTestWithDeviceConfigBuildComponents). + ExtendWithErrorHandler(errorHandler). + RunTestWithBp(t, bp) +} diff --git a/java/Android.bp b/java/Android.bp index 4af2a14eb..e07986975 100644 --- a/java/Android.bp +++ b/java/Android.bp @@ -48,6 +48,7 @@ bootstrap_go_package { "droidstubs.go", "fuzz.go", "gen.go", + "generated_java_library.go", "genrule.go", "hiddenapi.go", "hiddenapi_modular.go", @@ -92,6 +93,7 @@ bootstrap_go_package { "droidstubs_test.go", "fuzz_test.go", "genrule_test.go", + "generated_java_library_test.go", "hiddenapi_singleton_test.go", "jacoco_test.go", "java_test.go", diff --git a/java/base.go b/java/base.go index ed61e12ed..afb626a49 100644 --- a/java/base.go +++ b/java/base.go @@ -187,6 +187,9 @@ type CommonProperties struct { // A list of java_library instances that provide additional hiddenapi annotations for the library. Hiddenapi_additional_annotations []string + + // Additional srcJars tacked in by GeneratedJavaLibraryModule + Generated_srcjars []android.Path `android:"mutated"` } // Properties that are specific to device modules. Host module factories should not add these when @@ -1041,6 +1044,10 @@ func (j *Module) AddJSONData(d *map[string]interface{}) { } +func (module *Module) addGeneratedSrcJars(path android.Path) { + module.properties.Generated_srcjars = append(module.properties.Generated_srcjars, path) +} + func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs) @@ -1082,6 +1089,10 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { if aaptSrcJar != nil { srcJars = append(srcJars, aaptSrcJar) } + srcJars = append(srcJars, j.properties.Generated_srcjars...) + if len(j.properties.Generated_srcjars) > 0 { + fmt.Printf("Java module %s Generated_srcjars: %v\n", ctx.ModuleName(), j.properties.Generated_srcjars) + } srcFiles = srcFiles.FilterOutByExt(".srcjar") if j.properties.Jarjar_rules != nil { diff --git a/java/builder.go b/java/builder.go index 0c5773823..c4395e91d 100644 --- a/java/builder.go +++ b/java/builder.go @@ -305,6 +305,12 @@ type javaBuilderFlags struct { proto android.ProtoFlags } +func DefaultJavaBuilderFlags() javaBuilderFlags { + return javaBuilderFlags{ + javaVersion: JAVA_VERSION_8, + } +} + func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath, shardIdx int, srcFiles, srcJars android.Paths, flags javaBuilderFlags, deps android.Paths) { diff --git a/java/generated_java_library.go b/java/generated_java_library.go new file mode 100644 index 000000000..1b3de9fe0 --- /dev/null +++ b/java/generated_java_library.go @@ -0,0 +1,94 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package java + +import ( + "android/soong/android" +) + +type GeneratedJavaLibraryModule struct { + Library + callbacks GeneratedJavaLibraryCallbacks + moduleName string +} + +type GeneratedJavaLibraryCallbacks interface { + // Called from inside DepsMutator, gives a chance to AddDependencies + DepsMutator(module *GeneratedJavaLibraryModule, ctx android.BottomUpMutatorContext) + + // Called from inside GenerateAndroidBuildActions. Add the build rules to + // make the srcjar, and return the path to it. + GenerateSourceJarBuildActions(ctx android.ModuleContext) android.Path +} + +// GeneratedJavaLibraryModuleFactory provides a utility for modules that are generated +// source code, including ones outside the java package to build jar files +// from that generated source. +// +// To use GeneratedJavaLibraryModule, call GeneratedJavaLibraryModuleFactory with +// a callback interface and a properties object to add to the module. +// +// These modules will have some properties blocked, and it will be an error if +// modules attempt to set them. See the list of property names in GeneratedAndroidBuildActions +// for the list of those properties. +func GeneratedJavaLibraryModuleFactory(moduleName string, callbacks GeneratedJavaLibraryCallbacks, properties interface{}) android.Module { + module := &GeneratedJavaLibraryModule{ + callbacks: callbacks, + moduleName: moduleName, + } + module.addHostAndDeviceProperties() + module.initModuleAndImport(module) + android.InitApexModule(module) + android.InitBazelModule(module) + InitJavaModule(module, android.HostAndDeviceSupported) + if properties != nil { + module.AddProperties(properties) + } + return module +} + +func (module *GeneratedJavaLibraryModule) DepsMutator(ctx android.BottomUpMutatorContext) { + module.callbacks.DepsMutator(module, ctx) + module.Library.DepsMutator(ctx) +} + +func checkPropertyEmpty(ctx android.ModuleContext, module *GeneratedJavaLibraryModule, name string, value []string) { + if len(value) != 0 { + ctx.PropertyErrorf(name, "%s not allowed on %s", name, module.moduleName) + } +} + +func (module *GeneratedJavaLibraryModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + // These modules are all-generated, so disallow these properties to keep it simple. + // No additional sources + checkPropertyEmpty(ctx, module, "srcs", module.Library.properties.Srcs) + checkPropertyEmpty(ctx, module, "common_srcs", module.Library.properties.Common_srcs) + checkPropertyEmpty(ctx, module, "exclude_srcs", module.Library.properties.Exclude_srcs) + checkPropertyEmpty(ctx, module, "java_resource_dirs", module.Library.properties.Java_resource_dirs) + checkPropertyEmpty(ctx, module, "exclude_java_resource_dirs", module.Library.properties.Exclude_java_resource_dirs) + // No additional libraries. The generator should add anything necessary automatically + // by returning something from ____ (TODO: Additional libraries aren't needed now, so + // these are just blocked). + checkPropertyEmpty(ctx, module, "libs", module.Library.properties.Libs) + checkPropertyEmpty(ctx, module, "static_libs", module.Library.properties.Static_libs) + // Restrict these for no good reason other than to limit the surface area. If there's a + // good use case put them back. + checkPropertyEmpty(ctx, module, "plugins", module.Library.properties.Plugins) + checkPropertyEmpty(ctx, module, "exported_plugins", module.Library.properties.Exported_plugins) + + srcJarPath := module.callbacks.GenerateSourceJarBuildActions(ctx) + module.Library.properties.Generated_srcjars = append(module.Library.properties.Generated_srcjars, srcJarPath) + module.Library.GenerateAndroidBuildActions(ctx) +} diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go new file mode 100644 index 000000000..68f1f7edd --- /dev/null +++ b/java/generated_java_library_test.go @@ -0,0 +1,65 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package java + +import ( + "testing" + + "android/soong/android" +) + +func JavaGenLibTestFactory() android.Module { + callbacks := &JavaGenLibTestCallbacks{} + return GeneratedJavaLibraryModuleFactory("test_java_gen_lib", callbacks, &callbacks.properties) +} + +type JavaGenLibTestProperties struct { + Foo string +} + +type JavaGenLibTestCallbacks struct { + properties JavaGenLibTestProperties +} + +func (callbacks *JavaGenLibTestCallbacks) DepsMutator(module *GeneratedJavaLibraryModule, ctx android.BottomUpMutatorContext) { +} + +func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(ctx android.ModuleContext) android.Path { + return android.PathForOutput(ctx, "blah.srcjar") +} + +func testGenLib(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult { + return android.GroupFixturePreparers( + PrepareForIntegrationTestWithJava, + android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("test_java_gen_lib", JavaGenLibTestFactory) + }), + ). + ExtendWithErrorHandler(errorHandler). + RunTestWithBp(t, bp) +} + +func TestGenLib(t *testing.T) { + bp := ` + test_java_gen_lib { + name: "javagenlibtest", + foo: "bar", // Note: This won't parse if the property didn't get added + } + ` + result := testGenLib(t, android.FixtureExpectsNoErrors, bp) + + javagenlibtest := result.ModuleForTests("javagenlibtest", "android_common").Module().(*GeneratedJavaLibraryModule) + android.AssertPathsEndWith(t, "Generated_srcjars", []string{"/blah.srcjar"}, javagenlibtest.Library.properties.Generated_srcjars) +} diff --git a/java/java.go b/java/java.go index 3a8047143..a026610c2 100644 --- a/java/java.go +++ b/java/java.go @@ -273,6 +273,8 @@ type JavaInfo struct { // JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be // instrumented by jacoco. JacocoReportClassesFile android.Path + + // TODO: Add device config declarations here? } var JavaInfoProvider = blueprint.NewProvider(JavaInfo{})