Merge "Add bazel metrics proto."
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 07db3c2..63fe462 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -185,6 +185,8 @@
 		"frameworks/av/media/codec2/components/aom":          Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/media/codecs":                         Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/media/liberror":                       Bp2BuildDefaultTrueRecursively,
+		"frameworks/av/media/libshmem":                       Bp2BuildDefaultTrueRecursively,
+		"frameworks/av/media/audioaidlconversion":            Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/media/module/minijail":                Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/services/minijail":                    Bp2BuildDefaultTrueRecursively,
 		"frameworks/base/libs/androidfw":                     Bp2BuildDefaultTrue,
@@ -205,6 +207,7 @@
 		"frameworks/native/opengl/tests/testLatency":         Bp2BuildDefaultTrue,
 		"frameworks/native/opengl/tests/testPauseResume":     Bp2BuildDefaultTrue,
 		"frameworks/native/opengl/tests/testViewport":        Bp2BuildDefaultTrue,
+		"frameworks/native/libs/permission":                  Bp2BuildDefaultTrue,
 		"frameworks/native/services/batteryservice":          Bp2BuildDefaultTrue,
 		"frameworks/proto_logging/stats":                     Bp2BuildDefaultTrueRecursively,
 
@@ -305,6 +308,7 @@
 		"system/core/property_service/libpropertyinfoparser":     Bp2BuildDefaultTrueRecursively,
 		"system/core/property_service/libpropertyinfoserializer": Bp2BuildDefaultTrueRecursively,
 		"system/extras/toolchain-extras":                         Bp2BuildDefaultTrue,
+		"system/hardware/interfaces/media":                       Bp2BuildDefaultTrueRecursively,
 		"system/incremental_delivery/incfs":                      Bp2BuildDefaultTrue,
 		"system/libartpalette":                                   Bp2BuildDefaultTrueRecursively,
 		"system/libbase":                                         Bp2BuildDefaultTrueRecursively,
@@ -1360,7 +1364,10 @@
 
 	// Bazel prod-mode allowlist. Modules in this list are built by Bazel
 	// in either prod mode or staging mode.
-	ProdMixedBuildsEnabledList = []string{"com.android.tzdata"}
+	ProdMixedBuildsEnabledList = []string{
+		"com.android.tzdata",
+		"test1_com.android.tzdata",
+	}
 
 	// Staging-mode allowlist. Modules in this list are only built
 	// by Bazel with --bazel-mode-staging. This list should contain modules
@@ -1369,5 +1376,6 @@
 	// also be built - do not add them to this list.
 	StagingMixedBuildsEnabledList = []string{
 		"com.android.adbd",
+		"adbd_test",
 	}
 )
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 0b768a7..d132d43 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -667,10 +667,12 @@
 
 mixed_build_root(name = "buildroot",
     deps = [%s],
+    testonly = True, # Unblocks testonly deps.
 )
 
 phony_root(name = "phonyroot",
     deps = [":buildroot"],
+    testonly = True, # Unblocks testonly deps.
 )
 `
 	configNodeFormatString := `
@@ -678,6 +680,7 @@
     arch = "%s",
     os = "%s",
     deps = [%s],
+    testonly = True, # Unblocks testonly deps.
 )
 `
 
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 3b159d3..1ecb0af 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -455,6 +455,9 @@
 func bp2buildModuleLabel(ctx BazelConversionContext, module blueprint.Module) string {
 	moduleName := ctx.OtherModuleName(module)
 	moduleDir := ctx.OtherModuleDir(module)
+	if moduleDir == Bp2BuildTopLevel {
+		moduleDir = ""
+	}
 	return fmt.Sprintf("//%s:%s", moduleDir, moduleName)
 }
 
diff --git a/android/module.go b/android/module.go
index bf9737a..681f724 100644
--- a/android/module.go
+++ b/android/module.go
@@ -27,6 +27,7 @@
 	"text/scanner"
 
 	"android/soong/bazel"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
diff --git a/android/override_module.go b/android/override_module.go
index 51e74d4..2d30a85 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -28,6 +28,7 @@
 // module based on it.
 
 import (
+	"fmt"
 	"sort"
 	"sync"
 
@@ -48,6 +49,10 @@
 	// i.e. cases where an overriding module, too, is overridden by a prebuilt module.
 	setOverriddenByPrebuilt(overridden bool)
 	getOverriddenByPrebuilt() bool
+
+	// Directory containing the Blueprint definition of the overriding module
+	setModuleDir(string)
+	ModuleDir() string
 }
 
 // Base module struct for override module types
@@ -57,6 +62,8 @@
 	overridingProperties []interface{}
 
 	overriddenByPrebuilt bool
+
+	moduleDir string
 }
 
 type OverrideModuleProperties struct {
@@ -66,6 +73,14 @@
 	// TODO(jungjw): Add an optional override_name bool flag.
 }
 
+func (o *OverrideModuleBase) setModuleDir(d string) {
+	o.moduleDir = d
+}
+
+func (o *OverrideModuleBase) ModuleDir() string {
+	return o.moduleDir
+}
+
 func (o *OverrideModuleBase) getOverridingProperties() []interface{} {
 	return o.overridingProperties
 }
@@ -108,6 +123,7 @@
 
 	override(ctx BaseModuleContext, o OverrideModule)
 	GetOverriddenBy() string
+	GetOverriddenByModuleDir() string
 
 	setOverridesProperty(overridesProperties *[]string)
 
@@ -117,7 +133,8 @@
 }
 
 type overridableModuleProperties struct {
-	OverriddenBy string `blueprint:"mutated"`
+	OverriddenBy          string `blueprint:"mutated"`
+	OverriddenByModuleDir string `blueprint:"mutated"`
 }
 
 // Base module struct for overridable module types
@@ -196,6 +213,7 @@
 		*b.overridesProperty = append(*b.overridesProperty, ctx.ModuleName())
 	}
 	b.overridableModuleProperties.OverriddenBy = o.Name()
+	b.overridableModuleProperties.OverriddenByModuleDir = o.ModuleDir()
 }
 
 // GetOverriddenBy returns the name of the override module that has overridden this module.
@@ -206,6 +224,10 @@
 	return b.overridableModuleProperties.OverriddenBy
 }
 
+func (b *OverridableModuleBase) GetOverriddenByModuleDir() string {
+	return b.overridableModuleProperties.OverriddenByModuleDir
+}
+
 func (b *OverridableModuleBase) OverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) {
 }
 
@@ -254,7 +276,9 @@
 		})
 		baseModule := ctx.AddDependency(ctx.Module(), overrideBaseDepTag, *module.getOverrideModuleProperties().Base)[0]
 		if o, ok := baseModule.(OverridableModule); ok {
-			o.addOverride(ctx.Module().(OverrideModule))
+			overrideModule := ctx.Module().(OverrideModule)
+			overrideModule.setModuleDir(ctx.ModuleDir())
+			o.addOverride(overrideModule)
 		}
 	}
 }
@@ -314,11 +338,35 @@
 // ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
 // variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
 // or if this variant is not overridden.
-func ModuleNameWithPossibleOverride(ctx ModuleContext) string {
+func ModuleNameWithPossibleOverride(ctx BazelConversionContext) string {
 	if overridable, ok := ctx.Module().(OverridableModule); ok {
 		if o := overridable.GetOverriddenBy(); o != "" {
 			return o
 		}
 	}
-	return ctx.ModuleName()
+	return ctx.OtherModuleName(ctx.Module())
+}
+
+// ModuleDirWithPossibleOverride returns the dir of the OverrideModule that overrides the current
+// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
+// or if this variant is not overridden.
+func moduleDirWithPossibleOverride(ctx BazelConversionContext) string {
+	if overridable, ok := ctx.Module().(OverridableModule); ok {
+		if o := overridable.GetOverriddenByModuleDir(); o != "" {
+			return o
+		}
+	}
+	return ctx.OtherModuleDir(ctx.Module())
+}
+
+// MaybeBp2buildLabelOfOverridingModule returns the bazel label of the
+// overriding module of an OverridableModule (e.g. override_apex label of a base
+// apex), or the module's label itself if not overridden.
+func MaybeBp2buildLabelOfOverridingModule(ctx BazelConversionContext) string {
+	moduleName := ModuleNameWithPossibleOverride(ctx)
+	moduleDir := moduleDirWithPossibleOverride(ctx)
+	if moduleDir == Bp2BuildTopLevel {
+		moduleDir = ""
+	}
+	return fmt.Sprintf("//%s:%s", moduleDir, moduleName)
 }
diff --git a/apex/apex.go b/apex/apex.go
index 36ce658..fcac3ab 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1875,6 +1875,17 @@
 	bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx))
 }
 
+// GetBazelLabel returns the bazel label of this apexBundle, or the label of the
+// override_apex module overriding this apexBundle. An apexBundle can be
+// overridden by different override_apex modules (e.g. Google or Go variants),
+// which is handled by the overrides mutators.
+func (a *apexBundle) GetBazelLabel(ctx android.BazelConversionPathContext, module blueprint.Module) string {
+	if _, ok := ctx.Module().(android.OverridableModule); ok {
+		return android.MaybeBp2buildLabelOfOverridingModule(ctx)
+	}
+	return a.BazelModuleBase.GetBazelLabel(ctx, a)
+}
+
 func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
 	if !a.commonBuildActions(ctx) {
 		return
diff --git a/apex/apex_test.go b/apex/apex_test.go
index c0bdfc4..499d753 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -29,7 +29,6 @@
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
-	"android/soong/bazel/cquery"
 	"android/soong/bpf"
 	"android/soong/cc"
 	"android/soong/dexpreopt"
@@ -9804,98 +9803,3 @@
 	libcCoreVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared").Module()
 	android.AssertBoolEquals(t, "core variant should link against source libc", true, hasDep(libfooCoreVariant, libcCoreVariant))
 }
-
-func TestApexImageInMixedBuilds(t *testing.T) {
-	bp := `
-apex_key{
-	name: "foo_key",
-}
-apex {
-	name: "foo",
-	key: "foo_key",
-	updatable: true,
-	min_sdk_version: "31",
-	file_contexts: ":myapex-file_contexts",
-	bazel_module: { label: "//:foo" },
-}`
-
-	outputBaseDir := "out/bazel"
-	result := android.GroupFixturePreparers(
-		prepareForApexTest,
-		android.FixtureModifyConfig(func(config android.Config) {
-			config.BazelContext = android.MockBazelContext{
-				OutputBaseDir: outputBaseDir,
-				LabelToApexInfo: map[string]cquery.ApexInfo{
-					"//:foo": cquery.ApexInfo{
-						SignedOutput:          "signed_out.apex",
-						UnsignedOutput:        "unsigned_out.apex",
-						BundleKeyInfo:         []string{"public_key", "private_key"},
-						ContainerKeyInfo:      []string{"container_cert", "container_private"},
-						SymbolsUsedByApex:     "foo_using.txt",
-						JavaSymbolsUsedByApex: "foo_using.xml",
-						BundleFile:            "apex_bundle.zip",
-						InstalledFiles:        "installed-files.txt",
-						RequiresLibs:          []string{"//path/c:c", "//path/d:d"},
-
-						// unused
-						PackageName:  "pkg_name",
-						ProvidesLibs: []string{"a", "b"},
-					},
-				},
-			}
-		}),
-	).RunTestWithBp(t, bp)
-
-	m := result.ModuleForTests("foo", "android_common_foo_image").Module()
-	ab, ok := m.(*apexBundle)
-	if !ok {
-		t.Fatalf("Expected module to be an apexBundle, was not")
-	}
-
-	if w, g := "out/bazel/execroot/__main__/public_key", ab.publicKeyFile.String(); w != g {
-		t.Errorf("Expected public key %q, got %q", w, g)
-	}
-
-	if w, g := "out/bazel/execroot/__main__/private_key", ab.privateKeyFile.String(); w != g {
-		t.Errorf("Expected private key %q, got %q", w, g)
-	}
-
-	if w, g := "out/bazel/execroot/__main__/container_cert", ab.containerCertificateFile.String(); w != g {
-		t.Errorf("Expected public container key %q, got %q", w, g)
-	}
-
-	if w, g := "out/bazel/execroot/__main__/container_private", ab.containerPrivateKeyFile.String(); w != g {
-		t.Errorf("Expected private container key %q, got %q", w, g)
-	}
-
-	if w, g := "out/bazel/execroot/__main__/signed_out.apex", ab.outputFile.String(); w != g {
-		t.Errorf("Expected output file %q, got %q", w, g)
-	}
-
-	if w, g := "out/bazel/execroot/__main__/foo_using.txt", ab.nativeApisUsedByModuleFile.String(); w != g {
-		t.Errorf("Expected output file %q, got %q", w, g)
-	}
-
-	if w, g := "out/bazel/execroot/__main__/foo_using.xml", ab.javaApisUsedByModuleFile.String(); w != g {
-		t.Errorf("Expected output file %q, got %q", w, g)
-	}
-
-	if w, g := "out/bazel/execroot/__main__/installed-files.txt", ab.installedFilesFile.String(); w != g {
-		t.Errorf("Expected installed-files.txt %q, got %q", w, g)
-	}
-
-	mkData := android.AndroidMkDataForTest(t, result.TestContext, m)
-	var builder strings.Builder
-	mkData.Custom(&builder, "foo", "BAZEL_TARGET_", "", mkData)
-
-	data := builder.String()
-	if w := "ALL_MODULES.$(my_register_name).BUNDLE := out/bazel/execroot/__main__/apex_bundle.zip"; !strings.Contains(data, w) {
-		t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
-	}
-	if w := "$(call dist-for-goals,checkbuild,out/bazel/execroot/__main__/installed-files.txt:foo-installed-files.txt)"; !strings.Contains(data, w) {
-		t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
-	}
-	if w := "LOCAL_REQUIRED_MODULES := c d"; !strings.Contains(data, w) {
-		t.Errorf("Expected %q in androidmk data, but did not find it in %q", w, data)
-	}
-}
diff --git a/apex/bp2build_test.go b/apex/bp2build_test.go
new file mode 100644
index 0000000..58f30bd
--- /dev/null
+++ b/apex/bp2build_test.go
@@ -0,0 +1,238 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package apex
+
+import (
+	"android/soong/android"
+	"android/soong/bazel/cquery"
+	"strings"
+	"testing"
+)
+
+func TestApexImageInMixedBuilds(t *testing.T) {
+	bp := `
+apex_key{
+	name: "foo_key",
+}
+apex {
+	name: "foo",
+	key: "foo_key",
+	updatable: true,
+	min_sdk_version: "31",
+	file_contexts: ":myapex-file_contexts",
+	bazel_module: { label: "//:foo" },
+}`
+
+	outputBaseDir := "out/bazel"
+	result := android.GroupFixturePreparers(
+		prepareForApexTest,
+		android.FixtureModifyConfig(func(config android.Config) {
+			config.BazelContext = android.MockBazelContext{
+				OutputBaseDir: outputBaseDir,
+				LabelToApexInfo: map[string]cquery.ApexInfo{
+					"//:foo": cquery.ApexInfo{
+						SignedOutput:          "signed_out.apex",
+						UnsignedOutput:        "unsigned_out.apex",
+						BundleKeyInfo:         []string{"public_key", "private_key"},
+						ContainerKeyInfo:      []string{"container_cert", "container_private"},
+						SymbolsUsedByApex:     "foo_using.txt",
+						JavaSymbolsUsedByApex: "foo_using.xml",
+						BundleFile:            "apex_bundle.zip",
+						InstalledFiles:        "installed-files.txt",
+						RequiresLibs:          []string{"//path/c:c", "//path/d:d"},
+
+						// unused
+						PackageName:  "pkg_name",
+						ProvidesLibs: []string{"a", "b"},
+					},
+				},
+			}
+		}),
+	).RunTestWithBp(t, bp)
+
+	m := result.ModuleForTests("foo", "android_common_foo_image").Module()
+	ab, ok := m.(*apexBundle)
+	if !ok {
+		t.Fatalf("Expected module to be an apexBundle, was not")
+	}
+
+	if w, g := "out/bazel/execroot/__main__/public_key", ab.publicKeyFile.String(); w != g {
+		t.Errorf("Expected public key %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/private_key", ab.privateKeyFile.String(); w != g {
+		t.Errorf("Expected private key %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/container_cert", ab.containerCertificateFile.String(); w != g {
+		t.Errorf("Expected public container key %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/container_private", ab.containerPrivateKeyFile.String(); w != g {
+		t.Errorf("Expected private container key %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/signed_out.apex", ab.outputFile.String(); w != g {
+		t.Errorf("Expected output file %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/foo_using.txt", ab.nativeApisUsedByModuleFile.String(); w != g {
+		t.Errorf("Expected output file %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/foo_using.xml", ab.javaApisUsedByModuleFile.String(); w != g {
+		t.Errorf("Expected output file %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/installed-files.txt", ab.installedFilesFile.String(); w != g {
+		t.Errorf("Expected installed-files.txt %q, got %q", w, g)
+	}
+
+	mkData := android.AndroidMkDataForTest(t, result.TestContext, m)
+	var builder strings.Builder
+	mkData.Custom(&builder, "foo", "BAZEL_TARGET_", "", mkData)
+
+	data := builder.String()
+	if w := "ALL_MODULES.$(my_register_name).BUNDLE := out/bazel/execroot/__main__/apex_bundle.zip"; !strings.Contains(data, w) {
+		t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
+	}
+	if w := "$(call dist-for-goals,checkbuild,out/bazel/execroot/__main__/installed-files.txt:foo-installed-files.txt)"; !strings.Contains(data, w) {
+		t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
+	}
+	if w := "LOCAL_REQUIRED_MODULES := c d"; !strings.Contains(data, w) {
+		t.Errorf("Expected %q in androidmk data, but did not find it in %q", w, data)
+	}
+}
+
+func TestOverrideApexImageInMixedBuilds(t *testing.T) {
+	bp := `
+apex_key{
+	name: "foo_key",
+}
+apex_key{
+	name: "override_foo_key",
+}
+apex {
+	name: "foo",
+	key: "foo_key",
+	updatable: true,
+	min_sdk_version: "31",
+	package_name: "pkg_name",
+	file_contexts: ":myapex-file_contexts",
+	bazel_module: { label: "//:foo" },
+}
+override_apex {
+	name: "override_foo",
+	key: "override_foo_key",
+	package_name: "override_pkg_name",
+	base: "foo",
+	bazel_module: { label: "//:override_foo" },
+}
+`
+
+	outputBaseDir := "out/bazel"
+	result := android.GroupFixturePreparers(
+		prepareForApexTest,
+		android.FixtureModifyConfig(func(config android.Config) {
+			config.BazelContext = android.MockBazelContext{
+				OutputBaseDir: outputBaseDir,
+				LabelToApexInfo: map[string]cquery.ApexInfo{
+					"//:foo": cquery.ApexInfo{
+						SignedOutput:          "signed_out.apex",
+						UnsignedOutput:        "unsigned_out.apex",
+						BundleKeyInfo:         []string{"public_key", "private_key"},
+						ContainerKeyInfo:      []string{"container_cert", "container_private"},
+						SymbolsUsedByApex:     "foo_using.txt",
+						JavaSymbolsUsedByApex: "foo_using.xml",
+						BundleFile:            "apex_bundle.zip",
+						InstalledFiles:        "installed-files.txt",
+						RequiresLibs:          []string{"//path/c:c", "//path/d:d"},
+
+						// unused
+						PackageName:  "pkg_name",
+						ProvidesLibs: []string{"a", "b"},
+					},
+					"//:override_foo": cquery.ApexInfo{
+						SignedOutput:          "override_signed_out.apex",
+						UnsignedOutput:        "override_unsigned_out.apex",
+						BundleKeyInfo:         []string{"override_public_key", "override_private_key"},
+						ContainerKeyInfo:      []string{"override_container_cert", "override_container_private"},
+						SymbolsUsedByApex:     "override_foo_using.txt",
+						JavaSymbolsUsedByApex: "override_foo_using.xml",
+						BundleFile:            "override_apex_bundle.zip",
+						InstalledFiles:        "override_installed-files.txt",
+						RequiresLibs:          []string{"//path/c:c", "//path/d:d"},
+
+						// unused
+						PackageName:  "override_pkg_name",
+						ProvidesLibs: []string{"a", "b"},
+					},
+				},
+			}
+		}),
+	).RunTestWithBp(t, bp)
+
+	m := result.ModuleForTests("foo", "android_common_override_foo_foo_image").Module()
+	ab, ok := m.(*apexBundle)
+	if !ok {
+		t.Fatalf("Expected module to be an apexBundle, was not")
+	}
+
+	if w, g := "out/bazel/execroot/__main__/override_public_key", ab.publicKeyFile.String(); w != g {
+		t.Errorf("Expected public key %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/override_private_key", ab.privateKeyFile.String(); w != g {
+		t.Errorf("Expected private key %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/override_container_cert", ab.containerCertificateFile.String(); w != g {
+		t.Errorf("Expected public container key %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/override_container_private", ab.containerPrivateKeyFile.String(); w != g {
+		t.Errorf("Expected private container key %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/override_signed_out.apex", ab.outputFile.String(); w != g {
+		t.Errorf("Expected output file %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/override_foo_using.txt", ab.nativeApisUsedByModuleFile.String(); w != g {
+		t.Errorf("Expected output file %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/override_foo_using.xml", ab.javaApisUsedByModuleFile.String(); w != g {
+		t.Errorf("Expected output file %q, got %q", w, g)
+	}
+
+	if w, g := "out/bazel/execroot/__main__/override_installed-files.txt", ab.installedFilesFile.String(); w != g {
+		t.Errorf("Expected installed-files.txt %q, got %q", w, g)
+	}
+
+	mkData := android.AndroidMkDataForTest(t, result.TestContext, m)
+	var builder strings.Builder
+	mkData.Custom(&builder, "override_foo", "BAZEL_TARGET_", "", mkData)
+
+	data := builder.String()
+	if w := "ALL_MODULES.$(my_register_name).BUNDLE := out/bazel/execroot/__main__/override_apex_bundle.zip"; !strings.Contains(data, w) {
+		t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
+	}
+	if w := "$(call dist-for-goals,checkbuild,out/bazel/execroot/__main__/override_installed-files.txt:override_foo-installed-files.txt)"; !strings.Contains(data, w) {
+		t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
+	}
+	if w := "LOCAL_REQUIRED_MODULES := c d"; !strings.Contains(data, w) {
+		t.Errorf("Expected %q in androidmk data, but did not find it in %q", w, data)
+	}
+}
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index 9feb82b..7c9ae3b 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -11,7 +11,7 @@
 	GetPythonBinary     = &getPythonBinaryRequestType{}
 	GetCcInfo           = &getCcInfoType{}
 	GetApexInfo         = &getApexInfoType{}
-	GetCcUnstrippedInfo = &getCcUnstippedInfoType{}
+	GetCcUnstrippedInfo = &getCcUnstrippedInfoType{}
 )
 
 type CcInfo struct {
@@ -275,13 +275,13 @@
 // getCcUnstrippedInfoType implements cqueryRequest interface. It handles the
 // interaction with `bazel cquery` to retrieve CcUnstrippedInfo provided
 // by the` cc_binary` and `cc_shared_library` rules.
-type getCcUnstippedInfoType struct{}
+type getCcUnstrippedInfoType struct{}
 
-func (g getCcUnstippedInfoType) Name() string {
+func (g getCcUnstrippedInfoType) Name() string {
 	return "getCcUnstrippedInfo"
 }
 
-func (g getCcUnstippedInfoType) StarlarkFunctionBody() string {
+func (g getCcUnstrippedInfoType) StarlarkFunctionBody() string {
 	return `unstripped_tag = "//build/bazel/rules/cc:stripped_cc_common.bzl%CcUnstrippedInfo"
 p = providers(target)
 output_path = target.files.to_list()[0].path
@@ -298,7 +298,7 @@
 // ParseResult returns a value obtained by parsing the result of the request's Starlark function.
 // The given rawString must correspond to the string output which was created by evaluating the
 // Starlark given in StarlarkFunctionBody.
-func (g getCcUnstippedInfoType) ParseResult(rawString string) (CcUnstrippedInfo, error) {
+func (g getCcUnstrippedInfoType) ParseResult(rawString string) (CcUnstrippedInfo, error) {
 	var info CcUnstrippedInfo
 	err := parseJson(rawString, &info)
 	return info, err
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index ee6e5b8..728225a 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -1031,19 +1031,20 @@
 		"features": `[
         "disable_pack_relocations",
         "-no_undefined_symbols",
-        "-coverage",
     ]`,
-		"srcs": `["a.cpp"]`,
+		"native_coverage": `False`,
+		"srcs":            `["a.cpp"]`,
 	})...)
 	expected_targets = append(expected_targets, makeCcLibraryTargets("b", AttrNameToString{
-		"features": `["-coverage"] + select({
+		"features": `select({
         "//build/bazel/platforms/arch:x86_64": [
             "disable_pack_relocations",
             "-no_undefined_symbols",
         ],
         "//conditions:default": [],
     })`,
-		"srcs": `["b.cpp"]`,
+		"native_coverage": `False`,
+		"srcs":            `["b.cpp"]`,
 	})...)
 	expected_targets = append(expected_targets, makeCcLibraryTargets("c", AttrNameToString{
 		"features": `select({
diff --git a/cc/afdo_test.go b/cc/afdo_test.go
index f5d27ff..335910c 100644
--- a/cc/afdo_test.go
+++ b/cc/afdo_test.go
@@ -38,6 +38,7 @@
 }
 
 func TestAfdoDeps(t *testing.T) {
+	t.Parallel()
 	bp := `
 	cc_library_shared {
 		name: "libTest",
@@ -93,6 +94,7 @@
 }
 
 func TestAfdoEnabledOnStaticDepNoAfdo(t *testing.T) {
+	t.Parallel()
 	bp := `
 	cc_library_shared {
 		name: "libTest",
diff --git a/cc/binary.go b/cc/binary.go
index 998934e..54c1abc 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -644,6 +644,8 @@
 		Features: baseAttrs.features,
 
 		sdkAttributes: bp2BuildParseSdkAttributes(m),
+
+		Native_coverage: baseAttrs.Native_coverage,
 	}
 
 	m.convertTidyAttributes(ctx, &attrs.tidyAttributes)
@@ -703,4 +705,6 @@
 	sdkAttributes
 
 	tidyAttributes
+
+	Native_coverage *bool
 }
diff --git a/cc/binary_test.go b/cc/binary_test.go
index db6fb3a..43aff5c 100644
--- a/cc/binary_test.go
+++ b/cc/binary_test.go
@@ -22,6 +22,7 @@
 )
 
 func TestCcBinaryWithBazel(t *testing.T) {
+	t.Parallel()
 	bp := `
 cc_binary {
 	name: "foo",
@@ -55,6 +56,7 @@
 }
 
 func TestBinaryLinkerScripts(t *testing.T) {
+	t.Parallel()
 	result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
 		cc_binary {
 			name: "foo",
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 510ecee..66157ae 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -63,7 +63,7 @@
 
 	Enabled bazel.BoolAttribute
 
-	Native_coverage bazel.BoolAttribute
+	Native_coverage *bool
 
 	sdkAttributes
 
@@ -358,6 +358,7 @@
 	features        bazel.StringListAttribute
 	protoDependency *bazel.LabelAttribute
 	aidlDependency  *bazel.LabelAttribute
+	Native_coverage *bool
 }
 
 // Convenience struct to hold all attributes parsed from compiler properties.
@@ -753,10 +754,10 @@
 	compilerAttrs.convertStlProps(ctx, module)
 	(&linkerAttrs).convertStripProps(ctx, module)
 
+	var nativeCoverage *bool
 	if module.coverage != nil && module.coverage.Properties.Native_coverage != nil &&
 		!Bool(module.coverage.Properties.Native_coverage) {
-		// Native_coverage is arch neutral
-		(&linkerAttrs).features.Append(bazel.MakeStringListAttribute([]string{"-coverage"}))
+		nativeCoverage = BoolPtr(false)
 	}
 
 	productVariableProps := android.ProductVariableProperties(ctx)
@@ -812,6 +813,7 @@
 		*features,
 		protoDep.protoDep,
 		aidlDep,
+		nativeCoverage,
 	}
 }
 
diff --git a/cc/cc.go b/cc/cc.go
index 632bdca..6ca2575 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1858,7 +1858,22 @@
 	c.bazelHandler.QueueBazelCall(ctx, c.getBazelModuleLabel(ctx))
 }
 
+var (
+	mixedBuildSupportedCcTest = []string{
+		"adbd_test",
+	}
+)
+
+// IsMixedBuildSupported returns true if the module should be analyzed by Bazel
+// in any of the --bazel-mode(s). This filters at the module level and takes
+// precedence over the allowlists in allowlists/allowlists.go.
 func (c *Module) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
+	if c.testBinary() && !android.InList(c.Name(), mixedBuildSupportedCcTest) {
+		// Per-module rollout of mixed-builds for cc_test modules.
+		return false
+	}
+
+	// Enable mixed builds as long as the cc_* module type has a bazel handler.
 	return c.bazelHandler != nil
 }
 
@@ -1888,6 +1903,8 @@
 	}
 	mctx.ctx = mctx
 
+	// TODO(b/244432500): Get the tradefed config from the bazel target instead
+	// of generating it with Soong.
 	c.maybeInstall(mctx, apexInfo)
 }
 
@@ -2038,6 +2055,9 @@
 	}
 }
 
+// maybeInstall is called at the end of both GenerateAndroidBuildActions and
+// ProcessBazelQueryResponse to run the install hooks for installable modules,
+// like binaries and tests.
 func (c *Module) maybeInstall(ctx ModuleContext, apexInfo android.ApexInfo) {
 	if !proptools.BoolDefault(c.Installable(), true) {
 		// If the module has been specifically configure to not be installed then
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 6a22bd0..6dfd395 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -154,6 +154,7 @@
 }
 
 func TestVendorSrc(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library {
 			name: "libTest",
@@ -220,6 +221,7 @@
 }
 
 func TestInstallPartition(t *testing.T) {
+	t.Parallel()
 	t.Helper()
 	ctx := prepareForCcTest.RunTestWithBp(t, `
 		cc_library {
@@ -352,6 +354,7 @@
 }
 
 func TestVndk(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libvndk",
@@ -569,6 +572,7 @@
 }
 
 func TestVndkWithHostSupported(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library {
 			name: "libvndk_host_supported",
@@ -605,6 +609,7 @@
 }
 
 func TestVndkLibrariesTxtAndroidMk(t *testing.T) {
+	t.Parallel()
 	bp := `
 		llndk_libraries_txt {
 			name: "llndk.libraries.txt",
@@ -621,6 +626,7 @@
 }
 
 func TestVndkUsingCoreVariant(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libvndk",
@@ -673,6 +679,7 @@
 }
 
 func TestDataLibs(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_test_library {
 			name: "test_lib",
@@ -723,6 +730,7 @@
 }
 
 func TestDataLibsRelativeInstallPath(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_test_library {
 			name: "test_lib",
@@ -781,6 +789,7 @@
 }
 
 func TestTestBinaryTestSuites(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_test {
 			name: "main_test",
@@ -812,6 +821,7 @@
 }
 
 func TestTestLibraryTestSuites(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_test_library {
 			name: "main_test_lib",
@@ -843,6 +853,7 @@
 }
 
 func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
+	t.Parallel()
 	ctx := testCcNoVndk(t, `
 		cc_library {
 			name: "libvndk",
@@ -899,6 +910,7 @@
 }
 
 func TestVndkModuleError(t *testing.T) {
+	t.Parallel()
 	// Check the error message for vendor_available and product_available properties.
 	testCcErrorProductVndk(t, "vndk: vendor_available must be set to true when `vndk: {enabled: true}`", `
 		cc_library {
@@ -940,6 +952,7 @@
 }
 
 func TestVndkDepError(t *testing.T) {
+	t.Parallel()
 	// Check whether an error is emitted when a VNDK lib depends on a system lib.
 	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
 		cc_library {
@@ -1131,6 +1144,7 @@
 }
 
 func TestDoubleLoadbleDep(t *testing.T) {
+	t.Parallel()
 	// okay to link : LLNDK -> double_loadable VNDK
 	testCc(t, `
 		cc_library {
@@ -1235,6 +1249,7 @@
 }
 
 func TestDoubleLoadableDepError(t *testing.T) {
+	t.Parallel()
 	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
 	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
 		cc_library {
@@ -1317,6 +1332,7 @@
 }
 
 func TestCheckVndkMembershipBeforeDoubleLoadable(t *testing.T) {
+	t.Parallel()
 	testCcError(t, "module \"libvndksp\" variant .*: .*: VNDK-SP must only depend on VNDK-SP", `
 		cc_library {
 			name: "libvndksp",
@@ -1342,6 +1358,7 @@
 }
 
 func TestVndkExt(t *testing.T) {
+	t.Parallel()
 	// This test checks the VNDK-Ext properties.
 	bp := `
 		cc_library {
@@ -1429,6 +1446,7 @@
 }
 
 func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
+	t.Parallel()
 	// This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
 	ctx := testCcNoVndk(t, `
 		cc_library {
@@ -1460,6 +1478,7 @@
 }
 
 func TestVndkExtWithoutProductVndkVersion(t *testing.T) {
+	t.Parallel()
 	// This test checks the VNDK-Ext properties when PRODUCT_PRODUCT_VNDK_VERSION is not set.
 	ctx := testCcNoProductVndk(t, `
 		cc_library {
@@ -1491,6 +1510,7 @@
 }
 
 func TestVndkExtError(t *testing.T) {
+	t.Parallel()
 	// This test ensures an error is emitted in ill-formed vndk-ext definition.
 	testCcError(t, "must set `vendor: true` or `product_specific: true` to set `extends: \".*\"`", `
 		cc_library {
@@ -1581,6 +1601,7 @@
 }
 
 func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
+	t.Parallel()
 	// This test ensures an error is emitted for inconsistent support_system_process.
 	testCcError(t, "module \".*\" with mismatched support_system_process", `
 		cc_library {
@@ -1630,6 +1651,7 @@
 }
 
 func TestVndkExtVendorAvailableFalseError(t *testing.T) {
+	t.Parallel()
 	// This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
 	// with `private: true`.
 	testCcError(t, "`extends` refers module \".*\" which has `private: true`", `
@@ -1680,6 +1702,7 @@
 }
 
 func TestVendorModuleUseVndkExt(t *testing.T) {
+	t.Parallel()
 	// This test ensures a vendor module can depend on a VNDK-Ext library.
 	testCc(t, `
 		cc_library {
@@ -1734,6 +1757,7 @@
 }
 
 func TestVndkExtUseVendorLib(t *testing.T) {
+	t.Parallel()
 	// This test ensures a VNDK-Ext library can depend on a vendor library.
 	testCc(t, `
 		cc_library {
@@ -1798,6 +1822,7 @@
 }
 
 func TestProductVndkExtDependency(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libvndk",
@@ -1865,6 +1890,7 @@
 }
 
 func TestVndkSpExtUseVndkError(t *testing.T) {
+	t.Parallel()
 	// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
 	// library.
 	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
@@ -1951,6 +1977,7 @@
 }
 
 func TestVndkUseVndkExtError(t *testing.T) {
+	t.Parallel()
 	// This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
 	// VNDK-Ext/VNDK-SP-Ext library.
 	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
@@ -2096,6 +2123,7 @@
 }
 
 func TestEnforceProductVndkVersion(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libllndk",
@@ -2221,6 +2249,7 @@
 }
 
 func TestEnforceProductVndkVersionErrors(t *testing.T) {
+	t.Parallel()
 	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
 		cc_library {
 			name: "libprod",
@@ -2318,6 +2347,7 @@
 }
 
 func TestMakeLinkType(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libvndk",
@@ -2609,6 +2639,7 @@
 }
 
 func TestStaticLibDepReordering(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 	cc_library {
 		name: "a",
@@ -2648,6 +2679,7 @@
 }
 
 func TestStaticLibDepReorderingWithShared(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 	cc_library {
 		name: "a",
@@ -2695,6 +2727,7 @@
 }
 
 func TestLlndkLibrary(t *testing.T) {
+	t.Parallel()
 	result := prepareForCcTest.RunTestWithBp(t, `
 	cc_library {
 		name: "libllndk",
@@ -2782,6 +2815,7 @@
 }
 
 func TestLlndkHeaders(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 	cc_library_headers {
 		name: "libllndk_headers",
@@ -2914,6 +2948,7 @@
 `
 
 func TestRuntimeLibs(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, runtimeLibAndroidBp)
 
 	// runtime_libs for core variants use the module names without suffixes.
@@ -2950,6 +2985,7 @@
 }
 
 func TestExcludeRuntimeLibs(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, runtimeLibAndroidBp)
 
 	variant := "android_arm64_armv8-a_shared"
@@ -2962,6 +2998,7 @@
 }
 
 func TestRuntimeLibsNoVndk(t *testing.T) {
+	t.Parallel()
 	ctx := testCcNoVndk(t, runtimeLibAndroidBp)
 
 	// If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
@@ -3002,6 +3039,7 @@
 `
 
 func TestStaticLibDepExport(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, staticLibAndroidBp)
 
 	// Check the shared version of lib2.
@@ -3089,6 +3127,7 @@
 }
 
 func TestCompilerFlags(t *testing.T) {
+	t.Parallel()
 	for _, testCase := range compilerFlagsTestCases {
 		ctx := &mockContext{result: true}
 		CheckBadCompilerFlags(ctx, "", []string{testCase.in})
@@ -3102,6 +3141,7 @@
 }
 
 func TestRecovery(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library_shared {
 			name: "librecovery",
@@ -3137,6 +3177,7 @@
 }
 
 func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_prebuilt_test_library_shared {
 			name: "test_lib",
@@ -3183,6 +3224,7 @@
 }
 
 func TestVersionedStubs(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library_shared {
 			name: "libFoo",
@@ -3249,6 +3291,7 @@
 }
 
 func TestVersioningMacro(t *testing.T) {
+	t.Parallel()
 	for _, tc := range []struct{ moduleName, expected string }{
 		{"libc", "__LIBC_API__"},
 		{"libfoo", "__LIBFOO_API__"},
@@ -3269,6 +3312,7 @@
 }
 
 func TestStaticLibArchiveArgs(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library_static {
 			name: "foo",
@@ -3309,6 +3353,7 @@
 }
 
 func TestSharedLibLinkingArgs(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library_static {
 			name: "foo",
@@ -3357,6 +3402,7 @@
 }
 
 func TestStaticExecutable(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_binary {
 			name: "static_test",
@@ -3382,6 +3428,7 @@
 }
 
 func TestStaticDepsOrderWithStubs(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_binary {
 			name: "mybin",
@@ -3422,6 +3469,7 @@
 }
 
 func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
+	t.Parallel()
 	testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
 		cc_library {
 			name: "libA",
@@ -3549,10 +3597,12 @@
 }
 
 func TestAFLFuzzTargetForDevice(t *testing.T) {
+	t.Parallel()
 	VerifyAFLFuzzTargetVariant(t, "android_arm64_armv8-a")
 }
 
 func TestAFLFuzzTargetForLinuxHost(t *testing.T) {
+	t.Parallel()
 	if runtime.GOOS != "linux" {
 		t.Skip("requires linux")
 	}
@@ -3563,6 +3613,7 @@
 // Simple smoke test for the cc_fuzz target that ensures the rule compiles
 // correctly.
 func TestFuzzTarget(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_fuzz {
 			name: "fuzz_smoke_test",
@@ -3573,9 +3624,6 @@
 	ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
 }
 
-func TestAidl(t *testing.T) {
-}
-
 func assertString(t *testing.T, got, expected string) {
 	t.Helper()
 	if got != expected {
@@ -3604,6 +3652,7 @@
 }
 
 func TestDefaults(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_defaults {
 			name: "defaults",
@@ -3663,6 +3712,7 @@
 }
 
 func TestProductVariableDefaults(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_defaults {
 			name: "libfoo_defaults",
@@ -3724,6 +3774,7 @@
 }
 
 func TestInstallSharedLibs(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_binary {
 			name: "bin",
@@ -3819,6 +3870,7 @@
 }
 
 func TestStubsLibReexportsHeaders(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library_shared {
 			name: "libclient",
@@ -3851,6 +3903,7 @@
 }
 
 func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library {
 			name: "libfoo",
@@ -3869,6 +3922,7 @@
 }
 
 func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	for _, tc := range []struct {
 		name       string
 		sdkVersion string
@@ -3921,6 +3975,7 @@
 }
 
 func TestMinSdkVersionInClangTriple(t *testing.T) {
+	t.Parallel()
 	ctx := testCc(t, `
 		cc_library_shared {
 			name: "libfoo",
@@ -3933,6 +3988,7 @@
 }
 
 func TestNonDigitMinSdkVersionInClangTriple(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library_shared {
 			name: "libfoo",
@@ -3952,6 +4008,7 @@
 }
 
 func TestIncludeDirsExporting(t *testing.T) {
+	t.Parallel()
 
 	// Trim spaces from the beginning, end and immediately after any newline characters. Leaves
 	// embedded newline characters alone.
@@ -4223,6 +4280,7 @@
 }
 
 func TestIncludeDirectoryOrdering(t *testing.T) {
+	t.Parallel()
 	baseExpectedFlags := []string{
 		"${config.ArmThumbCflags}",
 		"${config.ArmCflags}",
@@ -4426,6 +4484,7 @@
 }
 
 func TestCcBuildBrokenClangProperty(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name                     string
 		clang                    bool
@@ -4476,6 +4535,7 @@
 }
 
 func TestCcBuildBrokenClangAsFlags(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name                    string
 		clangAsFlags            []string
@@ -4521,6 +4581,7 @@
 }
 
 func TestCcBuildBrokenClangCFlags(t *testing.T) {
+	t.Parallel()
 	tests := []struct {
 		name                   string
 		clangCFlags            []string
diff --git a/cc/library.go b/cc/library.go
index ed0ed01..8afc2fe 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -351,6 +351,7 @@
 		System_dynamic_deps:               *linkerAttrs.systemDynamicDeps.Clone().Append(staticAttrs.System_dynamic_deps),
 		Runtime_deps:                      linkerAttrs.runtimeDeps,
 		sdkAttributes:                     bp2BuildParseSdkAttributes(m),
+		Native_coverage:                   baseAttributes.Native_coverage,
 	}
 
 	sharedCommonAttrs := staticOrSharedAttributes{
@@ -369,6 +370,7 @@
 		System_dynamic_deps:               *linkerAttrs.systemDynamicDeps.Clone().Append(sharedAttrs.System_dynamic_deps),
 		Runtime_deps:                      linkerAttrs.runtimeDeps,
 		sdkAttributes:                     bp2BuildParseSdkAttributes(m),
+		Native_coverage:                   baseAttributes.Native_coverage,
 	}
 
 	staticTargetAttrs := &bazelCcLibraryStaticAttributes{
@@ -2869,6 +2871,7 @@
 		System_dynamic_deps:               linkerAttrs.systemDynamicDeps,
 		sdkAttributes:                     bp2BuildParseSdkAttributes(module),
 		Runtime_deps:                      linkerAttrs.runtimeDeps,
+		Native_coverage:                   baseAttributes.Native_coverage,
 	}
 
 	module.convertTidyAttributes(ctx, &commonAttrs.tidyAttributes)
@@ -2956,6 +2959,13 @@
 	}
 
 	tags := android.ApexAvailableTags(module)
+
+	// This lib needs some special handling in bazel, so add this tag to the build
+	// file.
+	if module.Name() == "libprofile-clang-extras" {
+		tags.Append(bazel.MakeStringListAttribute([]string{"NO_EXPORTING"}))
+	}
+
 	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name(), Tags: tags}, attrs)
 }
 
diff --git a/cc/library_headers_test.go b/cc/library_headers_test.go
index 3e448ba..1924b2f 100644
--- a/cc/library_headers_test.go
+++ b/cc/library_headers_test.go
@@ -59,6 +59,7 @@
 }
 
 func TestPrebuiltLibraryHeadersPreferred(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library_headers {
 			name: "headers",
diff --git a/cc/library_test.go b/cc/library_test.go
index 2bc9967..dab5bb8 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -23,6 +23,7 @@
 )
 
 func TestLibraryReuse(t *testing.T) {
+	t.Parallel()
 	t.Run("simple", func(t *testing.T) {
 		ctx := testCc(t, `
 		cc_library {
@@ -191,6 +192,7 @@
 }
 
 func TestStubsVersions(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libfoo",
@@ -214,6 +216,7 @@
 }
 
 func TestStubsVersions_NotSorted(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libfoo",
@@ -229,6 +232,7 @@
 }
 
 func TestStubsVersions_ParseError(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_library {
 			name: "libfoo",
@@ -243,6 +247,7 @@
 }
 
 func TestCcLibraryWithBazel(t *testing.T) {
+	t.Parallel()
 	bp := `
 cc_library {
 	name: "foo",
@@ -304,6 +309,7 @@
 }
 
 func TestLibraryVersionScript(t *testing.T) {
+	t.Parallel()
 	result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
 		cc_library {
 			name: "libfoo",
@@ -321,6 +327,7 @@
 }
 
 func TestLibraryDynamicList(t *testing.T) {
+	t.Parallel()
 	result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
 		cc_library {
 			name: "libfoo",
@@ -338,6 +345,7 @@
 }
 
 func TestCcLibrarySharedWithBazel(t *testing.T) {
+	t.Parallel()
 	bp := `
 cc_library_shared {
 	name: "foo",
@@ -383,6 +391,7 @@
 }
 
 func TestWholeStaticLibPrebuilts(t *testing.T) {
+	t.Parallel()
 	result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
 		cc_prebuilt_library_static {
 			name: "libprebuilt",
diff --git a/cc/lto_test.go b/cc/lto_test.go
index afd2c77..fbd91be 100644
--- a/cc/lto_test.go
+++ b/cc/lto_test.go
@@ -23,6 +23,7 @@
 )
 
 func TestThinLtoDeps(t *testing.T) {
+	t.Parallel()
 	bp := `
 	cc_library_shared {
 		name: "lto_enabled",
@@ -106,6 +107,7 @@
 }
 
 func TestThinLtoOnlyOnStaticDep(t *testing.T) {
+	t.Parallel()
 	bp := `
 	cc_library_shared {
 		name: "root",
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index 143602a..fe592dc 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -86,6 +86,7 @@
 }
 
 func TestAsan(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_binary {
 			name: "bin_with_asan",
@@ -233,6 +234,7 @@
 }
 
 func TestTsan(t *testing.T) {
+	t.Parallel()
 	bp := `
 	cc_binary {
 		name: "bin_with_tsan",
@@ -318,6 +320,7 @@
 		t.Skip("requires linux")
 	}
 
+	t.Parallel()
 	bp := `
 	cc_binary {
 		name: "bin_with_ubsan",
@@ -417,6 +420,7 @@
 }
 
 func TestFuzz(t *testing.T) {
+	t.Parallel()
 	bp := `
 		cc_binary {
 			name: "bin_with_fuzzer",
@@ -551,6 +555,7 @@
 }
 
 func TestUbsan(t *testing.T) {
+	t.Parallel()
 	if runtime.GOOS != "linux" {
 		t.Skip("requires linux")
 	}
@@ -829,6 +834,7 @@
 )
 
 func TestSanitizeMemtagHeap(t *testing.T) {
+	t.Parallel()
 	variant := "android_arm64_armv8-a"
 
 	result := android.GroupFixturePreparers(
@@ -901,6 +907,7 @@
 }
 
 func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) {
+	t.Parallel()
 	variant := "android_arm64_armv8-a"
 
 	result := android.GroupFixturePreparers(
@@ -975,6 +982,7 @@
 }
 
 func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) {
+	t.Parallel()
 	variant := "android_arm64_armv8-a"
 
 	result := android.GroupFixturePreparers(
diff --git a/cc/test.go b/cc/test.go
index dee6ed6..2a4861c 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -23,6 +23,7 @@
 
 	"android/soong/android"
 	"android/soong/bazel"
+	"android/soong/bazel/cquery"
 	"android/soong/tradefed"
 )
 
@@ -135,6 +136,7 @@
 // static_libs dependency on libgtests unless the gtest flag is set to false.
 func TestFactory() android.Module {
 	module := NewTest(android.HostAndDeviceSupported, true)
+	module.bazelHandler = &ccTestBazelHandler{module: module}
 	return module.Init()
 }
 
@@ -413,16 +415,8 @@
 	testInstallBase := getTestInstallBase(useVendor)
 	configs := getTradefedConfigOptions(ctx, &test.Properties, test.isolated(ctx))
 
-	test.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
-		SetTestConfigProp(test.Properties.Test_config).
-		SetTestTemplateConfigProp(test.Properties.Test_config_template).
-		SetTestSuites(test.testDecorator.InstallerProperties.Test_suites).
-		SetConfig(configs).
-		SetAutoGenConfig(test.Properties.Auto_gen_config).
-		SetTestInstallBase(testInstallBase).
-		SetDeviceTemplate("${NativeTestConfigTemplate}").
-		SetHostTemplate("${NativeHostTestConfigTemplate}").
-		Build()
+	test.testConfig = tradefed.AutoGenNativeTestConfig(ctx, test.Properties.Test_config,
+		test.Properties.Test_config_template, test.testDecorator.InstallerProperties.Test_suites, configs, test.Properties.Auto_gen_config, testInstallBase)
 
 	test.extraTestConfigs = android.PathsForModuleSrc(ctx, test.Properties.Test_options.Extra_test_configs)
 
@@ -500,6 +494,7 @@
 
 func NewTest(hod android.HostOrDeviceSupported, bazelable bool) *Module {
 	module, binary := newBinary(hod, bazelable)
+	module.bazelable = bazelable
 	module.multilib = android.MultilibBoth
 	binary.baseInstaller = NewTestInstaller()
 
@@ -635,15 +630,8 @@
 	if Bool(benchmark.Properties.Require_root) {
 		configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
 	}
-	benchmark.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
-		SetTestConfigProp(benchmark.Properties.Test_config).
-		SetTestTemplateConfigProp(benchmark.Properties.Test_config_template).
-		SetTestSuites(benchmark.Properties.Test_suites).
-		SetConfig(configs).
-		SetAutoGenConfig(benchmark.Properties.Auto_gen_config).
-		SetDeviceTemplate("${NativeBenchmarkTestConfigTemplate}").
-		SetHostTemplate("${NativeBenchmarkTestConfigTemplate}").
-		Build()
+	benchmark.testConfig = tradefed.AutoGenNativeBenchmarkTestConfig(ctx, benchmark.Properties.Test_config,
+		benchmark.Properties.Test_config_template, benchmark.Properties.Test_suites, configs, benchmark.Properties.Auto_gen_config)
 
 	benchmark.binaryDecorator.baseInstaller.dir = filepath.Join("benchmarktest", ctx.ModuleName())
 	benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName())
@@ -663,6 +651,30 @@
 	return module
 }
 
+type ccTestBazelHandler struct {
+	module *Module
+}
+
+var _ BazelHandler = (*ccTestBazelHandler)(nil)
+
+func (handler *ccTestBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
+	bazelCtx := ctx.Config().BazelContext
+	bazelCtx.QueueBazelRequest(label, cquery.GetCcUnstrippedInfo, android.GetConfigKey(ctx))
+}
+
+func (handler *ccTestBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
+	bazelCtx := ctx.Config().BazelContext
+	info, err := bazelCtx.GetCcUnstrippedInfo(label, android.GetConfigKey(ctx))
+	if err != nil {
+		ctx.ModuleErrorf(err.Error())
+		return
+	}
+
+	outputFilePath := android.PathForBazelOut(ctx, info.OutputFile)
+	handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
+	handler.module.linker.(*testBinary).unstrippedOutputFile = android.PathForBazelOut(ctx, info.UnstrippedOutput)
+}
+
 // binaryAttributes contains Bazel attributes corresponding to a cc test
 type testBinaryAttributes struct {
 	binaryAttributes
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 928ae17..713ccbe 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -110,6 +110,15 @@
 	return indexList(s, list) != -1
 }
 
+func deleteStaleMetrics(metricsFilePathSlice []string) error {
+	for _, metricsFilePath := range metricsFilePathSlice {
+		if err := os.Remove(metricsFilePath); err != nil && !os.IsNotExist(err) {
+			return fmt.Errorf("Failed to remove %s\nError message: %w", metricsFilePath, err)
+		}
+	}
+	return nil
+}
+
 // Main execution of soong_ui. The command format is as follows:
 //
 //	soong_ui <command> [<arg 1> <arg 2> ... <arg n>]
@@ -117,7 +126,6 @@
 // Command is the type of soong_ui execution. Only one type of
 // execution is specified. The args are specific to the command.
 func main() {
-	//TODO(juu): Add logic to soong_ui to delete a hardcoded list of metrics files
 	shared.ReexecWithDelveMaybe(os.Getenv("SOONG_UI_DELVE"), shared.ResolveDelveBinary())
 
 	buildStarted := time.Now()
@@ -187,6 +195,12 @@
 	bp2buildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"bp2build_metrics.pb")
 	soongBuildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_build_metrics.pb")
 
+	//Delete the stale metrics files
+	staleFileSlice := []string{buildErrorFile, rbeMetricsFile, soongMetricsFile, bp2buildMetricsFile, soongBuildMetricsFile}
+	if err := deleteStaleMetrics(staleFileSlice); err != nil {
+		log.Fatalln(err)
+	}
+
 	build.PrintOutDirWarning(buildCtx, config)
 
 	os.MkdirAll(logsDir, 0777)
diff --git a/java/aar.go b/java/aar.go
index 0fdde03..8a83792 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -29,8 +29,8 @@
 )
 
 type AndroidLibraryDependency interface {
+	LibraryDependency
 	ExportPackage() android.Path
-	ExportedProguardFlagFiles() android.Paths
 	ExportedRRODirs() []rroDir
 	ExportedStaticPackages() android.Paths
 	ExportedManifests() android.Paths
@@ -498,8 +498,7 @@
 
 	aarFile android.WritablePath
 
-	exportedProguardFlagFiles android.Paths
-	exportedStaticPackages    android.Paths
+	exportedStaticPackages android.Paths
 }
 
 var _ android.OutputFileProducer = (*AndroidLibrary)(nil)
@@ -514,10 +513,6 @@
 	}
 }
 
-func (a *AndroidLibrary) ExportedProguardFlagFiles() android.Paths {
-	return a.exportedProguardFlagFiles
-}
-
 func (a *AndroidLibrary) ExportedStaticPackages() android.Paths {
 	return a.exportedStaticPackages
 }
@@ -566,13 +561,16 @@
 	a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles,
 		android.PathsForModuleSrc(ctx, a.dexProperties.Optimize.Proguard_flags_files)...)
 	ctx.VisitDirectDeps(func(m android.Module) {
-		if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
-			a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
-			a.exportedStaticPackages = append(a.exportedStaticPackages, lib.ExportPackage())
-			a.exportedStaticPackages = append(a.exportedStaticPackages, lib.ExportedStaticPackages()...)
+		if ctx.OtherModuleDependencyTag(m) == staticLibTag {
+			if lib, ok := m.(LibraryDependency); ok {
+				a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
+			}
+			if alib, ok := m.(AndroidLibraryDependency); ok {
+				a.exportedStaticPackages = append(a.exportedStaticPackages, alib.ExportPackage())
+				a.exportedStaticPackages = append(a.exportedStaticPackages, alib.ExportedStaticPackages()...)
+			}
 		}
 	})
-
 	a.exportedProguardFlagFiles = android.FirstUniquePaths(a.exportedProguardFlagFiles)
 	a.exportedStaticPackages = android.FirstUniquePaths(a.exportedStaticPackages)
 
diff --git a/java/app.go b/java/app.go
index a822cbf..eb1b474 100755
--- a/java/app.go
+++ b/java/app.go
@@ -457,7 +457,7 @@
 func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
 	var staticLibProguardFlagFiles android.Paths
 	ctx.VisitDirectDeps(func(m android.Module) {
-		if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
+		if lib, ok := m.(LibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
 			staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
 		}
 	})
diff --git a/java/dex_test.go b/java/dex_test.go
index 6617873..fc6cd0f 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -155,3 +155,57 @@
 	android.AssertStringDoesNotContain(t, "expected no  static_lib header jar in foo javac classpath",
 		fooD8.Args["d8Flags"], staticLibHeader.String())
 }
+
+func TestProguardFlagsInheritance(t *testing.T) {
+	result := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd.RunTestWithBp(t, `
+		android_app {
+			name: "app",
+			static_libs: [
+				"primary_android_lib",
+				"primary_lib",
+			],
+			platform_apis: true,
+		}
+
+		java_library {
+			name: "primary_lib",
+			optimize: {
+				proguard_flags_files: ["primary.flags"],
+			},
+		}
+
+		android_library {
+			name: "primary_android_lib",
+			static_libs: ["secondary_lib"],
+			optimize: {
+				proguard_flags_files: ["primary_android.flags"],
+			},
+		}
+
+		java_library {
+			name: "secondary_lib",
+			static_libs: ["tertiary_lib"],
+			optimize: {
+				proguard_flags_files: ["secondary.flags"],
+			},
+		}
+
+		java_library {
+			name: "tertiary_lib",
+			optimize: {
+				proguard_flags_files: ["tertiary.flags"],
+			},
+		}
+	`)
+
+	app := result.ModuleForTests("app", "android_common")
+	appR8 := app.Rule("r8")
+	android.AssertStringDoesContain(t, "expected primary_lib's proguard flags from direct dep",
+		appR8.Args["r8Flags"], "primary.flags")
+	android.AssertStringDoesContain(t, "expected primary_android_lib's proguard flags from direct dep",
+		appR8.Args["r8Flags"], "primary_android.flags")
+	android.AssertStringDoesContain(t, "expected secondary_lib's proguard flags from inherited dep",
+		appR8.Args["r8Flags"], "secondary.flags")
+	android.AssertStringDoesContain(t, "expected tertiary_lib's proguard flags from inherited dep",
+		appR8.Args["r8Flags"], "tertiary.flags")
+}
diff --git a/java/java.go b/java/java.go
index dd24376..b3abc91 100644
--- a/java/java.go
+++ b/java/java.go
@@ -294,6 +294,11 @@
 	ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
 }
 
+// Provides transitive Proguard flag files to downstream DEX jars.
+type LibraryDependency interface {
+	ExportedProguardFlagFiles() android.Paths
+}
+
 // TODO(jungjw): Move this to kythe.go once it's created.
 type xref interface {
 	XrefJavaFiles() android.Paths
@@ -596,9 +601,17 @@
 type Library struct {
 	Module
 
+	exportedProguardFlagFiles android.Paths
+
 	InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths)
 }
 
+var _ LibraryDependency = (*Library)(nil)
+
+func (j *Library) ExportedProguardFlagFiles() android.Paths {
+	return j.exportedProguardFlagFiles
+}
+
 var _ android.ApexModule = (*Library)(nil)
 
 // Provides access to the list of permitted packages from apex boot jars.
@@ -694,6 +707,15 @@
 		}
 		j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...)
 	}
+
+	j.exportedProguardFlagFiles = append(j.exportedProguardFlagFiles,
+		android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files)...)
+	ctx.VisitDirectDeps(func(m android.Module) {
+		if lib, ok := m.(LibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
+			j.exportedProguardFlagFiles = append(j.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
+		}
+	})
+	j.exportedProguardFlagFiles = android.FirstUniquePaths(j.exportedProguardFlagFiles)
 }
 
 func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -888,10 +910,6 @@
 
 	// a list of extra test configuration files that should be installed with the module.
 	Extra_test_configs []string `android:"path,arch_variant"`
-
-	// Extra <option> tags to add to the auto generated test xml file. The "key"
-	// is optional in each of these.
-	Tradefed_options []tradefed.Option
 }
 
 type testProperties struct {
@@ -1170,18 +1188,8 @@
 		j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest)
 	}
 
-	j.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
-		SetTestConfigProp(j.testProperties.Test_config).
-		SetTestTemplateConfigProp(j.testProperties.Test_config_template).
-		SetTestSuites(j.testProperties.Test_suites).
-		SetConfig(configs).
-		SetOptionsForAutogenerated(j.testProperties.Test_options.Tradefed_options).
-		SetAutoGenConfig(j.testProperties.Auto_gen_config).
-		SetUnitTest(j.testProperties.Test_options.Unit_test).
-		SetDeviceTemplate("${JavaTestConfigTemplate}").
-		SetHostTemplate("${JavaHostTestConfigTemplate}").
-		SetHostUnitTestTemplate("${JavaHostUnitTestConfigTemplate}").
-		Build()
+	j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
+		j.testProperties.Test_suites, configs, j.testProperties.Auto_gen_config, j.testProperties.Test_options.Unit_test)
 
 	j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
 
@@ -1226,13 +1234,8 @@
 }
 
 func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	j.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
-		SetTestConfigProp(j.prebuiltTestProperties.Test_config).
-		SetTestSuites(j.prebuiltTestProperties.Test_suites).
-		SetDeviceTemplate("${JavaTestConfigTemplate}").
-		SetHostTemplate("${JavaHostTestConfigTemplate}").
-		SetHostUnitTestTemplate("${JavaHostUnitTestConfigTemplate}").
-		Build()
+	j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil,
+		j.prebuiltTestProperties.Test_suites, nil, nil, nil)
 
 	j.Import.GenerateAndroidBuildActions(ctx)
 }
diff --git a/java/java_test.go b/java/java_test.go
index 62a372c..dff1fd0 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1945,25 +1945,3 @@
 		}
 	}
 }
-
-func TestTradefedOptions(t *testing.T) {
-	result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
-java_test_host {
-	name: "foo",
-	test_options: {
-		tradefed_options: [
-			{
-				name: "exclude-path",
-				value: "org/apache"
-			}
-		]
-	}
-}
-`)
-	args := result.ModuleForTests("foo", "linux_glibc_common").
-		Output("out/soong/.intermediates/foo/linux_glibc_common/foo.config").Args
-	expected := proptools.NinjaAndShellEscape("<option name=\"exclude-path\" value=\"org/apache\" />")
-	if args["extraConfigs"] != expected {
-		t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"])
-	}
-}
diff --git a/java/robolectric.go b/java/robolectric.go
index 63e05d8..6e8d591 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -131,14 +131,9 @@
 	r.forceOSType = ctx.Config().BuildOS
 	r.forceArchType = ctx.Config().BuildArch
 
-	r.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
-		SetTestConfigProp(r.testProperties.Test_config).
-		SetTestTemplateConfigProp(r.testProperties.Test_config_template).
-		SetTestSuites(r.testProperties.Test_suites).
-		SetAutoGenConfig(r.testProperties.Auto_gen_config).
-		SetDeviceTemplate("${RobolectricTestConfigTemplate}").
-		SetHostTemplate("${RobolectricTestConfigTemplate}").
-		Build()
+	r.testConfig = tradefed.AutoGenRobolectricTestConfig(ctx, r.testProperties.Test_config,
+		r.testProperties.Test_config_template, r.testProperties.Test_suites,
+		r.testProperties.Auto_gen_config)
 	r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data)
 
 	roboTestConfig := android.PathForModuleGen(ctx, "robolectric").
diff --git a/python/test.go b/python/test.go
index 5781df7..b9b3465 100644
--- a/python/test.go
+++ b/python/test.go
@@ -67,14 +67,9 @@
 }
 
 func (test *testDecorator) install(ctx android.ModuleContext, file android.Path) {
-	test.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
-		SetTestConfigProp(test.testProperties.Test_config).
-		SetTestTemplateConfigProp(test.testProperties.Test_config_template).
-		SetTestSuites(test.binaryDecorator.binaryProperties.Test_suites).
-		SetAutoGenConfig(test.binaryDecorator.binaryProperties.Auto_gen_config).
-		SetDeviceTemplate("${PythonBinaryHostTestConfigTemplate}").
-		SetHostTemplate("${PythonBinaryHostTestConfigTemplate}").
-		Build()
+	test.testConfig = tradefed.AutoGenPythonBinaryHostTestConfig(ctx, test.testProperties.Test_config,
+		test.testProperties.Test_config_template, test.binaryDecorator.binaryProperties.Test_suites,
+		test.binaryDecorator.binaryProperties.Auto_gen_config)
 
 	test.binaryDecorator.pythonInstaller.dir = "nativetest"
 	test.binaryDecorator.pythonInstaller.dir64 = "nativetest64"
diff --git a/rust/benchmark.go b/rust/benchmark.go
index b417a2d..0e84243 100644
--- a/rust/benchmark.go
+++ b/rust/benchmark.go
@@ -112,14 +112,12 @@
 }
 
 func (benchmark *benchmarkDecorator) install(ctx ModuleContext) {
-	benchmark.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
-		SetTestConfigProp(benchmark.Properties.Test_config).
-		SetTestTemplateConfigProp(benchmark.Properties.Test_config_template).
-		SetTestSuites(benchmark.Properties.Test_suites).
-		SetAutoGenConfig(benchmark.Properties.Auto_gen_config).
-		SetDeviceTemplate("${RustDeviceBenchmarkConfigTemplate}").
-		SetHostTemplate("${RustHostBenchmarkConfigTemplate}").
-		Build()
+	benchmark.testConfig = tradefed.AutoGenRustBenchmarkConfig(ctx,
+		benchmark.Properties.Test_config,
+		benchmark.Properties.Test_config_template,
+		benchmark.Properties.Test_suites,
+		nil,
+		benchmark.Properties.Auto_gen_config)
 
 	// default relative install path is module name
 	if !Bool(benchmark.Properties.No_named_install_directory) {
diff --git a/rust/test.go b/rust/test.go
index ecc7d5d..0cc3bca 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -130,16 +130,13 @@
 		configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
 	}
 
-	test.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
-		SetTestConfigProp(test.Properties.Test_config).
-		SetTestTemplateConfigProp(test.Properties.Test_config_template).
-		SetTestSuites(test.Properties.Test_suites).
-		SetConfig(configs).
-		SetAutoGenConfig(test.Properties.Auto_gen_config).
-		SetTestInstallBase(testInstallBase).
-		SetDeviceTemplate("${RustDeviceTestConfigTemplate}").
-		SetHostTemplate("${RustHostTestConfigTemplate}").
-		Build()
+	test.testConfig = tradefed.AutoGenRustTestConfig(ctx,
+		test.Properties.Test_config,
+		test.Properties.Test_config_template,
+		test.Properties.Test_suites,
+		configs,
+		test.Properties.Auto_gen_config,
+		testInstallBase)
 
 	dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
 
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 4eae397..9627329 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -379,16 +379,8 @@
 		}
 		configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.PushFilePreparer", options})
 	}
-	s.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
-		SetTestConfigProp(s.testProperties.Test_config).
-		SetTestTemplateConfigProp(s.testProperties.Test_config_template).
-		SetTestSuites(s.testProperties.Test_suites).
-		SetConfig(configs).
-		SetAutoGenConfig(s.testProperties.Auto_gen_config).
-		SetOutputFileName(s.outputFilePath.Base()).
-		SetDeviceTemplate("${ShellTestConfigTemplate}").
-		SetHostTemplate("${ShellTestConfigTemplate}").
-		Build()
+	s.testConfig = tradefed.AutoGenShellTestConfig(ctx, s.testProperties.Test_config,
+		s.testProperties.Test_config_template, s.testProperties.Test_suites, configs, s.testProperties.Auto_gen_config, s.outputFilePath.Base())
 
 	s.dataModules = make(map[string]android.Path)
 	ctx.VisitDirectDeps(func(dep android.Module) {
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index 236e559..c2429ab 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -107,134 +107,15 @@
 
 }
 
-// MaybeAutoGenTestConfigBuilder provides a Build() method that will either
-// generate a AndroidTest.xml file, or use an existing user-supplied one.
-// It used to be a bunch of separate functions for each language, but was
-// converted to this builder pattern to have one function that accepts many
-// optional arguments.
-type MaybeAutoGenTestConfigBuilder struct {
-	ctx                     android.ModuleContext
-	name                    string
-	outputFileName          string
-	testConfigProp          *string
-	testConfigTemplateProp  *string
-	testSuites              []string
-	config                  []Config
-	configsForAutogenerated []Config
-	autoGenConfig           *bool
-	unitTest                *bool
-	testInstallBase         string
-	deviceTemplate          string
-	hostTemplate            string
-	hostUnitTestTemplate    string
+func autogenTemplate(ctx android.ModuleContext, output android.WritablePath, template string, configs []Config, testInstallBase string) {
+	autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), output, template, configs, "", testInstallBase)
 }
 
-func NewMaybeAutoGenTestConfigBuilder(ctx android.ModuleContext) *MaybeAutoGenTestConfigBuilder {
-	return &MaybeAutoGenTestConfigBuilder{
-		ctx:  ctx,
-		name: ctx.ModuleName(),
-	}
+func autogenTemplateWithName(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, testInstallBase string) {
+	autogenTemplateWithNameAndOutputFile(ctx, name, output, template, configs, "", testInstallBase)
 }
 
-func (b *MaybeAutoGenTestConfigBuilder) SetName(name string) *MaybeAutoGenTestConfigBuilder {
-	b.name = name
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetOutputFileName(outputFileName string) *MaybeAutoGenTestConfigBuilder {
-	b.outputFileName = outputFileName
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetTestConfigProp(testConfigProp *string) *MaybeAutoGenTestConfigBuilder {
-	b.testConfigProp = testConfigProp
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetTestTemplateConfigProp(testConfigTemplateProp *string) *MaybeAutoGenTestConfigBuilder {
-	b.testConfigTemplateProp = testConfigTemplateProp
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetTestSuites(testSuites []string) *MaybeAutoGenTestConfigBuilder {
-	b.testSuites = testSuites
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetConfig(config []Config) *MaybeAutoGenTestConfigBuilder {
-	b.config = config
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetOptionsForAutogenerated(configsForAutogenerated []Option) *MaybeAutoGenTestConfigBuilder {
-	configs := make([]Config, 0, len(configsForAutogenerated))
-	for _, c := range configsForAutogenerated {
-		configs = append(configs, c)
-	}
-	b.configsForAutogenerated = configs
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetUnitTest(unitTest *bool) *MaybeAutoGenTestConfigBuilder {
-	b.unitTest = unitTest
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetAutoGenConfig(autoGenConfig *bool) *MaybeAutoGenTestConfigBuilder {
-	b.autoGenConfig = autoGenConfig
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetTestInstallBase(testInstallBase string) *MaybeAutoGenTestConfigBuilder {
-	b.testInstallBase = testInstallBase
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetDeviceTemplate(deviceTemplate string) *MaybeAutoGenTestConfigBuilder {
-	b.deviceTemplate = deviceTemplate
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetHostTemplate(hostTemplate string) *MaybeAutoGenTestConfigBuilder {
-	b.hostTemplate = hostTemplate
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) SetHostUnitTestTemplate(hostUnitTestTemplate string) *MaybeAutoGenTestConfigBuilder {
-	b.hostUnitTestTemplate = hostUnitTestTemplate
-	return b
-}
-
-func (b *MaybeAutoGenTestConfigBuilder) Build() android.Path {
-	config := append(b.config, b.configsForAutogenerated...)
-	path, autogenPath := testConfigPath(b.ctx, b.testConfigProp, b.testSuites, b.autoGenConfig, b.testConfigTemplateProp)
-	if autogenPath != nil {
-		templatePath := getTestConfigTemplate(b.ctx, b.testConfigTemplateProp)
-		if templatePath.Valid() {
-			autogenTemplate(b.ctx, b.name, autogenPath, templatePath.String(), config, b.outputFileName, b.testInstallBase)
-		} else {
-			if b.ctx.Device() {
-				autogenTemplate(b.ctx, b.name, autogenPath, b.deviceTemplate, config, b.outputFileName, b.testInstallBase)
-			} else {
-				if Bool(b.unitTest) {
-					autogenTemplate(b.ctx, b.name, autogenPath, b.hostUnitTestTemplate, config, b.outputFileName, b.testInstallBase)
-				} else {
-					autogenTemplate(b.ctx, b.name, autogenPath, b.hostTemplate, config, b.outputFileName, b.testInstallBase)
-				}
-			}
-		}
-		return autogenPath
-	}
-	if len(b.configsForAutogenerated) > 0 {
-		b.ctx.ModuleErrorf("Extra tradefed configurations were provided for an autogenerated xml file, but the autogenerated xml file was not used.")
-	}
-	return path
-}
-
-func autogenTemplate(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, outputFileName string, testInstallBase string) {
-	if template == "" {
-		ctx.ModuleErrorf("Empty template")
-	}
+func autogenTemplateWithNameAndOutputFile(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, outputFileName string, testInstallBase string) {
 	var configStrings []string
 	for _, config := range configs {
 		configStrings = append(configStrings, config.Config())
@@ -256,6 +137,148 @@
 	})
 }
 
+func AutoGenNativeTestConfig(ctx android.ModuleContext, testConfigProp *string,
+	testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool, testInstallBase string) android.Path {
+
+	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+	if autogenPath != nil {
+		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+		if templatePath.Valid() {
+			autogenTemplate(ctx, autogenPath, templatePath.String(), config, testInstallBase)
+		} else {
+			if ctx.Device() {
+				autogenTemplate(ctx, autogenPath, "${NativeTestConfigTemplate}", config, testInstallBase)
+			} else {
+				autogenTemplate(ctx, autogenPath, "${NativeHostTestConfigTemplate}", config, testInstallBase)
+			}
+		}
+		return autogenPath
+	}
+	return path
+}
+
+func AutoGenShellTestConfig(ctx android.ModuleContext, testConfigProp *string,
+	testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool, outputFileName string) android.Path {
+	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+	if autogenPath != nil {
+		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+		if templatePath.Valid() {
+			autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), autogenPath, templatePath.String(), config, outputFileName, "")
+		} else {
+			autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), autogenPath, "${ShellTestConfigTemplate}", config, outputFileName, "")
+		}
+		return autogenPath
+	}
+	return path
+}
+
+func AutoGenNativeBenchmarkTestConfig(ctx android.ModuleContext, testConfigProp *string,
+	testConfigTemplateProp *string, testSuites []string, configs []Config, autoGenConfig *bool) android.Path {
+	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+	if autogenPath != nil {
+		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+		if templatePath.Valid() {
+			autogenTemplate(ctx, autogenPath, templatePath.String(), configs, "")
+		} else {
+			autogenTemplate(ctx, autogenPath, "${NativeBenchmarkTestConfigTemplate}", configs, "")
+		}
+		return autogenPath
+	}
+	return path
+}
+
+func AutoGenJavaTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string,
+	testSuites []string, config []Config, autoGenConfig *bool, unitTest *bool) android.Path {
+	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+	if autogenPath != nil {
+		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+		if templatePath.Valid() {
+			autogenTemplate(ctx, autogenPath, templatePath.String(), config, "")
+		} else {
+			if ctx.Device() {
+				autogenTemplate(ctx, autogenPath, "${JavaTestConfigTemplate}", config, "")
+			} else {
+				if Bool(unitTest) {
+					autogenTemplate(ctx, autogenPath, "${JavaHostUnitTestConfigTemplate}", config, "")
+				} else {
+					autogenTemplate(ctx, autogenPath, "${JavaHostTestConfigTemplate}", config, "")
+				}
+			}
+		}
+		return autogenPath
+	}
+	return path
+}
+
+func AutoGenPythonBinaryHostTestConfig(ctx android.ModuleContext, testConfigProp *string,
+	testConfigTemplateProp *string, testSuites []string, autoGenConfig *bool) android.Path {
+
+	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+	if autogenPath != nil {
+		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+		if templatePath.Valid() {
+			autogenTemplate(ctx, autogenPath, templatePath.String(), nil, "")
+		} else {
+			autogenTemplate(ctx, autogenPath, "${PythonBinaryHostTestConfigTemplate}", nil, "")
+		}
+		return autogenPath
+	}
+	return path
+}
+
+func AutoGenRustTestConfig(ctx android.ModuleContext, testConfigProp *string,
+	testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool, testInstallBase string) android.Path {
+	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+	if autogenPath != nil {
+		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+		if templatePath.Valid() {
+			autogenTemplate(ctx, autogenPath, templatePath.String(), config, testInstallBase)
+		} else {
+			if ctx.Device() {
+				autogenTemplate(ctx, autogenPath, "${RustDeviceTestConfigTemplate}", config, testInstallBase)
+			} else {
+				autogenTemplate(ctx, autogenPath, "${RustHostTestConfigTemplate}", config, testInstallBase)
+			}
+		}
+		return autogenPath
+	}
+	return path
+}
+
+func AutoGenRustBenchmarkConfig(ctx android.ModuleContext, testConfigProp *string,
+	testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool) android.Path {
+	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+	if autogenPath != nil {
+		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+		if templatePath.Valid() {
+			autogenTemplate(ctx, autogenPath, templatePath.String(), config, "")
+		} else {
+			if ctx.Device() {
+				autogenTemplate(ctx, autogenPath, "${RustDeviceBenchmarkConfigTemplate}", config, "")
+			} else {
+				autogenTemplate(ctx, autogenPath, "${RustHostBenchmarkConfigTemplate}", config, "")
+			}
+		}
+		return autogenPath
+	}
+	return path
+}
+
+func AutoGenRobolectricTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string,
+	testSuites []string, autoGenConfig *bool) android.Path {
+	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+	if autogenPath != nil {
+		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+		if templatePath.Valid() {
+			autogenTemplate(ctx, autogenPath, templatePath.String(), nil, "")
+		} else {
+			autogenTemplate(ctx, autogenPath, "${RobolectricTestConfigTemplate}", nil, "")
+		}
+		return autogenPath
+	}
+	return path
+}
+
 var autogenInstrumentationTest = pctx.StaticRule("autogenInstrumentationTest", blueprint.RuleParams{
 	Command: "${AutoGenTestConfigScript} $out $in ${EmptyTestConfig} $template ${extraConfigs}",
 	CommandDeps: []string{