Generate build timing metrics to proto format file

Test: Dumped the text formated based metrics file to out dir,
and checked the file.
Bug: b/63815990

Change-Id: Iff476f72a0be74eb53b6b26ef468d11c0f24a404
diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index a48a314..0eba5ce 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -30,6 +30,7 @@
     deps: [
         "soong-ui-build-paths",
         "soong-ui-logger",
+        "soong-ui-metrics",
         "soong-ui-status",
         "soong-ui-terminal",
         "soong-ui-tracer",
diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go
index 4dee638..c47f614 100644
--- a/ui/build/cleanbuild.go
+++ b/ui/build/cleanbuild.go
@@ -20,6 +20,8 @@
 	"os"
 	"path/filepath"
 	"strings"
+
+	"android/soong/ui/metrics"
 )
 
 func removeGlobs(ctx Context, globs ...string) {
@@ -158,7 +160,7 @@
 		return
 	}
 
-	ctx.BeginTrace("installclean")
+	ctx.BeginTrace(metrics.PrimaryNinja, "installclean")
 	defer ctx.EndTrace()
 
 	prevConfig := strings.TrimPrefix(strings.TrimSuffix(string(prev), suffix), prefix)
diff --git a/ui/build/config.go b/ui/build/config.go
index 5a6d5db..97b009a 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -217,6 +217,9 @@
 	} else {
 		content = strconv.FormatInt(time.Now().Unix(), 10)
 	}
+	if ctx.Metrics != nil {
+		ctx.Metrics.SetBuildDateTime(content)
+	}
 	err := ioutil.WriteFile(buildDateTimeFile, []byte(content), 0777)
 	if err != nil {
 		ctx.Fatalln("Failed to write BUILD_DATETIME to file:", err)
diff --git a/ui/build/context.go b/ui/build/context.go
index c8b00c3..249e898 100644
--- a/ui/build/context.go
+++ b/ui/build/context.go
@@ -18,6 +18,8 @@
 	"context"
 
 	"android/soong/ui/logger"
+	"android/soong/ui/metrics"
+	"android/soong/ui/metrics/metrics_proto"
 	"android/soong/ui/status"
 	"android/soong/ui/terminal"
 	"android/soong/ui/tracer"
@@ -31,6 +33,8 @@
 	context.Context
 	logger.Logger
 
+	Metrics *metrics.Metrics
+
 	Writer terminal.Writer
 	Status *status.Status
 
@@ -39,9 +43,12 @@
 }
 
 // BeginTrace starts a new Duration Event.
-func (c ContextImpl) BeginTrace(name string) {
+func (c ContextImpl) BeginTrace(name, desc string) {
 	if c.Tracer != nil {
-		c.Tracer.Begin(name, c.Thread)
+		c.Tracer.Begin(desc, c.Thread)
+	}
+	if c.Metrics != nil {
+		c.Metrics.TimeTracer.Begin(name, desc, c.Thread)
 	}
 }
 
@@ -50,11 +57,23 @@
 	if c.Tracer != nil {
 		c.Tracer.End(c.Thread)
 	}
+	if c.Metrics != nil {
+		c.Metrics.SetTimeMetrics(c.Metrics.TimeTracer.End(c.Thread))
+	}
 }
 
 // CompleteTrace writes a trace with a beginning and end times.
-func (c ContextImpl) CompleteTrace(name string, begin, end uint64) {
+func (c ContextImpl) CompleteTrace(name, desc string, begin, end uint64) {
 	if c.Tracer != nil {
-		c.Tracer.Complete(name, c.Thread, begin, end)
+		c.Tracer.Complete(desc, c.Thread, begin, end)
+	}
+	if c.Metrics != nil {
+		realTime := end - begin
+		c.Metrics.SetTimeMetrics(
+			metrics_proto.PerfInfo{
+				Desc:      &desc,
+				Name:      &name,
+				StartTime: &begin,
+				RealTime:  &realTime})
 	}
 }
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index ad57d02..1ab855d 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -19,6 +19,7 @@
 	"fmt"
 	"strings"
 
+	"android/soong/ui/metrics"
 	"android/soong/ui/status"
 )
 
@@ -69,7 +70,7 @@
 }
 
 func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool) (map[string]string, error) {
-	ctx.BeginTrace("dumpvars")
+	ctx.BeginTrace(metrics.RunKati, "dumpvars")
 	defer ctx.EndTrace()
 
 	cmd := Command(ctx, config, "dumpvars",
@@ -113,6 +114,9 @@
 			return nil, fmt.Errorf("Failed to parse make line: %q", line)
 		}
 	}
+	if ctx.Metrics != nil {
+		ctx.Metrics.SetMetadataMetrics(ret)
+	}
 
 	return ret, nil
 }
diff --git a/ui/build/finder.go b/ui/build/finder.go
index 3130f74..0f34b5e 100644
--- a/ui/build/finder.go
+++ b/ui/build/finder.go
@@ -23,6 +23,8 @@
 	"os"
 	"path/filepath"
 	"strings"
+
+	"android/soong/ui/metrics"
 )
 
 // This file provides an interface to the Finder for use in Soong UI
@@ -31,7 +33,7 @@
 // NewSourceFinder returns a new Finder configured to search for source files.
 // Callers of NewSourceFinder should call <f.Shutdown()> when done
 func NewSourceFinder(ctx Context, config Config) (f *finder.Finder) {
-	ctx.BeginTrace("find modules")
+	ctx.BeginTrace(metrics.RunSetupTool, "find modules")
 	defer ctx.EndTrace()
 
 	dir, err := os.Getwd()
diff --git a/ui/build/kati.go b/ui/build/kati.go
index d2e9fe9..205d5ae 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -21,6 +21,7 @@
 	"path/filepath"
 	"strings"
 
+	"android/soong/ui/metrics"
 	"android/soong/ui/status"
 )
 
@@ -101,7 +102,7 @@
 }
 
 func runKatiBuild(ctx Context, config Config) {
-	ctx.BeginTrace("kati build")
+	ctx.BeginTrace(metrics.RunKati, "kati build")
 	defer ctx.EndTrace()
 
 	args := []string{
@@ -137,7 +138,7 @@
 }
 
 func runKatiPackage(ctx Context, config Config) {
-	ctx.BeginTrace("kati package")
+	ctx.BeginTrace(metrics.RunKati, "kati package")
 	defer ctx.EndTrace()
 
 	args := []string{
@@ -178,7 +179,7 @@
 }
 
 func runKatiCleanSpec(ctx Context, config Config) {
-	ctx.BeginTrace("kati cleanspec")
+	ctx.BeginTrace(metrics.RunKati, "kati cleanspec")
 	defer ctx.EndTrace()
 
 	runKati(ctx, config, katiCleanspecSuffix, []string{
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index ab15e86..e5d6da1 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -22,11 +22,12 @@
 	"strings"
 	"time"
 
+	"android/soong/ui/metrics"
 	"android/soong/ui/status"
 )
 
 func runNinja(ctx Context, config Config) {
-	ctx.BeginTrace("ninja")
+	ctx.BeginTrace(metrics.PrimaryNinja, "ninja")
 	defer ctx.EndTrace()
 
 	fifo := filepath.Join(config.OutDir(), ".ninja_fifo")
diff --git a/ui/build/path.go b/ui/build/path.go
index 8260ff9..ee72cfd 100644
--- a/ui/build/path.go
+++ b/ui/build/path.go
@@ -25,6 +25,7 @@
 	"github.com/google/blueprint/microfactory"
 
 	"android/soong/ui/build/paths"
+	"android/soong/ui/metrics"
 )
 
 func parsePathDir(dir string) []string {
@@ -57,7 +58,7 @@
 		return
 	}
 
-	ctx.BeginTrace("path")
+	ctx.BeginTrace(metrics.RunSetupTool, "path")
 	defer ctx.EndTrace()
 
 	origPath, _ := config.Environment().Get("PATH")
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 478c02c..c89f0d5 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -22,15 +22,16 @@
 
 	"github.com/google/blueprint/microfactory"
 
+	"android/soong/ui/metrics"
 	"android/soong/ui/status"
 )
 
 func runSoong(ctx Context, config Config) {
-	ctx.BeginTrace("soong")
+	ctx.BeginTrace(metrics.RunSoong, "soong")
 	defer ctx.EndTrace()
 
 	func() {
-		ctx.BeginTrace("blueprint bootstrap")
+		ctx.BeginTrace(metrics.RunSoong, "blueprint bootstrap")
 		defer ctx.EndTrace()
 
 		cmd := Command(ctx, config, "blueprint bootstrap", "build/blueprint/bootstrap.bash", "-t")
@@ -48,7 +49,7 @@
 	}()
 
 	func() {
-		ctx.BeginTrace("environment check")
+		ctx.BeginTrace(metrics.RunSoong, "environment check")
 		defer ctx.EndTrace()
 
 		envFile := filepath.Join(config.SoongOutDir(), ".soong.environment")
@@ -84,7 +85,7 @@
 	cfg.TrimPath = absPath(ctx, ".")
 
 	func() {
-		ctx.BeginTrace("minibp")
+		ctx.BeginTrace(metrics.RunSoong, "minibp")
 		defer ctx.EndTrace()
 
 		minibp := filepath.Join(config.SoongOutDir(), ".minibootstrap/minibp")
@@ -94,7 +95,7 @@
 	}()
 
 	func() {
-		ctx.BeginTrace("bpglob")
+		ctx.BeginTrace(metrics.RunSoong, "bpglob")
 		defer ctx.EndTrace()
 
 		bpglob := filepath.Join(config.SoongOutDir(), ".minibootstrap/bpglob")
@@ -104,7 +105,7 @@
 	}()
 
 	ninja := func(name, file string) {
-		ctx.BeginTrace(name)
+		ctx.BeginTrace(metrics.RunSoong, name)
 		defer ctx.EndTrace()
 
 		fifo := filepath.Join(config.OutDir(), ".ninja_fifo")
diff --git a/ui/build/test_build.go b/ui/build/test_build.go
index 348d41f..5109465 100644
--- a/ui/build/test_build.go
+++ b/ui/build/test_build.go
@@ -22,6 +22,7 @@
 	"sort"
 	"strings"
 
+	"android/soong/ui/metrics"
 	"android/soong/ui/status"
 )
 
@@ -37,7 +38,7 @@
 		return
 	}
 
-	ctx.BeginTrace("test for dangling rules")
+	ctx.BeginTrace(metrics.TestRun, "test for dangling rules")
 	defer ctx.EndTrace()
 
 	ts := ctx.Status.StartTool()