Create avb_recovery_add_hash_footer_args entry in misc_info.txt

This CL creates an additional avb_recovery_add_hash_footer_args entry
for bootimages with a ramdisk that contains a recovery partition.

strings.ReplaceAll will be used to convert
```
--prop com.android.build.vendor_boot.fingerprint:generic/aosp_cf_x86_64_phone/vsoc_x86_64:Baklava/MAIN/eng.spanda:userdebug/test-keys
```
to
```
--prop com.android.build.recovery.fingerprint:generic/aosp_cf_x86_64_phone/vsoc_x86_64:Baklava/MAIN/eng.spanda:userdebug/test-keys
```

Test: Built and diff'd locally
Bug: 398036609
Change-Id: I0caa8aa9e2e86b9c78352d3038951e00f689dc1a
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 5ab0c68..485eae4 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -539,6 +539,14 @@
 
 	bootImgType := proptools.String(b.properties.Boot_image_type)
 	addStr("avb_"+bootImgType+"_add_hash_footer_args", b.getAvbHashFooterArgs(ctx))
+	if ramdisk := proptools.String(b.properties.Ramdisk_module); ramdisk != "" {
+		ramdiskModule := ctx.GetDirectDepWithTag(ramdisk, bootimgRamdiskDep)
+		fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider)
+		if fsInfo.HasOrIsRecovery {
+			// Create a dup entry for recovery
+			addStr("avb_recovery_add_hash_footer_args", strings.ReplaceAll(b.getAvbHashFooterArgs(ctx), bootImgType, "recovery"))
+		}
+	}
 	if b.properties.Avb_private_key != nil {
 		addStr("avb_"+bootImgType+"_algorithm", proptools.StringDefault(b.properties.Avb_algorithm, "SHA256_RSA4096"))
 		addStr("avb_"+bootImgType+"_key_path", android.PathForModuleSrc(ctx, proptools.String(b.properties.Avb_private_key)).String())
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 411770b..ad4366b 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -463,6 +463,9 @@
 	AvbAlgorithm     string
 	AvbHashAlgorithm string
 	AvbKey           android.Path
+	PartitionName    string
+	// HasOrIsRecovery returns true for recovery and for ramdisks with a recovery partition.
+	HasOrIsRecovery bool
 }
 
 // FullInstallPathInfo contains information about the "full install" paths of all the files
@@ -720,6 +723,8 @@
 		HasFsverity:         f.properties.Fsverity.Inputs.GetOrDefault(ctx, nil) != nil,
 		PropFileForMiscInfo: propFileForMiscInfo,
 		PartitionSize:       f.properties.Partition_size,
+		PartitionName:       f.partitionName(),
+		HasOrIsRecovery:     f.hasOrIsRecovery(ctx),
 	}
 	if proptools.Bool(f.properties.Use_avb) {
 		fsInfo.UseAvb = true
@@ -1307,6 +1312,19 @@
 	return
 }
 
+func (f *filesystem) hasOrIsRecovery(ctx android.ModuleContext) bool {
+	if f.partitionName() == "recovery" {
+		return true
+	}
+	ret := false
+	ctx.VisitDirectDepsWithTag(interPartitionInstallDependencyTag, func(m android.Module) {
+		if fsProvider, ok := android.OtherModuleProvider(ctx, m, FilesystemProvider); ok && fsProvider.PartitionName == "recovery" {
+			ret = true
+		}
+	})
+	return ret
+}
+
 func (f *filesystem) buildCpioImage(
 	ctx android.ModuleContext,
 	builder *android.RuleBuilder,