Provide Bazel timing breakdown for the mixed builds

Instead of single event in the build metrics
```
| soong_build.mixed_build.bazel          | 1:17.1 |
```
it will now show:
```
| soong_build.mixed_build.bazel          | 1:17.1 |
| soong_build.mixed_build.bazel.cquery   |   51.9 |
| soong_build.mixed_build.bazel.aquery   |   23.1 |
| soong_build.mixed_build.bazel.symlinks |    2.1 |
```

Test: treehugger
Change-Id: I84a7dda6e3122860da9aaa98bfa6afe33d392dcf
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index b3b698e..e2751d6 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -150,8 +150,9 @@
 	// ** end Cquery Results Retrieval Functions
 
 	// Issues commands to Bazel to receive results for all cquery requests
-	// queued in the BazelContext.
-	InvokeBazel(config Config) error
+	// queued in the BazelContext. The ctx argument is optional and is only
+	// used for performance data collection
+	InvokeBazel(config Config, ctx *Context) error
 
 	// Returns true if Bazel handling is enabled for the module with the given name.
 	// Note that this only implies "bazel mixed build" allowlisting. The caller
@@ -259,7 +260,7 @@
 	return result, nil
 }
 
-func (m MockBazelContext) InvokeBazel(_ Config) error {
+func (m MockBazelContext) InvokeBazel(_ Config, ctx *Context) error {
 	panic("unimplemented")
 }
 
@@ -355,7 +356,7 @@
 	panic("implement me")
 }
 
-func (n noopBazelContext) InvokeBazel(_ Config) error {
+func (n noopBazelContext) InvokeBazel(_ Config, ctx *Context) error {
 	panic("unimplemented")
 }
 
@@ -865,11 +866,48 @@
 	return filepath.Dir(p.soongOutDir)
 }
 
+const buildrootLabel = "@soong_injection//mixed_builds:buildroot"
+
+var (
+	cqueryCmd = bazelCommand{"cquery", fmt.Sprintf("deps(%s, 2)", buildrootLabel)}
+	aqueryCmd = bazelCommand{"aquery", fmt.Sprintf("deps(%s)", buildrootLabel)}
+	buildCmd  = bazelCommand{"build", "@soong_injection//mixed_builds:phonyroot"}
+)
+
 // Issues commands to Bazel to receive results for all cquery requests
 // queued in the BazelContext.
-func (context *bazelContext) InvokeBazel(config Config) error {
-	context.results = make(map[cqueryKey]string)
+func (context *bazelContext) InvokeBazel(config Config, ctx *Context) error {
+	if ctx != nil {
+		ctx.EventHandler.Begin("bazel")
+		defer ctx.EventHandler.End("bazel")
+	}
 
+	if metricsDir := context.paths.BazelMetricsDir(); metricsDir != "" {
+		if err := os.MkdirAll(metricsDir, 0777); err != nil {
+			return err
+		}
+	}
+	context.results = make(map[cqueryKey]string)
+	if err := context.runCquery(ctx); err != nil {
+		return err
+	}
+	if err := context.runAquery(config, ctx); err != nil {
+		return err
+	}
+	if err := context.generateBazelSymlinks(ctx); err != nil {
+		return err
+	}
+
+	// Clear requests.
+	context.requests = map[cqueryKey]bool{}
+	return nil
+}
+
+func (context *bazelContext) runCquery(ctx *Context) error {
+	if ctx != nil {
+		ctx.EventHandler.Begin("cquery")
+		defer ctx.EventHandler.End("cquery")
+	}
 	soongInjectionPath := absolutePath(context.paths.injectedFilesDir())
 	mixedBuildsPath := filepath.Join(soongInjectionPath, "mixed_builds")
 	if _, err := os.Stat(mixedBuildsPath); os.IsNotExist(err) {
@@ -878,13 +916,6 @@
 			return err
 		}
 	}
-
-	if metricsDir := context.paths.BazelMetricsDir(); metricsDir != "" {
-		err := os.MkdirAll(metricsDir, 0777)
-		if err != nil {
-			return err
-		}
-	}
 	if err := ioutil.WriteFile(filepath.Join(soongInjectionPath, "WORKSPACE.bazel"), []byte{}, 0666); err != nil {
 		return err
 	}
@@ -899,8 +930,6 @@
 		return err
 	}
 
-	const buildrootLabel = "@soong_injection//mixed_builds:buildroot"
-	cqueryCmd := bazelCommand{"cquery", fmt.Sprintf("deps(%s, 2)", buildrootLabel)}
 	cqueryCommandWithFlag := context.createBazelCommand(context.paths, bazel.CqueryBuildRootRunName, cqueryCmd,
 		"--output=starlark", "--starlark:file="+absolutePath(cqueryFileRelpath))
 	cqueryOutput, cqueryErrorMessage, cqueryErr := context.issueBazelCommand(cqueryCommandWithFlag)
@@ -926,7 +955,14 @@
 				getCqueryId(val), cqueryOutput, cqueryErrorMessage)
 		}
 	}
+	return nil
+}
 
+func (context *bazelContext) runAquery(config Config, ctx *Context) error {
+	if ctx != nil {
+		ctx.EventHandler.Begin("aquery")
+		defer ctx.EventHandler.End("aquery")
+	}
 	// Issue an aquery command to retrieve action information about the bazel build tree.
 	//
 	// Use jsonproto instead of proto; actual proto parsing would require a dependency on Bazel's
@@ -951,25 +987,25 @@
 			extraFlags = append(extraFlags, "--instrumentation_filter="+strings.Join(paths, ","))
 		}
 	}
-	aqueryCmd := bazelCommand{"aquery", fmt.Sprintf("deps(%s)", buildrootLabel)}
-	if aqueryOutput, _, err := context.issueBazelCommand(context.createBazelCommand(context.paths, bazel.AqueryBuildRootRunName, aqueryCmd,
-		extraFlags...)); err == nil {
-		context.buildStatements, context.depsets, err = bazel.AqueryBuildStatements([]byte(aqueryOutput))
-	} else {
+	aqueryOutput, _, err := context.issueBazelCommand(context.createBazelCommand(context.paths, bazel.AqueryBuildRootRunName, aqueryCmd,
+		extraFlags...))
+	if err != nil {
 		return err
 	}
+	context.buildStatements, context.depsets, err = bazel.AqueryBuildStatements([]byte(aqueryOutput))
+	return err
+}
 
+func (context *bazelContext) generateBazelSymlinks(ctx *Context) error {
+	if ctx != nil {
+		ctx.EventHandler.Begin("symlinks")
+		defer ctx.EventHandler.End("symlinks")
+	}
 	// Issue a build command of the phony root to generate symlink forests for dependencies of the
 	// Bazel build. This is necessary because aquery invocations do not generate this symlink forest,
 	// but some of symlinks may be required to resolve source dependencies of the build.
-	buildCmd := bazelCommand{"build", "@soong_injection//mixed_builds:phonyroot"}
-	if _, _, err := context.issueBazelCommand(context.createBazelCommand(context.paths, bazel.BazelBuildPhonyRootRunName, buildCmd)); err != nil {
-		return err
-	}
-
-	// Clear requests.
-	context.requests = map[cqueryKey]bool{}
-	return nil
+	_, _, err := context.issueBazelCommand(context.createBazelCommand(context.paths, bazel.BazelBuildPhonyRootRunName, buildCmd))
+	return err
 }
 
 func (context *bazelContext) BuildStatementsToRegister() []bazel.BuildStatement {