Fixes for avb flags in soong-generated partitions

The logic for what variables control what aspect of AVB is pretty
complicated, this brings make and soong closer together.

Bug: 381120092
Test: m out/soong/.intermediates/build/soong/fsgen/aosp_cf_x86_64_phone_generated_system_image/android_common/prop, diff with make's prop file
Change-Id: I6ada90262f4578d120c35b7f8d38c06c2b1d9c27
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index cd29dfd..6aec90a 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -18,6 +18,7 @@
 	"crypto/sha256"
 	"fmt"
 	"path/filepath"
+	"slices"
 	"strconv"
 	"strings"
 
@@ -750,6 +751,7 @@
 	fsProps.Avb_algorithm = avbInfo.avbAlgorithm
 	// BOARD_AVB_SYSTEM_ROLLBACK_INDEX
 	fsProps.Rollback_index = avbInfo.avbRollbackIndex
+	fsProps.Avb_hash_algorithm = avbInfo.avbHashAlgorithm
 
 	fsProps.Partition_name = proptools.StringPtr(partitionType)
 
@@ -783,6 +785,7 @@
 	avbAlgorithm     *string
 	avbRollbackIndex *int64
 	avbMode          *string
+	avbHashAlgorithm *string
 }
 
 func getAvbInfo(config android.Config, partitionType string) avbInfo {
@@ -792,10 +795,23 @@
 	boardAvbEnable := partitionVars.BoardAvbEnable
 	if boardAvbEnable {
 		result.avbEnable = proptools.BoolPtr(true)
+		// There are "global" and "specific" copies of a lot of these variables. Sometimes they
+		// choose the specific and then fall back to the global one if it's not set, other times
+		// the global one actually only applies to the vbmeta partition.
+		if partitionType == "vbmeta" {
+			if partitionVars.BoardAvbKeyPath != "" {
+				result.avbKeyPath = proptools.StringPtr(partitionVars.BoardAvbKeyPath)
+			}
+			if partitionVars.BoardAvbRollbackIndex != "" {
+				parsed, err := strconv.ParseInt(partitionVars.BoardAvbRollbackIndex, 10, 64)
+				if err != nil {
+					panic(fmt.Sprintf("Rollback index must be an int, got %s", partitionVars.BoardAvbRollbackIndex))
+				}
+				result.avbRollbackIndex = &parsed
+			}
+		}
 		if specificPartitionVars.BoardAvbKeyPath != "" {
 			result.avbKeyPath = proptools.StringPtr(specificPartitionVars.BoardAvbKeyPath)
-		} else if partitionVars.BoardAvbKeyPath != "" {
-			result.avbKeyPath = proptools.StringPtr(partitionVars.BoardAvbKeyPath)
 		}
 		if specificPartitionVars.BoardAvbAlgorithm != "" {
 			result.avbAlgorithm = proptools.StringPtr(specificPartitionVars.BoardAvbAlgorithm)
@@ -808,13 +824,24 @@
 				panic(fmt.Sprintf("Rollback index must be an int, got %s", specificPartitionVars.BoardAvbRollbackIndex))
 			}
 			result.avbRollbackIndex = &parsed
-		} else if partitionVars.BoardAvbRollbackIndex != "" {
-			parsed, err := strconv.ParseInt(partitionVars.BoardAvbRollbackIndex, 10, 64)
+		}
+		if specificPartitionVars.BoardAvbRollbackIndex != "" {
+			parsed, err := strconv.ParseInt(specificPartitionVars.BoardAvbRollbackIndex, 10, 64)
 			if err != nil {
-				panic(fmt.Sprintf("Rollback index must be an int, got %s", partitionVars.BoardAvbRollbackIndex))
+				panic(fmt.Sprintf("Rollback index must be an int, got %s", specificPartitionVars.BoardAvbRollbackIndex))
 			}
 			result.avbRollbackIndex = &parsed
 		}
+
+		// Make allows you to pass arbitrary arguments to avbtool via this variable, but in practice
+		// it's only used for --hash_algorithm. The soong module has a dedicated property for the
+		// hashtree algorithm, and doesn't allow custom arguments, so just extract the hashtree
+		// algorithm out of the arbitrary arguments.
+		addHashtreeFooterArgs := strings.Split(specificPartitionVars.BoardAvbAddHashtreeFooterArgs, " ")
+		if i := slices.Index(addHashtreeFooterArgs, "--hash_algorithm"); i >= 0 {
+			result.avbHashAlgorithm = &addHashtreeFooterArgs[i+1]
+		}
+
 		result.avbMode = proptools.StringPtr("make_legacy")
 	}
 	if result.avbKeyPath != nil {