Special-case Soong finder to look in out/api_surfaces

Add a new argument in soong_ui that will be used to gate this behavior.

This approach is expected to solve incrementality issues in multi-tree.
As part of soong's bootstrap process, all source dirs are added to deps
of out/soong/build.ninja (via globs). Since multitree_build writes to the
"source" api_surfaces directory, it changes its mtime and causes a
recompilation of out/soong/build.ninja in the subsequent invocation.

Test: TH (for single-tree)
Test: Inspected ninja files (for multi-tree)
(Run a full build)
touch out/api_surfaces/vendorapi/libc/.../math.h
orchestrator/prebuilts/build-tools/linux-x86/bin/nsjail --config
out/trees/vendor_aosp_cf_arm64_phone/nsjail.cfg --
prebuilts/build-tools/linux-x86/bin/ninja -f out/soong/bootstrap.ninja
-d explain -n out/soong/build.ninja
(ninja: no work to do)

Change-Id: Ib823163ec1153344a2f593daa8d7156c24ff5bc3
diff --git a/ui/build/config.go b/ui/build/config.go
index 36119f0..dff7c4f 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -82,6 +82,7 @@
 	skipSoong       bool
 	skipNinja       bool
 	skipSoongTests  bool
+	searchApiDir    bool // Scan the Android.bp files generated in out/api_surfaces
 
 	// From the product config
 	katiArgs        []string
@@ -725,6 +726,8 @@
 			c.bazelDevMode = true
 		} else if arg == "--bazel-mode-staging" {
 			c.bazelStagingMode = true
+		} else if arg == "--search-api-dir" {
+			c.searchApiDir = true
 		} else if len(arg) > 0 && arg[0] == '-' {
 			parseArgNum := func(def int) int {
 				if len(arg) > 2 {
@@ -884,6 +887,10 @@
 	return filepath.Join(c.OutDir(), "soong")
 }
 
+func (c *configImpl) ApiSurfacesOutDir() string {
+	return filepath.Join(c.OutDir(), "api_surfaces")
+}
+
 func (c *configImpl) PrebuiltOS() string {
 	switch runtime.GOOS {
 	case "linux":
diff --git a/ui/build/finder.go b/ui/build/finder.go
index 4d6ad42..3f628cf 100644
--- a/ui/build/finder.go
+++ b/ui/build/finder.go
@@ -63,7 +63,7 @@
 	// Set up configuration parameters for the Finder cache.
 	cacheParams := finder.CacheParams{
 		WorkingDirectory: dir,
-		RootDirs:         []string{"."},
+		RootDirs:         androidBpSearchDirs(config),
 		FollowSymlinks:   config.environ.IsEnvTrue("ALLOW_BP_UNDER_SYMLINKS"),
 		ExcludeDirs:      []string{".git", ".repo"},
 		PruneFiles:       pruneFiles,
@@ -100,6 +100,15 @@
 	return f
 }
 
+func androidBpSearchDirs(config Config) []string {
+	dirs := []string{"."} // always search from root of source tree.
+	if config.searchApiDir {
+		// Search in out/api_surfaces
+		dirs = append(dirs, config.ApiSurfacesOutDir())
+	}
+	return dirs
+}
+
 // Finds the list of Bazel-related files (BUILD, WORKSPACE and Starlark) in the tree.
 func findBazelFiles(entries finder.DirEntries) (dirNames []string, fileNames []string) {
 	matches := []string{}