Package releasetools.py in target_files.zip

This CL creates an intermediate filegroup, and adds that to
`Releasetools_extension` dep of the autogenerated android_device. This
dep will be used for packaging target_files.zip

Bug: 3493530
Test: Built and diff'd target_files.zip
Change-Id: I9a5a2c3dba5fd37924544e92cb2646837047600a
diff --git a/android/variable.go b/android/variable.go
index 4e1df3c..81999f3 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -713,6 +713,8 @@
 	ProductFsCasefold    string `json:",omitempty"`
 	ProductQuotaProjid   string `json:",omitempty"`
 	ProductFsCompression string `json:",omitempty"`
+
+	ReleaseToolsExtensionDir string `json:",omitempty"`
 }
 
 func boolPtr(v bool) *bool {
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 224c2ef..8d7f92f 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -75,7 +75,8 @@
 	Ab_ota_keys               []string
 	Ab_ota_postinstall_config []string
 
-	Ramdisk_node_list *string `android:"path"`
+	Ramdisk_node_list      *string `android:"path"`
+	Releasetools_extension *string `android:"path"`
 }
 
 type androidDevice struct {
@@ -477,7 +478,13 @@
 		builder.Command().Textf("cp").Input(fsInfos[partition].FilesystemConfig).Textf(" %s/META/%s", targetFilesDir.String(), a.filesystemConfigNameForTargetFiles(partition))
 	}
 	// Copy ramdisk_node_list
-	builder.Command().Textf("cp").Input(android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Ramdisk_node_list))).Textf(" %s/META/", targetFilesDir.String())
+	if ramdiskNodeList := android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Ramdisk_node_list)); ramdiskNodeList != nil {
+		builder.Command().Textf("cp").Input(ramdiskNodeList).Textf(" %s/META/", targetFilesDir.String())
+	}
+	// Copy releasetools.py
+	if releaseTools := android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Releasetools_extension)); releaseTools != nil {
+		builder.Command().Textf("cp").Input(releaseTools).Textf(" %s/META/", targetFilesDir.String())
+	}
 }
 
 // Filenames for the partition specific fs_config files.
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index 6a9fc92..c2721d2 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -320,6 +320,26 @@
 	return bootloaderFilegroupName, true
 }
 
+func (f *filesystemCreator) createReleaseToolsFilegroup(ctx android.LoadHookContext) (string, bool) {
+	releaseToolsDir := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.ReleaseToolsExtensionDir
+	if releaseToolsDir == "" {
+		return "", false
+	}
+
+	releaseToolsFilegroupName := generatedModuleName(ctx.Config(), "releasetools")
+	filegroupProps := &struct {
+		Name       *string
+		Srcs       []string
+		Visibility []string
+	}{
+		Name:       proptools.StringPtr(releaseToolsFilegroupName),
+		Srcs:       []string{"releasetools.py"},
+		Visibility: []string{"//visibility:public"},
+	}
+	ctx.CreateModuleInDirectory(android.FileGroupFactory, releaseToolsDir, filegroupProps)
+	return releaseToolsFilegroupName, true
+}
+
 func (f *filesystemCreator) createDeviceModule(
 	ctx android.LoadHookContext,
 	partitions allGeneratedPartitionData,
@@ -387,9 +407,13 @@
 		Ab_ota_postinstall_config: ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaPostInstallConfig,
 		Ramdisk_node_list:         proptools.StringPtr(":ramdisk_node_list"),
 	}
+
 	if bootloader, ok := f.createBootloaderFilegroup(ctx); ok {
 		deviceProps.Bootloader = proptools.StringPtr(":" + bootloader)
 	}
+	if releaseTools, ok := f.createReleaseToolsFilegroup(ctx); ok {
+		deviceProps.Releasetools_extension = proptools.StringPtr(":" + releaseTools)
+	}
 
 	ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps, deviceProps)
 }