diff --git a/android/container.go b/android/container.go
index c4fdd9c..05897dd 100644
--- a/android/container.go
+++ b/android/container.go
@@ -21,12 +21,22 @@
 	"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 @@
 	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 @@
 		name:       VendorVariation,
 		restricted: nil,
 	}
+
 	SystemContainer = &container{
 		name: "system",
 		restricted: []restriction{
@@ -90,6 +164,7 @@
 			},
 		},
 	}
+
 	ProductContainer = &container{
 		name: ProductVariation,
 		restricted: []restriction{
@@ -102,8 +177,10 @@
 			},
 		},
 	}
+
 	ApexContainer = initializeApexContainer()
-	CtsContainer  = &container{
+
+	CtsContainer = &container{
 		name: "cts",
 		restricted: []restriction{
 			{
@@ -116,6 +193,14 @@
 			},
 		},
 	}
+
+	allContainers = []*container{
+		VendorContainer,
+		SystemContainer,
+		ProductContainer,
+		ApexContainer,
+		CtsContainer,
+	}
 )
 
 func initializeApexContainer() *container {
@@ -155,68 +240,38 @@
 	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{
