diff options
Diffstat (limited to 'android/apex.go')
-rw-r--r-- | android/apex.go | 171 |
1 files changed, 118 insertions, 53 deletions
diff --git a/android/apex.go b/android/apex.go index c0acada13..dc0aeed17 100644 --- a/android/apex.go +++ b/android/apex.go @@ -90,7 +90,13 @@ type ApexInfo struct { TestApexes []string } -var ApexInfoProvider = blueprint.NewMutatorProvider[ApexInfo]("apex") +// AllApexInfo holds the ApexInfo of all apexes that include this module. +type AllApexInfo struct { + ApexInfos []ApexInfo +} + +var ApexInfoProvider = blueprint.NewMutatorProvider[ApexInfo]("apex_mutate") +var AllApexInfoProvider = blueprint.NewMutatorProvider[*AllApexInfo]("apex_info") func (i ApexInfo) AddJSONData(d *map[string]interface{}) { (*d)["Apex"] = map[string]interface{}{ @@ -586,75 +592,131 @@ func mergeApexVariations(apexInfos []ApexInfo) (merged []ApexInfo, aliases [][2] return merged, aliases } -// CreateApexVariations mutates a given module into multiple apex variants each of which is for an -// apexBundle (and/or the platform) where the module is part of. -func CreateApexVariations(mctx BottomUpMutatorContext, module ApexModule) []Module { +// IncomingApexTransition is called by apexTransitionMutator.IncomingTransition on modules that can be in apexes. +// The incomingVariation can be either the name of an apex if the dependency is coming directly from an apex +// module, or it can be the name of an apex variation (e.g. apex10000) if it is coming from another module that +// is in the apex. +func IncomingApexTransition(ctx IncomingTransitionContext, incomingVariation string) string { + module := ctx.Module().(ApexModule) base := module.apexModuleBase() - // Shortcut - if len(base.apexInfos) == 0 { - return nil + var apexInfos []ApexInfo + if allApexInfos, ok := ModuleProvider(ctx, AllApexInfoProvider); ok { + apexInfos = allApexInfos.ApexInfos } - // Do some validity checks. - // TODO(jiyong): is this the right place? - base.checkApexAvailableProperty(mctx) - - apexInfos := base.apexInfos - // base.apexInfos is only needed to propagate the list of apexes from apexInfoMutator to - // apexMutator. It is no longer accurate after mergeApexVariations, and won't be copied to - // all but the first created variant. Clear it so it doesn't accidentally get used later. - base.apexInfos = nil + // Dependencies from platform variations go to the platform variation. + if incomingVariation == "" { + return "" + } - slices.SortFunc(apexInfos, func(a, b ApexInfo) int { - return strings.Compare(a.ApexVariationName, b.ApexVariationName) - }) + // If this module has no apex variations the use the platform variation. + if len(apexInfos) == 0 { + return "" + } + // Convert the list of apex infos into from the AllApexInfoProvider into the merged list + // of apex variations and the aliases from apex names to apex variations. var aliases [][2]string - if !mctx.Module().(ApexModule).UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps { + if !module.UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps { apexInfos, aliases = mergeApexVariations(apexInfos) } + // Check if the incoming variation matches an apex name, and if so use the corresponding + // apex variation. + aliasIndex := slices.IndexFunc(aliases, func(alias [2]string) bool { + return alias[0] == incomingVariation + }) + if aliasIndex >= 0 { + return aliases[aliasIndex][1] + } + + // Check if the incoming variation matches an apex variation. + apexIndex := slices.IndexFunc(apexInfos, func(info ApexInfo) bool { + return info.ApexVariationName == incomingVariation + }) + if apexIndex >= 0 { + return incomingVariation + } + + return "" +} + +func MutateApexTransition(ctx BaseModuleContext, variation string) { + module := ctx.Module().(ApexModule) + base := module.apexModuleBase() + platformVariation := variation == "" + + var apexInfos []ApexInfo + if allApexInfos, ok := ModuleProvider(ctx, AllApexInfoProvider); ok { + apexInfos = allApexInfos.ApexInfos + } + + // Shortcut + if len(apexInfos) == 0 { + return + } + + // Do some validity checks. + // TODO(jiyong): is this the right place? + base.checkApexAvailableProperty(ctx) + + if !module.UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps { + apexInfos, _ = mergeApexVariations(apexInfos) + } + var inApex ApexMembership for _, a := range apexInfos { for _, apexContents := range a.ApexContents { - inApex = inApex.merge(apexContents.contents[mctx.ModuleName()]) + inApex = inApex.merge(apexContents.contents[ctx.ModuleName()]) } } base.ApexProperties.InAnyApex = true base.ApexProperties.DirectlyInAnyApex = inApex == directlyInApex - defaultVariation := "" - mctx.SetDefaultDependencyVariation(&defaultVariation) - - variations := []string{defaultVariation} - testApexes := []string{} - for _, a := range apexInfos { - variations = append(variations, a.ApexVariationName) - testApexes = append(testApexes, a.TestApexes...) + if platformVariation && !ctx.Host() && !module.AvailableFor(AvailableToPlatform) { + // Do not install the module for platform, but still allow it to output + // uninstallable AndroidMk entries in certain cases when they have side + // effects. TODO(jiyong): move this routine to somewhere else + module.MakeUninstallable() } - modules := mctx.CreateVariations(variations...) - for i, mod := range modules { - platformVariation := i == 0 - if platformVariation && !mctx.Host() && !mod.(ApexModule).AvailableFor(AvailableToPlatform) { - // Do not install the module for platform, but still allow it to output - // uninstallable AndroidMk entries in certain cases when they have side - // effects. TODO(jiyong): move this routine to somewhere else - mod.MakeUninstallable() - } - if !platformVariation { - mctx.SetVariationProvider(mod, ApexInfoProvider, apexInfos[i-1]) + if !platformVariation { + var thisApexInfo ApexInfo + + apexIndex := slices.IndexFunc(apexInfos, func(info ApexInfo) bool { + return info.ApexVariationName == variation + }) + if apexIndex >= 0 { + thisApexInfo = apexInfos[apexIndex] + } else { + panic(fmt.Errorf("failed to find apexInfo for incoming variation %q", variation)) } - // Set the value of TestApexes in every single apex variant. - // This allows each apex variant to be aware of the test apexes in the user provided apex_available. - mod.(ApexModule).apexModuleBase().ApexProperties.TestApexes = testApexes + + SetProvider(ctx, ApexInfoProvider, thisApexInfo) } - for _, alias := range aliases { - mctx.CreateAliasVariation(alias[0], alias[1]) + // Set the value of TestApexes in every single apex variant. + // This allows each apex variant to be aware of the test apexes in the user provided apex_available. + var testApexes []string + for _, a := range apexInfos { + testApexes = append(testApexes, a.TestApexes...) } + base.ApexProperties.TestApexes = testApexes - return modules +} + +func ApexInfoMutator(ctx TopDownMutatorContext, module ApexModule) { + base := module.apexModuleBase() + if len(base.apexInfos) > 0 { + apexInfos := slices.Clone(base.apexInfos) + slices.SortFunc(apexInfos, func(a, b ApexInfo) int { + return strings.Compare(a.ApexVariationName, b.ApexVariationName) + }) + SetProvider(ctx, AllApexInfoProvider, &AllApexInfo{apexInfos}) + // base.apexInfos is only needed to propagate the list of apexes from the apex module to its + // contents within apexInfoMutator. Clear it so it doesn't accidentally get used later. + base.apexInfos = nil + } } // UpdateUniqueApexVariationsForDeps sets UniqueApexVariationsForDeps if any dependencies that are @@ -665,13 +727,16 @@ func UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext, am ApexModul // InApexVariants list in common. It is used instead of DepIsInSameApex because it needs to // determine if the dep is in the same APEX due to being directly included, not only if it // is included _because_ it is a dependency. - anyInSameApex := func(a, b []ApexInfo) bool { - collectApexes := func(infos []ApexInfo) []string { - var ret []string - for _, info := range infos { - ret = append(ret, info.InApexVariants...) + anyInSameApex := func(a, b ApexModule) bool { + collectApexes := func(m ApexModule) []string { + if allApexInfo, ok := OtherModuleProvider(mctx, m, AllApexInfoProvider); ok { + var ret []string + for _, info := range allApexInfo.ApexInfos { + ret = append(ret, info.InApexVariants...) + } + return ret } - return ret + return nil } aApexes := collectApexes(a) @@ -689,7 +754,7 @@ func UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext, am ApexModul // If any of the dependencies requires unique apex variations, so does this module. mctx.VisitDirectDeps(func(dep Module) { if depApexModule, ok := dep.(ApexModule); ok { - if anyInSameApex(depApexModule.apexModuleBase().apexInfos, am.apexModuleBase().apexInfos) && + if anyInSameApex(depApexModule, am) && (depApexModule.UniqueApexVariations() || depApexModule.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps) { am.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps = true |