Add bazel staging mode to soong build.

This is to use bazel to build targets that are being prepared for an
incipient release to the prod mode allowlist.

Bug: 254265047
Test: m nothing
Test: m nothing --bazel-mode-dev
Test: m nothing --bazel-mode-staging
Change-Id: Ic78a59cf51dba83ef1ac26483586560ea9b24aaf
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 31368b2..6d3a63b 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -1347,4 +1347,8 @@
 	ProdMixedBuildsEnabledList = []string{
 		"com.android.adbd",
 	}
+
+	// Staging builds should be entirely prod, plus some near-ready ones. Add the
+	// new ones to the first argument as needed.
+	StagingMixedBuildsEnabledList = append([]string{}, ProdMixedBuildsEnabledList...)
 )
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 29695d6..b216d0a 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -386,6 +386,12 @@
 		for _, enabledProdModule := range allowlists.ProdMixedBuildsEnabledList {
 			enabledModules[enabledProdModule] = true
 		}
+	case BazelStagingMode:
+		modulesDefaultToBazel = false
+		for _, enabledStagingMode := range allowlists.StagingMixedBuildsEnabledList {
+			enabledModules[enabledStagingMode] = true
+
+		}
 	case BazelDevMode:
 		modulesDefaultToBazel = true
 
diff --git a/android/config.go b/android/config.go
index 4992882..1ed405b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -97,6 +97,11 @@
 	// allowlisted on an experimental basis.
 	BazelDevMode
 
+	// Use bazel during analysis of a few allowlisted build modules. The allowlist
+	// is considered "staging, as these are modules being prepared to be released
+	// into prod mode shortly after.
+	BazelStagingMode
+
 	// Use bazel during analysis of build modules from an allowlist carefully
 	// curated by the build team to be proven stable.
 	BazelProdMode
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 0ba25c8..70f58f5 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -88,6 +88,7 @@
 	flag.StringVar(&cmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output")
 	flag.BoolVar(&cmdlineArgs.EmptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file")
 	flag.BoolVar(&cmdlineArgs.BazelMode, "bazel-mode", false, "use bazel for analysis of certain modules")
+	flag.BoolVar(&cmdlineArgs.BazelMode, "bazel-mode-staging", false, "use bazel for analysis of certain near-ready modules")
 	flag.BoolVar(&cmdlineArgs.BazelModeDev, "bazel-mode-dev", false, "use bazel for analysis of a large number of modules (less stable)")
 
 	// Flags that probably shouldn't be flags of soong_build but we haven't found
@@ -142,6 +143,8 @@
 		buildMode = android.BazelDevMode
 	} else if cmdlineArgs.BazelMode {
 		buildMode = android.BazelProdMode
+	} else if cmdlineArgs.BazelModeStaging {
+		buildMode = android.BazelStagingMode
 	} else {
 		buildMode = android.AnalysisNoBazel
 	}
diff --git a/ui/build/build.go b/ui/build/build.go
index 2022e50..b9bd898 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -112,9 +112,19 @@
 // checkBazelMode fails the build if there are conflicting arguments for which bazel
 // build mode to use.
 func checkBazelMode(ctx Context, config Config) {
-	if config.bazelProdMode && config.bazelDevMode {
+	count := 0
+	if config.bazelProdMode {
+		count++
+	}
+	if config.bazelDevMode {
+		count++
+	}
+	if config.bazelStagingMode {
+		count++
+	}
+	if count > 1 {
 		ctx.Fatalln("Conflicting bazel mode.\n" +
-			"Do not specify both --bazel-mode and --bazel-mode-dev")
+			"Do not specify more than one of --bazel-mode and --bazel-mode-dev and --bazel-mode-staging ")
 	}
 }
 
diff --git a/ui/build/config.go b/ui/build/config.go
index f6f5b46..cde8d5d 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -100,8 +100,9 @@
 
 	pathReplaced bool
 
-	bazelProdMode bool
-	bazelDevMode  bool
+	bazelProdMode    bool
+	bazelDevMode     bool
+	bazelStagingMode bool
 
 	// Set by multiproduct_kati
 	emptyNinjaFile bool
@@ -721,6 +722,8 @@
 			c.bazelProdMode = true
 		} else if arg == "--bazel-mode-dev" {
 			c.bazelDevMode = true
+		} else if arg == "--bazel-mode-staging" {
+			c.bazelStagingMode = true
 		} else if len(arg) > 0 && arg[0] == '-' {
 			parseArgNum := func(def int) int {
 				if len(arg) > 2 {
@@ -1115,7 +1118,7 @@
 }
 
 func (c *configImpl) BazelBuildEnabled() bool {
-	return c.bazelProdMode || c.bazelDevMode
+	return c.bazelProdMode || c.bazelDevMode || c.bazelStagingMode
 }
 
 func (c *configImpl) StartRBE() bool {
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index 150ec35..9ea5110 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -1008,6 +1008,7 @@
 		useBazel            bool
 		bazelDevMode        bool
 		bazelProdMode       bool
+		bazelStagingMode    bool
 		expectedBuildConfig *smpb.BuildConfig
 	}{
 		{
@@ -1084,6 +1085,17 @@
 			},
 		},
 		{
+			name:             "bazel mixed build from staging mode",
+			environ:          Environment{},
+			bazelStagingMode: true,
+			expectedBuildConfig: &smpb.BuildConfig{
+				ForceUseGoma:    proto.Bool(false),
+				UseGoma:         proto.Bool(false),
+				UseRbe:          proto.Bool(false),
+				BazelMixedBuild: proto.Bool(true),
+			},
+		},
+		{
 			name:      "specified targets",
 			environ:   Environment{},
 			useBazel:  true,
@@ -1118,10 +1130,11 @@
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
 			c := &configImpl{
-				environ:       &tc.environ,
-				bazelDevMode:  tc.bazelDevMode,
-				bazelProdMode: tc.bazelProdMode,
-				arguments:     tc.arguments,
+				environ:          &tc.environ,
+				bazelDevMode:     tc.bazelDevMode,
+				bazelProdMode:    tc.bazelProdMode,
+				bazelStagingMode: tc.bazelStagingMode,
+				arguments:        tc.arguments,
 			}
 			config := Config{c}
 			checkBazelMode(ctx, config)
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 28c6ec9..c87f993 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -260,6 +260,9 @@
 	if config.bazelDevMode {
 		mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--bazel-mode-dev")
 	}
+	if config.bazelStagingMode {
+		mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--bazel-mode-staging")
+	}
 
 	mainSoongBuildInvocation := primaryBuilderInvocation(
 		config,