Add SoongExecutionMetrics to ninja run

This adds metrics for partial compilation to Soong.

- Soong_ui names the directory SOONG_METRICS_AGGREGATION_DIR, which it
  empties before each ninja run.
- Find_input_delta writes metrics there
- At the end of the build, Soong_ui aggregates the metrics that were
  written to generate the aggregated metrics.

Bug: b/376287012
Test: Manual, TH
Change-Id: I123df654f5b963fcd213b5c4d815173051f5d72e
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index c7134d7..9721794 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -27,6 +27,7 @@
 
 	"android/soong/shared"
 	"android/soong/ui/build"
+	"android/soong/ui/execution_metrics"
 	"android/soong/ui/logger"
 	"android/soong/ui/metrics"
 	"android/soong/ui/signal"
@@ -170,14 +171,16 @@
 		stat.Finish()
 	})
 	criticalPath := status.NewCriticalPath()
+	emet := execution_metrics.NewExecutionMetrics(log)
 	buildCtx := build.Context{ContextImpl: &build.ContextImpl{
-		Context:      ctx,
-		Logger:       log,
-		Metrics:      met,
-		Tracer:       trace,
-		Writer:       output,
-		Status:       stat,
-		CriticalPath: criticalPath,
+		Context:          ctx,
+		Logger:           log,
+		Metrics:          met,
+		ExecutionMetrics: emet,
+		Tracer:           trace,
+		Writer:           output,
+		Status:           stat,
+		CriticalPath:     criticalPath,
 	}}
 
 	freshConfig := func() build.Config {
@@ -194,6 +197,7 @@
 	rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
 	soongBuildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_build_metrics.pb")
 	buildTraceFile := filepath.Join(logsDir, c.logsPrefix+"build.trace.gz")
+	executionMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_execution_metrics.pb")
 
 	metricsFiles := []string{
 		buildErrorFile,        // build error strings
@@ -204,9 +208,16 @@
 	}
 
 	defer func() {
+		emet.Finish(buildCtx)
 		stat.Finish()
 		criticalPath.WriteToMetrics(met)
 		met.Dump(soongMetricsFile)
+		emet.Dump(executionMetricsFile, args)
+		// If there are execution metrics, upload them.
+		if _, err := os.Stat(executionMetricsFile); err == nil {
+			// TODO: Upload the metrics file.
+			// metricsFiles = append(metricsFiles, executionMetricsFile)
+		}
 		if !config.SkipMetricsUpload() {
 			build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, metricsFiles...)
 		}