Use `all_apex_contributions` for source/prebuilts selection

This flattened singleton module explicitly lists by module name whether source or
prebuilt version of a module should be used. If a module appears in this
metadata module, it supersedes all other source vs prebuilts selection
mechanism

Implementation details
- Update the module dep chain from <source> --> <prebuilt> to <source>
  --> <prebuilt> --> all_apex_contributions
- all_apex_contributions sets a provider which is bubbled up
  to the source module. This requires changing `prebuilt_select` to a
  bottom up mutator
- Update `usePrebuilt` to consult the new provider before falling back
  to existing source vs selection mechanisms. If (foo|prebuilt_foo) is
  listed in the selected `apex_contributions` modules, it
  will be used superseding any other selection mechanisms.
- Update this depTag to IsMetaDepTag so that bootclasspath_fragment's
  validation ignores this new dependency.

Test: Added unit tests to assert that this new mechanism supersedes
`use_source_config_var`

Bug: 308174768
Change-Id: I39a85639642711f3c96b6f18b94d626b55e80c66
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 5acef1d..edd014a 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -387,7 +387,7 @@
 
 func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
 	ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).Parallel()
-	ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
+	ctx.BottomUp("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
 	ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel()
 }
 
@@ -406,6 +406,8 @@
 
 // PrebuiltSourceDepsMutator adds dependencies to the prebuilt module from the
 // corresponding source module, if one exists for the same variant.
+// Add a dependency from the prebuilt to `all_apex_contributions`
+// 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
@@ -416,6 +418,14 @@
 			ctx.AddReverseDependency(ctx.Module(), PrebuiltDepTag, name)
 			p.properties.SourceExists = true
 		}
+		// Add a dependency from the prebuilt to the `all_apex_contributions`
+		// metadata module
+		// TODO: When all branches contain this singleton module, make this strict
+		// TODO: Add this dependency only for mainline prebuilts and not every prebuilt module
+		if ctx.OtherModuleExists("all_apex_contributions") {
+			ctx.AddDependency(m, acDepTag, "all_apex_contributions")
+		}
+
 	}
 }
 
@@ -439,7 +449,7 @@
 // If the visited module is the metadata module `all_apex_contributions`, it sets a
 // provider containing metadata about whether source or prebuilt of mainline modules should be used.
 // This logic was added here to prevent the overhead of creating a new mutator.
-func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
+func PrebuiltSelectModuleMutator(ctx BottomUpMutatorContext) {
 	m := ctx.Module()
 	if p := GetEmbeddedPrebuilt(m); p != nil {
 		if p.srcsSupplier == nil && p.srcsPropertyName == "" {
@@ -448,6 +458,17 @@
 		if !p.properties.SourceExists {
 			p.properties.UsePrebuilt = p.usePrebuilt(ctx, nil, m)
 		}
+		// Propagate the provider received from `all_apex_contributions`
+		// to the source module
+		ctx.VisitDirectDepsWithTag(acDepTag, func(am Module) {
+			if ctx.Config().Bp2buildMode() {
+				// This provider key is not applicable in bp2build
+				return
+			}
+			psi := ctx.OtherModuleProvider(am, PrebuiltSelectionInfoProvider).(PrebuiltSelectionInfoMap)
+			ctx.SetProvider(PrebuiltSelectionInfoProvider, psi)
+		})
+
 	} else if s, ok := ctx.Module().(Module); ok {
 		ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(prebuiltModule Module) {
 			p := GetEmbeddedPrebuilt(prebuiltModule)
@@ -491,7 +512,26 @@
 
 // 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 TopDownMutatorContext, source Module, prebuilt Module) bool {
+func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt Module) bool {
+	// Use `all_apex_contributions` for source vs prebuilt selection.
+	psi := PrebuiltSelectionInfoMap{}
+	ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(am Module) {
+		if ctx.OtherModuleHasProvider(am, PrebuiltSelectionInfoProvider) {
+			psi = ctx.OtherModuleProvider(am, PrebuiltSelectionInfoProvider).(PrebuiltSelectionInfoMap)
+		}
+	})
+	// If the source module is explicitly listed in the metadata module, use that
+	if source != nil && psi.IsSelected(source.base().BaseModuleName(), source.Name()) {
+		return false
+	}
+	// If the prebuilt module is explicitly listed in the metadata module, use that
+	if psi.IsSelected(prebuilt.base().BaseModuleName(), prebuilt.Name()) {
+		return true
+	}
+	// 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
+
 	if !ctx.Config().Bp2buildMode() {
 		if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 {
 			return false