Use the handwritten system image if it's defined

Currently cuttlefish uses a handwritten system image, we should
use that too to match the current behavior.

Bug: 392734113
Test: m --soong-only and launched emulator
Change-Id: Ibc4e7ef52d400933c44df5d4a5403834ccb3a03c
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index ebcc68b..9dcbec1 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -42,8 +42,85 @@
 	ctx.PreDepsMutators(RegisterCollectFileSystemDepsMutators)
 }
 
+type generatedPartitionData struct {
+	partitionType string
+	moduleName    string
+	// supported is true if the module was created successfully, false if there was some problem
+	// and the module couldn't be created.
+	supported   bool
+	handwritten bool
+}
+
+type allGeneratedPartitionData []generatedPartitionData
+
+func (d allGeneratedPartitionData) moduleNames() []string {
+	var result []string
+	for _, data := range d {
+		if data.supported {
+			result = append(result, data.moduleName)
+		}
+	}
+	return result
+}
+
+func (d allGeneratedPartitionData) types() []string {
+	var result []string
+	for _, data := range d {
+		if data.supported {
+			result = append(result, data.partitionType)
+		}
+	}
+	return result
+}
+
+func (d allGeneratedPartitionData) unsupportedTypes() []string {
+	var result []string
+	for _, data := range d {
+		if !data.supported {
+			result = append(result, data.partitionType)
+		}
+	}
+	return result
+}
+
+func (d allGeneratedPartitionData) names() []string {
+	var result []string
+	for _, data := range d {
+		if data.supported {
+			result = append(result, data.moduleName)
+		}
+	}
+	return result
+}
+
+func (d allGeneratedPartitionData) nameForType(ty string) string {
+	for _, data := range d {
+		if data.supported && data.partitionType == ty {
+			return data.moduleName
+		}
+	}
+	return ""
+}
+
+func (d allGeneratedPartitionData) typeForName(name string) string {
+	for _, data := range d {
+		if data.supported && data.moduleName == name {
+			return data.partitionType
+		}
+	}
+	return ""
+}
+
+func (d allGeneratedPartitionData) isHandwritten(name string) bool {
+	for _, data := range d {
+		if data.supported && data.moduleName == name {
+			return data.handwritten
+		}
+	}
+	return false
+}
+
 type filesystemCreatorProps struct {
-	Generated_partition_types   []string `blueprint:"mutated"`
 	Unsupported_partition_types []string `blueprint:"mutated"`
 
 	Vbmeta_module_names    []string `blueprint:"mutated"`
@@ -78,59 +155,71 @@
 	return module
 }
 
-func generatedPartitions(ctx android.EarlyModuleContext) []string {
+func generatedPartitions(ctx android.EarlyModuleContext) allGeneratedPartitionData {
 	partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
-	generatedPartitions := []string{"system"}
+
+	var result allGeneratedPartitionData
+	addGenerated := func(ty string) {
+		result = append(result, generatedPartitionData{
+			partitionType: ty,
+			moduleName:    generatedModuleNameForPartition(ctx.Config(), ty),
+			supported:     true,
+		})
+	}
+
+	if ctx.Config().UseSoongSystemImage() {
+		if ctx.Config().SoongDefinedSystemImage() == "" {
+			panic("PRODUCT_SOONG_DEFINED_SYSTEM_IMAGE must be set if USE_SOONG_DEFINED_SYSTEM_IMAGE is true")
+		}
+		result = append(result, generatedPartitionData{
+			partitionType: "system",
+			moduleName:    ctx.Config().SoongDefinedSystemImage(),
+			supported:     true,
+			handwritten:   true,
+		})
+	} else {
+		addGenerated("system")
+	}
 	if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
-		generatedPartitions = append(generatedPartitions, "system_ext")
+		addGenerated("system_ext")
 	}
 	if ctx.DeviceConfig().BuildingVendorImage() && ctx.DeviceConfig().VendorPath() == "vendor" {
-		generatedPartitions = append(generatedPartitions, "vendor")
+		addGenerated("vendor")
 	}
 	if ctx.DeviceConfig().BuildingProductImage() && ctx.DeviceConfig().ProductPath() == "product" {
-		generatedPartitions = append(generatedPartitions, "product")
+		addGenerated("product")
 	}
 	if ctx.DeviceConfig().BuildingOdmImage() && ctx.DeviceConfig().OdmPath() == "odm" {
-		generatedPartitions = append(generatedPartitions, "odm")
+		addGenerated("odm")
 	}
 	if ctx.DeviceConfig().BuildingUserdataImage() && ctx.DeviceConfig().UserdataPath() == "data" {
-		generatedPartitions = append(generatedPartitions, "userdata")
+		addGenerated("userdata")
 	}
 	if partitionVars.BuildingSystemDlkmImage {
-		generatedPartitions = append(generatedPartitions, "system_dlkm")
+		addGenerated("system_dlkm")
 	}
 	if partitionVars.BuildingVendorDlkmImage {
-		generatedPartitions = append(generatedPartitions, "vendor_dlkm")
+		addGenerated("vendor_dlkm")
 	}
 	if partitionVars.BuildingOdmDlkmImage {
-		generatedPartitions = append(generatedPartitions, "odm_dlkm")
+		addGenerated("odm_dlkm")
 	}
 	if partitionVars.BuildingRamdiskImage {
-		generatedPartitions = append(generatedPartitions, "ramdisk")
+		addGenerated("ramdisk")
 	}
 	if buildingVendorBootImage(partitionVars) {
-		generatedPartitions = append(generatedPartitions, "vendor_ramdisk")
+		addGenerated("vendor_ramdisk")
 	}
 	if ctx.DeviceConfig().BuildingRecoveryImage() && ctx.DeviceConfig().RecoveryPath() == "recovery" {
-		generatedPartitions = append(generatedPartitions, "recovery")
+		addGenerated("recovery")
 	}
-	return generatedPartitions
+	return result
 }
 
 func (f *filesystemCreator) createInternalModules(ctx android.LoadHookContext) {
-	soongGeneratedPartitions := generatedPartitions(ctx)
-	finalSoongGeneratedPartitions := make([]string, 0, len(soongGeneratedPartitions))
-	for _, partitionType := range soongGeneratedPartitions {
-		if f.createPartition(ctx, partitionType) {
-			f.properties.Generated_partition_types = append(f.properties.Generated_partition_types, partitionType)
-			finalSoongGeneratedPartitions = append(finalSoongGeneratedPartitions, partitionType)
-		} else {
-			f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, partitionType)
-		}
-	}
-	finalSoongGeneratedPartitionNames := make([]string, 0, len(finalSoongGeneratedPartitions))
-	for _, partitionType := range finalSoongGeneratedPartitions {
-		finalSoongGeneratedPartitionNames = append(finalSoongGeneratedPartitionNames, generatedModuleNameForPartition(ctx.Config(), partitionType))
+	partitions := generatedPartitions(ctx)
+	for i := range partitions {
+		f.createPartition(ctx, partitions, &partitions[i])
 	}
 	// Create android_info.prop
 	f.createAndroidInfo(ctx)
@@ -162,13 +251,13 @@
 
 	var systemOtherImageName string
 	if buildingSystemOtherImage(partitionVars) {
-		systemModule := generatedModuleNameForPartition(ctx.Config(), "system")
+		systemModule := partitions.nameForType("system")
 		systemOtherImageName = generatedModuleNameForPartition(ctx.Config(), "system_other")
 		ctx.CreateModule(
 			filesystem.SystemOtherImageFactory,
 			&filesystem.SystemOtherImageProperties{
 				System_image:                    &systemModule,
-				Preinstall_dexpreopt_files_from: finalSoongGeneratedPartitionNames,
+				Preinstall_dexpreopt_files_from: partitions.moduleNames(),
 			},
 			&struct {
 				Name *string
@@ -178,19 +267,19 @@
 		)
 	}
 
-	for _, x := range f.createVbmetaPartitions(ctx, finalSoongGeneratedPartitions) {
+	for _, x := range f.createVbmetaPartitions(ctx, partitions) {
 		f.properties.Vbmeta_module_names = append(f.properties.Vbmeta_module_names, x.moduleName)
 		f.properties.Vbmeta_partition_names = append(f.properties.Vbmeta_partition_names, x.partitionName)
 	}
 
 	var superImageSubpartitions []string
 	if buildingSuperImage(partitionVars) {
-		superImageSubpartitions = createSuperImage(ctx, finalSoongGeneratedPartitions, partitionVars, systemOtherImageName)
+		superImageSubpartitions = createSuperImage(ctx, partitions, partitionVars, systemOtherImageName)
 		f.properties.Super_image = ":" + generatedModuleNameForPartition(ctx.Config(), "super")
 	}
 
-	ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions = finalSoongGeneratedPartitions
-	f.createDeviceModule(ctx, finalSoongGeneratedPartitions, f.properties.Vbmeta_module_names, superImageSubpartitions)
+	ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions = partitions
+	f.createDeviceModule(ctx, partitions, f.properties.Vbmeta_module_names, superImageSubpartitions)
 }
 
 func generatedModuleName(cfg android.Config, suffix string) string {
@@ -233,7 +322,7 @@
 
 func (f *filesystemCreator) createDeviceModule(
 	ctx android.LoadHookContext,
-	generatedPartitionTypes []string,
+	partitions allGeneratedPartitionData,
 	vbmetaPartitions []string,
 	superImageSubPartitions []string,
 ) {
@@ -250,35 +339,35 @@
 	if f.properties.Super_image != "" {
 		partitionProps.Super_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "super"))
 	}
-	if android.InList("system", generatedPartitionTypes) && !android.InList("system", superImageSubPartitions) {
-		partitionProps.System_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
+	if modName := partitions.nameForType("system"); modName != "" && !android.InList("system", superImageSubPartitions) {
+		partitionProps.System_partition_name = proptools.StringPtr(modName)
 	}
-	if android.InList("system_ext", generatedPartitionTypes) && !android.InList("system_ext", superImageSubPartitions) {
-		partitionProps.System_ext_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
+	if modName := partitions.nameForType("system_ext"); modName != "" && !android.InList("system_ext", superImageSubPartitions) {
+		partitionProps.System_ext_partition_name = proptools.StringPtr(modName)
 	}
-	if android.InList("vendor", generatedPartitionTypes) && !android.InList("vendor", superImageSubPartitions) {
-		partitionProps.Vendor_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor"))
+	if modName := partitions.nameForType("vendor"); modName != "" && !android.InList("vendor", superImageSubPartitions) {
+		partitionProps.Vendor_partition_name = proptools.StringPtr(modName)
 	}
-	if android.InList("product", generatedPartitionTypes) && !android.InList("product", superImageSubPartitions) {
-		partitionProps.Product_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "product"))
+	if modName := partitions.nameForType("product"); modName != "" && !android.InList("product", superImageSubPartitions) {
+		partitionProps.Product_partition_name = proptools.StringPtr(modName)
 	}
-	if android.InList("odm", generatedPartitionTypes) && !android.InList("odm", superImageSubPartitions) {
-		partitionProps.Odm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm"))
+	if modName := partitions.nameForType("odm"); modName != "" && !android.InList("odm", superImageSubPartitions) {
+		partitionProps.Odm_partition_name = proptools.StringPtr(modName)
 	}
-	if android.InList("userdata", f.properties.Generated_partition_types) {
-		partitionProps.Userdata_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "userdata"))
+	if modName := partitions.nameForType("userdata"); modName != "" {
+		partitionProps.Userdata_partition_name = proptools.StringPtr(modName)
 	}
-	if android.InList("recovery", f.properties.Generated_partition_types) {
-		partitionProps.Recovery_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "recovery"))
+	if modName := partitions.nameForType("recovery"); modName != "" {
+		partitionProps.Recovery_partition_name = proptools.StringPtr(modName)
 	}
-	if android.InList("system_dlkm", f.properties.Generated_partition_types) && !android.InList("system_dlkm", superImageSubPartitions) {
-		partitionProps.System_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_dlkm"))
+	if modName := partitions.nameForType("system_dlkm"); modName != "" && !android.InList("system_dlkm", superImageSubPartitions) {
+		partitionProps.System_dlkm_partition_name = proptools.StringPtr(modName)
 	}
-	if android.InList("vendor_dlkm", f.properties.Generated_partition_types) && !android.InList("vendor_dlkm", superImageSubPartitions) {
-		partitionProps.Vendor_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_dlkm"))
+	if modName := partitions.nameForType("vendor_dlkm"); modName != "" && !android.InList("vendor_dlkm", superImageSubPartitions) {
+		partitionProps.Vendor_dlkm_partition_name = proptools.StringPtr(modName)
 	}
-	if android.InList("odm_dlkm", f.properties.Generated_partition_types) && !android.InList("odm_dlkm", superImageSubPartitions) {
-		partitionProps.Odm_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm_dlkm"))
+	if modName := partitions.nameForType("odm_dlkm"); modName != "" && !android.InList("odm_dlkm", superImageSubPartitions) {
+		partitionProps.Odm_dlkm_partition_name = proptools.StringPtr(modName)
 	}
 	if f.properties.Boot_image != "" {
 		partitionProps.Boot_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "boot"))
@@ -302,7 +391,8 @@
 	ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps, deviceProps)
 }
 
-func partitionSpecificFsProps(ctx android.EarlyModuleContext, fsProps *filesystem.FilesystemProperties, partitionVars android.PartitionVariables, partitionType string) {
+func partitionSpecificFsProps(ctx android.EarlyModuleContext, partitions allGeneratedPartitionData, fsProps *filesystem.FilesystemProperties, partitionType string) {
+	partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
 	switch partitionType {
 	case "system":
 		fsProps.Build_logtags = proptools.BoolPtr(true)
@@ -354,8 +444,8 @@
 		fsProps.Dirs = proptools.NewSimpleConfigurable(commonPartitionDirs)
 		fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
 
-		if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
-			fsProps.Import_aconfig_flags_from = []string{generatedModuleNameForPartition(ctx.Config(), "system_ext")}
+		if systemExtName := partitions.nameForType("system_ext"); systemExtName != "" {
+			fsProps.Import_aconfig_flags_from = []string{systemExtName}
 		}
 		fsProps.Stem = proptools.StringPtr("system.img")
 	case "system_ext":
@@ -371,9 +461,9 @@
 		fsProps.Stem = proptools.StringPtr("system_ext.img")
 	case "product":
 		fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
-		fsProps.Android_filesystem_deps.System = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
-		if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
-			fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
+		fsProps.Android_filesystem_deps.System = proptools.StringPtr(partitions.nameForType("system"))
+		if systemExtName := partitions.nameForType("system_ext"); systemExtName != "" {
+			fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(systemExtName)
 		}
 		fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
 		fsProps.Stem = proptools.StringPtr("product.img")
@@ -389,9 +479,9 @@
 				Name:   proptools.StringPtr("lib/modules"),
 			},
 		}
-		fsProps.Android_filesystem_deps.System = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
-		if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
-			fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
+		fsProps.Android_filesystem_deps.System = proptools.StringPtr(partitions.nameForType("system"))
+		if systemExtName := partitions.nameForType("system_ext"); systemExtName != "" {
+			fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(systemExtName)
 		}
 		fsProps.Security_patch = proptools.StringPtr(partitionVars.VendorSecurityPatch)
 		fsProps.Stem = proptools.StringPtr("vendor.img")
@@ -481,8 +571,8 @@
 		fsProps.Security_patch = proptools.StringPtr(partitionVars.OdmDlkmSecurityPatch)
 		fsProps.Stem = proptools.StringPtr("odm_dlkm.img")
 	case "vendor_ramdisk":
-		if android.InList("recovery", generatedPartitions(ctx)) {
-			fsProps.Include_files_of = []string{generatedModuleNameForPartition(ctx.Config(), "recovery")}
+		if recoveryName := partitions.nameForType("recovery"); recoveryName != "" {
+			fsProps.Include_files_of = []string{recoveryName}
 		}
 		fsProps.Stem = proptools.StringPtr("vendor_ramdisk.img")
 	}
@@ -496,16 +586,22 @@
 	}
 )
 
-// Creates a soong module to build the given partition. Returns false if we can't support building
-// it.
-func (f *filesystemCreator) createPartition(ctx android.LoadHookContext, partitionType string) bool {
-	baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)))
-
-	fsProps, supported := generateFsProps(ctx, partitionType)
-	if !supported {
-		return false
+// Creates a soong module to build the given partition.
+func (f *filesystemCreator) createPartition(ctx android.LoadHookContext, partitions allGeneratedPartitionData, partition *generatedPartitionData) {
+	// Nextgen team's handwritten soong system image, don't need to create anything ourselves
+	if partition.partitionType == "system" && ctx.Config().UseSoongSystemImage() {
+		return
 	}
 
+	baseProps := generateBaseProps(proptools.StringPtr(partition.moduleName))
+
+	fsProps, supported := generateFsProps(ctx, partitions, partition.partitionType)
+	if !supported {
+		partition.supported = false
+		return
+	}
+
+	partitionType := partition.partitionType
 	if partitionType == "vendor" || partitionType == "product" || partitionType == "system" {
 		fsProps.Linker_config.Gen_linker_config = proptools.BoolPtr(true)
 		if partitionType != "system" {
@@ -529,7 +625,6 @@
 	if partitionType == "vendor" {
 		f.createVendorBuildProp(ctx)
 	}
-	return true
 }
 
 // Creates filegroups for the files specified in BOARD_(partition_)AVB_KEY_PATH
@@ -731,7 +826,7 @@
 	moduleName := generatedModuleName(ctx.Config(), "recovery-prop.default")
 
 	var vendorBuildProp *string
-	if android.InList("vendor", generatedPartitions(ctx)) {
+	if ctx.DeviceConfig().BuildingVendorImage() && ctx.DeviceConfig().VendorPath() == "vendor" {
 		vendorBuildProp = proptools.StringPtr(":" + generatedModuleName(ctx.Config(), "vendor-build.prop"))
 	}
 
@@ -821,7 +916,7 @@
 	}
 }
 
-func generateFsProps(ctx android.EarlyModuleContext, partitionType string) (*filesystem.FilesystemProperties, bool) {
+func generateFsProps(ctx android.EarlyModuleContext, partitions allGeneratedPartitionData, partitionType string) (*filesystem.FilesystemProperties, bool) {
 	fsProps := &filesystem.FilesystemProperties{}
 
 	partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
@@ -889,7 +984,7 @@
 
 	}
 
-	partitionSpecificFsProps(ctx, fsProps, partitionVars, partitionType)
+	partitionSpecificFsProps(ctx, partitions, fsProps, partitionType)
 
 	return fsProps, true
 }
@@ -976,12 +1071,12 @@
 	return result
 }
 
-func (f *filesystemCreator) createFileListDiffTest(ctx android.ModuleContext, partitionType string) android.Path {
-	partitionModuleName := generatedModuleNameForPartition(ctx.Config(), partitionType)
+func (f *filesystemCreator) createFileListDiffTest(ctx android.ModuleContext, partitionType string, partitionModuleName string) android.Path {
 	partitionImage := ctx.GetDirectDepWithTag(partitionModuleName, generatedFilesystemDepTag)
 	filesystemInfo, ok := android.OtherModuleProvider(ctx, partitionImage, filesystem.FilesystemProvider)
 	if !ok {
 		ctx.ModuleErrorf("Expected module %s to provide FileysystemInfo", partitionModuleName)
+		return nil
 	}
 	makeFileList := android.PathForArbitraryOutput(ctx, fmt.Sprintf("target/product/%s/obj/PACKAGING/%s_intermediates/file_list.txt", ctx.Config().DeviceName(), partitionType))
 	diffTestResultFile := android.PathForModuleOut(ctx, fmt.Sprintf("diff_test_%s.txt", partitionModuleName))
@@ -1042,8 +1137,8 @@
 var generatedVbmetaPartitionDepTag imageDepTagType
 
 func (f *filesystemCreator) DepsMutator(ctx android.BottomUpMutatorContext) {
-	for _, partitionType := range f.properties.Generated_partition_types {
-		ctx.AddDependency(ctx.Module(), generatedFilesystemDepTag, generatedModuleNameForPartition(ctx.Config(), partitionType))
+	for _, name := range ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions.names() {
+		ctx.AddDependency(ctx.Module(), generatedFilesystemDepTag, name)
 	}
 	for _, vbmetaModule := range f.properties.Vbmeta_module_names {
 		ctx.AddDependency(ctx.Module(), generatedVbmetaPartitionDepTag, vbmetaModule)
@@ -1056,9 +1151,11 @@
 	}
 	f.HideFromMake()
 
+	partitions := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions
+
 	var content strings.Builder
 	generatedBp := android.PathForModuleOut(ctx, "soong_generated_product_config.bp")
-	for _, partition := range ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions {
+	for _, partition := range partitions.types() {
 		content.WriteString(generateBpContent(ctx, partition))
 		content.WriteString("\n")
 	}
@@ -1067,12 +1164,12 @@
 	ctx.Phony("product_config_to_bp", generatedBp)
 
 	var diffTestFiles []android.Path
-	for _, partitionType := range f.properties.Generated_partition_types {
-		diffTestFile := f.createFileListDiffTest(ctx, partitionType)
+	for _, partitionType := range partitions.types() {
+		diffTestFile := f.createFileListDiffTest(ctx, partitionType, partitions.nameForType(partitionType))
 		diffTestFiles = append(diffTestFiles, diffTestFile)
 		ctx.Phony(fmt.Sprintf("soong_generated_%s_filesystem_test", partitionType), diffTestFile)
 	}
-	for _, partitionType := range f.properties.Unsupported_partition_types {
+	for _, partitionType := range slices.Concat(partitions.unsupportedTypes(), f.properties.Unsupported_partition_types) {
 		diffTestFile := createFailingCommand(ctx, fmt.Sprintf("Couldn't build %s partition", partitionType))
 		diffTestFiles = append(diffTestFiles, diffTestFile)
 		ctx.Phony(fmt.Sprintf("soong_generated_%s_filesystem_test", partitionType), diffTestFile)
@@ -1118,13 +1215,13 @@
 }
 
 func generateBpContent(ctx android.EarlyModuleContext, partitionType string) string {
-	fsProps, fsTypeSupported := generateFsProps(ctx, partitionType)
+	fsGenState := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
+	fsProps, fsTypeSupported := generateFsProps(ctx, fsGenState.soongGeneratedPartitions, partitionType)
 	if !fsTypeSupported {
 		return ""
 	}
 
 	baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)))
-	fsGenState := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
 	deps := fsGenState.fsDeps[partitionType]
 	highPriorityDeps := fsGenState.generatedPrebuiltEtcModuleNames
 	depProps := generateDepStruct(*deps, highPriorityDeps)
diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go
index 9327669..9b25e77 100644
--- a/fsgen/fsgen_mutators.go
+++ b/fsgen/fsgen_mutators.go
@@ -60,8 +60,8 @@
 	depCandidates []string
 	// Map of names of partition to the information of modules to be added as deps
 	fsDeps map[string]*multilibDeps
-	// List of name of partitions to be generated by the filesystem_creator module
-	soongGeneratedPartitions []string
+	// Information about the main soong-generated partitions
+	soongGeneratedPartitions allGeneratedPartitionData
 	// Mutex to protect the fsDeps
 	fsDepsMutex sync.Mutex
 	// Map of _all_ soong module names to their corresponding installation properties
@@ -282,9 +282,12 @@
 	removeOverriddenDeps(mctx)
 	fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
 	fsDeps := fsGenState.fsDeps
-	soongGeneratedPartitionMap := getAllSoongGeneratedPartitionNames(mctx.Config(), fsGenState.soongGeneratedPartitions)
 	m := mctx.Module()
-	if partition, ok := soongGeneratedPartitionMap[m.Name()]; ok {
+	if partition := fsGenState.soongGeneratedPartitions.typeForName(m.Name()); partition != "" {
+		if fsGenState.soongGeneratedPartitions.isHandwritten(m.Name()) {
+			// Handwritten image, don't modify it
+			return
+		}
 		depsStruct := generateDepStruct(*fsDeps[partition], fsGenState.generatedPrebuiltEtcModuleNames)
 		if err := proptools.AppendMatchingProperties(m.GetProperties(), depsStruct, nil); err != nil {
 			mctx.ModuleErrorf(err.Error())
diff --git a/fsgen/super_img.go b/fsgen/super_img.go
index e353688..569f780 100644
--- a/fsgen/super_img.go
+++ b/fsgen/super_img.go
@@ -29,7 +29,7 @@
 
 func createSuperImage(
 	ctx android.LoadHookContext,
-	partitions []string,
+	partitions allGeneratedPartitionData,
 	partitionVars android.PartitionVariables,
 	systemOtherImageName string,
 ) []string {
@@ -90,40 +90,40 @@
 
 	var superImageSubpartitions []string
 	partitionNameProps := &filesystem.SuperImagePartitionNameProperties{}
-	if android.InList("system", partitions) {
-		partitionNameProps.System_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
+	if modName := partitions.nameForType("system"); modName != "" {
+		partitionNameProps.System_partition = proptools.StringPtr(modName)
 		superImageSubpartitions = append(superImageSubpartitions, "system")
 	}
-	if android.InList("system_ext", partitions) {
-		partitionNameProps.System_ext_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
+	if modName := partitions.nameForType("system_ext"); modName != "" {
+		partitionNameProps.System_ext_partition = proptools.StringPtr(modName)
 		superImageSubpartitions = append(superImageSubpartitions, "system_ext")
 	}
-	if android.InList("system_dlkm", partitions) {
-		partitionNameProps.System_dlkm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_dlkm"))
+	if modName := partitions.nameForType("system_dlkm"); modName != "" {
+		partitionNameProps.System_dlkm_partition = proptools.StringPtr(modName)
 		superImageSubpartitions = append(superImageSubpartitions, "system_dlkm")
 	}
-	if android.InList("system_other", partitions) {
-		partitionNameProps.System_other_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_other"))
+	if modName := partitions.nameForType("system_other"); modName != "" {
+		partitionNameProps.System_other_partition = proptools.StringPtr(modName)
 		superImageSubpartitions = append(superImageSubpartitions, "system_other")
 	}
-	if android.InList("product", partitions) {
-		partitionNameProps.Product_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "product"))
+	if modName := partitions.nameForType("product"); modName != "" {
+		partitionNameProps.Product_partition = proptools.StringPtr(modName)
 		superImageSubpartitions = append(superImageSubpartitions, "product")
 	}
-	if android.InList("vendor", partitions) {
-		partitionNameProps.Vendor_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor"))
+	if modName := partitions.nameForType("vendor"); modName != "" {
+		partitionNameProps.Vendor_partition = proptools.StringPtr(modName)
 		superImageSubpartitions = append(superImageSubpartitions, "vendor")
 	}
-	if android.InList("vendor_dlkm", partitions) {
-		partitionNameProps.Vendor_dlkm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_dlkm"))
+	if modName := partitions.nameForType("vendor_dlkm"); modName != "" {
+		partitionNameProps.Vendor_dlkm_partition = proptools.StringPtr(modName)
 		superImageSubpartitions = append(superImageSubpartitions, "vendor_dlkm")
 	}
-	if android.InList("odm", partitions) {
-		partitionNameProps.Odm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm"))
+	if modName := partitions.nameForType("odm"); modName != "" {
+		partitionNameProps.Odm_partition = proptools.StringPtr(modName)
 		superImageSubpartitions = append(superImageSubpartitions, "odm")
 	}
-	if android.InList("odm_dlkm", partitions) {
-		partitionNameProps.Odm_dlkm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm_dlkm"))
+	if modName := partitions.nameForType("odm_dlkm"); modName != "" {
+		partitionNameProps.Odm_dlkm_partition = proptools.StringPtr(modName)
 		superImageSubpartitions = append(superImageSubpartitions, "odm_dlkm")
 	}
 
diff --git a/fsgen/vbmeta_partitions.go b/fsgen/vbmeta_partitions.go
index be738ea..93425ae 100644
--- a/fsgen/vbmeta_partitions.go
+++ b/fsgen/vbmeta_partitions.go
@@ -17,7 +17,6 @@
 import (
 	"android/soong/android"
 	"android/soong/filesystem"
-	"slices"
 	"strconv"
 
 	"github.com/google/blueprint/proptools"
@@ -63,7 +62,7 @@
 // like vbmeta_system might contain the avb metadata for just a few products. In cuttlefish
 // vbmeta_system contains metadata about product, system, and system_ext. Using chained partitions,
 // that group of partitions can be updated independently from the other signed partitions.
-func (f *filesystemCreator) createVbmetaPartitions(ctx android.LoadHookContext, generatedPartitionTypes []string) []vbmetaModuleInfo {
+func (f *filesystemCreator) createVbmetaPartitions(ctx android.LoadHookContext, partitions allGeneratedPartitionData) []vbmetaModuleInfo {
 	partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
 	// Some products seem to have BuildingVbmetaImage as true even when BoardAvbEnable is false
 	if !partitionVars.BuildingVbmetaImage || !partitionVars.BoardAvbEnable {
@@ -114,11 +113,9 @@
 
 		var partitionModules []string
 		for _, partition := range props.Partitions {
-			if !slices.Contains(generatedPartitionTypes, partition) {
-				// The partition is probably unsupported.
-				continue
+			if modName := partitions.nameForType(partition); modName != "" {
+				partitionModules = append(partitionModules, modName)
 			}
-			partitionModules = append(partitionModules, generatedModuleNameForPartition(ctx.Config(), partition))
 		}
 
 		name := generatedModuleNameForPartition(ctx.Config(), chainedName)
@@ -218,7 +215,7 @@
 
 	var chainedPartitionModules []string
 	var includePartitionModules []string
-	allGeneratedPartitionTypes := append(generatedPartitionTypes,
+	allGeneratedPartitionTypes := append(partitions.types(),
 		chainedPartitionTypes...,
 	)
 	if len(f.properties.Boot_image) > 0 {