Merge "Migrate more unblocked modules."
diff --git a/android/Android.bp b/android/Android.bp
index 65332b2..cbd3459 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -98,6 +98,7 @@
         "apex_test.go",
         "arch_test.go",
         "bazel_handler_test.go",
+        "bazel_paths_test.go",
         "bazel_test.go",
         "config_test.go",
         "config_bp2build_test.go",
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 52f9a1b..672d7f6 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -37,14 +37,15 @@
 
 var (
 	Bp2buildDefaultConfig = Bp2BuildConfig{
-		"art/libartpalette":                     Bp2BuildDefaultTrueRecursively,
-		"art/libdexfile":                        Bp2BuildDefaultTrueRecursively,
-		"art/libnativebridge":                   Bp2BuildDefaultTrueRecursively,
-		"art/runtime":                           Bp2BuildDefaultTrueRecursively,
-		"art/tools":                             Bp2BuildDefaultTrue,
-		"bionic":                                Bp2BuildDefaultTrueRecursively,
-		"bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
-		"build/bazel/examples/apex/minimal":     Bp2BuildDefaultTrueRecursively,
+		"prebuilts/runtime/mainline/platform/sdk":            Bp2BuildDefaultTrueRecursively,
+		"art/libartpalette":                                  Bp2BuildDefaultTrueRecursively,
+		"art/libdexfile":                                     Bp2BuildDefaultTrueRecursively,
+		"art/libnativebridge":                                Bp2BuildDefaultTrueRecursively,
+		"art/runtime":                                        Bp2BuildDefaultTrueRecursively,
+		"art/tools":                                          Bp2BuildDefaultTrue,
+		"bionic":                                             Bp2BuildDefaultTrueRecursively,
+		"bootable/recovery/tools/recovery_l10n":              Bp2BuildDefaultTrue,
+		"build/bazel/examples/apex/minimal":                  Bp2BuildDefaultTrueRecursively,
 		"build/bazel/examples/soong_config_variables":        Bp2BuildDefaultTrueRecursively,
 		"build/bazel/examples/python":                        Bp2BuildDefaultTrueRecursively,
 		"build/bazel/examples/gensrcs":                       Bp2BuildDefaultTrueRecursively,
diff --git a/android/arch.go b/android/arch.go
index f732a7d..cbf77c7 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1832,10 +1832,10 @@
 	return ret
 }
 
-// firstTarget takes a list of Targets and a list of multilib values and returns a list of Targets
+// FirstTarget takes a list of Targets and a list of multilib values and returns a list of Targets
 // that contains zero or one Target for each OsType, selecting the one that matches the earliest
 // filter.
-func firstTarget(targets []Target, filters ...string) []Target {
+func FirstTarget(targets []Target, filters ...string) []Target {
 	// find the first target from each OS
 	var ret []Target
 	hasHost := false
@@ -1865,9 +1865,9 @@
 	case "common_first":
 		buildTargets = getCommonTargets(targets)
 		if prefer32 {
-			buildTargets = append(buildTargets, firstTarget(targets, "lib32", "lib64")...)
+			buildTargets = append(buildTargets, FirstTarget(targets, "lib32", "lib64")...)
 		} else {
-			buildTargets = append(buildTargets, firstTarget(targets, "lib64", "lib32")...)
+			buildTargets = append(buildTargets, FirstTarget(targets, "lib64", "lib32")...)
 		}
 	case "both":
 		if prefer32 {
@@ -1883,12 +1883,12 @@
 		buildTargets = filterMultilibTargets(targets, "lib64")
 	case "first":
 		if prefer32 {
-			buildTargets = firstTarget(targets, "lib32", "lib64")
+			buildTargets = FirstTarget(targets, "lib32", "lib64")
 		} else {
-			buildTargets = firstTarget(targets, "lib64", "lib32")
+			buildTargets = FirstTarget(targets, "lib64", "lib32")
 		}
 	case "first_prefer32":
-		buildTargets = firstTarget(targets, "lib32", "lib64")
+		buildTargets = FirstTarget(targets, "lib32", "lib64")
 	case "prefer32":
 		buildTargets = filterMultilibTargets(targets, "lib32")
 		if len(buildTargets) == 0 {
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index fa10f62..1d0a6d5 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -449,25 +449,51 @@
 	return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
 }
 
-// PathForBazelOut returns a Path representing the paths... under an output directory dedicated to
-// bazel-owned outputs.
-func PathForBazelOut(ctx PathContext, paths ...string) BazelOutPath {
-	execRootPathComponents := append([]string{"execroot", "__main__"}, paths...)
-	execRootPath := filepath.Join(execRootPathComponents...)
-	validatedExecRootPath, err := validatePath(execRootPath)
+// PathForBazelOutRelative returns a BazelOutPath representing the path under an output directory dedicated to
+// bazel-owned outputs. Calling .Rel() on the result will give the input path as relative to the given
+// relativeRoot.
+func PathForBazelOutRelative(ctx PathContext, relativeRoot string, path string) BazelOutPath {
+	validatedPath, err := validatePath(filepath.Join("execroot", "__main__", path))
 	if err != nil {
 		reportPathError(ctx, err)
 	}
+	relativeRootPath := filepath.Join("execroot", "__main__", relativeRoot)
+	if pathComponents := strings.Split(path, "/"); len(pathComponents) >= 3 &&
+		pathComponents[0] == "bazel-out" && pathComponents[2] == "bin" {
+		// If the path starts with something like: bazel-out/linux_x86_64-fastbuild-ST-b4ef1c4402f9/bin/
+		// make it relative to that folder. bazel-out/volatile-status.txt is an example
+		// of something that starts with bazel-out but is not relative to the bin folder
+		relativeRootPath = filepath.Join("execroot", "__main__", pathComponents[0], pathComponents[1], pathComponents[2], relativeRoot)
+	}
 
-	outputPath := OutputPath{basePath{"", ""},
+	var relPath string
+	if relPath, err = filepath.Rel(relativeRootPath, validatedPath); err != nil || strings.HasPrefix(relPath, "../") {
+		// We failed to make this path relative to execroot/__main__, fall back to a non-relative path
+		// One case where this happens is when path is ../bazel_tools/something
+		relativeRootPath = ""
+		relPath = validatedPath
+	}
+
+	outputPath := OutputPath{
+		basePath{"", ""},
 		ctx.Config().soongOutDir,
-		ctx.Config().BazelContext.OutputBase()}
+		ctx.Config().BazelContext.OutputBase(),
+	}
 
 	return BazelOutPath{
-		OutputPath: outputPath.withRel(validatedExecRootPath),
+		// .withRel() appends its argument onto the current path, and only the most
+		// recently appended part is returned by outputPath.rel().
+		// So outputPath.rel() will return relPath.
+		OutputPath: outputPath.withRel(relativeRootPath).withRel(relPath),
 	}
 }
 
+// PathForBazelOut returns a BazelOutPath representing the path under an output directory dedicated to
+// bazel-owned outputs.
+func PathForBazelOut(ctx PathContext, path string) BazelOutPath {
+	return PathForBazelOutRelative(ctx, "", path)
+}
+
 // PathsForBazelOut returns a list of paths representing the paths under an output directory
 // dedicated to Bazel-owned outputs.
 func PathsForBazelOut(ctx PathContext, paths []string) Paths {
diff --git a/android/bazel_paths_test.go b/android/bazel_paths_test.go
new file mode 100644
index 0000000..b047511
--- /dev/null
+++ b/android/bazel_paths_test.go
@@ -0,0 +1,108 @@
+// 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 android
+
+import (
+	"path/filepath"
+	"testing"
+)
+
+type TestBazelPathContext struct{}
+
+func (*TestBazelPathContext) Config() Config {
+	cfg := NullConfig("out", "out/soong")
+	cfg.BazelContext = MockBazelContext{
+		OutputBaseDir: "out/bazel",
+	}
+	return cfg
+}
+
+func (*TestBazelPathContext) AddNinjaFileDeps(deps ...string) {
+	panic("Unimplemented")
+}
+
+func TestPathForBazelOut(t *testing.T) {
+	ctx := &TestBazelPathContext{}
+	out := PathForBazelOut(ctx, "foo/bar/baz/boq.txt")
+	expectedPath := filepath.Join(ctx.Config().BazelContext.OutputBase(), "execroot/__main__/foo/bar/baz/boq.txt")
+	if out.String() != expectedPath {
+		t.Errorf("incorrect OutputPath: expected %q, got %q", expectedPath, out.String())
+	}
+
+	expectedRelPath := "foo/bar/baz/boq.txt"
+	if out.Rel() != expectedRelPath {
+		t.Errorf("incorrect OutputPath.Rel(): expected %q, got %q", expectedRelPath, out.Rel())
+	}
+}
+
+func TestPathForBazelOutRelative(t *testing.T) {
+	ctx := &TestBazelPathContext{}
+	out := PathForBazelOutRelative(ctx, "foo/bar", "foo/bar/baz/boq.txt")
+
+	expectedPath := filepath.Join(ctx.Config().BazelContext.OutputBase(), "execroot/__main__/foo/bar/baz/boq.txt")
+	if out.String() != expectedPath {
+		t.Errorf("incorrect OutputPath: expected %q, got %q", expectedPath, out.String())
+	}
+
+	expectedRelPath := "baz/boq.txt"
+	if out.Rel() != expectedRelPath {
+		t.Errorf("incorrect OutputPath.Rel(): expected %q, got %q", expectedRelPath, out.Rel())
+	}
+}
+
+func TestPathForBazelOutRelativeUnderBinFolder(t *testing.T) {
+	ctx := &TestBazelPathContext{}
+	out := PathForBazelOutRelative(ctx, "foo/bar", "bazel-out/linux_x86_64-fastbuild-ST-b4ef1c4402f9/bin/foo/bar/baz/boq.txt")
+
+	expectedPath := filepath.Join(ctx.Config().BazelContext.OutputBase(), "execroot/__main__/bazel-out/linux_x86_64-fastbuild-ST-b4ef1c4402f9/bin/foo/bar/baz/boq.txt")
+	if out.String() != expectedPath {
+		t.Errorf("incorrect OutputPath: expected %q, got %q", expectedPath, out.String())
+	}
+
+	expectedRelPath := "baz/boq.txt"
+	if out.Rel() != expectedRelPath {
+		t.Errorf("incorrect OutputPath.Rel(): expected %q, got %q", expectedRelPath, out.Rel())
+	}
+}
+
+func TestPathForBazelOutOutsideOfExecroot(t *testing.T) {
+	ctx := &TestBazelPathContext{}
+	out := PathForBazelOut(ctx, "../bazel_tools/linux_x86_64-fastbuild/bin/tools/android/java_base_extras.jar")
+
+	expectedPath := filepath.Join(ctx.Config().BazelContext.OutputBase(), "execroot/bazel_tools/linux_x86_64-fastbuild/bin/tools/android/java_base_extras.jar")
+	if out.String() != expectedPath {
+		t.Errorf("incorrect OutputPath: expected %q, got %q", expectedPath, out.String())
+	}
+
+	expectedRelPath := "execroot/bazel_tools/linux_x86_64-fastbuild/bin/tools/android/java_base_extras.jar"
+	if out.Rel() != expectedRelPath {
+		t.Errorf("incorrect OutputPath.Rel(): expected %q, got %q", expectedRelPath, out.Rel())
+	}
+}
+
+func TestPathForBazelOutRelativeWithParentDirectoryRoot(t *testing.T) {
+	ctx := &TestBazelPathContext{}
+	out := PathForBazelOutRelative(ctx, "../bazel_tools", "../bazel_tools/foo/bar/baz.sh")
+
+	expectedPath := filepath.Join(ctx.Config().BazelContext.OutputBase(), "execroot/bazel_tools/foo/bar/baz.sh")
+	if out.String() != expectedPath {
+		t.Errorf("incorrect OutputPath: expected %q, got %q", expectedPath, out.String())
+	}
+
+	expectedRelPath := "foo/bar/baz.sh"
+	if out.Rel() != expectedRelPath {
+		t.Errorf("incorrect OutputPath.Rel(): expected %q, got %q", expectedRelPath, out.Rel())
+	}
+}
diff --git a/android/config.go b/android/config.go
index eb01baa..ef71292 100644
--- a/android/config.go
+++ b/android/config.go
@@ -416,7 +416,7 @@
 	config.BuildOSTarget = config.Targets[config.BuildOS][0]
 	config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
 	config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0]
-	config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0]
+	config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
 	config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64")
 	config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a")
 	config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm")
@@ -554,7 +554,7 @@
 	// Compilation targets for Android.
 	if len(config.Targets[Android]) > 0 {
 		config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0]
-		config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0]
+		config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
 	}
 
 	config.BazelContext, err = NewBazelContext(config)
diff --git a/android/filegroup.go b/android/filegroup.go
index 14ed783..9e5769a 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -178,8 +178,7 @@
 
 	bazelOuts := make(Paths, 0, len(filePaths))
 	for _, p := range filePaths {
-		src := PathForBazelOut(ctx, p)
-		bazelOuts = append(bazelOuts, src)
+		bazelOuts = append(bazelOuts, PathForBazelOutRelative(ctx, ctx.ModuleDir(), p))
 	}
 
 	fg.srcs = bazelOuts
diff --git a/android/license_metadata.go b/android/license_metadata.go
index 6a5b0da..48c1383 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -105,7 +105,7 @@
 
 	if p := base.commonProperties.Effective_package_name; p != nil {
 		args = append(args,
-			"-p "+proptools.NinjaAndShellEscape(*p))
+			`-p "`+proptools.NinjaAndShellEscape(*p)+`"`)
 	}
 
 	args = append(args,
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 5843487..4e4fa42 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -110,6 +110,18 @@
 	return strings.TrimPrefix(name, "prebuilt_")
 }
 
+// RemoveOptionalPrebuiltPrefixFromBazelLabel removes the "prebuilt_" prefix from the *target name* of a Bazel label.
+// This differs from RemoveOptionalPrebuiltPrefix in that it does not remove it from the start of the string, but
+// instead removes it from the target name itself.
+func RemoveOptionalPrebuiltPrefixFromBazelLabel(label string) string {
+	splitLabel := strings.Split(label, ":")
+	bazelModuleNameNoPrebuilt := RemoveOptionalPrebuiltPrefix(splitLabel[1])
+	return strings.Join([]string{
+		splitLabel[0],
+		bazelModuleNameNoPrebuilt,
+	}, ":")
+}
+
 func (p *Prebuilt) Name(name string) string {
 	return PrebuiltNameFromSource(name)
 }
diff --git a/apex/Android.bp b/apex/Android.bp
index d3417c2..fcdf8e6 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -25,6 +25,7 @@
         "apex.go",
         "apex_singleton.go",
         "builder.go",
+        "constants.go",
         "deapexer.go",
         "key.go",
         "prebuilt.go",
diff --git a/apex/apex.go b/apex/apex.go
index 7a2a04a..64e1760 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2523,8 +2523,10 @@
 		}
 
 		// Prebuilts
-		prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
-		attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
+		if overridableProperties.Prebuilts != nil {
+			prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts)
+			attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList)
+		}
 
 		// Compressible
 		if overridableProperties.Compressible != nil {
diff --git a/apex/builder.go b/apex/builder.go
index 9119363..73e9b73 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -650,6 +650,8 @@
 			optFlags = append(optFlags, "--manifest_json "+a.manifestJsonOut.String())
 		}
 
+		optFlags = append(optFlags, "--apex_version "+defaultManifestVersion)
+
 		optFlags = append(optFlags, "--payload_fs_type "+a.payloadFsType.string())
 
 		ctx.Build(pctx, android.BuildParams{
diff --git a/apex/constants.go b/apex/constants.go
new file mode 100644
index 0000000..c68edb7
--- /dev/null
+++ b/apex/constants.go
@@ -0,0 +1,36 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// 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
+
+// This file contains branch specific constants. They are stored in a separate
+// file to minimise the potential of merge conflicts between branches when
+// the code from the package is changed.
+
+// The default manifest version for all the modules on this branch.
+// This version code will be used only if there is no version field in the
+// module's apex_manifest.json. Release branches have their version injected
+// into apex_manifest.json by the tooling and will not use the version set
+// here. Developers can also set the version field locally in the
+// apex_manifest.json to build a module with a specific version.
+//
+// The value follows the schema from go/mainline-version-codes, and is chosen
+// based on the branch such that the builds from testing and development
+// branches will have a version higher than the prebuilts.
+// Versions per branch:
+// * x-dev           - xx0090000 (where xx is the branch SDK level)
+// * AOSP            - xx9990000
+// * x-mainline-prod - xx9990000
+// * master          - 990090000
+const defaultManifestVersion = "339990000"
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index e0ce194..34548ed 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -51,6 +51,7 @@
         "conversion_test.go",
         "filegroup_conversion_test.go",
         "genrule_conversion_test.go",
+        "gensrcs_conversion_test.go",
         "java_binary_host_conversion_test.go",
         "java_import_conversion_test.go",
         "java_library_conversion_test.go",
diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go
index 3f1349f..05045ee 100644
--- a/bp2build/apex_conversion_test.go
+++ b/bp2build/apex_conversion_test.go
@@ -18,6 +18,7 @@
 	"android/soong/android"
 	"android/soong/apex"
 	"android/soong/cc"
+	"android/soong/etc"
 	"android/soong/java"
 	"android/soong/sh"
 
@@ -39,6 +40,7 @@
 	ctx.RegisterModuleType("apex_key", apex.ApexKeyFactory)
 	ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory)
 	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+	ctx.RegisterModuleType("prebuilt_etc", etc.PrebuiltEtcFactory)
 }
 
 func runOverrideApexTestCase(t *testing.T, tc bp2buildTestCase) {
@@ -57,6 +59,7 @@
 	ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory)
 	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 	ctx.RegisterModuleType("apex", apex.BundleFactory)
+	ctx.RegisterModuleType("prebuilt_etc", etc.PrebuiltEtcFactory)
 }
 
 func TestApexBundleSimple(t *testing.T) {
@@ -89,13 +92,13 @@
 	bazel_module: { bp2build_available: false },
 }
 
-cc_library {
-	name: "pretend_prebuilt_1",
+prebuilt_etc {
+	name: "prebuilt_1",
 	bazel_module: { bp2build_available: false },
 }
 
-cc_library {
-	name: "pretend_prebuilt_2",
+prebuilt_etc {
+	name: "prebuilt_2",
 	bazel_module: { bp2build_available: false },
 }
 
@@ -130,8 +133,8 @@
 		"sh_binary_2",
 	],
 	prebuilts: [
-	    "pretend_prebuilt_1",
-	    "pretend_prebuilt_2",
+	    "prebuilt_1",
+	    "prebuilt_2",
 	],
 	package_name: "com.android.apogee.test.package",
 }
@@ -165,8 +168,8 @@
         "//conditions:default": [],
     })`,
 				"prebuilts": `[
-        ":pretend_prebuilt_1",
-        ":pretend_prebuilt_2",
+        ":prebuilt_1",
+        ":prebuilt_2",
     ]`,
 				"updatable":    "False",
 				"compressible": "False",
@@ -549,13 +552,13 @@
 	bazel_module: { bp2build_available: false },
 }
 
-cc_library {
-	name: "pretend_prebuilt_1",
+prebuilt_etc {
+	name: "prebuilt_1",
 	bazel_module: { bp2build_available: false },
 }
 
-cc_library {
-	name: "pretend_prebuilt_2",
+prebuilt_etc {
+	name: "prebuilt_2",
 	bazel_module: { bp2build_available: false },
 }
 
@@ -590,8 +593,8 @@
 		"sh_binary_2",
 	],
 	prebuilts: [
-	    "pretend_prebuilt_1",
-	    "pretend_prebuilt_2",
+	    "prebuilt_1",
+	    "prebuilt_2",
 	],
 	bazel_module: { bp2build_available: false },
 }
@@ -818,3 +821,127 @@
 			}),
 		}})
 }
+
+func TestApexBundleSimple_NoPrebuiltsOverride(t *testing.T) {
+	runOverrideApexTestCase(t, bp2buildTestCase{
+		description:                "override_apex - no override",
+		moduleTypeUnderTest:        "override_apex",
+		moduleTypeUnderTestFactory: apex.OverrideApexFactory,
+		filesystem: map[string]string{
+			"system/sepolicy/apex/Android.bp": `
+filegroup {
+	name: "com.android.apogee-file_contexts",
+	srcs: [ "apogee-file_contexts", ],
+	bazel_module: { bp2build_available: false },
+}`,
+		},
+		blueprint: `
+prebuilt_etc {
+	name: "prebuilt_file",
+	bazel_module: { bp2build_available: false },
+}
+
+apex {
+	name: "com.android.apogee",
+	bazel_module: { bp2build_available: false },
+    prebuilts: ["prebuilt_file"]
+}
+
+override_apex {
+	name: "com.google.android.apogee",
+	base: ":com.android.apogee",
+}
+`,
+		expectedBazelTargets: []string{
+			makeBazelTarget("apex", "com.google.android.apogee", attrNameToString{
+				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
+				"manifest":      `"apex_manifest.json"`,
+				"prebuilts":     `[":prebuilt_file"]`,
+			}),
+		}})
+}
+
+func TestApexBundleSimple_PrebuiltsOverride(t *testing.T) {
+	runOverrideApexTestCase(t, bp2buildTestCase{
+		description:                "override_apex - ooverride",
+		moduleTypeUnderTest:        "override_apex",
+		moduleTypeUnderTestFactory: apex.OverrideApexFactory,
+		filesystem: map[string]string{
+			"system/sepolicy/apex/Android.bp": `
+filegroup {
+	name: "com.android.apogee-file_contexts",
+	srcs: [ "apogee-file_contexts", ],
+	bazel_module: { bp2build_available: false },
+}`,
+		},
+		blueprint: `
+prebuilt_etc {
+	name: "prebuilt_file",
+	bazel_module: { bp2build_available: false },
+}
+
+prebuilt_etc {
+	name: "prebuilt_file2",
+	bazel_module: { bp2build_available: false },
+}
+
+apex {
+	name: "com.android.apogee",
+	bazel_module: { bp2build_available: false },
+    prebuilts: ["prebuilt_file"]
+}
+
+override_apex {
+	name: "com.google.android.apogee",
+	base: ":com.android.apogee",
+    prebuilts: ["prebuilt_file2"]
+}
+`,
+		expectedBazelTargets: []string{
+			makeBazelTarget("apex", "com.google.android.apogee", attrNameToString{
+				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
+				"manifest":      `"apex_manifest.json"`,
+				"prebuilts":     `[":prebuilt_file2"]`,
+			}),
+		}})
+}
+
+func TestApexBundleSimple_PrebuiltsOverrideEmptyList(t *testing.T) {
+	runOverrideApexTestCase(t, bp2buildTestCase{
+		description:                "override_apex - override with empty list",
+		moduleTypeUnderTest:        "override_apex",
+		moduleTypeUnderTestFactory: apex.OverrideApexFactory,
+		filesystem: map[string]string{
+			"system/sepolicy/apex/Android.bp": `
+filegroup {
+	name: "com.android.apogee-file_contexts",
+	srcs: [ "apogee-file_contexts", ],
+	bazel_module: { bp2build_available: false },
+}`,
+		},
+		blueprint: `
+prebuilt_etc {
+	name: "prebuilt_file",
+	bazel_module: { bp2build_available: false },
+}
+
+apex {
+	name: "com.android.apogee",
+	bazel_module: { bp2build_available: false },
+    prebuilts: ["prebuilt_file"]
+}
+
+override_apex {
+	name: "com.google.android.apogee",
+	base: ":com.android.apogee",
+    prebuilts: [],
+}
+`,
+		expectedBazelTargets: []string{
+			makeBazelTarget("apex", "com.google.android.apogee", attrNameToString{
+				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
+				"manifest":      `"apex_manifest.json"`,
+				"prebuilts":     `[]`,
+			}),
+		}})
+}
diff --git a/bp2build/gensrcs_conversion_test.go b/bp2build/gensrcs_conversion_test.go
index ebe60bf..7682663 100644
--- a/bp2build/gensrcs_conversion_test.go
+++ b/bp2build/gensrcs_conversion_test.go
@@ -65,7 +65,7 @@
 
 	for _, test := range testcases {
 		expectedBazelTargets := []string{
-			makeBazelTarget("gensrcs", "foo", test.expectedBazelAttrs),
+			makeBazelTargetNoRestrictions("gensrcs", "foo", test.expectedBazelAttrs),
 		}
 		t.Run(test.name, func(t *testing.T) {
 			runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
diff --git a/cc/builder.go b/cc/builder.go
index 72f7d12..70bbd6a 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -925,7 +925,6 @@
 
 	outputFile := android.PathForModuleOut(ctx, baseName+".abidiff")
 	libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
-	createReferenceDumpFlags := ""
 
 	var extraFlags []string
 	if checkAllApis {
@@ -936,18 +935,8 @@
 			"-allow-unreferenced-elf-symbol-changes")
 	}
 
-	if exportedHeaderFlags == "" {
-		extraFlags = append(extraFlags, "-advice-only")
-	}
-
 	if isLlndk || isNdk {
-		createReferenceDumpFlags = "--llndk"
-		if isLlndk {
-			// TODO(b/130324828): "-consider-opaque-types-different" should apply to
-			// both LLNDK and NDK shared libs. However, a known issue in header-abi-diff
-			// breaks libaaudio. Remove the if-guard after the issue is fixed.
-			extraFlags = append(extraFlags, "-consider-opaque-types-different")
-		}
+		extraFlags = append(extraFlags, "-consider-opaque-types-different")
 	}
 	if isVndkExt {
 		extraFlags = append(extraFlags, "-allow-extensions")
@@ -966,7 +955,7 @@
 			"libName":                  libName,
 			"arch":                     ctx.Arch().ArchType.Name,
 			"extraFlags":               strings.Join(extraFlags, " "),
-			"createReferenceDumpFlags": createReferenceDumpFlags,
+			"createReferenceDumpFlags": "",
 		},
 	})
 	return android.OptionalPathForPath(outputFile)
diff --git a/cc/cc.go b/cc/cc.go
index da8a807..55c0e48 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1789,13 +1789,20 @@
 var _ android.MixedBuildBuildable = (*Module)(nil)
 
 func (c *Module) getBazelModuleLabel(ctx android.BaseModuleContext) string {
+	var bazelModuleLabel string
 	if c.typ() == fullLibrary && c.static() {
 		// cc_library is a special case in bp2build; two targets are generated -- one for each
 		// of the shared and static variants. The shared variant keeps the module name, but the
 		// static variant uses a different suffixed name.
-		return bazelLabelForStaticModule(ctx, c)
+		bazelModuleLabel = bazelLabelForStaticModule(ctx, c)
+	} else {
+		bazelModuleLabel = c.GetBazelLabel(ctx, c)
 	}
-	return c.GetBazelLabel(ctx, c)
+	labelNoPrebuilt := bazelModuleLabel
+	if c.IsPrebuilt() {
+		labelNoPrebuilt = android.RemoveOptionalPrebuiltPrefixFromBazelLabel(bazelModuleLabel)
+	}
+	return labelNoPrebuilt
 }
 
 func (c *Module) QueueBazelCall(ctx android.BaseModuleContext) {
diff --git a/cc/pgo.go b/cc/pgo.go
index 0632c15..463e2e6 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -41,7 +41,6 @@
 
 const profileInstrumentFlag = "-fprofile-generate=/data/local/tmp"
 const profileUseInstrumentFormat = "-fprofile-use=%s"
-const profileUseSamplingFormat = "-fprofile-sample-accurate -fprofile-sample-use=%s"
 
 func getPgoProfileProjects(config android.DeviceConfig) []string {
 	return config.OnceStringSlice(pgoProfileProjectsConfigKey, func() []string {
@@ -56,12 +55,11 @@
 type PgoProperties struct {
 	Pgo struct {
 		Instrumentation    *bool
-		Sampling           *bool   `android:"arch_variant"`
 		Profile_file       *string `android:"arch_variant"`
 		Benchmarks         []string
 		Enable_profile_use *bool `android:"arch_variant"`
 		// Additional compiler flags to use when building this module
-		// for profiling (either instrumentation or sampling).
+		// for profiling.
 		Cflags []string `android:"arch_variant"`
 	} `android:"arch_variant"`
 
@@ -79,10 +77,6 @@
 	return props.Pgo.Instrumentation != nil && *props.Pgo.Instrumentation == true
 }
 
-func (props *PgoProperties) isSampling() bool {
-	return props.Pgo.Sampling != nil && *props.Pgo.Sampling == true
-}
-
 func (pgo *pgo) props() []interface{} {
 	return []interface{}{&pgo.Properties}
 }
@@ -135,18 +129,8 @@
 	return android.OptionalPathForPath(nil)
 }
 
-func (props *PgoProperties) profileUseFlag(ctx ModuleContext, file string) string {
-	if props.isInstrumentation() {
-		return fmt.Sprintf(profileUseInstrumentFormat, file)
-	}
-	if props.isSampling() {
-		return fmt.Sprintf(profileUseSamplingFormat, file)
-	}
-	return ""
-}
-
 func (props *PgoProperties) profileUseFlags(ctx ModuleContext, file string) []string {
-	flags := []string{props.profileUseFlag(ctx, file)}
+	flags := []string{fmt.Sprintf(profileUseInstrumentFormat, file)}
 	flags = append(flags, profileUseOtherFlags...)
 	return flags
 }
@@ -169,19 +153,14 @@
 		// if profileFile gets updated
 		flags.CFlagsDeps = append(flags.CFlagsDeps, profileFilePath)
 		flags.LdFlagsDeps = append(flags.LdFlagsDeps, profileFilePath)
-
-		if props.isSampling() {
-			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-no-warn-sample-unused=true")
-		}
 	}
 	return flags
 }
 
 func (props *PgoProperties) isPGO(ctx BaseModuleContext) bool {
 	isInstrumentation := props.isInstrumentation()
-	isSampling := props.isSampling()
 
-	profileKindPresent := isInstrumentation || isSampling
+	profileKindPresent := isInstrumentation
 	filePresent := props.Pgo.Profile_file != nil
 	benchmarksPresent := len(props.Pgo.Benchmarks) > 0
 
@@ -194,7 +173,7 @@
 	if !profileKindPresent || !filePresent {
 		var missing []string
 		if !profileKindPresent {
-			missing = append(missing, "profile kind (either \"instrumentation\" or \"sampling\" property)")
+			missing = append(missing, "profile kind")
 		}
 		if !filePresent {
 			missing = append(missing, "profile_file property")
@@ -208,14 +187,6 @@
 		ctx.ModuleErrorf("Instrumentation PGO specification is missing benchmark property")
 	}
 
-	if isSampling {
-		ctx.ModuleErrorf("Sampling PGO is deprecated, use AFDO instead")
-	}
-
-	if isSampling && isInstrumentation {
-		ctx.PropertyErrorf("pgo", "Exactly one of \"instrumentation\" and \"sampling\" properties must be set")
-	}
-
 	return true
 }
 
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index a29e618..8c404d3 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -55,6 +55,13 @@
 	// This is needed only if this library is linked by other modules in build time.
 	// Only makes sense for the Windows target.
 	Windows_import_lib *string `android:"path,arch_variant"`
+
+	// MixedBuildsDisabled is true if and only if building this prebuilt is explicitly disabled in mixed builds for either
+	// its static or shared version on the current build variant. This is to prevent Bazel targets for build variants with
+	// which either the static or shared version is incompatible from participating in mixed buiods. Please note that this
+	// is an override and does not fully determine whether Bazel or Soong will be used. For the full determination, see
+	// cc.ProcessBazelQueryResponse, cc.QueueBazelCall, and cc.MixedBuildsDisabled.
+	MixedBuildsDisabled bool `blueprint:"mutated"`
 }
 
 type prebuiltLinker struct {
@@ -244,6 +251,7 @@
 
 func (p *prebuiltLibraryLinker) disablePrebuilt() {
 	p.properties.Srcs = nil
+	p.properties.MixedBuildsDisabled = true
 }
 
 // Implements versionedInterface
@@ -255,6 +263,7 @@
 	module, library := NewLibrary(hod)
 	module.compiler = nil
 	module.bazelable = true
+	module.bazelHandler = &prebuiltLibraryBazelHandler{module: module, library: library}
 
 	prebuilt := &prebuiltLibraryLinker{
 		libraryDecorator: library,
@@ -310,8 +319,6 @@
 func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
 	module, library := NewPrebuiltLibrary(hod, "srcs")
 	library.BuildOnlyShared()
-	module.bazelable = true
-	module.bazelHandler = &prebuiltSharedLibraryBazelHandler{module: module, library: library}
 
 	// Prebuilt shared libraries can be included in APEXes
 	android.InitApexModule(module)
@@ -329,8 +336,7 @@
 func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
 	module, library := NewPrebuiltLibrary(hod, "srcs")
 	library.BuildOnlyStatic()
-	module.bazelable = true
-	module.bazelHandler = &prebuiltStaticLibraryBazelHandler{module: module, library: library}
+
 	return module, library
 }
 
@@ -406,29 +412,52 @@
 	properties prebuiltObjectProperties
 }
 
-type prebuiltStaticLibraryBazelHandler struct {
+type prebuiltLibraryBazelHandler struct {
 	module  *Module
 	library *libraryDecorator
 }
 
-var _ BazelHandler = (*prebuiltStaticLibraryBazelHandler)(nil)
+var _ BazelHandler = (*prebuiltLibraryBazelHandler)(nil)
 
-func (h *prebuiltStaticLibraryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
+func (h *prebuiltLibraryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
+	if h.module.linker.(*prebuiltLibraryLinker).properties.MixedBuildsDisabled {
+		return
+	}
 	bazelCtx := ctx.Config().BazelContext
 	bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKey(ctx))
 }
 
-func (h *prebuiltStaticLibraryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
+func (h *prebuiltLibraryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
+	if h.module.linker.(*prebuiltLibraryLinker).properties.MixedBuildsDisabled {
+		return
+	}
 	bazelCtx := ctx.Config().BazelContext
 	ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
 	if err != nil {
 		ctx.ModuleErrorf(err.Error())
 		return
 	}
+
+	if h.module.static() {
+		if ok := h.processStaticBazelQueryResponse(ctx, label, ccInfo); !ok {
+			return
+		}
+	} else if h.module.Shared() {
+		if ok := h.processSharedBazelQueryResponse(ctx, label, ccInfo); !ok {
+			return
+		}
+	} else {
+		return
+	}
+
+	h.module.maybeUnhideFromMake()
+}
+
+func (h *prebuiltLibraryBazelHandler) processStaticBazelQueryResponse(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool {
 	staticLibs := ccInfo.CcStaticLibraryFiles
 	if len(staticLibs) > 1 {
 		ctx.ModuleErrorf("expected 1 static library from bazel target %q, got %s", label, staticLibs)
-		return
+		return false
 	}
 
 	// TODO(b/184543518): cc_prebuilt_library_static may have properties for re-exporting flags
@@ -443,7 +472,7 @@
 
 	if len(staticLibs) == 0 {
 		h.module.outputFile = android.OptionalPath{}
-		return
+		return true
 	}
 
 	out := android.PathForBazelOut(ctx, staticLibs[0])
@@ -455,31 +484,15 @@
 
 		TransitiveStaticLibrariesForOrdering: depSet,
 	})
+
+	return true
 }
 
-type prebuiltSharedLibraryBazelHandler struct {
-	module  *Module
-	library *libraryDecorator
-}
-
-var _ BazelHandler = (*prebuiltSharedLibraryBazelHandler)(nil)
-
-func (h *prebuiltSharedLibraryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
-	bazelCtx := ctx.Config().BazelContext
-	bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKey(ctx))
-}
-
-func (h *prebuiltSharedLibraryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
-	bazelCtx := ctx.Config().BazelContext
-	ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
-	if err != nil {
-		ctx.ModuleErrorf(err.Error())
-		return
-	}
+func (h *prebuiltLibraryBazelHandler) processSharedBazelQueryResponse(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool {
 	sharedLibs := ccInfo.CcSharedLibraryFiles
-	if len(sharedLibs) != 1 {
+	if len(sharedLibs) > 1 {
 		ctx.ModuleErrorf("expected 1 shared library from bazel target %s, got %q", label, sharedLibs)
-		return
+		return false
 	}
 
 	// TODO(b/184543518): cc_prebuilt_library_shared may have properties for re-exporting flags
@@ -487,14 +500,9 @@
 	// TODO(eakammer):Add stub-related flags if this library is a stub library.
 	// h.library.exportVersioningMacroIfNeeded(ctx)
 
-	// Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise
-	// validation will fail. For now, set this to an empty list.
-	// TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation.
-	h.library.collectedSnapshotHeaders = android.Paths{}
-
 	if len(sharedLibs) == 0 {
 		h.module.outputFile = android.OptionalPath{}
-		return
+		return true
 	}
 
 	out := android.PathForBazelOut(ctx, sharedLibs[0])
@@ -519,6 +527,7 @@
 
 	h.library.setFlagExporterInfoFromCcInfo(ctx, ccInfo)
 	h.module.maybeUnhideFromMake()
+	return true
 }
 
 func (p *prebuiltObjectLinker) prebuilt() *android.Prebuilt {
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 901f458..e959157 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -381,6 +381,149 @@
 	assertString(t, static2.OutputFile().Path().Base(), "libf.hwasan.a")
 }
 
+func TestPrebuiltLibraryWithBazel(t *testing.T) {
+	const bp = `
+cc_prebuilt_library {
+	name: "foo",
+	shared: {
+		srcs: ["foo.so"],
+	},
+	static: {
+		srcs: ["foo.a"],
+	},
+	bazel_module: { label: "//foo/bar:bar" },
+}`
+	outBaseDir := "outputbase"
+	result := android.GroupFixturePreparers(
+		prepareForPrebuiltTest,
+		android.FixtureModifyConfig(func(config android.Config) {
+			config.BazelContext = android.MockBazelContext{
+				OutputBaseDir: outBaseDir,
+				LabelToCcInfo: map[string]cquery.CcInfo{
+					"//foo/bar:bar": cquery.CcInfo{
+						CcSharedLibraryFiles: []string{"foo.so"},
+					},
+					"//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{
+						CcStaticLibraryFiles: []string{"foo.a"},
+					},
+				},
+			}
+		}),
+	).RunTestWithBp(t, bp)
+	sharedFoo := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
+	pathPrefix := outBaseDir + "/execroot/__main__/"
+
+	sharedInfo := result.ModuleProvider(sharedFoo, SharedLibraryInfoProvider).(SharedLibraryInfo)
+	android.AssertPathRelativeToTopEquals(t,
+		"prebuilt library shared target path did not exist or did not match expected. If the base path is what does not match, it is likely that Soong built this module instead of Bazel.",
+		pathPrefix+"foo.so", sharedInfo.SharedLibrary)
+
+	outputFiles, err := sharedFoo.(android.OutputFileProducer).OutputFiles("")
+	if err != nil {
+		t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
+	}
+	expectedOutputFiles := []string{pathPrefix + "foo.so"}
+	android.AssertDeepEquals(t,
+		"prebuilt library shared target output files did not match expected.",
+		expectedOutputFiles, outputFiles.Strings())
+
+	staticFoo := result.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module()
+	staticInfo := result.ModuleProvider(staticFoo, StaticLibraryInfoProvider).(StaticLibraryInfo)
+	android.AssertPathRelativeToTopEquals(t,
+		"prebuilt library static target path did not exist or did not match expected. If the base path is what does not match, it is likely that Soong built this module instead of Bazel.",
+		pathPrefix+"foo.a", staticInfo.StaticLibrary)
+
+	staticOutputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("")
+	if err != nil {
+		t.Errorf("Unexpected error getting cc_object staticOutputFiles %s", err)
+	}
+	expectedStaticOutputFiles := []string{pathPrefix + "foo.a"}
+	android.AssertDeepEquals(t,
+		"prebuilt library static target output files did not match expected.",
+		expectedStaticOutputFiles, staticOutputFiles.Strings())
+}
+
+func TestPrebuiltLibraryWithBazelStaticDisabled(t *testing.T) {
+	const bp = `
+cc_prebuilt_library {
+	name: "foo",
+	shared: {
+		srcs: ["foo.so"],
+	},
+	static: {
+		enabled: false
+	},
+	bazel_module: { label: "//foo/bar:bar" },
+}`
+	outBaseDir := "outputbase"
+	result := android.GroupFixturePreparers(
+		prepareForPrebuiltTest,
+		android.FixtureModifyConfig(func(config android.Config) {
+			config.BazelContext = android.MockBazelContext{
+				OutputBaseDir: outBaseDir,
+				LabelToCcInfo: map[string]cquery.CcInfo{
+					"//foo/bar:bar": cquery.CcInfo{
+						CcSharedLibraryFiles: []string{"foo.so"},
+					},
+				},
+			}
+		}),
+	).RunTestWithBp(t, bp)
+	sharedFoo := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
+	pathPrefix := outBaseDir + "/execroot/__main__/"
+
+	sharedInfo := result.ModuleProvider(sharedFoo, SharedLibraryInfoProvider).(SharedLibraryInfo)
+	android.AssertPathRelativeToTopEquals(t,
+		"prebuilt library shared target path did not exist or did not match expected. If the base path is what does not match, it is likely that Soong built this module instead of Bazel.",
+		pathPrefix+"foo.so", sharedInfo.SharedLibrary)
+
+	outputFiles, err := sharedFoo.(android.OutputFileProducer).OutputFiles("")
+	if err != nil {
+		t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
+	}
+	expectedOutputFiles := []string{pathPrefix + "foo.so"}
+	android.AssertDeepEquals(t,
+		"prebuilt library shared target output files did not match expected.",
+		expectedOutputFiles, outputFiles.Strings())
+}
+
+func TestPrebuiltLibraryStaticWithBazel(t *testing.T) {
+	const bp = `
+cc_prebuilt_library_static {
+	name: "foo",
+	srcs: ["foo.so"],
+	bazel_module: { label: "//foo/bar:bar" },
+}`
+	outBaseDir := "outputbase"
+	result := android.GroupFixturePreparers(
+		prepareForPrebuiltTest,
+		android.FixtureModifyConfig(func(config android.Config) {
+			config.BazelContext = android.MockBazelContext{
+				OutputBaseDir: outBaseDir,
+				LabelToCcInfo: map[string]cquery.CcInfo{
+					"//foo/bar:bar": cquery.CcInfo{
+						CcStaticLibraryFiles: []string{"foo.so"},
+					},
+				},
+			}
+		}),
+	).RunTestWithBp(t, bp)
+	staticFoo := result.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module()
+	pathPrefix := outBaseDir + "/execroot/__main__/"
+
+	info := result.ModuleProvider(staticFoo, StaticLibraryInfoProvider).(StaticLibraryInfo)
+	android.AssertPathRelativeToTopEquals(t,
+		"prebuilt library static path did not match expected. If the base path is what does not match, it is likely that Soong built this module instead of Bazel.",
+		pathPrefix+"foo.so", info.StaticLibrary)
+
+	outputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("")
+	if err != nil {
+		t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
+	}
+	expectedOutputFiles := []string{pathPrefix + "foo.so"}
+	android.AssertDeepEquals(t, "prebuilt library static output files did not match expected.", expectedOutputFiles, outputFiles.Strings())
+}
+
 func TestPrebuiltLibrarySharedWithBazelWithoutToc(t *testing.T) {
 	const bp = `
 cc_prebuilt_library_shared {
diff --git a/cc/tidy.go b/cc/tidy.go
index ac1521b..ff49c64 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -144,8 +144,23 @@
 		tidyChecks += config.TidyChecksForDir(ctx.ModuleDir())
 	}
 	if len(tidy.Properties.Tidy_checks) > 0 {
-		tidyChecks = tidyChecks + "," + strings.Join(esc(ctx, "tidy_checks",
-			config.ClangRewriteTidyChecks(tidy.Properties.Tidy_checks)), ",")
+		// If Tidy_checks contains "-*", ignore all checks before "-*".
+		localChecks := tidy.Properties.Tidy_checks
+		ignoreGlobalChecks := false
+		for n, check := range tidy.Properties.Tidy_checks {
+			if check == "-*" {
+				ignoreGlobalChecks = true
+				localChecks = tidy.Properties.Tidy_checks[n:]
+			}
+		}
+		if ignoreGlobalChecks {
+			tidyChecks = "-checks=" + strings.Join(esc(ctx, "tidy_checks",
+				config.ClangRewriteTidyChecks(localChecks)), ",")
+		} else {
+			tidyChecks = tidyChecks + "," + strings.Join(esc(ctx, "tidy_checks",
+				config.ClangRewriteTidyChecks(localChecks)), ",")
+		}
+
 	}
 	if ctx.Windows() {
 		// https://b.corp.google.com/issues/120614316
diff --git a/cc/tidy_test.go b/cc/tidy_test.go
index 339b302..14b33b2 100644
--- a/cc/tidy_test.go
+++ b/cc/tidy_test.go
@@ -16,11 +16,83 @@
 
 import (
 	"fmt"
+	"strings"
 	"testing"
 
 	"android/soong/android"
 )
 
+func TestTidyChecks(t *testing.T) {
+	// The "tidy_checks" property defines additional checks appended
+	// to global default. But there are some checks disabled after
+	// the local tidy_checks.
+	bp := `
+		cc_library_shared { // has global checks + extraGlobalChecks
+			name: "libfoo_1",
+			srcs: ["foo.c"],
+		}
+		cc_library_shared { // has only local checks + extraGlobalChecks
+			name: "libfoo_2",
+			srcs: ["foo.c"],
+			tidy_checks: ["-*", "xyz-*"],
+		}
+		cc_library_shared { // has global checks + local checks + extraGlobalChecks
+			name: "libfoo_3",
+			srcs: ["foo.c"],
+			tidy_checks: ["-abc*", "xyz-*", "mycheck"],
+		}
+		cc_library_shared { // has only local checks after "-*" + extraGlobalChecks
+			name: "libfoo_4",
+			srcs: ["foo.c"],
+			tidy_checks: ["-abc*", "xyz-*", "mycheck", "-*", "xyz-*"],
+		}`
+	ctx := testCc(t, bp)
+
+	globalChecks := "-checks=${config.TidyDefaultGlobalChecks},"
+	firstXyzChecks := "-checks='-*','xyz-*',"
+	localXyzChecks := "'-*','xyz-*'"
+	localAbcChecks := "'-abc*','xyz-*',mycheck"
+	extraGlobalChecks := ",-bugprone-easily-swappable-parameters,"
+	testCases := []struct {
+		libNumber int      // 1,2,3,...
+		checks    []string // must have substrings in -checks
+		noChecks  []string // must not have substrings in -checks
+	}{
+		{1, []string{globalChecks, extraGlobalChecks}, []string{localXyzChecks, localAbcChecks}},
+		{2, []string{firstXyzChecks, extraGlobalChecks}, []string{globalChecks, localAbcChecks}},
+		{3, []string{globalChecks, localAbcChecks, extraGlobalChecks}, []string{localXyzChecks}},
+		{4, []string{firstXyzChecks, extraGlobalChecks}, []string{globalChecks, localAbcChecks}},
+	}
+	t.Run("caseTidyChecks", func(t *testing.T) {
+		variant := "android_arm64_armv8-a_shared"
+		for _, test := range testCases {
+			libName := fmt.Sprintf("libfoo_%d", test.libNumber)
+			flags := ctx.ModuleForTests(libName, variant).Rule("clangTidy").Args["tidyFlags"]
+			splitFlags := strings.Split(flags, " ")
+			foundCheckFlag := false
+			for _, flag := range splitFlags {
+				if strings.HasPrefix(flag, "-checks=") {
+					foundCheckFlag = true
+					for _, check := range test.checks {
+						if !strings.Contains(flag, check) {
+							t.Errorf("tidyFlags for %s does not contain %s.", libName, check)
+						}
+					}
+					for _, check := range test.noChecks {
+						if strings.Contains(flag, check) {
+							t.Errorf("tidyFlags for %s should not contain %s.", libName, check)
+						}
+					}
+					break
+				}
+			}
+			if !foundCheckFlag {
+				t.Errorf("tidyFlags for %s does not contain -checks=.", libName)
+			}
+		}
+	})
+}
+
 func TestWithTidy(t *testing.T) {
 	// When WITH_TIDY=1 or (ALLOW_LOCAL_TIDY_TRUE=1 and local tidy:true)
 	// a C++ library should depend on .tidy files.
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index bd5a1bd..c548ef8 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -446,6 +446,8 @@
 
 	// FIXME: 'autotest_lib' is a symlink back to external/autotest, and this causes an infinite symlink expansion error for Bazel
 	excludes = append(excludes, "external/autotest/venv/autotest_lib")
+	excludes = append(excludes, "external/autotest/autotest_lib")
+	excludes = append(excludes, "external/autotest/client/autotest_lib/client")
 
 	// FIXME: The external/google-fruit/extras/bazel_root/third_party/fruit dir is poison
 	// It contains several symlinks back to real source dirs, and those source dirs contain BUILD files we want to ignore
diff --git a/java/java.go b/java/java.go
index 0dfb968..feb49ad 100644
--- a/java/java.go
+++ b/java/java.go
@@ -864,7 +864,25 @@
 	Data_native_bins []string `android:"arch_variant"`
 
 	// list of device binary modules that should be installed alongside the test
-	Data_device_bins []string `android:"arch_variant"`
+	// This property only adds the first variant of the dependency
+	Data_device_bins_first []string `android:"arch_variant"`
+
+	// list of device binary modules that should be installed alongside the test
+	// This property adds 64bit AND 32bit variants of the dependency
+	Data_device_bins_both []string `android:"arch_variant"`
+
+	// list of device binary modules that should be installed alongside the test
+	// This property only adds 64bit variants of the dependency
+	Data_device_bins_64 []string `android:"arch_variant"`
+
+	// list of device binary modules that should be installed alongside the test
+	// This property adds 32bit variants of the dependency if available, or else
+	// defaults to the 64bit variant
+	Data_device_bins_prefer32 []string `android:"arch_variant"`
+
+	// list of device binary modules that should be installed alongside the test
+	// This property only adds 32bit variants of the dependency
+	Data_device_bins_32 []string `android:"arch_variant"`
 }
 
 type testHelperLibraryProperties struct {
@@ -931,6 +949,83 @@
 	return true
 }
 
+func (j *TestHost) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext) {
+	if len(j.testHostProperties.Data_device_bins_first) > 0 {
+		deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations()
+		ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_first...)
+	}
+
+	var maybeAndroid32Target *android.Target
+	var maybeAndroid64Target *android.Target
+	android32TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib32")
+	android64TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib64")
+	if len(android32TargetList) > 0 {
+		maybeAndroid32Target = &android32TargetList[0]
+	}
+	if len(android64TargetList) > 0 {
+		maybeAndroid64Target = &android64TargetList[0]
+	}
+
+	if len(j.testHostProperties.Data_device_bins_both) > 0 {
+		if maybeAndroid32Target == nil && maybeAndroid64Target == nil {
+			ctx.PropertyErrorf("data_device_bins_both", "no device targets available. Targets: %q", ctx.Config().Targets)
+			return
+		}
+		if maybeAndroid32Target != nil {
+			ctx.AddFarVariationDependencies(
+				maybeAndroid32Target.Variations(),
+				dataDeviceBinsTag,
+				j.testHostProperties.Data_device_bins_both...,
+			)
+		}
+		if maybeAndroid64Target != nil {
+			ctx.AddFarVariationDependencies(
+				maybeAndroid64Target.Variations(),
+				dataDeviceBinsTag,
+				j.testHostProperties.Data_device_bins_both...,
+			)
+		}
+	}
+
+	if len(j.testHostProperties.Data_device_bins_prefer32) > 0 {
+		if maybeAndroid32Target != nil {
+			ctx.AddFarVariationDependencies(
+				maybeAndroid32Target.Variations(),
+				dataDeviceBinsTag,
+				j.testHostProperties.Data_device_bins_prefer32...,
+			)
+		} else {
+			if maybeAndroid64Target == nil {
+				ctx.PropertyErrorf("data_device_bins_prefer32", "no device targets available. Targets: %q", ctx.Config().Targets)
+				return
+			}
+			ctx.AddFarVariationDependencies(
+				maybeAndroid64Target.Variations(),
+				dataDeviceBinsTag,
+				j.testHostProperties.Data_device_bins_prefer32...,
+			)
+		}
+	}
+
+	if len(j.testHostProperties.Data_device_bins_32) > 0 {
+		if maybeAndroid32Target == nil {
+			ctx.PropertyErrorf("data_device_bins_32", "cannot find 32bit device target. Targets: %q", ctx.Config().Targets)
+			return
+		}
+		deviceVariations := maybeAndroid32Target.Variations()
+		ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_32...)
+	}
+
+	if len(j.testHostProperties.Data_device_bins_64) > 0 {
+		if maybeAndroid64Target == nil {
+			ctx.PropertyErrorf("data_device_bins_64", "cannot find 64bit device target. Targets: %q", ctx.Config().Targets)
+			return
+		}
+		deviceVariations := maybeAndroid64Target.Variations()
+		ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_64...)
+	}
+}
+
 func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) {
 	if len(j.testHostProperties.Data_native_bins) > 0 {
 		for _, target := range ctx.MultiTargets() {
@@ -938,11 +1033,6 @@
 		}
 	}
 
-	if len(j.testHostProperties.Data_device_bins) > 0 {
-		deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations()
-		ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins...)
-	}
-
 	if len(j.testProperties.Jni_libs) > 0 {
 		for _, target := range ctx.MultiTargets() {
 			sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
@@ -950,6 +1040,8 @@
 		}
 	}
 
+	j.addDataDeviceBinsDeps(ctx)
+
 	j.deps(ctx)
 }
 
@@ -957,17 +1049,40 @@
 	j.extraResources = append(j.extraResources, p)
 }
 
+func (j *TestHost) dataDeviceBins() []string {
+	ret := make([]string, 0,
+		len(j.testHostProperties.Data_device_bins_first)+
+			len(j.testHostProperties.Data_device_bins_both)+
+			len(j.testHostProperties.Data_device_bins_prefer32)+
+			len(j.testHostProperties.Data_device_bins_32)+
+			len(j.testHostProperties.Data_device_bins_64),
+	)
+
+	ret = append(ret, j.testHostProperties.Data_device_bins_first...)
+	ret = append(ret, j.testHostProperties.Data_device_bins_both...)
+	ret = append(ret, j.testHostProperties.Data_device_bins_prefer32...)
+	ret = append(ret, j.testHostProperties.Data_device_bins_32...)
+	ret = append(ret, j.testHostProperties.Data_device_bins_64...)
+
+	return ret
+}
+
 func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	var configs []tradefed.Config
-	if len(j.testHostProperties.Data_device_bins) > 0 {
+	dataDeviceBins := j.dataDeviceBins()
+	if len(dataDeviceBins) > 0 {
 		// add Tradefed configuration to push device bins to device for testing
 		remoteDir := filepath.Join("/data/local/tests/unrestricted/", j.Name())
 		options := []tradefed.Option{{Name: "cleanup", Value: "true"}}
-		for _, bin := range j.testHostProperties.Data_device_bins {
+		for _, bin := range dataDeviceBins {
 			fullPath := filepath.Join(remoteDir, bin)
 			options = append(options, tradefed.Option{Name: "push-file", Key: bin, Value: fullPath})
 		}
-		configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.PushFilePreparer", options})
+		configs = append(configs, tradefed.Object{
+			Type:    "target_preparer",
+			Class:   "com.android.tradefed.targetprep.PushFilePreparer",
+			Options: options,
+		})
 	}
 
 	j.Test.generateAndroidBuildActionsWithConfig(ctx, configs)
diff --git a/java/java_test.go b/java/java_test.go
index 56a4248..32b0b0f 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1498,62 +1498,172 @@
 }
 
 func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) {
-	bp := `
-		java_test_host {
-			name: "foo",
-			srcs: ["test.java"],
-			data_device_bins: ["bar"],
-		}
-
-		cc_binary {
-			name: "bar",
-		}
-	`
-
-	ctx := android.GroupFixturePreparers(
-		PrepareForIntegrationTestWithJava,
-	).RunTestWithBp(t, bp)
-
-	buildOS := ctx.Config.BuildOS.String()
-	fooVariant := ctx.ModuleForTests("foo", buildOS+"_common")
-	barVariant := ctx.ModuleForTests("bar", "android_arm64_armv8-a")
-	fooMod := fooVariant.Module().(*TestHost)
-
-	relocated := barVariant.Output("bar")
-	expectedInput := "out/soong/.intermediates/bar/android_arm64_armv8-a/unstripped/bar"
-	android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input)
-
-	entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0]
-	expectedData := []string{
-		"out/soong/.intermediates/bar/android_arm64_armv8-a/bar:bar",
+	testCases := []struct {
+		dataDeviceBinType  string
+		depCompileMultilib string
+		variants           []string
+		expectedError      string
+	}{
+		{
+			dataDeviceBinType:  "first",
+			depCompileMultilib: "first",
+			variants:           []string{"android_arm64_armv8-a"},
+		},
+		{
+			dataDeviceBinType:  "first",
+			depCompileMultilib: "both",
+			variants:           []string{"android_arm64_armv8-a"},
+		},
+		{
+			// this is true because our testing framework is set up with
+			// Targets ~ [<64bit target>, <32bit target>], where 64bit is "first"
+			dataDeviceBinType:  "first",
+			depCompileMultilib: "32",
+			expectedError:      `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
+		},
+		{
+			dataDeviceBinType:  "first",
+			depCompileMultilib: "64",
+			variants:           []string{"android_arm64_armv8-a"},
+		},
+		{
+			dataDeviceBinType:  "both",
+			depCompileMultilib: "both",
+			variants: []string{
+				"android_arm_armv7-a-neon",
+				"android_arm64_armv8-a",
+			},
+		},
+		{
+			dataDeviceBinType:  "both",
+			depCompileMultilib: "32",
+			expectedError:      `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
+		},
+		{
+			dataDeviceBinType:  "both",
+			depCompileMultilib: "64",
+			expectedError:      `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
+		},
+		{
+			dataDeviceBinType:  "both",
+			depCompileMultilib: "first",
+			expectedError:      `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
+		},
+		{
+			dataDeviceBinType:  "32",
+			depCompileMultilib: "32",
+			variants:           []string{"android_arm_armv7-a-neon"},
+		},
+		{
+			dataDeviceBinType:  "32",
+			depCompileMultilib: "first",
+			expectedError:      `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
+		},
+		{
+			dataDeviceBinType:  "32",
+			depCompileMultilib: "both",
+			variants:           []string{"android_arm_armv7-a-neon"},
+		},
+		{
+			dataDeviceBinType:  "32",
+			depCompileMultilib: "64",
+			expectedError:      `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
+		},
+		{
+			dataDeviceBinType:  "64",
+			depCompileMultilib: "64",
+			variants:           []string{"android_arm64_armv8-a"},
+		},
+		{
+			dataDeviceBinType:  "64",
+			depCompileMultilib: "both",
+			variants:           []string{"android_arm64_armv8-a"},
+		},
+		{
+			dataDeviceBinType:  "64",
+			depCompileMultilib: "first",
+			variants:           []string{"android_arm64_armv8-a"},
+		},
+		{
+			dataDeviceBinType:  "64",
+			depCompileMultilib: "32",
+			expectedError:      `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
+		},
+		{
+			dataDeviceBinType:  "prefer32",
+			depCompileMultilib: "32",
+			variants:           []string{"android_arm_armv7-a-neon"},
+		},
+		{
+			dataDeviceBinType:  "prefer32",
+			depCompileMultilib: "both",
+			variants:           []string{"android_arm_armv7-a-neon"},
+		},
+		{
+			dataDeviceBinType:  "prefer32",
+			depCompileMultilib: "first",
+			expectedError:      `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
+		},
+		{
+			dataDeviceBinType:  "prefer32",
+			depCompileMultilib: "64",
+			expectedError:      `Android.bp:2:3: dependency "bar" of "foo" missing variant`,
+		},
 	}
-	actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
-	android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, expectedData, actualData)
-}
 
-func TestDataDeviceBinsAutogenTradefedConfig(t *testing.T) {
-	bp := `
+	bpTemplate := `
 		java_test_host {
 			name: "foo",
 			srcs: ["test.java"],
-			data_device_bins: ["bar"],
+			data_device_bins_%s: ["bar"],
 		}
 
 		cc_binary {
 			name: "bar",
+			compile_multilib: "%s",
 		}
 	`
 
-	ctx := android.GroupFixturePreparers(
-		PrepareForIntegrationTestWithJava,
-	).RunTestWithBp(t, bp)
+	for _, tc := range testCases {
+		bp := fmt.Sprintf(bpTemplate, tc.dataDeviceBinType, tc.depCompileMultilib)
 
-	buildOS := ctx.Config.BuildOS.String()
-	fooModule := ctx.ModuleForTests("foo", buildOS+"_common")
-	expectedAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />`
+		errorHandler := android.FixtureExpectsNoErrors
+		if tc.expectedError != "" {
+			errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError)
+		}
 
-	autogen := fooModule.Rule("autogen")
-	if !strings.Contains(autogen.Args["extraConfigs"], expectedAutogenConfig) {
-		t.Errorf("foo extraConfigs %v does not contain %q", autogen.Args["extraConfigs"], expectedAutogenConfig)
+		testName := fmt.Sprintf(`data_device_bins_%s with compile_multilib:"%s"`, tc.dataDeviceBinType, tc.depCompileMultilib)
+		t.Run(testName, func(t *testing.T) {
+			ctx := android.GroupFixturePreparers(PrepareForIntegrationTestWithJava).
+				ExtendWithErrorHandler(errorHandler).
+				RunTestWithBp(t, bp)
+			if tc.expectedError != "" {
+				return
+			}
+
+			buildOS := ctx.Config.BuildOS.String()
+			fooVariant := ctx.ModuleForTests("foo", buildOS+"_common")
+			fooMod := fooVariant.Module().(*TestHost)
+			entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0]
+
+			expectedAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />`
+			autogen := fooVariant.Rule("autogen")
+			if !strings.Contains(autogen.Args["extraConfigs"], expectedAutogenConfig) {
+				t.Errorf("foo extraConfigs %v does not contain %q", autogen.Args["extraConfigs"], expectedAutogenConfig)
+			}
+
+			expectedData := []string{}
+			for _, variant := range tc.variants {
+				barVariant := ctx.ModuleForTests("bar", variant)
+				relocated := barVariant.Output("bar")
+				expectedInput := fmt.Sprintf("out/soong/.intermediates/bar/%s/unstripped/bar", variant)
+				android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input)
+
+				expectedData = append(expectedData, fmt.Sprintf("out/soong/.intermediates/bar/%s/bar:bar", variant))
+			}
+
+			actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
+			android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, expectedData, actualData)
+		})
 	}
 }
diff --git a/rust/config/global.go b/rust/config/global.go
index 554cfe2..647a7cf 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
 var pctx = android.NewPackageContext("android/soong/rust/config")
 
 var (
-	RustDefaultVersion = "1.61.0"
+	RustDefaultVersion = "1.61.0.p1"
 	RustDefaultBase    = "prebuilts/rust/"
 	DefaultEdition     = "2021"
 	Stdlibs            = []string{
diff --git a/rust/coverage.go b/rust/coverage.go
index 651ce6e..5ea481f 100644
--- a/rust/coverage.go
+++ b/rust/coverage.go
@@ -56,7 +56,7 @@
 		flags.Coverage = true
 		coverage := ctx.GetDirectDepWithTag(CovLibraryName, cc.CoverageDepTag).(cc.LinkableInterface)
 		flags.RustFlags = append(flags.RustFlags,
-			"-Z instrument-coverage", "-g")
+			"-C instrument-coverage", "-g")
 		flags.LinkFlags = append(flags.LinkFlags,
 			profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open")
 		deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path())
diff --git a/rust/coverage_test.go b/rust/coverage_test.go
index f3cd375..0f599d7 100644
--- a/rust/coverage_test.go
+++ b/rust/coverage_test.go
@@ -56,7 +56,7 @@
 	fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
 	buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
 
-	rustcCoverageFlags := []string{"-Z instrument-coverage", " -g "}
+	rustcCoverageFlags := []string{"-C instrument-coverage", " -g "}
 	for _, flag := range rustcCoverageFlags {
 		missingErrorStr := "missing rustc flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
 		containsErrorStr := "contains rustc flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
diff --git a/ui/build/build.go b/ui/build/build.go
index aadf4af..ec42b70 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -266,6 +266,7 @@
 	}
 
 	if config.StartRBE() {
+		cleanupRBELogsDir(ctx, config)
 		startRBE(ctx, config)
 		defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
 	}
diff --git a/ui/build/config.go b/ui/build/config.go
index 0092ff1..5765f21 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -19,12 +19,14 @@
 	"encoding/json"
 	"fmt"
 	"io/ioutil"
+	"math/rand"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"runtime"
 	"strconv"
 	"strings"
+	"syscall"
 	"time"
 
 	"android/soong/shared"
@@ -42,6 +44,15 @@
 	envConfigFetchTimeout = 10 * time.Second
 )
 
+var (
+	rbeRandPrefix int
+)
+
+func init() {
+	rand.Seed(time.Now().UnixNano())
+	rbeRandPrefix = rand.Intn(1000)
+}
+
 type Config struct{ *configImpl }
 
 type configImpl struct {
@@ -1144,34 +1155,25 @@
 	return true
 }
 
-func (c *configImpl) rbeLogDir() string {
-	for _, f := range []string{"RBE_log_dir", "FLAG_log_dir"} {
+func (c *configImpl) rbeProxyLogsDir() string {
+	for _, f := range []string{"RBE_proxy_log_dir", "FLAG_output_dir"} {
 		if v, ok := c.environ.Get(f); ok {
 			return v
 		}
 	}
-	if c.Dist() {
-		return c.LogsDir()
-	}
-	return c.OutDir()
+	buildTmpDir := shared.TempDirForOutDir(c.SoongOutDir())
+	return filepath.Join(buildTmpDir, "rbe")
 }
 
-func (c *configImpl) rbeStatsOutputDir() string {
-	for _, f := range []string{"RBE_output_dir", "FLAG_output_dir"} {
-		if v, ok := c.environ.Get(f); ok {
-			return v
+func (c *configImpl) shouldCleanupRBELogsDir() bool {
+	// Perform a log directory cleanup only when the log directory
+	// is auto created by the build rather than user-specified.
+	for _, f := range []string{"RBE_proxy_log_dir", "FLAG_output_dir"} {
+		if _, ok := c.environ.Get(f); ok {
+			return false
 		}
 	}
-	return c.rbeLogDir()
-}
-
-func (c *configImpl) rbeLogPath() string {
-	for _, f := range []string{"RBE_log_path", "FLAG_log_path"} {
-		if v, ok := c.environ.Get(f); ok {
-			return v
-		}
-	}
-	return fmt.Sprintf("text://%v/reproxy_log.txt", c.rbeLogDir())
+	return true
 }
 
 func (c *configImpl) rbeExecRoot() string {
@@ -1223,19 +1225,21 @@
 	return "RBE_use_application_default_credentials", "true"
 }
 
-func (c *configImpl) IsGooglerEnvironment() bool {
-	cf := "ANDROID_BUILD_ENVIRONMENT_CONFIG"
-	if v, ok := c.environ.Get(cf); ok {
-		return v == "googler"
-	}
-	return false
-}
+func (c *configImpl) rbeSockAddr(dir string) (string, error) {
+	maxNameLen := len(syscall.RawSockaddrUnix{}.Path)
+	base := fmt.Sprintf("reproxy_%v.sock", rbeRandPrefix)
 
-func (c *configImpl) GoogleProdCredsExist() bool {
-	if _, err := exec.Command("/usr/bin/prodcertstatus", "--simple_output", "--nocheck_loas").Output(); err != nil {
-		return false
+	name := filepath.Join(dir, base)
+	if len(name) < maxNameLen {
+		return name, nil
 	}
-	return true
+
+	name = filepath.Join("/tmp", base)
+	if len(name) < maxNameLen {
+		return name, nil
+	}
+
+	return "", fmt.Errorf("cannot generate a proxy socket address shorter than the limit of %v", maxNameLen)
 }
 
 func (c *configImpl) UseRemoteBuild() bool {
diff --git a/ui/build/rbe.go b/ui/build/rbe.go
index 78d37b4..3e558f7 100644
--- a/ui/build/rbe.go
+++ b/ui/build/rbe.go
@@ -16,12 +16,9 @@
 
 import (
 	"fmt"
-	"math/rand"
 	"os"
 	"path/filepath"
 	"runtime"
-	"syscall"
-	"time"
 
 	"android/soong/ui/metrics"
 )
@@ -54,34 +51,16 @@
 	return cmdPath
 }
 
-func sockAddr(dir string) (string, error) {
-	maxNameLen := len(syscall.RawSockaddrUnix{}.Path)
-	rand.Seed(time.Now().UnixNano())
-	base := fmt.Sprintf("reproxy_%v.sock", rand.Intn(1000))
-
-	name := filepath.Join(dir, base)
-	if len(name) < maxNameLen {
-		return name, nil
-	}
-
-	name = filepath.Join("/tmp", base)
-	if len(name) < maxNameLen {
-		return name, nil
-	}
-
-	return "", fmt.Errorf("cannot generate a proxy socket address shorter than the limit of %v", maxNameLen)
-}
-
 func getRBEVars(ctx Context, config Config) map[string]string {
 	vars := map[string]string{
-		"RBE_log_path":   config.rbeLogPath(),
-		"RBE_log_dir":    config.rbeLogDir(),
+		"RBE_log_dir":    config.rbeProxyLogsDir(),
 		"RBE_re_proxy":   config.rbeReproxy(),
 		"RBE_exec_root":  config.rbeExecRoot(),
-		"RBE_output_dir": config.rbeStatsOutputDir(),
+		"RBE_output_dir": config.rbeProxyLogsDir(),
+		"RBE_proxy_log_dir": config.rbeProxyLogsDir(),
 	}
 	if config.StartRBE() {
-		name, err := sockAddr(absPath(ctx, config.TempDir()))
+		name, err := config.rbeSockAddr(absPath(ctx, config.TempDir()))
 		if err != nil {
 			ctx.Fatalf("Error retrieving socket address: %v", err)
 			return nil
@@ -100,6 +79,17 @@
 	return vars
 }
 
+func cleanupRBELogsDir(ctx Context, config Config) {
+	if !config.shouldCleanupRBELogsDir() {
+		return
+	}
+
+	rbeTmpDir := config.rbeProxyLogsDir()
+	if err := os.RemoveAll(rbeTmpDir); err != nil {
+		fmt.Fprintln(ctx.Writer, "\033[33mUnable to remove RBE log directory: ", err, "\033[0m")
+	}
+}
+
 func startRBE(ctx Context, config Config) {
 	ctx.BeginTrace(metrics.RunSetupTool, "rbe_bootstrap")
 	defer ctx.EndTrace()
@@ -110,6 +100,11 @@
 	if n := ulimitOrFatal(ctx, config, "-n"); n < rbeLeastNFiles {
 		ctx.Fatalf("max open files is insufficient: %d; want >= %d.\n", n, rbeLeastNFiles)
 	}
+	if _, err := os.Stat(config.rbeProxyLogsDir()); os.IsNotExist(err) {
+		if err := os.MkdirAll(config.rbeProxyLogsDir(), 0744); err != nil {
+			ctx.Fatalf("Unable to create logs dir (%v) for RBE: %v", config.rbeProxyLogsDir, err)
+		}
+	}
 
 	cmd := Command(ctx, config, "startRBE bootstrap", rbeCommand(ctx, config, bootstrapCmd))
 
@@ -119,7 +114,6 @@
 }
 
 func stopRBE(ctx Context, config Config) {
-	defer checkProdCreds(ctx, config)
 	cmd := Command(ctx, config, "stopRBE bootstrap", rbeCommand(ctx, config, bootstrapCmd), "-shutdown")
 	output, err := cmd.CombinedOutput()
 	if err != nil {
@@ -132,15 +126,6 @@
 	}
 }
 
-func checkProdCreds(ctx Context, config Config) {
-	if !config.IsGooglerEnvironment() || config.GoogleProdCredsExist() {
-		return
-	}
-	fmt.Fprintln(ctx.Writer, "")
-	fmt.Fprintln(ctx.Writer, "\033[33mWARNING: Missing LOAS credentials, please run `gcert`. This will result in failing RBE builds in the future, see go/build-fast#authentication.\033[0m")
-	fmt.Fprintln(ctx.Writer, "")
-}
-
 // DumpRBEMetrics creates a metrics protobuf file containing RBE related metrics.
 // The protobuf file is created if RBE is enabled and the proxy service has
 // started. The proxy service is shutdown in order to dump the RBE metrics to the
@@ -161,7 +146,7 @@
 		return
 	}
 
-	outputDir := config.rbeStatsOutputDir()
+	outputDir := config.rbeProxyLogsDir()
 	if outputDir == "" {
 		ctx.Fatal("RBE output dir variable not defined. Aborting metrics dumping.")
 	}
diff --git a/ui/build/rbe_test.go b/ui/build/rbe_test.go
index 8ff96bc..266f76b 100644
--- a/ui/build/rbe_test.go
+++ b/ui/build/rbe_test.go
@@ -56,7 +56,8 @@
 			env := Environment(tt.env)
 			env.Set("OUT_DIR", tmpDir)
 			env.Set("RBE_DIR", tmpDir)
-			env.Set("RBE_output_dir", t.TempDir())
+			env.Set("RBE_output_dir", tmpDir)
+			env.Set("RBE_proxy_log_dir", tmpDir)
 			config := Config{&configImpl{
 				environ: &env,
 			}}