Loading android/apex.go +118 −53 Original line number Diff line number Diff line Loading @@ -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{}{ Loading Loading @@ -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...) } modules := mctx.CreateVariations(variations...) for i, mod := range modules { platformVariation := i == 0 if platformVariation && !mctx.Host() && !mod.(ApexModule).AvailableFor(AvailableToPlatform) { 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 mod.MakeUninstallable() module.MakeUninstallable() } if !platformVariation { mctx.SetVariationProvider(mod, ApexInfoProvider, apexInfos[i-1]) 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)) } SetProvider(ctx, ApexInfoProvider, thisApexInfo) } // 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 var testApexes []string for _, a := range apexInfos { testApexes = append(testApexes, a.TestApexes...) } base.ApexProperties.TestApexes = testApexes for _, alias := range aliases { mctx.CreateAliasVariation(alias[0], alias[1]) } 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 Loading @@ -665,14 +727,17 @@ 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 { 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 infos { for _, info := range allApexInfo.ApexInfos { ret = append(ret, info.InApexVariants...) } return ret } return nil } aApexes := collectApexes(a) bApexes := collectApexes(b) Loading @@ -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 Loading apex/apex.go +35 −30 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { // Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether // it should create a platform variant. ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel() ctx.BottomUp("apex", apexMutator).Parallel() ctx.Transition("apex", &apexTransitionMutator{}) ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel() ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel() // Register after apex_info mutator so that it can use ApexVariationName Loading Loading @@ -1084,6 +1084,10 @@ func apexInfoMutator(mctx android.TopDownMutatorContext) { if a, ok := mctx.Module().(ApexInfoMutator); ok { a.ApexInfoMutator(mctx) } if am, ok := mctx.Module().(android.ApexModule); ok { android.ApexInfoMutator(mctx, am) } enforceAppUpdatability(mctx) } Loading Loading @@ -1284,40 +1288,41 @@ func markPlatformAvailability(mctx android.BottomUpMutatorContext) { } } // apexMutator visits each module and creates apex variations if the module was marked in the // previous run of apexInfoMutator. func apexMutator(mctx android.BottomUpMutatorContext) { if !mctx.Module().Enabled() { return } // This is the usual path. if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() { android.CreateApexVariations(mctx, am) return } type apexTransitionMutator struct{} func (a *apexTransitionMutator) Split(ctx android.BaseModuleContext) []string { // apexBundle itself is mutated so that it and its dependencies have the same apex variant. // Note that a default variation "" is also created as an alias, and the default dependency // variation is set to the default variation. This is to allow an apex to depend on another // module which is outside of the apex. This is because the dependent module is not mutated // for this apex variant. createApexVariation := func(apexBundleName string) { defaultVariation := "" mctx.SetDefaultDependencyVariation(&defaultVariation) mctx.CreateVariations(apexBundleName) mctx.CreateAliasVariation(defaultVariation, apexBundleName) } if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) { createApexVariation(ai.ApexVariationName()) } else if o, ok := mctx.Module().(*OverrideApex); ok { if ai, ok := ctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) { return []string{ai.ApexVariationName()} } else if o, ok := ctx.Module().(*OverrideApex); ok { apexBundleName := o.GetOverriddenModuleName() if apexBundleName == "" { mctx.ModuleErrorf("base property is not set") return ctx.ModuleErrorf("base property is not set") } createApexVariation(apexBundleName) return []string{apexBundleName} } return []string{""} } func (a *apexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { return sourceVariation } func (a *apexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() { return android.IncomingApexTransition(ctx, incomingVariation) } else if ai, ok := ctx.Module().(ApexInfoMutator); ok { return ai.ApexVariationName() } else if o, ok := ctx.Module().(*OverrideApex); ok { return o.GetOverriddenModuleName() } return "" } func (a *apexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() { android.MutateApexTransition(ctx, variation) } } Loading java/testing.go +23 −9 Original line number Diff line number Diff line Loading @@ -711,7 +711,7 @@ var PrepareForTestWithFakeApexMutator = android.GroupFixturePreparers( func registerFakeApexMutator(ctx android.RegistrationContext) { ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("apex", fakeApexMutator).Parallel() ctx.Transition("apex", &fakeApexMutator{}) }) } Loading @@ -726,16 +726,30 @@ var _ apexModuleBase = (*SdkLibrary)(nil) // `apex_available`. It helps us avoid a dependency on the real mutator defined in "soong-apex", // which will cause a cyclic dependency, and it provides an easy way to create an APEX variant for // testing without dealing with all the complexities in the real mutator. func fakeApexMutator(mctx android.BottomUpMutatorContext) { switch mctx.Module().(type) { type fakeApexMutator struct{} func (f *fakeApexMutator) Split(ctx android.BaseModuleContext) []string { switch ctx.Module().(type) { case *Library, *SdkLibrary: if len(mctx.Module().(apexModuleBase).ApexAvailable()) > 0 { modules := mctx.CreateVariations("", "apex1000") return []string{"", "apex1000"} } return []string{""} } func (f *fakeApexMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { return sourceVariation } func (f *fakeApexMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { return incomingVariation } func (f *fakeApexMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { if variation != "" { apexInfo := android.ApexInfo{ ApexVariationName: "apex1000", } mctx.SetVariationProvider(modules[1], android.ApexInfoProvider, apexInfo) } android.SetProvider(ctx, android.ApexInfoProvider, apexInfo) } } Loading Loading
android/apex.go +118 −53 Original line number Diff line number Diff line Loading @@ -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{}{ Loading Loading @@ -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...) } modules := mctx.CreateVariations(variations...) for i, mod := range modules { platformVariation := i == 0 if platformVariation && !mctx.Host() && !mod.(ApexModule).AvailableFor(AvailableToPlatform) { 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 mod.MakeUninstallable() module.MakeUninstallable() } if !platformVariation { mctx.SetVariationProvider(mod, ApexInfoProvider, apexInfos[i-1]) 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)) } SetProvider(ctx, ApexInfoProvider, thisApexInfo) } // 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 var testApexes []string for _, a := range apexInfos { testApexes = append(testApexes, a.TestApexes...) } base.ApexProperties.TestApexes = testApexes for _, alias := range aliases { mctx.CreateAliasVariation(alias[0], alias[1]) } 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 Loading @@ -665,14 +727,17 @@ 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 { 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 infos { for _, info := range allApexInfo.ApexInfos { ret = append(ret, info.InApexVariants...) } return ret } return nil } aApexes := collectApexes(a) bApexes := collectApexes(b) Loading @@ -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 Loading
apex/apex.go +35 −30 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { // Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether // it should create a platform variant. ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel() ctx.BottomUp("apex", apexMutator).Parallel() ctx.Transition("apex", &apexTransitionMutator{}) ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel() ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel() // Register after apex_info mutator so that it can use ApexVariationName Loading Loading @@ -1084,6 +1084,10 @@ func apexInfoMutator(mctx android.TopDownMutatorContext) { if a, ok := mctx.Module().(ApexInfoMutator); ok { a.ApexInfoMutator(mctx) } if am, ok := mctx.Module().(android.ApexModule); ok { android.ApexInfoMutator(mctx, am) } enforceAppUpdatability(mctx) } Loading Loading @@ -1284,40 +1288,41 @@ func markPlatformAvailability(mctx android.BottomUpMutatorContext) { } } // apexMutator visits each module and creates apex variations if the module was marked in the // previous run of apexInfoMutator. func apexMutator(mctx android.BottomUpMutatorContext) { if !mctx.Module().Enabled() { return } // This is the usual path. if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() { android.CreateApexVariations(mctx, am) return } type apexTransitionMutator struct{} func (a *apexTransitionMutator) Split(ctx android.BaseModuleContext) []string { // apexBundle itself is mutated so that it and its dependencies have the same apex variant. // Note that a default variation "" is also created as an alias, and the default dependency // variation is set to the default variation. This is to allow an apex to depend on another // module which is outside of the apex. This is because the dependent module is not mutated // for this apex variant. createApexVariation := func(apexBundleName string) { defaultVariation := "" mctx.SetDefaultDependencyVariation(&defaultVariation) mctx.CreateVariations(apexBundleName) mctx.CreateAliasVariation(defaultVariation, apexBundleName) } if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) { createApexVariation(ai.ApexVariationName()) } else if o, ok := mctx.Module().(*OverrideApex); ok { if ai, ok := ctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) { return []string{ai.ApexVariationName()} } else if o, ok := ctx.Module().(*OverrideApex); ok { apexBundleName := o.GetOverriddenModuleName() if apexBundleName == "" { mctx.ModuleErrorf("base property is not set") return ctx.ModuleErrorf("base property is not set") } createApexVariation(apexBundleName) return []string{apexBundleName} } return []string{""} } func (a *apexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { return sourceVariation } func (a *apexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() { return android.IncomingApexTransition(ctx, incomingVariation) } else if ai, ok := ctx.Module().(ApexInfoMutator); ok { return ai.ApexVariationName() } else if o, ok := ctx.Module().(*OverrideApex); ok { return o.GetOverriddenModuleName() } return "" } func (a *apexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() { android.MutateApexTransition(ctx, variation) } } Loading
java/testing.go +23 −9 Original line number Diff line number Diff line Loading @@ -711,7 +711,7 @@ var PrepareForTestWithFakeApexMutator = android.GroupFixturePreparers( func registerFakeApexMutator(ctx android.RegistrationContext) { ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("apex", fakeApexMutator).Parallel() ctx.Transition("apex", &fakeApexMutator{}) }) } Loading @@ -726,16 +726,30 @@ var _ apexModuleBase = (*SdkLibrary)(nil) // `apex_available`. It helps us avoid a dependency on the real mutator defined in "soong-apex", // which will cause a cyclic dependency, and it provides an easy way to create an APEX variant for // testing without dealing with all the complexities in the real mutator. func fakeApexMutator(mctx android.BottomUpMutatorContext) { switch mctx.Module().(type) { type fakeApexMutator struct{} func (f *fakeApexMutator) Split(ctx android.BaseModuleContext) []string { switch ctx.Module().(type) { case *Library, *SdkLibrary: if len(mctx.Module().(apexModuleBase).ApexAvailable()) > 0 { modules := mctx.CreateVariations("", "apex1000") return []string{"", "apex1000"} } return []string{""} } func (f *fakeApexMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { return sourceVariation } func (f *fakeApexMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { return incomingVariation } func (f *fakeApexMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { if variation != "" { apexInfo := android.ApexInfo{ ApexVariationName: "apex1000", } mctx.SetVariationProvider(modules[1], android.ApexInfoProvider, apexInfo) } android.SetProvider(ctx, android.ApexInfoProvider, apexInfo) } } Loading