Refactor containers
Implementation details: - Add documentations - Convert container determiniation logic to function pointers, in order to make addition/deletion of containers more scalable Test: m nothing Bug: 338660802 Change-Id: I4f7a9a027e00584bb895ce8559f621bae1e985f6
This commit is contained in:
@@ -21,12 +21,22 @@ import (
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Start of the definitions of exception functions and the lookup table.
|
||||
//
|
||||
// Functions cannot be used as a value passed in providers, because functions are not
|
||||
// hashable. As a workaround, the [exceptionHandleFuncLabel] enum values are passed using providers,
|
||||
// and the corresponding functions are called from [exceptionHandleFunctionsTable] map.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type exceptionHandleFunc func(ModuleContext, Module, Module) bool
|
||||
|
||||
type StubsAvailableModule interface {
|
||||
IsStubsModule() bool
|
||||
}
|
||||
|
||||
// Returns true if the dependency module is a stubs module
|
||||
var depIsStubsModule = func(_ ModuleContext, _, dep Module) bool {
|
||||
var depIsStubsModule exceptionHandleFunc = func(_ ModuleContext, _, dep Module) bool {
|
||||
if stubsModule, ok := dep.(StubsAvailableModule); ok {
|
||||
return stubsModule.IsStubsModule()
|
||||
}
|
||||
@@ -41,13 +51,76 @@ const (
|
||||
checkStubs exceptionHandleFuncLabel = iota
|
||||
)
|
||||
|
||||
// Functions cannot be used as a value passed in providers, because functions are not
|
||||
// hashable. As a workaround, the exceptionHandleFunc enum values are passed using providers,
|
||||
// and the corresponding functions are called from this map.
|
||||
var exceptionHandleFunctionsTable = map[exceptionHandleFuncLabel]func(ModuleContext, Module, Module) bool{
|
||||
var exceptionHandleFunctionsTable = map[exceptionHandleFuncLabel]exceptionHandleFunc{
|
||||
checkStubs: depIsStubsModule,
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Start of the definitions of container determination functions.
|
||||
//
|
||||
// Similar to the above section, below defines the functions used to determine
|
||||
// the container of each modules.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type containerBoundaryFunc func(mctx ModuleContext) bool
|
||||
|
||||
var vendorContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
|
||||
m, ok := mctx.Module().(ImageInterface)
|
||||
return mctx.Module().InstallInVendor() || (ok && m.VendorVariantNeeded(mctx))
|
||||
}
|
||||
|
||||
var systemContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
|
||||
module := mctx.Module()
|
||||
|
||||
return !module.InstallInTestcases() &&
|
||||
!module.InstallInData() &&
|
||||
!module.InstallInRamdisk() &&
|
||||
!module.InstallInVendorRamdisk() &&
|
||||
!module.InstallInDebugRamdisk() &&
|
||||
!module.InstallInRecovery() &&
|
||||
!module.InstallInVendor() &&
|
||||
!module.InstallInOdm() &&
|
||||
!module.InstallInProduct() &&
|
||||
determineModuleKind(module.base(), mctx.blueprintBaseModuleContext()) == platformModule
|
||||
}
|
||||
|
||||
var productContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
|
||||
m, ok := mctx.Module().(ImageInterface)
|
||||
return mctx.Module().InstallInProduct() || (ok && m.ProductVariantNeeded(mctx))
|
||||
}
|
||||
|
||||
var apexContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
|
||||
_, ok := ModuleProvider(mctx, AllApexInfoProvider)
|
||||
return ok
|
||||
}
|
||||
|
||||
var ctsContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
|
||||
props := mctx.Module().GetProperties()
|
||||
for _, prop := range props {
|
||||
val := reflect.ValueOf(prop).Elem()
|
||||
if val.Kind() == reflect.Struct {
|
||||
testSuites := val.FieldByName("Test_suites")
|
||||
if testSuites.IsValid() && testSuites.Kind() == reflect.Slice && slices.Contains(testSuites.Interface().([]string), "cts") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Map of [*container] to the [containerBoundaryFunc]
|
||||
var containerBoundaryFunctionsTable = map[*container]containerBoundaryFunc{
|
||||
VendorContainer: vendorContainerBoundaryFunc,
|
||||
SystemContainer: systemContainerBoundaryFunc,
|
||||
ProductContainer: productContainerBoundaryFunc,
|
||||
ApexContainer: apexContainerBoundaryFunc,
|
||||
CtsContainer: ctsContainerBoundaryFunc,
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// End of the definitions of container determination functions.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type InstallableModule interface {
|
||||
EnforceApiContainerChecks() bool
|
||||
}
|
||||
@@ -77,6 +150,7 @@ var (
|
||||
name: VendorVariation,
|
||||
restricted: nil,
|
||||
}
|
||||
|
||||
SystemContainer = &container{
|
||||
name: "system",
|
||||
restricted: []restriction{
|
||||
@@ -90,6 +164,7 @@ var (
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ProductContainer = &container{
|
||||
name: ProductVariation,
|
||||
restricted: []restriction{
|
||||
@@ -102,8 +177,10 @@ var (
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ApexContainer = initializeApexContainer()
|
||||
CtsContainer = &container{
|
||||
|
||||
CtsContainer = &container{
|
||||
name: "cts",
|
||||
restricted: []restriction{
|
||||
{
|
||||
@@ -116,6 +193,14 @@ var (
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
allContainers = []*container{
|
||||
VendorContainer,
|
||||
SystemContainer,
|
||||
ProductContainer,
|
||||
ApexContainer,
|
||||
CtsContainer,
|
||||
}
|
||||
)
|
||||
|
||||
func initializeApexContainer() *container {
|
||||
@@ -155,68 +240,38 @@ func (c *ContainersInfo) BelongingContainers() []*container {
|
||||
return c.belongingContainers
|
||||
}
|
||||
|
||||
var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]()
|
||||
|
||||
// Determines if the module can be installed in the system partition or not.
|
||||
// Logic is identical to that of modulePartition(...) defined in paths.go
|
||||
func installInSystemPartition(ctx ModuleContext) bool {
|
||||
module := ctx.Module()
|
||||
return !module.InstallInTestcases() &&
|
||||
!module.InstallInData() &&
|
||||
!module.InstallInRamdisk() &&
|
||||
!module.InstallInVendorRamdisk() &&
|
||||
!module.InstallInDebugRamdisk() &&
|
||||
!module.InstallInRecovery() &&
|
||||
!module.InstallInVendor() &&
|
||||
!module.InstallInOdm() &&
|
||||
!module.InstallInProduct() &&
|
||||
determineModuleKind(module.base(), ctx.blueprintBaseModuleContext()) == platformModule
|
||||
func (c *ContainersInfo) ApexNames() (ret []string) {
|
||||
for _, apex := range c.belongingApexes {
|
||||
ret = append(ret, apex.InApexModules...)
|
||||
}
|
||||
slices.Sort(ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
func generateContainerInfo(ctx ModuleContext) ContainersInfo {
|
||||
inSystem := installInSystemPartition(ctx)
|
||||
inProduct := ctx.Module().InstallInProduct()
|
||||
inVendor := ctx.Module().InstallInVendor()
|
||||
inCts := false
|
||||
inApex := false
|
||||
|
||||
if m, ok := ctx.Module().(ImageInterface); ok {
|
||||
inProduct = inProduct || m.ProductVariantNeeded(ctx)
|
||||
inVendor = inVendor || m.VendorVariantNeeded(ctx)
|
||||
// Returns true if any of the apex the module belongs to is updatable.
|
||||
func (c *ContainersInfo) UpdatableApex() bool {
|
||||
for _, apex := range c.belongingApexes {
|
||||
if apex.Updatable {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
props := ctx.Module().GetProperties()
|
||||
for _, prop := range props {
|
||||
val := reflect.ValueOf(prop).Elem()
|
||||
if val.Kind() == reflect.Struct {
|
||||
testSuites := val.FieldByName("Test_suites")
|
||||
if testSuites.IsValid() && testSuites.Kind() == reflect.Slice && slices.Contains(testSuites.Interface().([]string), "cts") {
|
||||
inCts = true
|
||||
}
|
||||
var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]()
|
||||
|
||||
func generateContainerInfo(ctx ModuleContext) ContainersInfo {
|
||||
var containers []*container
|
||||
|
||||
for _, cnt := range allContainers {
|
||||
if containerBoundaryFunctionsTable[cnt](ctx) {
|
||||
containers = append(containers, cnt)
|
||||
}
|
||||
}
|
||||
|
||||
var belongingApexes []ApexInfo
|
||||
if apexInfo, ok := ModuleProvider(ctx, AllApexInfoProvider); ok {
|
||||
belongingApexes = apexInfo.ApexInfos
|
||||
inApex = true
|
||||
}
|
||||
|
||||
containers := []*container{}
|
||||
if inSystem {
|
||||
containers = append(containers, SystemContainer)
|
||||
}
|
||||
if inProduct {
|
||||
containers = append(containers, ProductContainer)
|
||||
}
|
||||
if inVendor {
|
||||
containers = append(containers, VendorContainer)
|
||||
}
|
||||
if inCts {
|
||||
containers = append(containers, CtsContainer)
|
||||
}
|
||||
if inApex {
|
||||
containers = append(containers, ApexContainer)
|
||||
}
|
||||
|
||||
return ContainersInfo{
|
||||
|
Reference in New Issue
Block a user