diff --git a/android/androidmk.go b/android/androidmk.go index 1f1bd701b..124523f4c 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -79,12 +79,14 @@ type AndroidMkEntries struct { header bytes.Buffer footer bytes.Buffer - AddCustomEntries func(name, prefix, moduleDir string, entries *AndroidMkEntries) + ExtraEntries []AndroidMkExtraEntriesFunc EntryMap map[string][]string entryOrder []string } +type AndroidMkExtraEntriesFunc func(entries *AndroidMkEntries) + func (a *AndroidMkEntries) SetString(name, value string) { if _, ok := a.EntryMap[name]; !ok { a.entryOrder = append(a.entryOrder, name) @@ -246,9 +248,8 @@ func (a *AndroidMkEntries) fillInEntries(config Config, bpPath string, mod bluep prefix = "2ND_" + prefix } } - blueprintDir := filepath.Dir(bpPath) - if a.AddCustomEntries != nil { - a.AddCustomEntries(name, prefix, blueprintDir, a) + for _, extra := range a.ExtraEntries { + extra(a) } // Write to footer. diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go index 9722a2540..d29ed16f6 100644 --- a/android/prebuilt_etc.go +++ b/android/prebuilt_etc.go @@ -155,16 +155,18 @@ func (p *PrebuiltEtc) AndroidMkEntries() AndroidMkEntries { Class: "ETC", SubName: nameSuffix, OutputFile: OptionalPathForPath(p.outputFilePath), - AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) { - entries.SetString("LOCAL_MODULE_TAGS", "optional") - entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString()) - entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base()) - entries.SetString("LOCAL_UNINSTALLABLE_MODULE", strconv.FormatBool(!p.Installable())) - if p.additionalDependencies != nil { - for _, path := range *p.additionalDependencies { - entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", path.String()) + ExtraEntries: []AndroidMkExtraEntriesFunc{ + func(entries *AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_TAGS", "optional") + entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString()) + entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base()) + entries.SetString("LOCAL_UNINSTALLABLE_MODULE", strconv.FormatBool(!p.Installable())) + if p.additionalDependencies != nil { + for _, path := range *p.additionalDependencies { + entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", path.String()) + } } - } + }, }, } } diff --git a/android/sh_binary.go b/android/sh_binary.go index 2855aa040..ba0c8be7d 100644 --- a/android/sh_binary.go +++ b/android/sh_binary.go @@ -133,8 +133,10 @@ func (s *ShBinary) AndroidMkEntries() AndroidMkEntries { Class: "EXECUTABLES", OutputFile: OptionalPathForPath(s.outputFilePath), Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk", - AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) { - s.customAndroidMkEntries(entries) + ExtraEntries: []AndroidMkExtraEntriesFunc{ + func(entries *AndroidMkEntries) { + s.customAndroidMkEntries(entries) + }, }, } } @@ -156,20 +158,22 @@ func (s *ShTest) AndroidMkEntries() AndroidMkEntries { Class: "NATIVE_TESTS", OutputFile: OptionalPathForPath(s.outputFilePath), Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk", - AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) { - s.customAndroidMkEntries(entries) + ExtraEntries: []AndroidMkExtraEntriesFunc{ + func(entries *AndroidMkEntries) { + s.customAndroidMkEntries(entries) - entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...) - entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config)) - for _, d := range s.data { - rel := d.Rel() - path := d.String() - if !strings.HasSuffix(path, rel) { - panic(fmt.Errorf("path %q does not end with %q", path, rel)) + entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...) + entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config)) + for _, d := range s.data { + rel := d.Rel() + path := d.String() + if !strings.HasSuffix(path, rel) { + panic(fmt.Errorf("path %q does not end with %q", path, rel)) + } + path = strings.TrimSuffix(path, rel) + entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel) } - path = strings.TrimSuffix(path, rel) - entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel) - } + }, }, } } diff --git a/apex/apex.go b/apex/apex.go index 806158a9d..832188d81 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1687,11 +1687,13 @@ func (p *Prebuilt) AndroidMkEntries() android.AndroidMkEntries { Class: "ETC", OutputFile: android.OptionalPathForPath(p.inputApex), Include: "$(BUILD_PREBUILT)", - AddCustomEntries: func(name, prefix, moduleDir string, entries *android.AndroidMkEntries) { - entries.SetString("LOCAL_MODULE_PATH", filepath.Join("$(OUT_DIR)", p.installDir.RelPathString())) - entries.SetString("LOCAL_MODULE_STEM", p.installFilename) - entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable()) - entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", p.properties.Overrides...) + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_PATH", filepath.Join("$(OUT_DIR)", p.installDir.RelPathString())) + entries.SetString("LOCAL_MODULE_STEM", p.installFilename) + entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable()) + entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", p.properties.Overrides...) + }, }, } } diff --git a/java/androidmk.go b/java/androidmk.go index c00e070a0..0e8e42248 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -122,6 +122,15 @@ func testSuiteComponent(w io.Writer, test_suites []string) { } } +func testSuiteComponentEntries(entries *android.AndroidMkEntries, test_suites []string) { + entries.SetString("LOCAL_MODULE_TAGS", "tests") + if len(test_suites) > 0 { + entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", test_suites...) + } else { + entries.SetString("LOCAL_COMPATIBILITY_SUITE", "null-suite") + } +} + func (j *Test) AndroidMk() android.AndroidMkData { data := j.Library.AndroidMk() data.Extra = append(data.Extra, func(w io.Writer, outputFile android.Path) { @@ -614,22 +623,33 @@ func (a *AndroidAppImport) AndroidMkEntries() android.AndroidMkEntries { Class: "APPS", OutputFile: android.OptionalPathForPath(a.outputFile), Include: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk", - AddCustomEntries: func(name, prefix, moduleDir string, entries *android.AndroidMkEntries) { - entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", Bool(a.properties.Privileged)) - if a.certificate != nil { - entries.SetString("LOCAL_CERTIFICATE", a.certificate.Pem.String()) - } else { - entries.SetString("LOCAL_CERTIFICATE", "PRESIGNED") - } - entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", a.properties.Overrides...) - if len(a.dexpreopter.builtInstalled) > 0 { - entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", a.dexpreopter.builtInstalled) - } - entries.AddStrings("LOCAL_INSTALLED_MODULE_STEM", a.installPath.Rel()) + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { + entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", Bool(a.properties.Privileged)) + if a.certificate != nil { + entries.SetString("LOCAL_CERTIFICATE", a.certificate.Pem.String()) + } else { + entries.SetString("LOCAL_CERTIFICATE", "PRESIGNED") + } + entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", a.properties.Overrides...) + if len(a.dexpreopter.builtInstalled) > 0 { + entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", a.dexpreopter.builtInstalled) + } + entries.AddStrings("LOCAL_INSTALLED_MODULE_STEM", a.installPath.Rel()) + }, }, } } +func (a *AndroidTestImport) AndroidMkEntries() android.AndroidMkEntries { + entries := a.AndroidAppImport.AndroidMkEntries() + entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) { + testSuiteComponentEntries(entries, a.testProperties.Test_suites) + androidMkEntriesWriteTestData(a.data, entries) + }) + return entries +} + func androidMkWriteTestData(data android.Paths, ret *android.AndroidMkData) { var testFiles []string for _, d := range data { @@ -641,3 +661,11 @@ func androidMkWriteTestData(data android.Paths, ret *android.AndroidMkData) { }) } } + +func androidMkEntriesWriteTestData(data android.Paths, entries *android.AndroidMkEntries) { + var testFiles []string + for _, d := range data { + testFiles = append(testFiles, d.String()+":"+d.Rel()) + } + entries.AddStrings("LOCAL_COMPATIBILITY_SUPPORT_FILES", testFiles...) +} diff --git a/java/app.go b/java/app.go index f5a5da01b..7df4358d7 100644 --- a/java/app.go +++ b/java/app.go @@ -39,6 +39,7 @@ func init() { android.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory) android.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory) android.RegisterModuleType("android_app_import", AndroidAppImportFactory) + android.RegisterModuleType("android_test_import", AndroidTestImportFactory) initAndroidAppImportVariantGroupTypes() } @@ -866,6 +867,10 @@ func (a *AndroidAppImport) uncompressDex( } func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { + a.generateAndroidBuildActions(ctx) +} + +func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) { numCertPropsSet := 0 if String(a.properties.Certificate) != "" { numCertPropsSet++ @@ -1024,6 +1029,39 @@ func AndroidAppImportFactory() android.Module { return module } +type AndroidTestImport struct { + AndroidAppImport + + testProperties testProperties + + data android.Paths +} + +func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { + a.generateAndroidBuildActions(ctx) + + a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) +} + +// android_test_import imports a prebuilt test apk with additional processing specified in the +// module. DPI or arch variant configurations can be made as with android_app_import. +func AndroidTestImportFactory() android.Module { + module := &AndroidTestImport{} + module.AddProperties(&module.properties) + module.AddProperties(&module.dexpreoptProperties) + module.AddProperties(&module.usesLibrary.usesLibraryProperties) + module.AddProperties(&module.testProperties) + module.populateAllVariantStructs() + android.AddLoadHook(module, func(ctx android.LoadHookContext) { + module.processVariants(ctx) + }) + + InitJavaModule(module, android.DeviceSupported) + android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk") + + return module +} + type UsesLibraryProperties struct { // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file. Uses_libs []string diff --git a/java/app_test.go b/java/app_test.go index be1ff2945..f2aaec344 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -1381,6 +1381,34 @@ func TestAndroidAppImport_ArchVariants(t *testing.T) { } } +func TestAndroidTestImport(t *testing.T) { + ctx, config := testJava(t, ` + android_test_import { + name: "foo", + apk: "prebuilts/apk/app.apk", + presigned: true, + data: [ + "testdata/data", + ], + } + `) + + test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport) + + // Check android mks. + entries := android.AndroidMkEntriesForTest(t, config, "", test) + expected := []string{"tests"} + actual := entries.EntryMap["LOCAL_MODULE_TAGS"] + if !reflect.DeepEqual(expected, actual) { + t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual) + } + expected = []string{"testdata/data:testdata/data"} + actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] + if !reflect.DeepEqual(expected, actual) { + t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual) + } +} + func TestStl(t *testing.T) { ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` cc_library { diff --git a/java/java_test.go b/java/java_test.go index 5fcdf9670..c55e32553 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -66,6 +66,7 @@ func testContext(bp string, fs map[string][]byte) *android.TestContext { ctx.RegisterModuleType("android_library", android.ModuleFactoryAdaptor(AndroidLibraryFactory)) ctx.RegisterModuleType("android_test", android.ModuleFactoryAdaptor(AndroidTestFactory)) ctx.RegisterModuleType("android_test_helper_app", android.ModuleFactoryAdaptor(AndroidTestHelperAppFactory)) + ctx.RegisterModuleType("android_test_import", android.ModuleFactoryAdaptor(AndroidTestImportFactory)) ctx.RegisterModuleType("java_binary", android.ModuleFactoryAdaptor(BinaryFactory)) ctx.RegisterModuleType("java_binary_host", android.ModuleFactoryAdaptor(BinaryHostFactory)) ctx.RegisterModuleType("java_device_for_host", android.ModuleFactoryAdaptor(DeviceForHostFactory)) @@ -200,6 +201,8 @@ func testContext(bp string, fs map[string][]byte) *android.TestContext { "cert/new_cert.x509.pem": nil, "cert/new_cert.pk8": nil, + + "testdata/data": nil, } for k, v := range fs { diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index 792edf388..f1da20394 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -77,9 +77,11 @@ func (p *platformCompatConfig) AndroidMkEntries() android.AndroidMkEntries { Class: "ETC", OutputFile: android.OptionalPathForPath(p.configFile), Include: "$(BUILD_PREBUILT)", - AddCustomEntries: func(name, prefix, moduleDir string, entries *android.AndroidMkEntries) { - entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString()) - entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base()) + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString()) + entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base()) + }, }, } }