Copy android-info.txt to PRODUCT_OUT

By creating a timestamp file to copy the generated android-info.txt
file.

Test: m out/soong/.intermediates/aosp_cf_x86_64_phone_generated_android_info.prop/android_common/android-info.txt --soong-only
Bug: 376727180
Change-Id: I5a5eb5cfd27490ddccfb5470e9998e6a035e04c1
diff --git a/android/android_info.go b/android/android_info.go
index a8d3d4e..f2cbc65 100644
--- a/android/android_info.go
+++ b/android/android_info.go
@@ -58,17 +58,19 @@
 	androidInfoTxtName := proptools.StringDefault(p.properties.Stem, ctx.ModuleName()+".txt")
 	androidInfoTxt := PathForModuleOut(ctx, androidInfoTxtName)
 	androidInfoProp := androidInfoTxt.ReplaceExtension(ctx, "prop")
+	timestamp := PathForModuleOut(ctx, "timestamp")
 
 	if boardInfoFiles := PathsForModuleSrc(ctx, p.properties.Board_info_files); len(boardInfoFiles) > 0 {
 		ctx.Build(pctx, BuildParams{
-			Rule:   mergeAndRemoveComments,
-			Inputs: boardInfoFiles,
-			Output: androidInfoTxt,
+			Rule:       mergeAndRemoveComments,
+			Inputs:     boardInfoFiles,
+			Output:     androidInfoTxt,
+			Validation: timestamp,
 		})
 	} else if bootloaderBoardName := proptools.String(p.properties.Bootloader_board_name); bootloaderBoardName != "" {
-		WriteFileRule(ctx, androidInfoTxt, "board="+bootloaderBoardName)
+		WriteFileRule(ctx, androidInfoTxt, "board="+bootloaderBoardName, timestamp)
 	} else {
-		WriteFileRule(ctx, androidInfoTxt, "")
+		WriteFileRule(ctx, androidInfoTxt, "", timestamp)
 	}
 
 	// Create android_info.prop
@@ -79,6 +81,18 @@
 	})
 
 	ctx.SetOutputFiles(Paths{androidInfoProp}, "")
+
+	builder := NewRuleBuilder(pctx, ctx)
+	builder.Command().Text("touch").Output(timestamp)
+	if !ctx.Config().KatiEnabled() {
+		cpPath := PathForModuleInPartitionInstall(ctx, "").Join(ctx, androidInfoTxtName)
+		builder.Command().
+			Text("rsync").
+			Flag("-a").
+			Input(androidInfoTxt).
+			Text(cpPath.String())
+	}
+	builder.Build("copy_android_info", "Copy android-info.txt")
 }
 
 // android_info module generate a file named android-info.txt that contains various information
@@ -86,6 +100,6 @@
 func AndroidInfoFactory() Module {
 	module := &androidInfoModule{}
 	module.AddProperties(&module.properties)
-	InitAndroidModule(module)
+	InitAndroidArchModule(module, DeviceSupported, MultilibCommon)
 	return module
 }
diff --git a/android/raw_files.go b/android/raw_files.go
index 9d7f5e8..fd37196 100644
--- a/android/raw_files.go
+++ b/android/raw_files.go
@@ -18,7 +18,6 @@
 	"crypto/sha1"
 	"encoding/hex"
 	"fmt"
-	"github.com/google/blueprint"
 	"io"
 	"io/fs"
 	"os"
@@ -26,25 +25,27 @@
 	"strings"
 	"testing"
 
+	"github.com/google/blueprint"
+
 	"github.com/google/blueprint/proptools"
 )
 
 // WriteFileRule creates a ninja rule to write contents to a file by immediately writing the
 // contents, plus a trailing newline, to a file in out/soong/raw-${TARGET_PRODUCT}, and then creating
 // a ninja rule to copy the file into place.
-func WriteFileRule(ctx BuilderContext, outputFile WritablePath, content string) {
-	writeFileRule(ctx, outputFile, content, true, false)
+func WriteFileRule(ctx BuilderContext, outputFile WritablePath, content string, validations ...Path) {
+	writeFileRule(ctx, outputFile, content, true, false, validations)
 }
 
 // WriteFileRuleVerbatim creates a ninja rule to write contents to a file by immediately writing the
 // contents to a file in out/soong/raw-${TARGET_PRODUCT}, and then creating a ninja rule to copy the file into place.
-func WriteFileRuleVerbatim(ctx BuilderContext, outputFile WritablePath, content string) {
-	writeFileRule(ctx, outputFile, content, false, false)
+func WriteFileRuleVerbatim(ctx BuilderContext, outputFile WritablePath, content string, validations ...Path) {
+	writeFileRule(ctx, outputFile, content, false, false, validations)
 }
 
 // WriteExecutableFileRuleVerbatim is the same as WriteFileRuleVerbatim, but runs chmod +x on the result
-func WriteExecutableFileRuleVerbatim(ctx BuilderContext, outputFile WritablePath, content string) {
-	writeFileRule(ctx, outputFile, content, false, true)
+func WriteExecutableFileRuleVerbatim(ctx BuilderContext, outputFile WritablePath, content string, validations ...Path) {
+	writeFileRule(ctx, outputFile, content, false, true, validations)
 }
 
 // tempFile provides a testable wrapper around a file in out/soong/.temp.  It writes to a temporary file when
@@ -124,7 +125,7 @@
 	return tempFile, hex.EncodeToString(hash.Sum(nil))
 }
 
-func writeFileRule(ctx BuilderContext, outputFile WritablePath, content string, newline bool, executable bool) {
+func writeFileRule(ctx BuilderContext, outputFile WritablePath, content string, newline bool, executable bool, validations Paths) {
 	// Write the contents to a temporary file while computing its hash.
 	tempFile, hash := writeContentToTempFileAndHash(ctx, content, newline)
 
@@ -186,6 +187,7 @@
 		Input:       rawPath,
 		Output:      outputFile,
 		Description: "raw " + outputFile.Base(),
+		Validations: validations,
 	})
 }