Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c31b2497 authored by Spandan Das's avatar Spandan Das Committed by Gerrit Code Review
Browse files

Merge changes from topic "apex_contributions_build_flags" into main

* changes:
  Special-case java_sdk_library in source vs prebuilt selection
  Use `all_apex_contributions` for source/prebuilts selection
  Create a singleton all_apex_contributions module type
parents 38ec22a8 fc12d2f4
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -130,3 +130,8 @@ buildinfo_prop {
    // Currently, only microdroid can refer to buildinfo.prop
    visibility: ["//packages/modules/Virtualization/microdroid"],
}

// container for apex_contributions selected using build flags
all_apex_contributions {
    name: "all_apex_contributions",
}
+108 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
package android

import (
	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
)

@@ -24,6 +25,7 @@ func init() {

func RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
	ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
	ctx.RegisterSingletonModuleType("all_apex_contributions", allApexContributionsFactory)
}

type apexContributions struct {
@@ -65,3 +67,109 @@ func apexContributionsFactory() Module {
// prebuilts selection.
func (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
}

// A container for apex_contributions.
// Based on product_config, it will create a dependency on the selected
// apex_contributions per mainline module
type allApexContributions struct {
	SingletonModuleBase
}

func allApexContributionsFactory() SingletonModule {
	module := &allApexContributions{}
	InitAndroidModule(module)
	return module
}

type apexContributionsDepTag struct {
	blueprint.BaseDependencyTag
}

var (
	acDepTag = apexContributionsDepTag{}
)

// Creates a dep to each selected apex_contributions
func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) {
	ctx.AddDependency(ctx.Module(), acDepTag, ctx.Config().AllApexContributions()...)
}

// Set PrebuiltSelectionInfoProvider in post deps phase
func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
	addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
		for _, content := range m.Contents() {
			if !ctx.OtherModuleExists(content) {
				ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
			}
			pi := &PrebuiltSelectionInfo{
				baseModuleName:     RemoveOptionalPrebuiltPrefix(content),
				selectedModuleName: content,
				metadataModuleName: m.Name(),
				apiDomain:          m.ApiDomain(),
			}
			p.Add(ctx, pi)
		}
	}

	if ctx.Config().Bp2buildMode() { // Skip bp2build
		return
	}
	p := PrebuiltSelectionInfoMap{}
	ctx.VisitDirectDepsWithTag(acDepTag, func(child Module) {
		if m, ok := child.(*apexContributions); ok {
			addContentsToProvider(&p, m)
		} else {
			ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
		}
	})
	ctx.SetProvider(PrebuiltSelectionInfoProvider, p)
}

// A provider containing metadata about whether source or prebuilt should be used
// This provider will be used in prebuilt_select mutator to redirect deps
var PrebuiltSelectionInfoProvider = blueprint.NewMutatorProvider(PrebuiltSelectionInfoMap{}, "prebuilt_select")

// Map of baseModuleName to the selected source or prebuilt
type PrebuiltSelectionInfoMap map[string]PrebuiltSelectionInfo

// Add a new entry to the map with some validations
func (pm *PrebuiltSelectionInfoMap) Add(ctx BaseModuleContext, p *PrebuiltSelectionInfo) {
	if p == nil {
		return
	}
	// Do not allow dups. If the base module (without the prebuilt_) has been added before, raise an exception.
	if old, exists := (*pm)[p.baseModuleName]; exists {
		ctx.ModuleErrorf("Cannot use Soong module: %s from apex_contributions: %s because it has been added previously as: %s from apex_contributions: %s\n",
			p.selectedModuleName, p.metadataModuleName, old.selectedModuleName, old.metadataModuleName,
		)
	}
	(*pm)[p.baseModuleName] = *p
}

type PrebuiltSelectionInfo struct {
	// e.g. libc
	baseModuleName string
	// e.g. (libc|prebuilt_libc)
	selectedModuleName string
	// Name of the apex_contributions module
	metadataModuleName string
	// e.g. com.android.runtime
	apiDomain string
}

// Returns true if `name` is explicitly requested using one of the selected
// apex_contributions metadata modules.
func (p *PrebuiltSelectionInfoMap) IsSelected(baseModuleName, name string) bool {
	if i, exists := (*p)[baseModuleName]; exists {
		return i.selectedModuleName == name
	} else {
		return false
	}
}

// This module type does not have any build actions.
func (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
}

func (a *allApexContributions) GenerateSingletonBuildActions(ctx SingletonContext) {
}
+38 −0
Original line number Diff line number Diff line
@@ -2129,3 +2129,41 @@ func (c *config) GetBuildFlag(name string) (string, bool) {
	val, ok := c.productVariables.BuildFlags[name]
	return val, ok
}

var (
	mainlineApexContributionBuildFlags = []string{
		"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES",
		"RELEASE_APEX_CONTRIBUTIONS_APPSEARCH",
		"RELEASE_APEX_CONTRIBUTIONS_ART",
		"RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH",
		"RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE",
		"RELEASE_APEX_CONTRIBUTIONS_CONNECTIVITY",
		"RELEASE_APEX_CONTRIBUTIONS_CONSCRYPT",
		"RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY",
		"RELEASE_APEX_CONTRIBUTIONS_DEVICELOCK",
		"RELEASE_APEX_CONTRIBUTIONS_HEALTHFITNESS",
		"RELEASE_APEX_CONTRIBUTIONS_IPSEC",
		"RELEASE_APEX_CONTRIBUTIONS_MEDIA",
		"RELEASE_APEX_CONTRIBUTIONS_MEDIAPROVIDER",
		"RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION",
		"RELEASE_APEX_CONTRIBUTIONS_PERMISSION",
		"RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING",
		"RELEASE_APEX_CONTRIBUTIONS_SCHEDULING",
		"RELEASE_APEX_CONTRIBUTIONS_SDKEXTENSIONS",
		"RELEASE_APEX_CONTRIBUTIONS_STATSD",
		"RELEASE_APEX_CONTRIBUTIONS_UWB",
		"RELEASE_APEX_CONTRIBUTIONS_WIFI",
	}
)

// Returns the list of _selected_ apex_contributions
// Each mainline module will have one entry in the list
func (c *config) AllApexContributions() []string {
	ret := []string{}
	for _, f := range mainlineApexContributionBuildFlags {
		if val, exists := c.GetBuildFlag(f); exists && val != "" {
			ret = append(ret, val)
		}
	}
	return ret
}
+2 −0
Original line number Diff line number Diff line
@@ -3231,6 +3231,8 @@ func IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
		return true
	} else if tag == licensesTag {
		return true
	} else if tag == acDepTag {
		return true
	}
	return false
}
+90 −3
Original line number Diff line number Diff line
@@ -387,7 +387,7 @@ func RegisterPrebuiltsPreArchMutators(ctx RegisterMutatorsContext) {

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 @@ func PrebuiltRenameMutator(ctx BottomUpMutatorContext) {

// 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 @@ func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) {
			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")
		}

	}
}

@@ -435,7 +445,11 @@ func checkInvariantsForSourceAndPrebuilt(ctx BaseModuleContext, s, p Module) {

// PrebuiltSelectModuleMutator marks prebuilts that are used, either overriding source modules or
// because the source module doesn't exist.  It also disables installing overridden source modules.
func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
//
// 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 BottomUpMutatorContext) {
	m := ctx.Module()
	if p := GetEmbeddedPrebuilt(m); p != nil {
		if p.srcsSupplier == nil && p.srcsPropertyName == "" {
@@ -444,6 +458,17 @@ func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
		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)
@@ -455,6 +480,11 @@ func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
			}
		})
	}
	// If this is `all_apex_contributions`, set a provider containing
	// metadata about source vs prebuilts selection
	if am, ok := m.(*allApexContributions); ok {
		am.SetPrebuiltSelectionInfoProvider(ctx)
	}
}

// PrebuiltPostDepsMutator replaces dependencies on the source module with dependencies on the
@@ -480,9 +510,66 @@ func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) {
	}
}

// A wrapper around PrebuiltSelectionInfoMap.IsSelected with special handling for java_sdk_library
// java_sdk_library is a macro that creates
// 1. top-level impl library
// 2. stub libraries (suffixed with .stubs...)
//
// java_sdk_library_import is a macro that creates
// 1. top-level "impl" library
// 2. stub libraries (suffixed with .stubs...)
//
// the impl of java_sdk_library_import is a "hook" for hiddenapi and dexpreopt processing. It does not have an impl jar, but acts as a shim
// to provide the jar deapxed from the prebuilt apex
//
// isSelected uses `all_apex_contributions` to supersede source vs prebuilts selection of the stub libraries. It does not supersede the
// selection of the top-level "impl" library so that this hook can work
//
// TODO (b/308174306) - Fix this when we need to support multiple prebuilts in main
func isSelected(psi PrebuiltSelectionInfoMap, m Module) bool {
	if sdkLibrary, ok := m.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil {
		sln := proptools.String(sdkLibrary.SdkLibraryName())
		// This is the top-level library
		// Do not supersede the existing prebuilts vs source selection mechanisms
		if sln == m.base().BaseModuleName() {
			return false
		}

		// Stub library created by java_sdk_library_import
		if p := GetEmbeddedPrebuilt(m); p != nil {
			return psi.IsSelected(sln, PrebuiltNameFromSource(sln))
		}

		// Stub library created by java_sdk_library
		return psi.IsSelected(sln, sln)
	}
	return psi.IsSelected(m.base().BaseModuleName(), m.Name())
}

// 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 && isSelected(psi, source) {
		return false
	}
	// If the prebuilt module is explicitly listed in the metadata module, use that
	if isSelected(psi, prebuilt) {
		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
Loading