Generate META/dynamic_partitions_info.txt of target_files.zip

dynamic_partitions_info.txt is generated by
`dump-dynamic-partitions-info` in make, and its contents are similar to
misc_info.txt of the device's super_image.

This CL creates this file in target_files.zip. The common contents are
refactored to a helper function in super_image, and this helper function
will be used to generate misc_info.txt of the super_image, and
META/dynamic_partitions_info.txt

Bug: 399788100
Test: Built META/dynamic_partitions_info.txt
Test: diff between make and soong (after sort)
< build_super_empty_partition=true

Change-Id: Ifd8ef89008d8ce3a2baaa73466236325b635c6e5
---
>
> ab_update=true
3c4
< dynamic_partition_list=    product system system_ext system_dlkm odm vendor vendor_dlkm odm_dlkm
---
> dynamic_partition_list=odm odm_dlkm product system system_dlkm system_ext vendor vendor_dlkm
7c8
< super_google_system_dynamic_partitions_partition_list=    product system system_ext system_dlkm
---
> super_google_system_dynamic_partitions_partition_list=product system system_ext system_dlkm
9c10
< super_google_vendor_dynamic_partitions_partition_list=    odm vendor vendor_dlkm odm_dlkm
---
> super_google_vendor_dynamic_partitions_partition_list=odm vendor vendor_dlkm odm_dlkm

There are some formatting diffs. `build_super_empty_image` seems to be
main missing info. I have added a TODO to add that.

Change-Id: I68d0a43b0c3e53ea88246784392cd7706dd2a9e9
diff --git a/filesystem/super_image.go b/filesystem/super_image.go
index 58c938a..74c7b65 100644
--- a/filesystem/super_image.go
+++ b/filesystem/super_image.go
@@ -114,6 +114,8 @@
 	// Mapping from the sub-partition type to its re-exported FileSystemInfo providers from the
 	// sub-partitions.
 	SubImageInfo map[string]FilesystemInfo
+
+	DynamicPartitionsInfo android.Path
 }
 
 var SuperImageProvider = blueprint.NewProvider[SuperImageInfo]()
@@ -173,8 +175,9 @@
 		Output(output)
 	builder.Build("build_super_image", fmt.Sprintf("Creating super image %s", s.BaseModuleName()))
 	android.SetProvider(ctx, SuperImageProvider, SuperImageInfo{
-		SuperImage:   output,
-		SubImageInfo: subImageInfos,
+		SuperImage:            output,
+		SubImageInfo:          subImageInfos,
+		DynamicPartitionsInfo: s.generateDynamicPartitionsInfo(ctx),
 	})
 	ctx.SetOutputFiles([]android.Path{output}, "")
 	ctx.CheckbuildFile(output)
@@ -186,6 +189,7 @@
 
 func (s *superImage) buildMiscInfo(ctx android.ModuleContext) (android.Path, android.Paths, map[string]FilesystemInfo) {
 	var miscInfoString strings.Builder
+	partitionList := s.dumpDynamicPartitionInfo(ctx, &miscInfoString)
 	addStr := func(name string, value string) {
 		miscInfoString.WriteString(name)
 		miscInfoString.WriteRune('=')
@@ -193,71 +197,6 @@
 		miscInfoString.WriteRune('\n')
 	}
 
-	addStr("build_super_partition", "true")
-	addStr("use_dynamic_partitions", strconv.FormatBool(proptools.Bool(s.properties.Use_dynamic_partitions)))
-	if proptools.Bool(s.properties.Retrofit) {
-		addStr("dynamic_partition_retrofit", "true")
-	}
-	addStr("lpmake", "lpmake")
-	addStr("super_metadata_device", proptools.String(s.properties.Metadata_device))
-	if len(s.properties.Block_devices) > 0 {
-		addStr("super_block_devices", strings.Join(s.properties.Block_devices, " "))
-	}
-	addStr("super_partition_size", strconv.Itoa(proptools.Int(s.properties.Size)))
-	// TODO: In make, there's more complicated logic than just this surrounding super_*_device_size
-	addStr("super_super_device_size", strconv.Itoa(proptools.Int(s.properties.Size)))
-	var groups, partitionList []string
-	for _, groupInfo := range s.properties.Partition_groups {
-		groups = append(groups, groupInfo.Name)
-		partitionList = append(partitionList, groupInfo.PartitionList...)
-		addStr("super_"+groupInfo.Name+"_group_size", groupInfo.GroupSize)
-		addStr("super_"+groupInfo.Name+"_partition_list", strings.Join(groupInfo.PartitionList, " "))
-	}
-	initialPartitionListLen := len(partitionList)
-	partitionList = android.SortedUniqueStrings(partitionList)
-	if len(partitionList) != initialPartitionListLen {
-		ctx.ModuleErrorf("Duplicate partitions found in the partition_groups property")
-	}
-	addStr("super_partition_groups", strings.Join(groups, " "))
-	addStr("dynamic_partition_list", strings.Join(partitionList, " "))
-
-	addStr("ab_update", strconv.FormatBool(proptools.Bool(s.properties.Ab_update)))
-
-	if proptools.Bool(s.properties.Virtual_ab.Enable) {
-		addStr("virtual_ab", "true")
-		if proptools.Bool(s.properties.Virtual_ab.Retrofit) {
-			addStr("virtual_ab_retrofit", "true")
-		}
-		addStr("virtual_ab_compression", strconv.FormatBool(proptools.Bool(s.properties.Virtual_ab.Compression)))
-		if s.properties.Virtual_ab.Compression_method != nil {
-			matched, _ := regexp.MatchString("^[a-zA-Z0-9_-]+$", *s.properties.Virtual_ab.Compression_method)
-			if !matched {
-				ctx.PropertyErrorf("virtual_ab.compression_method", "compression_method cannot have special characters")
-			}
-			addStr("virtual_ab_compression_method", *s.properties.Virtual_ab.Compression_method)
-		}
-		if s.properties.Virtual_ab.Compression_factor != nil {
-			addStr("virtual_ab_compression_factor", strconv.FormatInt(*s.properties.Virtual_ab.Compression_factor, 10))
-		}
-		if s.properties.Virtual_ab.Cow_version != nil {
-			addStr("virtual_ab_cow_version", strconv.FormatInt(*s.properties.Virtual_ab.Cow_version, 10))
-		}
-
-	} else {
-		if s.properties.Virtual_ab.Retrofit != nil {
-			ctx.PropertyErrorf("virtual_ab.retrofit", "This property cannot be set when virtual_ab is disabled")
-		}
-		if s.properties.Virtual_ab.Compression != nil {
-			ctx.PropertyErrorf("virtual_ab.compression", "This property cannot be set when virtual_ab is disabled")
-		}
-		if s.properties.Virtual_ab.Compression_method != nil {
-			ctx.PropertyErrorf("virtual_ab.compression_method", "This property cannot be set when virtual_ab is disabled")
-		}
-		if s.properties.Virtual_ab.Compression_factor != nil {
-			ctx.PropertyErrorf("virtual_ab.compression_factor", "This property cannot be set when virtual_ab is disabled")
-		}
-	}
-
 	subImageInfo := make(map[string]FilesystemInfo)
 	var deps android.Paths
 
@@ -346,3 +285,87 @@
 	android.WriteFileRule(ctx, miscInfo, miscInfoString.String(), missingPartitionErrorMessageFile)
 	return miscInfo, deps, subImageInfo
 }
+
+func (s *superImage) dumpDynamicPartitionInfo(ctx android.ModuleContext, sb *strings.Builder) []string {
+	addStr := func(name string, value string) {
+		sb.WriteString(name)
+		sb.WriteRune('=')
+		sb.WriteString(value)
+		sb.WriteRune('\n')
+	}
+
+	addStr("build_super_partition", "true")
+	addStr("use_dynamic_partitions", strconv.FormatBool(proptools.Bool(s.properties.Use_dynamic_partitions)))
+	if proptools.Bool(s.properties.Retrofit) {
+		addStr("dynamic_partition_retrofit", "true")
+	}
+	addStr("lpmake", "lpmake")
+	addStr("super_metadata_device", proptools.String(s.properties.Metadata_device))
+	if len(s.properties.Block_devices) > 0 {
+		addStr("super_block_devices", strings.Join(s.properties.Block_devices, " "))
+	}
+	addStr("super_partition_size", strconv.Itoa(proptools.Int(s.properties.Size)))
+	// TODO: In make, there's more complicated logic than just this surrounding super_*_device_size
+	addStr("super_super_device_size", strconv.Itoa(proptools.Int(s.properties.Size)))
+	var groups, partitionList []string
+	for _, groupInfo := range s.properties.Partition_groups {
+		groups = append(groups, groupInfo.Name)
+		partitionList = append(partitionList, groupInfo.PartitionList...)
+		addStr("super_"+groupInfo.Name+"_group_size", groupInfo.GroupSize)
+		addStr("super_"+groupInfo.Name+"_partition_list", strings.Join(groupInfo.PartitionList, " "))
+	}
+	initialPartitionListLen := len(partitionList)
+	partitionList = android.SortedUniqueStrings(partitionList)
+	if len(partitionList) != initialPartitionListLen {
+		ctx.ModuleErrorf("Duplicate partitions found in the partition_groups property")
+	}
+	addStr("super_partition_groups", strings.Join(groups, " "))
+	addStr("dynamic_partition_list", strings.Join(partitionList, " "))
+
+	addStr("ab_update", strconv.FormatBool(proptools.Bool(s.properties.Ab_update)))
+
+	if proptools.Bool(s.properties.Virtual_ab.Enable) {
+		addStr("virtual_ab", "true")
+		if proptools.Bool(s.properties.Virtual_ab.Retrofit) {
+			addStr("virtual_ab_retrofit", "true")
+		}
+		addStr("virtual_ab_compression", strconv.FormatBool(proptools.Bool(s.properties.Virtual_ab.Compression)))
+		if s.properties.Virtual_ab.Compression_method != nil {
+			matched, _ := regexp.MatchString("^[a-zA-Z0-9_-]+$", *s.properties.Virtual_ab.Compression_method)
+			if !matched {
+				ctx.PropertyErrorf("virtual_ab.compression_method", "compression_method cannot have special characters")
+			}
+			addStr("virtual_ab_compression_method", *s.properties.Virtual_ab.Compression_method)
+		}
+		if s.properties.Virtual_ab.Compression_factor != nil {
+			addStr("virtual_ab_compression_factor", strconv.FormatInt(*s.properties.Virtual_ab.Compression_factor, 10))
+		}
+		if s.properties.Virtual_ab.Cow_version != nil {
+			addStr("virtual_ab_cow_version", strconv.FormatInt(*s.properties.Virtual_ab.Cow_version, 10))
+		}
+
+	} else {
+		if s.properties.Virtual_ab.Retrofit != nil {
+			ctx.PropertyErrorf("virtual_ab.retrofit", "This property cannot be set when virtual_ab is disabled")
+		}
+		if s.properties.Virtual_ab.Compression != nil {
+			ctx.PropertyErrorf("virtual_ab.compression", "This property cannot be set when virtual_ab is disabled")
+		}
+		if s.properties.Virtual_ab.Compression_method != nil {
+			ctx.PropertyErrorf("virtual_ab.compression_method", "This property cannot be set when virtual_ab is disabled")
+		}
+		if s.properties.Virtual_ab.Compression_factor != nil {
+			ctx.PropertyErrorf("virtual_ab.compression_factor", "This property cannot be set when virtual_ab is disabled")
+		}
+	}
+
+	return partitionList
+}
+
+func (s *superImage) generateDynamicPartitionsInfo(ctx android.ModuleContext) android.Path {
+	var contents strings.Builder
+	s.dumpDynamicPartitionInfo(ctx, &contents)
+	dynamicPartitionsInfo := android.PathForModuleOut(ctx, "dynamic_partitions_info.txt")
+	android.WriteFileRule(ctx, dynamicPartitionsInfo, contents.String())
+	return dynamicPartitionsInfo
+}