Add a basic target_files.zip

Only contains the vendor image files for now, will expand in followup
cls.

Bug: 385383524
Test: m out/soong/.intermediates/build/soong/fsgen/aosp_cf_x86_64_phone_generated_device/android_common/target_files.zip
Change-Id: I517e7022b5c6294a2f8e5246f52897b406b63cd7
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index ab1b96e..ea46556 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -79,5 +79,39 @@
 }
 
 func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	a.buildTargetFilesZip(ctx)
+}
 
+func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) {
+	targetFilesDir := android.PathForModuleOut(ctx, "target_files_dir")
+	targetFilesZip := android.PathForModuleOut(ctx, "target_files.zip")
+
+	builder := android.NewRuleBuilder(pctx, ctx)
+	builder.Command().Textf("rm -rf %s", targetFilesDir.String())
+	builder.Command().Textf("mkdir -p %s", targetFilesDir.String())
+	if a.partitionProps.Vendor_partition_name != nil {
+		fsInfo := a.getFilesystemInfo(ctx, *a.partitionProps.Vendor_partition_name)
+		builder.Command().Textf("mkdir -p %s/VENDOR", targetFilesDir.String())
+		builder.Command().
+			BuiltTool("acp").
+			Textf("-rd %s/. %s/VENDOR", fsInfo.RootDir, targetFilesDir).
+			Implicit(fsInfo.Output) // so that the staging dir is built
+	}
+	builder.Command().
+		BuiltTool("soong_zip").
+		Text("-d").
+		FlagWithOutput("-o ", targetFilesZip).
+		FlagWithArg("-C ", targetFilesDir.String()).
+		FlagWithArg("-D ", targetFilesDir.String()).
+		Text("-sha256")
+	builder.Build("target_files_"+ctx.ModuleName(), "Build target_files.zip")
+}
+
+func (a *androidDevice) getFilesystemInfo(ctx android.ModuleContext, depName string) FilesystemInfo {
+	fsMod := ctx.GetDirectDepWithTag(depName, filesystemDepTag)
+	fsInfo, ok := android.OtherModuleProvider(ctx, fsMod, FilesystemProvider)
+	if !ok {
+		ctx.ModuleErrorf("Expected dependency %s to be a filesystem", depName)
+	}
+	return fsInfo
 }
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 2244aff..57b361b 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -335,8 +335,14 @@
 }
 
 type FilesystemInfo struct {
+	// The built filesystem image
+	Output android.Path
 	// A text file containing the list of paths installed on the partition.
 	FileListFile android.Path
+	// The root staging directory used to build the output filesystem. If consuming this, make sure
+	// to add a dependency on the Output file, as you cannot add dependencies on directories
+	// in ninja.
+	RootDir android.Path
 }
 
 var FilesystemProvider = blueprint.NewProvider[FilesystemInfo]()
@@ -410,13 +416,14 @@
 	if f.filesystemBuilder.ShouldUseVintfFragmentModuleOnly() {
 		f.validateVintfFragments(ctx)
 	}
+	var rootDir android.Path
 	switch f.fsType(ctx) {
 	case ext4Type, erofsType, f2fsType:
-		f.output = f.buildImageUsingBuildImage(ctx)
+		f.output, rootDir = f.buildImageUsingBuildImage(ctx)
 	case compressedCpioType:
-		f.output = f.buildCpioImage(ctx, true)
+		f.output, rootDir = f.buildCpioImage(ctx, true)
 	case cpioType:
-		f.output = f.buildCpioImage(ctx, false)
+		f.output, rootDir = f.buildCpioImage(ctx, false)
 	default:
 		return
 	}
@@ -429,7 +436,9 @@
 	android.WriteFileRule(ctx, fileListFile, f.installedFilesList())
 
 	android.SetProvider(ctx, FilesystemProvider, FilesystemInfo{
+		Output:       f.output,
 		FileListFile: fileListFile,
+		RootDir:      rootDir,
 	})
 	f.fileListFile = fileListFile
 
@@ -576,7 +585,7 @@
 	return f.partitionName()
 }
 
-func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) android.Path {
+func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) (android.Path, android.Path) {
 	rootDir := android.PathForModuleOut(ctx, f.rootDirString()).OutputPath
 	rebasedDir := rootDir
 	if f.properties.Base_dir != nil {
@@ -627,7 +636,7 @@
 	// rootDir is not deleted. Might be useful for quick inspection.
 	builder.Build("build_filesystem_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
 
-	return output
+	return output, rootDir
 }
 
 func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.Path {
@@ -789,7 +798,7 @@
 	}
 }
 
-func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool) android.Path {
+func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool) (android.Path, android.Path) {
 	if proptools.Bool(f.properties.Use_avb) {
 		ctx.PropertyErrorf("use_avb", "signing compresed cpio image using avbtool is not supported."+
 			"Consider adding this to bootimg module and signing the entire boot image.")
@@ -842,7 +851,7 @@
 	// rootDir is not deleted. Might be useful for quick inspection.
 	builder.Build("build_cpio_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
 
-	return output
+	return output, rootDir
 }
 
 var validPartitions = []string{