diff --git a/android/apex_contributions.go b/android/apex_contributions.go index 8b72f8e4f..4cd8dda93 100644 --- a/android/apex_contributions.go +++ b/android/apex_contributions.go @@ -119,7 +119,10 @@ func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) { func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) { addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) { for _, content := range m.Contents() { - if !ctx.OtherModuleExists(content) && !ctx.Config().AllowMissingDependencies() { + // Verify that the module listed in contents exists in the tree + // Remove the prebuilt_ prefix to account for partner worksapces where the source module does not + // exist, and PrebuiltRenameMutator renames `prebuilt_foo` to `foo` + if !ctx.OtherModuleExists(content) && !ctx.OtherModuleExists(RemoveOptionalPrebuiltPrefix(content)) && !ctx.Config().AllowMissingDependencies() { ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name()) } pi := &PrebuiltSelectionInfo{ diff --git a/android/config.go b/android/config.go index 6b8691186..4745a1638 100644 --- a/android/config.go +++ b/android/config.go @@ -2005,41 +2005,41 @@ func (c *config) UseResourceProcessorByDefault() bool { } var ( - mainlineApexContributionBuildFlags = []string{ - "RELEASE_APEX_CONTRIBUTIONS_ADBD", - "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", - "RELEASE_APEX_CONTRIBUTIONS_APPSEARCH", - "RELEASE_APEX_CONTRIBUTIONS_ART", - "RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH", - "RELEASE_APEX_CONTRIBUTIONS_CAPTIVEPORTALLOGIN", - "RELEASE_APEX_CONTRIBUTIONS_CELLBROADCAST", - "RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE", - "RELEASE_APEX_CONTRIBUTIONS_CONNECTIVITY", - "RELEASE_APEX_CONTRIBUTIONS_CONSCRYPT", - "RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY", - "RELEASE_APEX_CONTRIBUTIONS_DEVICELOCK", - "RELEASE_APEX_CONTRIBUTIONS_DOCUMENTSUIGOOGLE", - "RELEASE_APEX_CONTRIBUTIONS_EXTSERVICES", - "RELEASE_APEX_CONTRIBUTIONS_HEALTHFITNESS", - "RELEASE_APEX_CONTRIBUTIONS_IPSEC", - "RELEASE_APEX_CONTRIBUTIONS_MEDIA", - "RELEASE_APEX_CONTRIBUTIONS_MEDIAPROVIDER", - "RELEASE_APEX_CONTRIBUTIONS_MODULE_METADATA", - "RELEASE_APEX_CONTRIBUTIONS_NETWORKSTACKGOOGLE", - "RELEASE_APEX_CONTRIBUTIONS_NEURALNETWORKS", - "RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION", - "RELEASE_APEX_CONTRIBUTIONS_PERMISSION", - "RELEASE_APEX_CONTRIBUTIONS_PRIMARY_LIBS", - "RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING", - "RELEASE_APEX_CONTRIBUTIONS_RESOLV", - "RELEASE_APEX_CONTRIBUTIONS_SCHEDULING", - "RELEASE_APEX_CONTRIBUTIONS_SDKEXTENSIONS", - "RELEASE_APEX_CONTRIBUTIONS_SWCODEC", - "RELEASE_APEX_CONTRIBUTIONS_STATSD", - "RELEASE_APEX_CONTRIBUTIONS_TELEMETRY_TVP", - "RELEASE_APEX_CONTRIBUTIONS_TZDATA", - "RELEASE_APEX_CONTRIBUTIONS_UWB", - "RELEASE_APEX_CONTRIBUTIONS_WIFI", + mainlineApexContributionBuildFlagsToApexNames = map[string]string{ + "RELEASE_APEX_CONTRIBUTIONS_ADBD": "com.android.adbd", + "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "com.android.adservices", + "RELEASE_APEX_CONTRIBUTIONS_APPSEARCH": "com.android.appsearch", + "RELEASE_APEX_CONTRIBUTIONS_ART": "com.android.art", + "RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH": "com.android.btservices", + "RELEASE_APEX_CONTRIBUTIONS_CAPTIVEPORTALLOGIN": "", + "RELEASE_APEX_CONTRIBUTIONS_CELLBROADCAST": "com.android.cellbroadcast", + "RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE": "com.android.configinfrastructure", + "RELEASE_APEX_CONTRIBUTIONS_CONNECTIVITY": "com.android.tethering", + "RELEASE_APEX_CONTRIBUTIONS_CONSCRYPT": "com.android.conscrypt", + "RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY": "", + "RELEASE_APEX_CONTRIBUTIONS_DEVICELOCK": "com.android.devicelock", + "RELEASE_APEX_CONTRIBUTIONS_DOCUMENTSUIGOOGLE": "", + "RELEASE_APEX_CONTRIBUTIONS_EXTSERVICES": "com.android.extservices", + "RELEASE_APEX_CONTRIBUTIONS_HEALTHFITNESS": "com.android.healthfitness", + "RELEASE_APEX_CONTRIBUTIONS_IPSEC": "com.android.ipsec", + "RELEASE_APEX_CONTRIBUTIONS_MEDIA": "com.android.media", + "RELEASE_APEX_CONTRIBUTIONS_MEDIAPROVIDER": "com.android.mediaprovider", + "RELEASE_APEX_CONTRIBUTIONS_MODULE_METADATA": "", + "RELEASE_APEX_CONTRIBUTIONS_NETWORKSTACKGOOGLE": "", + "RELEASE_APEX_CONTRIBUTIONS_NEURALNETWORKS": "com.android.neuralnetworks", + "RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION": "com.android.ondevicepersonalization", + "RELEASE_APEX_CONTRIBUTIONS_PERMISSION": "com.android.permission", + "RELEASE_APEX_CONTRIBUTIONS_PRIMARY_LIBS": "", + "RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING": "com.android.rkpd", + "RELEASE_APEX_CONTRIBUTIONS_RESOLV": "com.android.resolv", + "RELEASE_APEX_CONTRIBUTIONS_SCHEDULING": "com.android.scheduling", + "RELEASE_APEX_CONTRIBUTIONS_SDKEXTENSIONS": "com.android.sdkext", + "RELEASE_APEX_CONTRIBUTIONS_SWCODEC": "com.android.media.swcodec", + "RELEASE_APEX_CONTRIBUTIONS_STATSD": "com.android.os.statsd", + "RELEASE_APEX_CONTRIBUTIONS_TELEMETRY_TVP": "", + "RELEASE_APEX_CONTRIBUTIONS_TZDATA": "com.android.tzdata", + "RELEASE_APEX_CONTRIBUTIONS_UWB": "com.android.uwb", + "RELEASE_APEX_CONTRIBUTIONS_WIFI": "com.android.wifi", } ) @@ -2047,7 +2047,7 @@ var ( // Each mainline module will have one entry in the list func (c *config) AllApexContributions() []string { ret := []string{} - for _, f := range mainlineApexContributionBuildFlags { + for _, f := range SortedKeys(mainlineApexContributionBuildFlagsToApexNames) { if val, exists := c.GetBuildFlag(f); exists && val != "" { ret = append(ret, val) } @@ -2055,6 +2055,10 @@ func (c *config) AllApexContributions() []string { return ret } +func (c *config) AllMainlineApexNames() []string { + return SortedStringValues(mainlineApexContributionBuildFlagsToApexNames) +} + func (c *config) BuildIgnoreApexContributionContents() *bool { return c.productVariables.BuildIgnoreApexContributionContents } diff --git a/android/prebuilt.go b/android/prebuilt.go index 51b86a56f..921fb3c11 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -423,15 +423,7 @@ func PrebuiltRenameMutator(ctx BottomUpMutatorContext) { // The metadata will be used for source vs prebuilts selection func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) { m := ctx.Module() - // If this module is a prebuilt, is enabled and has not been renamed to source then add a - // dependency onto the source if it is present. - if p := GetEmbeddedPrebuilt(m); p != nil && m.Enabled(ctx) && !p.properties.PrebuiltRenamedToSource { - bmn, _ := m.(baseModuleName) - name := bmn.BaseModuleName() - if ctx.OtherModuleReverseDependencyVariantExists(name) { - ctx.AddReverseDependency(ctx.Module(), PrebuiltDepTag, name) - p.properties.SourceExists = true - } + if p := GetEmbeddedPrebuilt(m); p != nil { // Add a dependency from the prebuilt to the `all_apex_contributions` // metadata module // TODO: When all branches contain this singleton module, make this strict @@ -439,7 +431,16 @@ func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) { if ctx.OtherModuleExists("all_apex_contributions") { ctx.AddDependency(m, AcDepTag, "all_apex_contributions") } - + if m.Enabled(ctx) && !p.properties.PrebuiltRenamedToSource { + // If this module is a prebuilt, is enabled and has not been renamed to source then add a + // dependency onto the source if it is present. + bmn, _ := m.(baseModuleName) + name := bmn.BaseModuleName() + if ctx.OtherModuleReverseDependencyVariantExists(name) { + ctx.AddReverseDependency(ctx.Module(), PrebuiltDepTag, name) + p.properties.SourceExists = true + } + } } } @@ -668,12 +669,37 @@ func (p *Prebuilt) variantIsDisabled(ctx BaseMutatorContext, prebuilt Module) bo return p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 } +type apexVariationName interface { + ApexVariationName() string +} + // usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt // will be used if it is marked "prefer" or if the source module is disabled. func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt Module) bool { + isMainlinePrebuilt := func(prebuilt Module) bool { + apex, ok := prebuilt.(apexVariationName) + if !ok { + return false + } + // Prebuilts of aosp apexes in prebuilts/runtime + // Used in minimal art branches + if prebuilt.base().BaseModuleName() == apex.ApexVariationName() { + return false + } + return InList(apex.ApexVariationName(), ctx.Config().AllMainlineApexNames()) + } + // Use `all_apex_contributions` for source vs prebuilt selection. psi := PrebuiltSelectionInfoMap{} - ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(am Module) { + var psiDepTag blueprint.DependencyTag + if p := GetEmbeddedPrebuilt(ctx.Module()); p != nil { + // This is a prebuilt module, visit all_apex_contributions to get the info + psiDepTag = AcDepTag + } else { + // This is a source module, visit any of its prebuilts to get the info + psiDepTag = PrebuiltDepTag + } + ctx.VisitDirectDepsWithTag(psiDepTag, func(am Module) { psi, _ = OtherModuleProvider(ctx, am, PrebuiltSelectionInfoProvider) }) @@ -686,6 +712,11 @@ func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt M return true } + // If this is a mainline prebuilt, but has not been flagged, hide it. + if isMainlinePrebuilt(prebuilt) { + return false + } + // If the baseModuleName could not be found in the metadata module, // fall back to the existing source vs prebuilt selection. // TODO: Drop the fallback mechanisms diff --git a/apex/apex_test.go b/apex/apex_test.go index dcfc67592..9a314472d 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -11433,6 +11433,118 @@ func TestInstallationRulesForMultipleApexPrebuilts(t *testing.T) { } } +// Test that product packaging installs the selected mainline module in workspaces withtout source mainline module +func TestInstallationRulesForMultipleApexPrebuiltsWithoutSource(t *testing.T) { + // for a mainline module family, check that only the flagged soong module is visible to make + checkHideFromMake := func(t *testing.T, ctx *android.TestContext, visibleModuleNames []string, hiddenModuleNames []string) { + variation := func(moduleName string) string { + ret := "android_common_com.android.adservices" + if moduleName == "com.google.android.foo" { + ret = "android_common_com.google.android.foo_com.google.android.foo" + } + return ret + } + + for _, visibleModuleName := range visibleModuleNames { + visibleModule := ctx.ModuleForTests(visibleModuleName, variation(visibleModuleName)).Module() + android.AssertBoolEquals(t, "Apex "+visibleModuleName+" selected using apex_contributions should be visible to make", false, visibleModule.IsHideFromMake()) + } + + for _, hiddenModuleName := range hiddenModuleNames { + hiddenModule := ctx.ModuleForTests(hiddenModuleName, variation(hiddenModuleName)).Module() + android.AssertBoolEquals(t, "Apex "+hiddenModuleName+" not selected using apex_contributions should be hidden from make", true, hiddenModule.IsHideFromMake()) + + } + } + + bp := ` + apex_key { + name: "com.android.adservices.key", + public_key: "com.android.adservices.avbpubkey", + private_key: "com.android.adservices.pem", + } + + // AOSP source apex + apex { + name: "com.android.adservices", + key: "com.android.adservices.key", + updatable: false, + } + + // Prebuilt Google APEX. + + prebuilt_apex { + name: "com.google.android.adservices", + apex_name: "com.android.adservices", + src: "com.android.foo-arm.apex", + } + + // Another Prebuilt Google APEX + prebuilt_apex { + name: "com.google.android.adservices.v2", + apex_name: "com.android.adservices", + src: "com.android.foo-arm.apex", + } + + // APEX contribution modules + + + apex_contributions { + name: "adservices.prebuilt.contributions", + api_domain: "com.android.adservices", + contents: ["prebuilt_com.google.android.adservices"], + } + + apex_contributions { + name: "adservices.prebuilt.v2.contributions", + api_domain: "com.android.adservices", + contents: ["prebuilt_com.google.android.adservices.v2"], + } + ` + + testCases := []struct { + desc string + selectedApexContributions string + expectedVisibleModuleNames []string + expectedHiddenModuleNames []string + }{ + { + desc: "No apex contributions selected, source aosp apex should be visible, and mainline prebuilts should be hidden", + selectedApexContributions: "", + expectedVisibleModuleNames: []string{"com.android.adservices"}, + expectedHiddenModuleNames: []string{"com.google.android.adservices", "com.google.android.adservices.v2"}, + }, + { + desc: "Prebuilt apex prebuilt_com.android.foo is selected", + selectedApexContributions: "adservices.prebuilt.contributions", + expectedVisibleModuleNames: []string{"com.android.adservices", "com.google.android.adservices"}, + expectedHiddenModuleNames: []string{"com.google.android.adservices.v2"}, + }, + { + desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected", + selectedApexContributions: "adservices.prebuilt.v2.contributions", + expectedVisibleModuleNames: []string{"com.android.adservices", "com.google.android.adservices.v2"}, + expectedHiddenModuleNames: []string{"com.google.android.adservices"}, + }, + } + + for _, tc := range testCases { + preparer := android.GroupFixturePreparers( + android.FixtureMergeMockFs(map[string][]byte{ + "system/sepolicy/apex/com.android.adservices-file_contexts": nil, + }), + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.BuildFlags = map[string]string{ + "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": tc.selectedApexContributions, + } + }), + ) + ctx := testApex(t, bp, preparer) + + checkHideFromMake(t, ctx, tc.expectedVisibleModuleNames, tc.expectedHiddenModuleNames) + } +} + func TestAconfifDeclarationsValidation(t *testing.T) { aconfigDeclarationLibraryString := func(moduleNames []string) (ret string) { for _, moduleName := range moduleNames { diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go index 919cb01ac..533f937af 100644 --- a/apex/bootclasspath_fragment_test.go +++ b/apex/bootclasspath_fragment_test.go @@ -561,6 +561,7 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,")) java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{ + `all_apex_contributions`, `dex2oatd`, `prebuilt_art-bootclasspath-fragment`, `prebuilt_com.android.art.apex.selector`, @@ -568,6 +569,7 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { }) java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_com.android.art", []string{ + `all_apex_contributions`, `dex2oatd`, `prebuilt_bar`, `prebuilt_com.android.art.deapexer`, diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go index f6c53b270..452a43efa 100644 --- a/apex/systemserver_classpath_fragment_test.go +++ b/apex/systemserver_classpath_fragment_test.go @@ -274,6 +274,7 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) { ctx := result.TestContext java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{ + `all_apex_contributions`, `dex2oatd`, `prebuilt_myapex.apex.selector`, `prebuilt_myapex.deapexer`, @@ -281,6 +282,7 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) { }) java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{ + `all_apex_contributions`, `prebuilt_bar`, `prebuilt_foo`, `prebuilt_myapex.deapexer`, @@ -432,6 +434,7 @@ func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) { ctx := result.TestContext java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{ + `all_apex_contributions`, `prebuilt_bar`, `prebuilt_foo`, `prebuilt_myapex.deapexer`, diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 39f8c760b..5f0c174d9 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -923,6 +923,7 @@ func TestJavaSdkLibraryImport(t *testing.T) { } CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ + `all_apex_contributions`, `dex2oatd`, `prebuilt_sdklib.stubs`, `prebuilt_sdklib.stubs.source.test`,