Merge "Don't call `getArguments` unnecessarily" into main
diff --git a/android/config.go b/android/config.go
index e026782..52d7f3b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1299,6 +1299,10 @@
 	return otaPaths
 }
 
+func (c *config) ExtraOtaRecoveryKeys() []string {
+	return c.productVariables.ExtraOtaRecoveryKeys
+}
+
 func (c *config) BuildKeys() string {
 	defaultCert := String(c.productVariables.DefaultAppCertificate)
 	if defaultCert == "" || defaultCert == filepath.Join(testKeyDir, "testkey") {
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 9cb90da..28ecd53 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -753,18 +753,58 @@
 // This file is subsequently used by add_img_to_target_files to create additioanl metadata files like apex_info.pb
 // TODO (b/399788119): Complete the migration of misc_info.txt
 func (a *androidDevice) addMiscInfo(ctx android.ModuleContext) android.Path {
+	buildType := func() string {
+		if ctx.Config().Debuggable() {
+			return "userdebug"
+		} else if ctx.Config().Eng() {
+			return "eng"
+		} else {
+			return "user"
+		}
+	}
+	defaultAppCertificate := func() string {
+		pem, _ := ctx.Config().DefaultAppCertificate(ctx)
+		return strings.TrimSuffix(pem.String(), ".x509.pem")
+	}
+
 	builder := android.NewRuleBuilder(pctx, ctx)
 	miscInfo := android.PathForModuleOut(ctx, "misc_info.txt")
 	builder.Command().
 		Textf("rm -f %s", miscInfo).
 		Textf("&& echo recovery_api_version=%s >> %s", ctx.Config().VendorConfig("recovery").String("recovery_api_version"), miscInfo).
 		Textf("&& echo fstab_version=%s >> %s", ctx.Config().VendorConfig("recovery").String("recovery_fstab_version"), miscInfo).
+		Textf("&& echo build_type=%s >> %s", buildType(), miscInfo).
+		Textf("&& echo default_system_dev_certificate=%s >> %s", defaultAppCertificate(), miscInfo).
 		ImplicitOutput(miscInfo)
+	if len(ctx.Config().ExtraOtaRecoveryKeys()) > 0 {
+		builder.Command().Textf(`echo "extra_recovery_keys=%s" >> %s`, strings.Join(ctx.Config().ExtraOtaRecoveryKeys(), ""), miscInfo)
+	} else {
+		if a.partitionProps.Boot_partition_name != nil {
+			builder.Command().
+				Textf("echo mkbootimg_args='--header_version %s' >> %s", a.getBootimgHeaderVersion(ctx, a.partitionProps.Boot_partition_name), miscInfo).
+				// TODO: Use boot's header version for recovery for now since cuttlefish does not set `BOARD_RECOVERY_MKBOOTIMG_ARGS`
+				Textf(" && echo recovery_mkbootimg_args='--header_version %s' >> %s", a.getBootimgHeaderVersion(ctx, a.partitionProps.Boot_partition_name), miscInfo)
+		}
+		if a.partitionProps.Init_boot_partition_name != nil {
+			builder.Command().
+				Textf("echo mkbootimg_init_args='--header_version' %s >> %s", a.getBootimgHeaderVersion(ctx, a.partitionProps.Init_boot_partition_name), miscInfo)
+		}
+		builder.Command().
+			Textf("echo mkbootimg_version_args='--os_version %s --os_patch_level %s' >> %s", ctx.Config().PlatformVersionLastStable(), ctx.Config().PlatformSecurityPatch(), miscInfo).
+			Textf(" && echo multistage_support=1 >> %s", miscInfo).
+			Textf(" && echo blockimgdiff_versions=3,4 >> %s", miscInfo)
+	}
+	fsInfos := a.getFsInfos(ctx)
+	if _, ok := fsInfos["vendor"]; ok {
+		builder.Command().Textf("echo board_uses_vendorimage=true >> %s", miscInfo)
+	}
+	if fsInfos["system"].ErofsCompressHints != nil {
+		builder.Command().Textf("echo erofs_default_compress_hints=%s >> %s", fsInfos["system"].ErofsCompressHints, miscInfo)
+	}
 
 	if a.partitionProps.Recovery_partition_name == nil {
 		builder.Command().Textf("echo no_recovery=true >> %s", miscInfo)
 	}
-	fsInfos := a.getFsInfos(ctx)
 	for _, partition := range android.SortedKeys(fsInfos) {
 		if fsInfos[partition].PropFileForMiscInfo != nil {
 			builder.Command().Text("cat").Input(fsInfos[partition].PropFileForMiscInfo).Textf(" >> %s", miscInfo)
@@ -813,6 +853,12 @@
 	return miscInfo
 }
 
+func (a *androidDevice) getBootimgHeaderVersion(ctx android.ModuleContext, bootImgName *string) string {
+	bootImg := ctx.GetDirectDepProxyWithTag(proptools.String(bootImgName), filesystemDepTag)
+	bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider)
+	return bootImgInfo.HeaderVersion
+}
+
 // addImgToTargetFiles invokes `add_img_to_target_files` and creates the following files in META/
 // - apex_info.pb
 // - care_map.pb
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index a1c4bce..5ab0c68 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -244,6 +244,7 @@
 		Bootconfig:          b.getBootconfigPath(ctx),
 		Output:              output,
 		PropFileForMiscInfo: b.buildPropFileForMiscInfo(ctx),
+		HeaderVersion:       proptools.String(b.properties.Header_version),
 	})
 
 	extractedPublicKey := android.PathForModuleOut(ctx, b.partitionName()+".avbpubkey")
@@ -292,6 +293,7 @@
 	Bootconfig          android.Path
 	Output              android.Path
 	PropFileForMiscInfo android.Path
+	HeaderVersion       string
 }
 
 func (b *bootimg) getKernelPath(ctx android.ModuleContext) android.Path {