Merge "cosmetic changes"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index a19a041..b0c87d4 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -46,7 +46,6 @@
 		"bionic":                                Bp2BuildDefaultTrueRecursively,
 		"bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
 
-		"build/bazel/examples/aidl":                   Bp2BuildDefaultTrueRecursively,
 		"build/bazel/examples/apex/minimal":           Bp2BuildDefaultTrueRecursively,
 		"build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively,
 		"build/bazel/examples/python":                 Bp2BuildDefaultTrueRecursively,
@@ -174,7 +173,35 @@
 		"frameworks/native/opengl/tests/testViewport":        Bp2BuildDefaultTrue,
 		"frameworks/proto_logging/stats/stats_log_api_gen":   Bp2BuildDefaultTrueRecursively,
 
-		"libnativehelper":                                  Bp2BuildDefaultTrueRecursively,
+		"hardware/interfaces":                          Bp2BuildDefaultTrue,
+		"hardware/interfaces/configstore/1.0":          Bp2BuildDefaultTrue,
+		"hardware/interfaces/configstore/1.1":          Bp2BuildDefaultTrue,
+		"hardware/interfaces/configstore/utils":        Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/allocator/2.0":   Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/allocator/3.0":   Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/allocator/4.0":   Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/bufferqueue/1.0": Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/bufferqueue/2.0": Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/common/1.0":      Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/common/1.1":      Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/common/1.2":      Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/mapper/2.0":      Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/mapper/2.1":      Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/mapper/3.0":      Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/mapper/4.0":      Bp2BuildDefaultTrue,
+		"hardware/interfaces/media/1.0":                Bp2BuildDefaultTrue,
+		"hardware/interfaces/media/bufferpool/2.0":     Bp2BuildDefaultTrue,
+		"hardware/interfaces/media/c2/1.0":             Bp2BuildDefaultTrue,
+		"hardware/interfaces/media/c2/1.1":             Bp2BuildDefaultTrue,
+		"hardware/interfaces/media/c2/1.2":             Bp2BuildDefaultTrue,
+		"hardware/interfaces/media/omx/1.0":            Bp2BuildDefaultTrue,
+		"hardware/interfaces/neuralnetworks/1.0":       Bp2BuildDefaultTrue,
+		"hardware/interfaces/neuralnetworks/1.1":       Bp2BuildDefaultTrue,
+		"hardware/interfaces/neuralnetworks/1.2":       Bp2BuildDefaultTrue,
+		"hardware/interfaces/neuralnetworks/1.3":       Bp2BuildDefaultTrue,
+
+		"libnativehelper": Bp2BuildDefaultTrueRecursively,
+
 		"packages/apps/DevCamera":                          Bp2BuildDefaultTrue,
 		"packages/apps/HTMLViewer":                         Bp2BuildDefaultTrue,
 		"packages/apps/Protips":                            Bp2BuildDefaultTrue,
@@ -220,10 +247,18 @@
 		"system/libartpalette":                                   Bp2BuildDefaultTrueRecursively,
 		"system/libbase":                                         Bp2BuildDefaultTrueRecursively,
 		"system/libfmq":                                          Bp2BuildDefaultTrue,
+		"system/libhidl/libhidlmemory":                           Bp2BuildDefaultTrue,
+		"system/libhidl/transport":                               Bp2BuildDefaultTrue,
+		"system/libhidl/transport/allocator/1.0":                 Bp2BuildDefaultTrue,
 		"system/libhidl/transport/base/1.0":                      Bp2BuildDefaultTrue,
 		"system/libhidl/transport/manager/1.0":                   Bp2BuildDefaultTrue,
 		"system/libhidl/transport/manager/1.1":                   Bp2BuildDefaultTrue,
 		"system/libhidl/transport/manager/1.2":                   Bp2BuildDefaultTrue,
+		"system/libhidl/transport/memory/1.0":                    Bp2BuildDefaultTrue,
+		"system/libhidl/transport/memory/token/1.0":              Bp2BuildDefaultTrue,
+		"system/libhidl/transport/safe_union/1.0":                Bp2BuildDefaultTrue,
+		"system/libhidl/transport/token/1.0":                     Bp2BuildDefaultTrue,
+		"system/libhidl/transport/token/1.0/utils":               Bp2BuildDefaultTrue,
 		"system/libhwbinder":                                     Bp2BuildDefaultTrueRecursively,
 		"system/libprocinfo":                                     Bp2BuildDefaultTrue,
 		"system/libziparchive":                                   Bp2BuildDefaultTrueRecursively,
@@ -620,4 +655,9 @@
 		"prebuilt_platform-robolectric-4.5.1-prebuilt",
 		"prebuilt_currysrc_org.eclipse",
 	}
+
+	ProdMixedBuildsEnabledList = []string{
+		// This list left intentionally empty for now. Add specific module names
+		// to have them built by Bazel in Prod Mixed Builds mode.
+	}
 )
diff --git a/android/bazel.go b/android/bazel.go
index 71eb036..3ae3d6f 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -219,16 +219,16 @@
 	// in the synthetic Bazel workspace.
 	keepExistingBuildFile map[string]bool
 
-	// Per-module allowlist to always opt modules in of both bp2build and mixed builds.
-	// These modules are usually in directories with many other modules that are not ready for
-	// conversion.
+	// Per-module allowlist to always opt modules into both bp2build and Bazel Dev Mode mixed
+	// builds. These modules are usually in directories with many other modules that are not ready
+	// for conversion.
 	//
 	// A module can either be in this list or its directory allowlisted entirely
 	// in bp2buildDefaultConfig, but not both at the same time.
 	moduleAlwaysConvert map[string]bool
 
-	// Per-module-type allowlist to always opt modules in to both bp2build and mixed builds
-	// when they have the same type as one listed.
+	// Per-module-type allowlist to always opt modules in to both bp2build and
+	// Bazel Dev Mode mixed builds when they have the same type as one listed.
 	moduleTypeAlwaysConvert map[string]bool
 
 	// Per-module denylist to always opt modules out of bp2build conversion.
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index d87f988..93b6779 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -343,7 +343,30 @@
 }
 
 func NewBazelContext(c *config) (BazelContext, error) {
-	if !c.IsMixedBuildsEnabled() {
+	var modulesDefaultToBazel bool
+	disabledModules := map[string]bool{}
+	enabledModules := map[string]bool{}
+
+	switch c.BuildMode {
+	case BazelProdMode:
+		modulesDefaultToBazel = false
+
+		for _, enabledProdModule := range allowlists.ProdMixedBuildsEnabledList {
+			enabledModules[enabledProdModule] = true
+		}
+	case BazelDevMode:
+		modulesDefaultToBazel = true
+
+		// Don't use partially-converted cc_library targets in mixed builds,
+		// since mixed builds would generally rely on both static and shared
+		// variants of a cc_library.
+		for staticOnlyModule, _ := range GetBp2BuildAllowList().ccLibraryStaticOnly {
+			disabledModules[staticOnlyModule] = true
+		}
+		for _, disabledDevModule := range allowlists.MixedBuildsDisabledList {
+			disabledModules[disabledDevModule] = true
+		}
+	default:
 		return noopBazelContext{}, nil
 	}
 
@@ -352,24 +375,12 @@
 		return nil, err
 	}
 
-	// TODO(cparsons): Use a different allowlist depending on prod vs. dev
-	// bazel mode.
-	disabledModules := map[string]bool{}
-	// Don't use partially-converted cc_library targets in mixed builds,
-	// since mixed builds would generally rely on both static and shared
-	// variants of a cc_library.
-	for staticOnlyModule, _ := range GetBp2BuildAllowList().ccLibraryStaticOnly {
-		disabledModules[staticOnlyModule] = true
-	}
-	for _, disabledDevModule := range allowlists.MixedBuildsDisabledList {
-		disabledModules[disabledDevModule] = true
-	}
-
 	return &bazelContext{
 		bazelRunner:           &builtinBazelRunner{},
 		paths:                 p,
 		requests:              make(map[cqueryKey]bool),
-		modulesDefaultToBazel: true,
+		modulesDefaultToBazel: modulesDefaultToBazel,
+		bazelEnabledModules:   enabledModules,
 		bazelDisabledModules:  disabledModules,
 	}, nil
 }
diff --git a/android/config.go b/android/config.go
index 5ca9420..a07cb6c 100644
--- a/android/config.go
+++ b/android/config.go
@@ -96,7 +96,6 @@
 
 	// Use bazel during analysis of build modules from an allowlist carefully
 	// curated by the build team to be proven stable.
-	// TODO(cparsons): Implement this mode.
 	BazelProdMode
 )
 
@@ -481,14 +480,6 @@
 		config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
 	}
 
-	// Checking USE_BAZEL_ANALYSIS must be done here instead of in the caller, so
-	// that we can invoke IsEnvTrue (which also registers the env var as a
-	// dependency of the build).
-	// TODO(cparsons): Remove this hack once USE_BAZEL_ANALYSIS is removed.
-	if buildMode == AnalysisNoBazel && config.IsEnvTrue("USE_BAZEL_ANALYSIS") {
-		buildMode = BazelDevMode
-	}
-
 	config.BuildMode = buildMode
 	config.BazelContext, err = NewBazelContext(config)
 	config.bp2buildPackageConfig = GetBp2BuildAllowList()
@@ -678,9 +669,7 @@
 // DeviceProduct returns the current product target. There could be multiple of
 // these per device type.
 //
-// NOTE: Do not base conditional logic on this value. It may break product
-//
-//	inheritance.
+// NOTE: Do not base conditional logic on this value. It may break product inheritance.
 func (c *config) DeviceProduct() string {
 	return *c.productVariables.DeviceProduct
 }
@@ -1630,6 +1619,10 @@
 	return uncheckedFinalApiLevel(apiLevel)
 }
 
+func (c *deviceConfig) BuildBrokenClangProperty() bool {
+	return c.config.productVariables.BuildBrokenClangProperty
+}
+
 func (c *deviceConfig) BuildBrokenEnforceSyspropOwner() bool {
 	return c.config.productVariables.BuildBrokenEnforceSyspropOwner
 }
diff --git a/android/variable.go b/android/variable.go
index 2d7b0bf..7a080fe 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -430,6 +430,7 @@
 
 	ShippingApiLevel *string `json:",omitempty"`
 
+	BuildBrokenClangProperty           bool     `json:",omitempty"`
 	BuildBrokenDepfile                 *bool    `json:",omitempty"`
 	BuildBrokenEnforceSyspropOwner     bool     `json:",omitempty"`
 	BuildBrokenTrebleSyspropNeverallow bool     `json:",omitempty"`
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index d327157..cb25627 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -18,7 +18,6 @@
         "testing.go",
     ],
     deps: [
-        "aidl-soong-rules",
         "soong-android",
         "soong-android-allowlists",
         "soong-android-soongconfig",
@@ -37,7 +36,6 @@
     ],
     testSrcs: [
         "aar_conversion_test.go",
-        "aidl_interface_conversion_test.go",
         "android_app_certificate_conversion_test.go",
         "android_app_conversion_test.go",
         "apex_conversion_test.go",
diff --git a/bp2build/aidl_interface_conversion_test.go b/bp2build/aidl_interface_conversion_test.go
deleted file mode 100644
index 38d902d..0000000
--- a/bp2build/aidl_interface_conversion_test.go
+++ /dev/null
@@ -1,249 +0,0 @@
-package bp2build
-
-import (
-	"android/soong/aidl"
-	"android/soong/android"
-	"testing"
-)
-
-func runAidlInterfaceTestCase(t *testing.T, tc Bp2buildTestCase) {
-	t.Helper()
-	RunBp2BuildTestCase(
-		t,
-		func(ctx android.RegistrationContext) {
-			ctx.RegisterModuleType("aidl_interface", aidl.AidlInterfaceFactory)
-			ctx.RegisterModuleType("aidl_interface_headers", aidl.AidlInterfaceHeadersFactory)
-		},
-		tc,
-	)
-}
-
-func TestAidlInterfaceHeaders(t *testing.T) {
-	runAidlInterfaceTestCase(t, Bp2buildTestCase{
-		Description: `aidl_interface_headers`,
-		Blueprint: `
-aidl_interface_headers {
-    name: "aidl-interface-headers",
-	include_dir: "src",
-	srcs: [
-		"src/A.aidl",
-	],
-}
-`,
-		ExpectedBazelTargets: []string{
-			MakeBazelTargetNoRestrictions("aidl_library", "aidl-interface-headers", AttrNameToString{
-				"strip_import_prefix": `"src"`,
-				"hdrs":                `["src/A.aidl"]`,
-			}),
-		},
-	})
-}
-
-func TestAidlInterface(t *testing.T) {
-	runAidlInterfaceTestCase(t, Bp2buildTestCase{
-		Description: `aidl_interface with single "latest" aidl_interface import`,
-		Blueprint: `
-aidl_interface_headers {
-    name: "aidl-interface-headers",
-}
-aidl_interface {
-    name: "aidl-interface-import",
-    versions: [
-        "1",
-        "2",
-    ],
-}
-aidl_interface {
-    name: "aidl-interface1",
-    flags: ["--flag1"],
-    imports: [
-        "aidl-interface-import-V1",
-    ],
-    headers: [
-        "aidl-interface-headers",
-    ],
-    versions: [
-        "1",
-        "2",
-        "3",
-    ],
-}`,
-		ExpectedBazelTargets: []string{
-			MakeBazelTargetNoRestrictions("aidl_library", "aidl-interface-headers", AttrNameToString{}),
-			MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface-import", AttrNameToString{
-				"backends": `[
-        "cpp",
-        "java",
-        "ndk",
-    ]`,
-				"versions": `[
-        "1",
-        "2",
-    ]`,
-			}),
-			MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", AttrNameToString{
-				"backends": `[
-        "cpp",
-        "java",
-        "ndk",
-    ]`,
-				"deps": `[
-        ":aidl-interface-import-V1",
-        ":aidl-interface-headers",
-    ]`,
-				"flags": `["--flag1"]`,
-				"versions": `[
-        "1",
-        "2",
-        "3",
-    ]`,
-			}),
-		},
-	})
-}
-
-func TestAidlInterfaceWithNoProperties(t *testing.T) {
-	runAidlInterfaceTestCase(t, Bp2buildTestCase{
-		Description: `aidl_interface no properties set`,
-		Blueprint: `
-aidl_interface {
-    name: "aidl-interface1",
-}
-`,
-		ExpectedBazelTargets: []string{
-			MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", AttrNameToString{
-				"backends": `[
-        "cpp",
-        "java",
-        "ndk",
-    ]`,
-			}),
-		},
-	})
-}
-
-func TestAidlInterfaceWithDisabledBackends(t *testing.T) {
-	runAidlInterfaceTestCase(t, Bp2buildTestCase{
-		Description: `aidl_interface with some backends disabled`,
-		Blueprint: `
-aidl_interface {
-    name: "aidl-interface1",
-    backend: {
-        ndk: {
-            enabled: false,
-        },
-        cpp: {
-            enabled: false,
-        },
-    },
-}
-`,
-		ExpectedBazelTargets: []string{
-			MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", AttrNameToString{
-				"backends": `["java"]`,
-			}),
-		},
-	})
-}
-
-func TestAidlInterfaceWithLatestImport(t *testing.T) {
-	runAidlInterfaceTestCase(t, Bp2buildTestCase{
-		Description: `aidl_interface with single "latest" aidl_interface import`,
-		Blueprint: `
-aidl_interface {
-    name: "aidl-interface-import",
-    versions: [
-        "1",
-        "2",
-    ],
-}
-aidl_interface {
-    name: "aidl-interface1",
-    imports: [
-        "aidl-interface-import",
-    ],
-    versions: [
-        "1",
-        "2",
-        "3",
-    ],
-}`,
-		ExpectedBazelTargets: []string{
-			MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface-import", AttrNameToString{
-				"backends": `[
-        "cpp",
-        "java",
-        "ndk",
-    ]`,
-				"versions": `[
-        "1",
-        "2",
-    ]`,
-			}),
-			MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", AttrNameToString{
-				"backends": `[
-        "cpp",
-        "java",
-        "ndk",
-    ]`,
-				"deps": `[":aidl-interface-import-latest"]`,
-				"versions": `[
-        "1",
-        "2",
-        "3",
-    ]`,
-			}),
-		},
-	})
-}
-
-func TestAidlInterfaceWithVersionedImport(t *testing.T) {
-	runAidlInterfaceTestCase(t, Bp2buildTestCase{
-		Description: `aidl_interface with single versioned aidl_interface import`,
-		Blueprint: `
-aidl_interface {
-    name: "aidl-interface-import",
-    versions: [
-        "1",
-        "2",
-    ],
-}
-aidl_interface {
-    name: "aidl-interface1",
-    imports: [
-        "aidl-interface-import-V2",
-    ],
-    versions: [
-        "1",
-        "2",
-        "3",
-    ],
-}`,
-		ExpectedBazelTargets: []string{
-			MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface-import", AttrNameToString{
-				"backends": `[
-        "cpp",
-        "java",
-        "ndk",
-    ]`,
-				"versions": `[
-        "1",
-        "2",
-    ]`,
-			}),
-			MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", AttrNameToString{
-				"backends": `[
-        "cpp",
-        "java",
-        "ndk",
-    ]`,
-				"deps": `[":aidl-interface-import-V2"]`,
-				"versions": `[
-        "1",
-        "2",
-        "3",
-    ]`,
-			}),
-		},
-	})
-}
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index f5a5938..b57cf35 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -501,3 +501,36 @@
 		ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 	})
 }
+
+func TestJavaLibraryAidlNonAdjacentAidlFilegroup(t *testing.T) {
+	runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{
+		Description:                "java_library with non adjacent aidl filegroup",
+		ModuleTypeUnderTest:        "java_library",
+		ModuleTypeUnderTestFactory: java.LibraryFactory,
+		Filesystem: map[string]string{
+			"path/to/A/Android.bp": `
+filegroup {
+	name: "A_aidl",
+	srcs: ["aidl/A.aidl"],
+	path: "aidl",
+}`,
+		},
+		Blueprint: `
+java_library {
+	name: "foo",
+	srcs: [
+		":A_aidl",
+	],
+}`,
+		ExpectedBazelTargets: []string{
+			makeBazelTarget("java_aidl_library", "foo_java_aidl_library", AttrNameToString{
+				"deps": `["//path/to/A:A_aidl"]`,
+			}),
+			makeBazelTarget("java_library", "foo", AttrNameToString{
+				"exports": `[":foo_java_aidl_library"]`,
+			}),
+		},
+	}, func(ctx android.RegistrationContext) {
+		ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+	})
+}
diff --git a/cc/builder.go b/cc/builder.go
index f3faca8..35ae69b 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -282,7 +282,7 @@
 	sAbiDiff = pctx.RuleFunc("sAbiDiff",
 		func(ctx android.PackageRuleContext) blueprint.RuleParams {
 			commandStr := "($sAbiDiffer ${extraFlags} -lib ${libName} -arch ${arch} -o ${out} -new ${in} -old ${referenceDump})"
-			commandStr += "|| (echo 'error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py ${createReferenceDumpFlags} -l ${libName}'"
+			commandStr += "|| (echo '${errorMessage}'"
 			commandStr += " && (mkdir -p $$DIST_DIR/abidiffs && cp ${out} $$DIST_DIR/abidiffs/)"
 			commandStr += " && exit 1)"
 			return blueprint.RuleParams{
@@ -290,7 +290,7 @@
 				CommandDeps: []string{"$sAbiDiffer"},
 			}
 		},
-		"extraFlags", "referenceDump", "libName", "arch", "createReferenceDumpFlags")
+		"extraFlags", "referenceDump", "libName", "arch", "errorMessage")
 
 	// Rule to unzip a reference abi dump.
 	unzipRefSAbiDump = pctx.AndroidStaticRule("unzipRefSAbiDump",
@@ -940,9 +940,21 @@
 			"-allow-unreferenced-elf-symbol-changes")
 	}
 
-	// TODO(b/241496591): Remove -advice-only after b/239792343 and b/239790286 are reolved.
+	var errorMessage string
+	// When error occurs in previous version ABI diff, Developers can't just update ABI
+	// reference but need to follow instructions to ensure ABI backward compatibility.
 	if previousVersionDiff {
+		// TODO(b/241496591): Remove -advice-only after b/239792343 and b/239790286 are reolved.
 		extraFlags = append(extraFlags, "-advice-only")
+		errorMessage = "error: Please follow development/vndk/tools/header-checker/README.md to ensure the ABI compatibility between your source code and version " + prevVersion + "."
+		// The prevVersion is expected as a string of int, skip it if not.
+		if prevVersionInt, err := strconv.Atoi(prevVersion); err == nil {
+			sourceVersion := strconv.Itoa(prevVersionInt + 1)
+			extraFlags = append(extraFlags, "-target-version", sourceVersion)
+		}
+	} else {
+		errorMessage = "error: Please update ABI references with: $ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName
+		extraFlags = append(extraFlags, "-target-version", "current")
 	}
 
 	if isLlndk || isNdk {
@@ -961,11 +973,11 @@
 		Input:       inputDump,
 		Implicit:    referenceDump,
 		Args: map[string]string{
-			"referenceDump":            referenceDump.String(),
-			"libName":                  libName,
-			"arch":                     ctx.Arch().ArchType.Name,
-			"extraFlags":               strings.Join(extraFlags, " "),
-			"createReferenceDumpFlags": "",
+			"referenceDump": referenceDump.String(),
+			"libName":       libName,
+			"arch":          ctx.Arch().ArchType.Name,
+			"extraFlags":    strings.Join(extraFlags, " "),
+			"errorMessage":  errorMessage,
 		},
 	})
 	return android.OptionalPathForPath(outputFile)
diff --git a/cc/cc.go b/cc/cc.go
index 336771a..f1e9bf6 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1900,6 +1900,8 @@
 
 	if c.Properties.Clang != nil && *c.Properties.Clang == false {
 		ctx.PropertyErrorf("clang", "false (GCC) is no longer supported")
+	} else if c.Properties.Clang != nil && !ctx.DeviceConfig().BuildBrokenClangProperty() {
+		ctx.PropertyErrorf("clang", "property is deprecated, see Changes.md file")
 	}
 
 	flags := Flags{
diff --git a/cc/cc_test.go b/cc/cc_test.go
index f025700..36174d6 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -4336,3 +4336,53 @@
 	}
 
 }
+
+func TestCcBuildBrokenClangProperty(t *testing.T) {
+	tests := []struct {
+		name                     string
+		clang                    bool
+		BuildBrokenClangProperty bool
+		err                      string
+	}{
+		{
+			name:  "error when clang is set to false",
+			clang: false,
+			err:   "is no longer supported",
+		},
+		{
+			name:  "error when clang is set to true",
+			clang: true,
+			err:   "property is deprecated, see Changes.md",
+		},
+		{
+			name:                     "no error when BuildBrokenClangProperty is explicitly set to true",
+			clang:                    true,
+			BuildBrokenClangProperty: true,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			bp := fmt.Sprintf(`
+			cc_library {
+			   name: "foo",
+			   clang: %t,
+			}`, test.clang)
+
+			if test.err == "" {
+				android.GroupFixturePreparers(
+					prepareForCcTest,
+					android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+						if test.BuildBrokenClangProperty {
+							variables.BuildBrokenClangProperty = test.BuildBrokenClangProperty
+						}
+					}),
+				).RunTestWithBp(t, bp)
+			} else {
+				prepareForCcTest.
+					ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
+					RunTestWithBp(t, bp)
+			}
+		})
+	}
+}
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 6930943..d15dea1 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -84,6 +84,8 @@
 	flag.StringVar(&bp2buildMarker, "bp2build_marker", "", "If set, run bp2build, touch the specified marker file then exit")
 	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.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
 	// the time to remove them yet
@@ -131,6 +133,10 @@
 		buildMode = android.GenerateModuleGraph
 	} else if docFile != "" {
 		buildMode = android.GenerateDocFile
+	} else if cmdlineArgs.BazelModeDev {
+		buildMode = android.BazelDevMode
+	} else if cmdlineArgs.BazelMode {
+		buildMode = android.BazelProdMode
 	} else {
 		buildMode = android.AnalysisNoBazel
 	}
diff --git a/go.mod b/go.mod
index 2e28ab6..8c1a9f0 100644
--- a/go.mod
+++ b/go.mod
@@ -1,17 +1,13 @@
 module android/soong
 
-require (
-	google.golang.org/protobuf v0.0.0
-	github.com/google/blueprint v0.0.0
-	android/soong/aidl v0.0.0
-)
+require google.golang.org/protobuf v0.0.0
+
+require github.com/google/blueprint v0.0.0
 
 replace google.golang.org/protobuf v0.0.0 => ../../external/golang-protobuf
 
 replace github.com/google/blueprint v0.0.0 => ../blueprint
 
-replace android/soong/aidl v0.0.0 => ../../system/tools/aidl/build
-
 // Indirect deps from golang-protobuf
 exclude github.com/golang/protobuf v1.5.0
 
diff --git a/tests/apex_comparison_tests.sh b/tests/apex_comparison_tests.sh
index 4b2f795..ac3c177 100755
--- a/tests/apex_comparison_tests.sh
+++ b/tests/apex_comparison_tests.sh
@@ -33,6 +33,10 @@
 SOONG_OUTPUT_DIR="$OUTPUT_DIR/soong"
 BAZEL_OUTPUT_DIR="$OUTPUT_DIR/bazel"
 
+function call_bazel() {
+  tools/bazel --output_base="$BAZEL_OUTPUT_DIR" $@
+}
+
 function cleanup {
   # call bazel clean because some bazel outputs don't have w bits.
   call_bazel clean
@@ -54,9 +58,6 @@
 ######################
 build/soong/soong_ui.bash --make-mode BP2BUILD_VERBOSE=1 --skip-soong-tests bp2build
 
-function call_bazel() {
-  tools/bazel --output_base="$BAZEL_OUTPUT_DIR" $@
-}
 BAZEL_OUT="$(call_bazel info output_path)"
 
 call_bazel build --config=bp2build --config=ci --config=android_arm \
diff --git a/tests/lib.sh b/tests/lib.sh
index 643b46a..6210e77 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -93,7 +93,6 @@
   symlink_directory external/go-cmp
   symlink_directory external/golang-protobuf
   symlink_directory external/starlark-go
-  symlink_directory system/tools/aidl
 
   touch "$MOCK_TOP/Android.bp"
 }
diff --git a/ui/build/build.go b/ui/build/build.go
index f7a2d7b..c61baa1 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -110,6 +110,24 @@
 	RunAllWithBazel = RunProductConfig | RunSoong | RunKati | RunKatiNinja | RunBazel
 )
 
+// checkBazelMode fails the build if there are conflicting arguments for which bazel
+// build mode to use.
+func checkBazelMode(ctx Context, config Config) {
+	// TODO(cparsons): Remove USE_BAZEL_ANALYSIS handling.
+	if config.Environment().IsEnvTrue("USE_BAZEL_ANALYSIS") {
+		if config.bazelProdMode || config.bazelDevMode {
+			ctx.Fatalf("USE_BAZEL_ANALYSIS is deprecated.\n" +
+				"Unset USE_BAZEL_ANALYSIS when using --bazel-mode or --bazel-mode-dev.")
+		} else {
+			config.bazelDevMode = true
+		}
+	}
+	if config.bazelProdMode && config.bazelDevMode {
+		ctx.Fatalf("Conflicting bazel mode.\n" +
+			"Do not specify both --bazel-mode and --bazel-mode-dev")
+	}
+}
+
 // checkProblematicFiles fails the build if existing Android.mk or CleanSpec.mk files are found at the root of the tree.
 func checkProblematicFiles(ctx Context) {
 	files := []string{"Android.mk", "CleanSpec.mk"}
@@ -221,6 +239,8 @@
 
 	defer waitForDist(ctx)
 
+	checkBazelMode(ctx, config)
+
 	// checkProblematicFiles aborts the build if Android.mk or CleanSpec.mk are found at the root of the tree.
 	checkProblematicFiles(ctx)
 
diff --git a/ui/build/config.go b/ui/build/config.go
index e140867..590aeb9 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -99,7 +99,10 @@
 
 	pathReplaced bool
 
-	useBazel bool
+	// TODO(b/243077098): Remove useBazel.
+	useBazel      bool
+	bazelProdMode bool
+	bazelDevMode  bool
 
 	// During Bazel execution, Bazel cannot write outside OUT_DIR.
 	// So if DIST_DIR is set to an external dir (outside of OUT_DIR), we need to rig it temporarily and then migrate files at the end of the build.
@@ -130,18 +133,6 @@
 	BUILD_MODULES
 )
 
-type bazelBuildMode int
-
-// Bazel-related build modes.
-const (
-	// Don't use bazel at all.
-	noBazel bazelBuildMode = iota
-
-	// Generate synthetic build files and incorporate these files into a build which
-	// partially uses Bazel. Build metadata may come from Android.bp or BUILD files.
-	mixedBuild
-)
-
 // checkTopDir validates that the current directory is at the root directory of the source tree.
 func checkTopDir(ctx Context) {
 	if _, err := os.Stat(srcDirFileCheck); err != nil {
@@ -496,7 +487,7 @@
 		UseGoma:         proto.Bool(config.UseGoma()),
 		UseRbe:          proto.Bool(config.UseRBE()),
 		BazelAsNinja:    proto.Bool(config.UseBazel()),
-		BazelMixedBuild: proto.Bool(config.bazelBuildMode() == mixedBuild),
+		BazelMixedBuild: proto.Bool(config.BazelBuildEnabled()),
 	}
 	c.Targets = append(c.Targets, config.arguments...)
 
@@ -747,6 +738,10 @@
 			c.skipSoongTests = true
 		} else if arg == "--mk-metrics" {
 			c.reportMkMetrics = true
+		} else if arg == "--bazel-mode" {
+			c.bazelProdMode = true
+		} else if arg == "--bazel-mode-dev" {
+			c.bazelDevMode = true
 		} else if len(arg) > 0 && arg[0] == '-' {
 			parseArgNum := func(def int) int {
 				if len(arg) > 2 {
@@ -1134,16 +1129,13 @@
 	return false
 }
 
+// TODO(b/243077098): Remove UseBazel.
 func (c *configImpl) UseBazel() bool {
 	return c.useBazel
 }
 
-func (c *configImpl) bazelBuildMode() bazelBuildMode {
-	if c.Environment().IsEnvTrue("USE_BAZEL_ANALYSIS") {
-		return mixedBuild
-	} else {
-		return noBazel
-	}
+func (c *configImpl) BazelBuildEnabled() bool {
+	return c.bazelProdMode || c.bazelDevMode
 }
 
 func (c *configImpl) StartRBE() bool {
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index e293275..63716b0 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -28,6 +28,7 @@
 	"android/soong/ui/logger"
 	smpb "android/soong/ui/metrics/metrics_proto"
 	"android/soong/ui/status"
+	"google.golang.org/protobuf/encoding/prototext"
 
 	"google.golang.org/protobuf/proto"
 )
@@ -1005,6 +1006,8 @@
 		environ             Environment
 		arguments           []string
 		useBazel            bool
+		bazelDevMode        bool
+		bazelProdMode       bool
 		expectedBuildConfig *smpb.BuildConfig
 	}{
 		{
@@ -1064,7 +1067,7 @@
 			},
 		},
 		{
-			name:    "bazel mixed build",
+			name:    "bazel mixed build from env",
 			environ: Environment{"USE_BAZEL_ANALYSIS=1"},
 			expectedBuildConfig: &smpb.BuildConfig{
 				ForceUseGoma:    proto.Bool(false),
@@ -1075,6 +1078,30 @@
 			},
 		},
 		{
+			name:         "bazel mixed build from dev mode",
+			environ:      Environment{},
+			bazelDevMode: true,
+			expectedBuildConfig: &smpb.BuildConfig{
+				ForceUseGoma:    proto.Bool(false),
+				UseGoma:         proto.Bool(false),
+				UseRbe:          proto.Bool(false),
+				BazelAsNinja:    proto.Bool(false),
+				BazelMixedBuild: proto.Bool(true),
+			},
+		},
+		{
+			name:          "bazel mixed build from prod mode",
+			environ:       Environment{},
+			bazelProdMode: true,
+			expectedBuildConfig: &smpb.BuildConfig{
+				ForceUseGoma:    proto.Bool(false),
+				UseGoma:         proto.Bool(false),
+				UseRbe:          proto.Bool(false),
+				BazelAsNinja:    proto.Bool(false),
+				BazelMixedBuild: proto.Bool(true),
+			},
+		},
+		{
 			name:      "specified targets",
 			environ:   Environment{},
 			useBazel:  true,
@@ -1094,9 +1121,9 @@
 				"FORCE_USE_GOMA=1",
 				"USE_GOMA=1",
 				"USE_RBE=1",
-				"USE_BAZEL_ANALYSIS=1",
 			},
-			useBazel: true,
+			useBazel:     true,
+			bazelDevMode: true,
 			expectedBuildConfig: &smpb.BuildConfig{
 				ForceUseGoma:    proto.Bool(true),
 				UseGoma:         proto.Bool(true),
@@ -1107,17 +1134,23 @@
 		},
 	}
 
+	ctx := testContext()
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
 			c := &configImpl{
-				environ:   &tc.environ,
-				useBazel:  tc.useBazel,
-				arguments: tc.arguments,
+				environ:       &tc.environ,
+				useBazel:      tc.useBazel,
+				bazelDevMode:  tc.bazelDevMode,
+				bazelProdMode: tc.bazelProdMode,
+				arguments:     tc.arguments,
 			}
 			config := Config{c}
+			checkBazelMode(ctx, config)
 			actualBuildConfig := buildConfig(config)
 			if expected := tc.expectedBuildConfig; !proto.Equal(expected, actualBuildConfig) {
-				t.Errorf("Expected build config != actual build config: %#v != %#v", *expected, *actualBuildConfig)
+				t.Errorf("Build config mismatch.\n"+
+					"Expected build config: %#v\n"+
+					"Actual build config: %#v", prototext.Format(expected), prototext.Format(actualBuildConfig))
 			}
 		})
 	}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 73678e4..ff6d68f 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -253,6 +253,12 @@
 	if config.EmptyNinjaFile() {
 		mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--empty-ninja-file")
 	}
+	if config.bazelProdMode {
+		mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--bazel-mode")
+	}
+	if config.bazelDevMode {
+		mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--bazel-mode-dev")
+	}
 
 	mainSoongBuildInvocation := primaryBuilderInvocation(
 		config,
@@ -262,7 +268,7 @@
 		fmt.Sprintf("analyzing Android.bp files and generating ninja file at %s", config.SoongNinjaFile()),
 	)
 
-	if config.bazelBuildMode() == mixedBuild {
+	if config.BazelBuildEnabled() {
 		// Mixed builds call Bazel from soong_build and they therefore need the
 		// Bazel workspace to be available. Make that so by adding a dependency on
 		// the bp2build marker file to the action that invokes soong_build .
@@ -372,9 +378,6 @@
 	// unused variables were changed?
 	envFile := filepath.Join(config.SoongOutDir(), availableEnvFile)
 
-	buildMode := config.bazelBuildMode()
-	integratedBp2Build := buildMode == mixedBuild
-
 	// This is done unconditionally, but does not take a measurable amount of time
 	bootstrapBlueprint(ctx, config)
 
@@ -404,7 +407,7 @@
 
 		checkEnvironmentFile(soongBuildEnv, config.UsedEnvFile(soongBuildTag))
 
-		if integratedBp2Build || config.Bp2Build() {
+		if config.BazelBuildEnabled() || config.Bp2Build() {
 			checkEnvironmentFile(soongBuildEnv, config.UsedEnvFile(bp2buildTag))
 		}