Merge "Remove METADATA files from implicit dependencies of SBOMs" into main
diff --git a/android/config.go b/android/config.go
index 27d3b87..94285f8 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1834,6 +1834,10 @@
 	return Bool(c.productVariables.CompressedApex) && !c.UnbundledBuildApps()
 }
 
+func (c *config) DefaultApexPayloadType() string {
+	return StringDefault(c.productVariables.DefaultApexPayloadType, "ext4")
+}
+
 func (c *config) UseSoongSystemImage() bool {
 	return Bool(c.productVariables.UseSoongSystemImage)
 }
diff --git a/android/variable.go b/android/variable.go
index 88cf5a5..7ae9a43 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -408,9 +408,10 @@
 
 	Ndk_abis *bool `json:",omitempty"`
 
-	ForceApexSymlinkOptimization *bool `json:",omitempty"`
-	CompressedApex               *bool `json:",omitempty"`
-	Aml_abis                     *bool `json:",omitempty"`
+	ForceApexSymlinkOptimization *bool   `json:",omitempty"`
+	CompressedApex               *bool   `json:",omitempty"`
+	DefaultApexPayloadType       *string `json:",omitempty"`
+	Aml_abis                     *bool   `json:",omitempty"`
 
 	DexpreoptGlobalConfig *string `json:",omitempty"`
 
@@ -612,6 +613,7 @@
 	// Boot image stuff
 	BuildingRamdiskImage            bool   `json:",omitempty"`
 	ProductBuildBootImage           bool   `json:",omitempty"`
+	ProductBuildVendorBootImage     string `json:",omitempty"`
 	ProductBuildInitBootImage       bool   `json:",omitempty"`
 	BoardUsesRecoveryAsBoot         bool   `json:",omitempty"`
 	BoardPrebuiltBootimage          string `json:",omitempty"`
@@ -620,6 +622,7 @@
 	BoardInitBootimagePartitionSize string `json:",omitempty"`
 	BoardBootHeaderVersion          string `json:",omitempty"`
 	TargetKernelPath                string `json:",omitempty"`
+	BoardUsesGenericKernelImage     bool   `json:",omitempty"`
 
 	// Avb (android verified boot) stuff
 	BoardAvbEnable          bool                                `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index dc24df3..91d01b0 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1752,7 +1752,8 @@
 }
 
 func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
-	switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
+	defaultFsType := ctx.Config().DefaultApexPayloadType()
+	switch proptools.StringDefault(a.properties.Payload_fs_type, defaultFsType) {
 	case ext4FsType:
 		a.payloadFsType = ext4
 	case f2fsFsType:
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index ba5319f..28cec27 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -710,6 +710,7 @@
 	"odm_dlkm",
 	"system_dlkm",
 	"ramdisk",
+	"vendor_ramdisk",
 }
 
 func (f *filesystem) addMakeBuiltFiles(ctx android.ModuleContext, builder *android.RuleBuilder, rootDir android.Path) {
diff --git a/fsgen/boot_imgs.go b/fsgen/boot_imgs.go
index 66d9107..1f8c05d 100644
--- a/fsgen/boot_imgs.go
+++ b/fsgen/boot_imgs.go
@@ -3,7 +3,9 @@
 import (
 	"android/soong/android"
 	"android/soong/filesystem"
+	"fmt"
 	"path/filepath"
+	"strconv"
 
 	"github.com/google/blueprint/proptools"
 )
@@ -52,6 +54,27 @@
 	return true
 }
 
+func createVendorBootImage(ctx android.LoadHookContext) bool {
+	partitionVariables := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
+
+	bootImageName := generatedModuleNameForPartition(ctx.Config(), "vendor_boot")
+
+	ctx.CreateModule(
+		filesystem.BootimgFactory,
+		&filesystem.BootimgProperties{
+			Vendor_boot:    proptools.BoolPtr(true),
+			Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_ramdisk")),
+			Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
+		},
+		&struct {
+			Name *string
+		}{
+			Name: proptools.StringPtr(bootImageName),
+		},
+	)
+	return true
+}
+
 // Returns the equivalent of the BUILDING_BOOT_IMAGE variable in make. Derived from this logic:
 // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/board_config.mk;l=458;drc=5b55f926830963c02ab1d2d91e46442f04ba3af0
 func buildingBootImage(partitionVars android.PartitionVariables) bool {
@@ -76,3 +99,27 @@
 
 	return false
 }
+
+// Returns the equivalent of the BUILDING_VENDOR_BOOT_IMAGE variable in make. Derived from this logic:
+// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/board_config.mk;l=518;drc=5b55f926830963c02ab1d2d91e46442f04ba3af0
+func buildingVendorBootImage(partitionVars android.PartitionVariables) bool {
+	if v, exists := boardBootHeaderVersion(partitionVars); exists && v >= 3 {
+		x := partitionVars.ProductBuildVendorBootImage
+		if x == "" || x == "true" {
+			return true
+		}
+	}
+
+	return false
+}
+
+func boardBootHeaderVersion(partitionVars android.PartitionVariables) (int, bool) {
+	if len(partitionVars.BoardBootHeaderVersion) == 0 {
+		return 0, false
+	}
+	v, err := strconv.ParseInt(partitionVars.BoardBootHeaderVersion, 10, 32)
+	if err != nil {
+		panic(fmt.Sprintf("BOARD_BOOT_HEADER_VERSION must be an int, got: %q", partitionVars.BoardBootHeaderVersion))
+	}
+	return int(v), true
+}
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index b1b8f6a..6eae23a 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -48,7 +48,8 @@
 	Vbmeta_module_names    []string `blueprint:"mutated"`
 	Vbmeta_partition_names []string `blueprint:"mutated"`
 
-	Boot_image string `blueprint:"mutated" android:"path_device_first"`
+	Boot_image        string `blueprint:"mutated" android:"path_device_first"`
+	Vendor_boot_image string `blueprint:"mutated" android:"path_device_first"`
 }
 
 type filesystemCreator struct {
@@ -74,6 +75,7 @@
 }
 
 func generatedPartitions(ctx android.LoadHookContext) []string {
+	partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
 	generatedPartitions := []string{"system"}
 	if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
 		generatedPartitions = append(generatedPartitions, "system_ext")
@@ -90,18 +92,21 @@
 	if ctx.DeviceConfig().BuildingUserdataImage() && ctx.DeviceConfig().UserdataPath() == "data" {
 		generatedPartitions = append(generatedPartitions, "userdata")
 	}
-	if ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BuildingSystemDlkmImage {
+	if partitionVars.BuildingSystemDlkmImage {
 		generatedPartitions = append(generatedPartitions, "system_dlkm")
 	}
-	if ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BuildingVendorDlkmImage {
+	if partitionVars.BuildingVendorDlkmImage {
 		generatedPartitions = append(generatedPartitions, "vendor_dlkm")
 	}
-	if ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BuildingOdmDlkmImage {
+	if partitionVars.BuildingOdmDlkmImage {
 		generatedPartitions = append(generatedPartitions, "odm_dlkm")
 	}
-	if ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BuildingRamdiskImage {
+	if partitionVars.BuildingRamdiskImage {
 		generatedPartitions = append(generatedPartitions, "ramdisk")
 	}
+	if buildingVendorBootImage(partitionVars) {
+		generatedPartitions = append(generatedPartitions, "vendor_ramdisk")
+	}
 	return generatedPartitions
 }
 
@@ -117,13 +122,21 @@
 		}
 	}
 
-	if buildingBootImage(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse) {
+	partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
+	if buildingBootImage(partitionVars) {
 		if createBootImage(ctx) {
 			f.properties.Boot_image = ":" + generatedModuleNameForPartition(ctx.Config(), "boot")
 		} else {
 			f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, "boot")
 		}
 	}
+	if buildingVendorBootImage(partitionVars) {
+		if createVendorBootImage(ctx) {
+			f.properties.Vendor_boot_image = ":" + generatedModuleNameForPartition(ctx.Config(), "vendor_boot")
+		} else {
+			f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, "vendor_boot")
+		}
+	}
 
 	for _, x := range createVbmetaPartitions(ctx, finalSoongGeneratedPartitions) {
 		f.properties.Vbmeta_module_names = append(f.properties.Vbmeta_module_names, x.moduleName)
@@ -182,13 +195,13 @@
 	ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps)
 }
 
-func partitionSpecificFsProps(fsProps *filesystem.FilesystemProperties, partitionType string) {
+func partitionSpecificFsProps(fsProps *filesystem.FilesystemProperties, partitionVars android.PartitionVariables, partitionType string) {
 	switch partitionType {
 	case "system":
 		fsProps.Build_logtags = proptools.BoolPtr(true)
 		// https://source.corp.google.com/h/googleplex-android/platform/build//639d79f5012a6542ab1f733b0697db45761ab0f3:core/packaging/flags.mk;l=21;drc=5ba8a8b77507f93aa48cc61c5ba3f31a4d0cbf37;bpv=1;bpt=0
 		fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
-		// Identical to that of the generic_system_image
+		// Identical to that of the aosp_shared_system_image
 		fsProps.Fsverity.Inputs = []string{
 			"etc/boot-image.prof",
 			"etc/dirty-image-objects",
@@ -248,7 +261,28 @@
 		}
 	case "userdata":
 		fsProps.Base_dir = proptools.StringPtr("data")
-
+	case "ramdisk":
+		// Following the logic in https://cs.android.com/android/platform/superproject/main/+/c3c5063df32748a8806ce5da5dd0db158eab9ad9:build/make/core/Makefile;l=1307
+		fsProps.Dirs = android.NewSimpleConfigurable([]string{
+			"debug_ramdisk",
+			"dev",
+			"metadata",
+			"mnt",
+			"proc",
+			"second_stage_resources",
+			"sys",
+		})
+		if partitionVars.BoardUsesGenericKernelImage {
+			fsProps.Dirs.AppendSimpleValue([]string{
+				"first_stage_ramdisk/debug_ramdisk",
+				"first_stage_ramdisk/dev",
+				"first_stage_ramdisk/metadata",
+				"first_stage_ramdisk/mnt",
+				"first_stage_ramdisk/proc",
+				"first_stage_ramdisk/second_stage_resources",
+				"first_stage_ramdisk/sys",
+			})
+		}
 	}
 }
 
@@ -568,7 +602,7 @@
 
 	fsProps.Is_auto_generated = proptools.BoolPtr(true)
 
-	partitionSpecificFsProps(fsProps, partitionType)
+	partitionSpecificFsProps(fsProps, partitionVars, partitionType)
 
 	// system_image properties that are not set:
 	// - filesystemProperties.Avb_hash_algorithm
@@ -699,6 +733,14 @@
 		diffTestFiles = append(diffTestFiles, diffTestFile)
 		ctx.Phony("soong_generated_boot_filesystem_test", diffTestFile)
 	}
+	if f.properties.Vendor_boot_image != "" {
+		diffTestFile := android.PathForModuleOut(ctx, "vendor_boot_diff_test.txt")
+		soongBootImg := android.PathForModuleSrc(ctx, f.properties.Boot_image)
+		makeBootImage := android.PathForArbitraryOutput(ctx, fmt.Sprintf("target/product/%s/vendor_boot.img", ctx.Config().DeviceName()))
+		createDiffTest(ctx, diffTestFile, soongBootImg, makeBootImage)
+		diffTestFiles = append(diffTestFiles, diffTestFile)
+		ctx.Phony("soong_generated_vendor_boot_filesystem_test", diffTestFile)
+	}
 	ctx.Phony("soong_generated_filesystem_tests", diffTestFiles...)
 }
 
diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go
index 0d18660..12f9956 100644
--- a/fsgen/fsgen_mutators.go
+++ b/fsgen/fsgen_mutators.go
@@ -146,7 +146,8 @@
 					"fs_config_files_odm_dlkm": defaultDepCandidateProps(ctx.Config()),
 					"odm_dlkm-build.prop":      defaultDepCandidateProps(ctx.Config()),
 				},
-				"ramdisk": {},
+				"ramdisk":        {},
+				"vendor_ramdisk": {},
 			},
 			fsDepsMutex:                     sync.Mutex{},
 			moduleToInstallationProps:       map[string]installationProperties{},
diff --git a/java/app.go b/java/app.go
index 8bb73cb..7f80160 100644
--- a/java/app.go
+++ b/java/app.go
@@ -164,7 +164,7 @@
 type overridableAppProperties struct {
 	// The name of a certificate in the default certificate directory, blank to use the default product certificate,
 	// or an android_app_certificate module name in the form ":module".
-	Certificate *string
+	Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
 
 	// Name of the signing certificate lineage file or filegroup module.
 	Lineage *string `android:"path"`
@@ -1252,7 +1252,7 @@
 	if overridden {
 		return ":" + certificate
 	}
-	return String(a.overridableAppProperties.Certificate)
+	return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
 }
 
 func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
diff --git a/java/app_import.go b/java/app_import.go
index f044c68..8951c7d 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -97,7 +97,7 @@
 
 	// The name of a certificate in the default certificate directory or an android_app_certificate
 	// module name in the form ":module". Should be empty if presigned or default_dev_cert is set.
-	Certificate *string
+	Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
 
 	// Names of extra android_app_certificate modules to sign the apk with in the form ":module".
 	Additional_certificates []string
@@ -240,7 +240,7 @@
 }
 
 func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
-	cert := android.SrcIsModule(String(a.properties.Certificate))
+	cert := android.SrcIsModule(a.properties.Certificate.GetOrDefault(ctx, ""))
 	if cert != "" {
 		ctx.AddDependency(ctx.Module(), certificateTag, cert)
 	}
@@ -323,7 +323,7 @@
 	}
 
 	numCertPropsSet := 0
-	if String(a.properties.Certificate) != "" {
+	if a.properties.Certificate.GetOrDefault(ctx, "") != "" {
 		numCertPropsSet++
 	}
 	if Bool(a.properties.Presigned) {
@@ -406,7 +406,7 @@
 		// If the certificate property is empty at this point, default_dev_cert must be set to true.
 		// Which makes processMainCert's behavior for the empty cert string WAI.
 		_, _, certificates := collectAppDeps(ctx, a, false, false)
-		a.certificate, certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
+		a.certificate, certificates = processMainCert(a.ModuleBase, a.properties.Certificate.GetOrDefault(ctx, ""), certificates, ctx)
 		signed := android.PathForModuleOut(ctx, "signed", apkFilename)
 		var lineageFile android.Path
 		if lineage := String(a.properties.Lineage); lineage != "" {
diff --git a/java/rro.go b/java/rro.go
index 8bb9be2..f225e1f 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -50,7 +50,7 @@
 type RuntimeResourceOverlayProperties struct {
 	// the name of a certificate in the default certificate directory or an android_app_certificate
 	// module name in the form ":module".
-	Certificate *string
+	Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
 
 	// Name of the signing certificate lineage file.
 	Lineage *string
@@ -119,7 +119,7 @@
 		r.aapt.deps(ctx, sdkDep)
 	}
 
-	cert := android.SrcIsModule(String(r.properties.Certificate))
+	cert := android.SrcIsModule(r.properties.Certificate.GetOrDefault(ctx, ""))
 	if cert != "" {
 		ctx.AddDependency(ctx.Module(), certificateTag, cert)
 	}
@@ -166,7 +166,7 @@
 
 	// Sign the built package
 	_, _, certificates := collectAppDeps(ctx, r, false, false)
-	r.certificate, certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
+	r.certificate, certificates = processMainCert(r.ModuleBase, r.properties.Certificate.GetOrDefault(ctx, ""), certificates, ctx)
 	signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
 	var lineageFile android.Path
 	if lineage := String(r.properties.Lineage); lineage != "" {