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"
|
"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 {
|
type StubsAvailableModule interface {
|
||||||
IsStubsModule() bool
|
IsStubsModule() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the dependency module is a stubs module
|
// 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 {
|
if stubsModule, ok := dep.(StubsAvailableModule); ok {
|
||||||
return stubsModule.IsStubsModule()
|
return stubsModule.IsStubsModule()
|
||||||
}
|
}
|
||||||
@@ -41,13 +51,76 @@ const (
|
|||||||
checkStubs exceptionHandleFuncLabel = iota
|
checkStubs exceptionHandleFuncLabel = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
// Functions cannot be used as a value passed in providers, because functions are not
|
var exceptionHandleFunctionsTable = map[exceptionHandleFuncLabel]exceptionHandleFunc{
|
||||||
// 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{
|
|
||||||
checkStubs: depIsStubsModule,
|
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 {
|
type InstallableModule interface {
|
||||||
EnforceApiContainerChecks() bool
|
EnforceApiContainerChecks() bool
|
||||||
}
|
}
|
||||||
@@ -77,6 +150,7 @@ var (
|
|||||||
name: VendorVariation,
|
name: VendorVariation,
|
||||||
restricted: nil,
|
restricted: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemContainer = &container{
|
SystemContainer = &container{
|
||||||
name: "system",
|
name: "system",
|
||||||
restricted: []restriction{
|
restricted: []restriction{
|
||||||
@@ -90,6 +164,7 @@ var (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
ProductContainer = &container{
|
ProductContainer = &container{
|
||||||
name: ProductVariation,
|
name: ProductVariation,
|
||||||
restricted: []restriction{
|
restricted: []restriction{
|
||||||
@@ -102,7 +177,9 @@ var (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
ApexContainer = initializeApexContainer()
|
ApexContainer = initializeApexContainer()
|
||||||
|
|
||||||
CtsContainer = &container{
|
CtsContainer = &container{
|
||||||
name: "cts",
|
name: "cts",
|
||||||
restricted: []restriction{
|
restricted: []restriction{
|
||||||
@@ -116,6 +193,14 @@ var (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allContainers = []*container{
|
||||||
|
VendorContainer,
|
||||||
|
SystemContainer,
|
||||||
|
ProductContainer,
|
||||||
|
ApexContainer,
|
||||||
|
CtsContainer,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func initializeApexContainer() *container {
|
func initializeApexContainer() *container {
|
||||||
@@ -155,68 +240,38 @@ func (c *ContainersInfo) BelongingContainers() []*container {
|
|||||||
return c.belongingContainers
|
return c.belongingContainers
|
||||||
}
|
}
|
||||||
|
|
||||||
var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]()
|
func (c *ContainersInfo) ApexNames() (ret []string) {
|
||||||
|
for _, apex := range c.belongingApexes {
|
||||||
// Determines if the module can be installed in the system partition or not.
|
ret = append(ret, apex.InApexModules...)
|
||||||
// Logic is identical to that of modulePartition(...) defined in paths.go
|
}
|
||||||
func installInSystemPartition(ctx ModuleContext) bool {
|
slices.Sort(ret)
|
||||||
module := ctx.Module()
|
return ret
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]()
|
||||||
|
|
||||||
func generateContainerInfo(ctx ModuleContext) ContainersInfo {
|
func generateContainerInfo(ctx ModuleContext) ContainersInfo {
|
||||||
inSystem := installInSystemPartition(ctx)
|
var containers []*container
|
||||||
inProduct := ctx.Module().InstallInProduct()
|
|
||||||
inVendor := ctx.Module().InstallInVendor()
|
|
||||||
inCts := false
|
|
||||||
inApex := false
|
|
||||||
|
|
||||||
if m, ok := ctx.Module().(ImageInterface); ok {
|
for _, cnt := range allContainers {
|
||||||
inProduct = inProduct || m.ProductVariantNeeded(ctx)
|
if containerBoundaryFunctionsTable[cnt](ctx) {
|
||||||
inVendor = inVendor || m.VendorVariantNeeded(ctx)
|
containers = append(containers, cnt)
|
||||||
}
|
|
||||||
|
|
||||||
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 belongingApexes []ApexInfo
|
var belongingApexes []ApexInfo
|
||||||
if apexInfo, ok := ModuleProvider(ctx, AllApexInfoProvider); ok {
|
if apexInfo, ok := ModuleProvider(ctx, AllApexInfoProvider); ok {
|
||||||
belongingApexes = apexInfo.ApexInfos
|
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{
|
return ContainersInfo{
|
||||||
|
Reference in New Issue
Block a user