diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 399d9b92f..cebbae9a6 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -639,7 +639,7 @@ func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutator return false } - name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) + name := java.ModuleStemForDeapexing(child) if _, ok := tag.(android.RequiresFilesFromPrebuiltApexTag); ok { commonModules = append(commonModules, name) diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go index 201780175..0ebab4d8c 100644 --- a/java/classpath_fragment.go +++ b/java/classpath_fragment.go @@ -103,8 +103,8 @@ type classpathJar struct { func gatherPossibleApexModuleNamesAndStems(ctx android.ModuleContext, contents []string, tag blueprint.DependencyTag) []string { set := map[string]struct{}{} for _, name := range contents { - dep := ctx.GetDirectDepWithTag(name, tag) - set[name] = struct{}{} + dep, _ := ctx.GetDirectDepWithTag(name, tag).(android.Module) + set[ModuleStemForDeapexing(dep)] = struct{}{} if m, ok := dep.(ModuleWithStem); ok { set[m.Stem()] = struct{}{} } else { diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 01f60d403..f7e3cb93a 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -726,13 +726,19 @@ func (m *apexNameToApexExportsInfoMap) javaLibraryDexPathOnHost(ctx android.Modu return nil, false } +// Returns the stem of an artifact inside a prebuilt apex +func ModuleStemForDeapexing(m android.Module) string { + bmn, _ := m.(interface{ BaseModuleName() string }) + return bmn.BaseModuleName() +} + // Returns the java libraries exported by the apex for hiddenapi and dexpreopt // This information can come from two mechanisms // 1. New: Direct deps to _selected_ apexes. The apexes return a ApexExportsInfo // 2. Legacy: An edge to java_library or java_import (java_sdk_library) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes // TODO: b/308174306 - Once all mainline modules have been flagged, drop (2) func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNameToApexExportsInfoMap apexNameToApexExportsInfoMap) android.Path { - if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, pair.apex, android.RemoveOptionalPrebuiltPrefix(pair.jarModule.Name())); found { + if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, pair.apex, ModuleStemForDeapexing(pair.jarModule)); found { return dex } // TODO: b/308174306 - Remove the legacy mechanism diff --git a/java/system_modules.go b/java/system_modules.go index f3446483b..92e31cdf9 100644 --- a/java/system_modules.go +++ b/java/system_modules.go @@ -19,6 +19,7 @@ import ( "strings" "github.com/google/blueprint" + "github.com/google/blueprint/proptools" "android/soong/android" ) @@ -210,7 +211,7 @@ func (system *SystemModules) AndroidMk() android.AndroidMkData { // type and the one to use is selected at runtime. func systemModulesImportFactory() android.Module { module := &systemModulesImport{} - module.AddProperties(&module.properties) + module.AddProperties(&module.properties, &module.prebuiltProperties) android.InitPrebuiltModule(module, &module.properties.Libs) android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon) android.InitDefaultableModule(module) @@ -219,13 +220,39 @@ func systemModulesImportFactory() android.Module { type systemModulesImport struct { SystemModules - prebuilt android.Prebuilt + prebuilt android.Prebuilt + prebuiltProperties prebuiltSystemModulesProperties +} + +type prebuiltSystemModulesProperties 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 } func (system *systemModulesImport) Name() string { return system.prebuilt.Name(system.ModuleBase.Name()) } +// BaseModuleName returns the source module that will get shadowed by this prebuilt +// e.g. +// +// java_system_modules_import { +// name: "my_system_modules.v1", +// source_module_name: "my_system_modules", +// } +// +// java_system_modules_import { +// name: "my_system_modules.v2", +// source_module_name: "my_system_modules", +// } +// +// `BaseModuleName` for both will return `my_system_modules` +func (system *systemModulesImport) BaseModuleName() string { + return proptools.StringDefault(system.prebuiltProperties.Source_module_name, system.ModuleBase.Name()) +} + func (system *systemModulesImport) Prebuilt() *android.Prebuilt { return &system.prebuilt } diff --git a/java/system_modules_test.go b/java/system_modules_test.go index 2ceca5d0b..336dd2134 100644 --- a/java/system_modules_test.go +++ b/java/system_modules_test.go @@ -15,6 +15,7 @@ package java import ( + "fmt" "testing" "android/soong/android" @@ -111,3 +112,85 @@ func TestJavaSystemModulesMixSourceAndPrebuilt(t *testing.T) { expectedPrebuiltPaths := getModuleHeaderJarsAsRelativeToTopPaths(result, "prebuilt_system-module1", "prebuilt_system-module2") android.AssertArrayString(t, "prebuilt system modules inputs", expectedPrebuiltPaths, prebuiltInputs.RelativeToTop().Strings()) } + +func TestMultipleSystemModulesPrebuilts(t *testing.T) { + bp := ` + // an rdep + java_library { + name: "foo", + sdk_version: "none", + system_modules: "my_system_modules", + } + + // multiple variations of java_system_modules + // source + java_system_modules { + name: "my_system_modules", + libs: ["bar"], + } + java_library { + name: "bar", + srcs: ["bar.java"], + } + // prebuilt "v1" + java_system_modules_import { + name: "my_system_modules.v1", + source_module_name: "my_system_modules", + libs: ["bar.v1"], + } + java_import { + name: "bar.v1", + source_module_name: "bar", + jars: ["bar.v1.jar"], + } + // prebuilt "v2" + java_system_modules_import { + name: "my_system_modules.v2", + source_module_name: "my_system_modules", + libs: ["bar.v2"], + } + java_import { + name: "bar.v2", + source_module_name: "bar", + jars: ["bar.v2.jar"], + } + + // selectors + apex_contributions { + name: "myapex_contributions", + contents: ["%v"], + } + ` + testCases := []struct { + desc string + selectedDependencyName string + }{ + { + desc: "Source system_modules is selected using apex_contributions", + selectedDependencyName: "my_system_modules", + }, + { + desc: "Prebuilt system_modules v1 is selected using apex_contributions", + selectedDependencyName: "prebuilt_my_system_modules.v1", + }, + { + desc: "Prebuilt system_modules v2 is selected using apex_contributions", + selectedDependencyName: "prebuilt_my_system_modules.v2", + }, + } + + for _, tc := range testCases { + res := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.BuildFlags = map[string]string{ + "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions", + } + }), + ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName)) + + // check that rdep gets the correct variation of system_modules + hasDep := CheckModuleHasDependency(t, res.TestContext, "foo", "android_common", tc.selectedDependencyName) + android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from foo to %s\n", tc.selectedDependencyName), true, hasDep) + } +}