Merge "Drop host variant of lidbexfile in >=V snapshots" into main
diff --git a/aconfig/codegen/rust_aconfig_library_test.go b/aconfig/codegen/rust_aconfig_library_test.go
index 1bd5397..fe28f94 100644
--- a/aconfig/codegen/rust_aconfig_library_test.go
+++ b/aconfig/codegen/rust_aconfig_library_test.go
@@ -11,7 +11,7 @@
 func TestRustAconfigLibrary(t *testing.T) {
 	result := android.GroupFixturePreparers(
 		PrepareForTestWithAconfigBuildComponents,
-		rust.PrepareForTestWithRustIncludeVndk,
+		rust.PrepareForIntegrationTestWithRust,
 		android.PrepareForTestWithArchMutator,
 		android.PrepareForTestWithDefaults,
 		android.PrepareForTestWithPrebuilts,
@@ -100,7 +100,7 @@
 	t.Helper()
 	result := android.GroupFixturePreparers(
 		PrepareForTestWithAconfigBuildComponents,
-		rust.PrepareForTestWithRustIncludeVndk).
+		rust.PrepareForIntegrationTestWithRust).
 		ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
 		RunTestWithBp(t, fmt.Sprintf(`
 			rust_library {
@@ -162,7 +162,7 @@
 	t.Helper()
 	android.GroupFixturePreparers(
 		PrepareForTestWithAconfigBuildComponents,
-		rust.PrepareForTestWithRustIncludeVndk).
+		rust.PrepareForIntegrationTestWithRust).
 		ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(err)).
 		RunTestWithBp(t, fmt.Sprintf(`
 			rust_library {
diff --git a/android/config.go b/android/config.go
index 2ee3b93..651b6ea 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1448,10 +1448,6 @@
 	return StringDefault(c.config.productVariables.DeviceCurrentApiLevelForVendorModules, "current")
 }
 
-func (c *deviceConfig) PlatformVndkVersion() string {
-	return String(c.config.productVariables.Platform_vndk_version)
-}
-
 func (c *deviceConfig) ExtraVndkVersions() []string {
 	return c.config.productVariables.ExtraVndkVersions
 }
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 5a94a0f..91ba05b 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -71,6 +71,9 @@
 	//
 	// If specified then the prefer property is ignored in favor of the value of the Soong config
 	// variable.
+	//
+	// DEPRECATED: This property is being deprecated b/308188211.
+	// Use RELEASE_APEX_CONTRIBUTIONS build flags to select prebuilts of mainline modules.
 	Use_source_config_var *ConfigVarProperties
 }
 
diff --git a/android/selects_test.go b/android/selects_test.go
index b4e226f..adbe59a 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -202,7 +202,7 @@
 			},
 		},
 		{
-			name: "Can't append bools",
+			name: "true + false = true",
 			bp: `
 			my_module_type {
 				name: "foo",
@@ -213,7 +213,30 @@
 				}) + false,
 			}
 			`,
-			expectedError: "my_bool: Cannot append bools",
+			provider: selectsTestProvider{
+				my_bool: proptools.BoolPtr(true),
+			},
+		},
+		{
+			name: "false + false = false",
+			bp: `
+			my_module_type {
+				name: "foo",
+				my_bool: select(soong_config_variable("my_namespace", "my_variable"), {
+					"a": true,
+					"b": false,
+					_: true,
+				}) + false,
+			}
+			`,
+			vendorVars: map[string]map[string]string{
+				"my_namespace": {
+					"my_variable": "b",
+				},
+			},
+			provider: selectsTestProvider{
+				my_bool: proptools.BoolPtr(false),
+			},
 		},
 		{
 			name: "Append string",
diff --git a/android/variable.go b/android/variable.go
index 9b630c0..fc5ae23 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -209,7 +209,6 @@
 	Platform_base_sdk_extension_version       *int     `json:",omitempty"`
 	Platform_version_active_codenames         []string `json:",omitempty"`
 	Platform_version_all_preview_codenames    []string `json:",omitempty"`
-	Platform_vndk_version                     *string  `json:",omitempty"`
 	Platform_systemsdk_versions               []string `json:",omitempty"`
 	Platform_security_patch                   *string  `json:",omitempty"`
 	Platform_preview_sdk_version              *string  `json:",omitempty"`
@@ -597,7 +596,6 @@
 		Platform_sdk_final:                     boolPtr(false),
 		Platform_version_active_codenames:      []string{"S"},
 		Platform_version_all_preview_codenames: []string{"S"},
-		Platform_vndk_version:                  stringPtr("S"),
 
 		HostArch:                    stringPtr("x86_64"),
 		HostSecondaryArch:           stringPtr("x86"),
diff --git a/apex/apex.go b/apex/apex.go
index 8d2979e..d437efe 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -739,7 +739,7 @@
 // image variation name.
 func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
 	if a.vndkApex {
-		return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
+		return cc.VendorVariationPrefix, a.vndkVersion()
 	}
 
 	prefix := android.CoreVariation
@@ -748,9 +748,6 @@
 		if a.SocSpecific() || a.DeviceSpecific() {
 			prefix = cc.VendorVariationPrefix
 			vndkVersion = deviceConfig.VndkVersion()
-		} else if a.ProductSpecific() {
-			prefix = cc.ProductVariationPrefix
-			vndkVersion = deviceConfig.PlatformVndkVersion()
 		}
 	} else {
 		if a.SocSpecific() || a.DeviceSpecific() {
@@ -759,9 +756,6 @@
 			prefix = cc.ProductVariation
 		}
 	}
-	if vndkVersion == "current" {
-		vndkVersion = deviceConfig.PlatformVndkVersion()
-	}
 
 	return prefix, vndkVersion
 }
diff --git a/apex/builder.go b/apex/builder.go
index 50db631..9bd4b61 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -277,7 +277,7 @@
 	// VNDK APEX name is determined at runtime, so update "name" in apex_manifest
 	optCommands := []string{}
 	if a.vndkApex {
-		apexName := vndkApexNamePrefix + a.vndkVersion(ctx.DeviceConfig())
+		apexName := vndkApexNamePrefix + a.vndkVersion()
 		optCommands = append(optCommands, "-v name "+apexName)
 	}
 
@@ -1043,7 +1043,7 @@
 	if a.vndkApex {
 		overrideName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(vndkApexName)
 		if overridden {
-			return overrideName + ".v" + a.vndkVersion(ctx.DeviceConfig())
+			return overrideName + ".v" + a.vndkVersion()
 		}
 		return ""
 	}
diff --git a/apex/vndk.go b/apex/vndk.go
index 377c1c0..781aa3c 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -45,16 +45,12 @@
 	return bundle
 }
 
-func (a *apexBundle) vndkVersion(config android.DeviceConfig) string {
-	vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current")
-	if vndkVersion == "current" {
-		vndkVersion = config.PlatformVndkVersion()
-	}
-	return vndkVersion
+func (a *apexBundle) vndkVersion() string {
+	return proptools.StringDefault(a.vndkProperties.Vndk_version, "current")
 }
 
 type apexVndkProperties struct {
-	// Indicates VNDK version of which this VNDK APEX bundles VNDK libs. Default is Platform VNDK Version.
+	// Indicates VNDK version of which this VNDK APEX bundles VNDK libs.
 	Vndk_version *string
 }
 
@@ -64,7 +60,7 @@
 			mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
 		}
 
-		vndkVersion := ab.vndkVersion(mctx.DeviceConfig())
+		vndkVersion := ab.vndkVersion()
 		if vndkVersion != "" {
 			apiLevel, err := android.ApiLevelFromUser(mctx, vndkVersion)
 			if err != nil {
@@ -73,17 +69,9 @@
 			}
 
 			targets := mctx.MultiTargets()
-			if len(targets) > 0 && apiLevel.LessThan(cc.MinApiForArch(mctx, targets[0].Arch.ArchType)) &&
-				vndkVersion != mctx.DeviceConfig().PlatformVndkVersion() {
+			if len(targets) > 0 && apiLevel.LessThan(cc.MinApiForArch(mctx, targets[0].Arch.ArchType)) {
 				// Disable VNDK APEXes for VNDK versions less than the minimum supported API
-				// level for the primary architecture. This validation is skipped if the VNDK
-				// version matches the platform VNDK version, which can occur when the device
-				// config targets the 'current' VNDK (see `vndkVersion`).
-				ab.Disable()
-			}
-			if proptools.String(ab.vndkProperties.Vndk_version) != "" &&
-				mctx.DeviceConfig().PlatformVndkVersion() != "" &&
-				apiLevel.GreaterThanOrEqualTo(android.ApiLevelOrPanic(mctx, mctx.DeviceConfig().PlatformVndkVersion())) {
+				// level for the primary architecture.
 				ab.Disable()
 			}
 		}
@@ -93,20 +81,11 @@
 func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) {
 	if m, ok := mctx.Module().(*cc.Module); ok && cc.IsForVndkApex(mctx, m) {
 		vndkVersion := m.VndkVersion()
-		// For VNDK-Lite device, we gather core-variants of VNDK-Sp libraries, which doesn't have VNDK version defined
-		if vndkVersion == "" {
-			vndkVersion = mctx.DeviceConfig().PlatformVndkVersion()
-		}
 
 		if vndkVersion == "" {
 			return
 		}
-
-		if vndkVersion == mctx.DeviceConfig().PlatformVndkVersion() {
-			vndkVersion = "current"
-		} else {
-			vndkVersion = "v" + vndkVersion
-		}
+		vndkVersion = "v" + vndkVersion
 
 		vndkApexName := "com.android.vndk." + vndkVersion
 
diff --git a/cc/builder.go b/cc/builder.go
index e4d5be2..f28f47f 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -375,13 +375,14 @@
 	localCppFlags        string
 	localLdFlags         string
 
-	libFlags      string // Flags to add to the linker directly after specifying libraries to link.
-	extraLibFlags string // Flags to add to the linker last.
-	tidyFlags     string // Flags that apply to clang-tidy
-	sAbiFlags     string // Flags that apply to header-abi-dumps
-	aidlFlags     string // Flags that apply to aidl source files
-	rsFlags       string // Flags that apply to renderscript source files
-	toolchain     config.Toolchain
+	noOverrideFlags string // Flags appended at the end so they are not overridden.
+	libFlags        string // Flags to add to the linker directly after specifying libraries to link.
+	extraLibFlags   string // Flags to add to the linker last.
+	tidyFlags       string // Flags that apply to clang-tidy
+	sAbiFlags       string // Flags that apply to header-abi-dumps
+	aidlFlags       string // Flags that apply to aidl source files
+	rsFlags         string // Flags that apply to renderscript source files
+	toolchain       config.Toolchain
 
 	// True if these extra features are enabled.
 	tidy          bool
@@ -485,7 +486,8 @@
 		flags.localCommonFlags + " " +
 		flags.localToolingCFlags + " " +
 		flags.localConlyFlags + " " +
-		flags.systemIncludeFlags
+		flags.systemIncludeFlags + " " +
+		flags.noOverrideFlags
 
 	cflags := flags.globalCommonFlags + " " +
 		flags.globalCFlags + " " +
@@ -493,7 +495,8 @@
 		flags.localCommonFlags + " " +
 		flags.localCFlags + " " +
 		flags.localConlyFlags + " " +
-		flags.systemIncludeFlags
+		flags.systemIncludeFlags + " " +
+		flags.noOverrideFlags
 
 	toolingCppflags := flags.globalCommonFlags + " " +
 		flags.globalToolingCFlags + " " +
@@ -501,7 +504,8 @@
 		flags.localCommonFlags + " " +
 		flags.localToolingCFlags + " " +
 		flags.localToolingCppFlags + " " +
-		flags.systemIncludeFlags
+		flags.systemIncludeFlags + " " +
+		flags.noOverrideFlags
 
 	cppflags := flags.globalCommonFlags + " " +
 		flags.globalCFlags + " " +
@@ -509,7 +513,8 @@
 		flags.localCommonFlags + " " +
 		flags.localCFlags + " " +
 		flags.localCppFlags + " " +
-		flags.systemIncludeFlags
+		flags.systemIncludeFlags + " " +
+		flags.noOverrideFlags
 
 	asflags := flags.globalCommonFlags + " " +
 		flags.globalAsFlags + " " +
@@ -522,26 +527,6 @@
 		sAbiDumpFiles = make(android.Paths, 0, len(srcFiles))
 	}
 
-	cflags += " ${config.NoOverrideGlobalCflags}"
-	toolingCflags += " ${config.NoOverrideGlobalCflags}"
-	cppflags += " ${config.NoOverrideGlobalCflags}"
-	toolingCppflags += " ${config.NoOverrideGlobalCflags}"
-
-	if flags.toolchain.Is64Bit() {
-		cflags += " ${config.NoOverride64GlobalCflags}"
-		toolingCflags += " ${config.NoOverride64GlobalCflags}"
-		cppflags += " ${config.NoOverride64GlobalCflags}"
-		toolingCppflags += " ${config.NoOverride64GlobalCflags}"
-	}
-
-	modulePath := ctx.ModuleDir()
-	if android.IsThirdPartyPath(modulePath) {
-		cflags += " ${config.NoOverrideExternalGlobalCflags}"
-		toolingCflags += " ${config.NoOverrideExternalGlobalCflags}"
-		cppflags += " ${config.NoOverrideExternalGlobalCflags}"
-		toolingCppflags += " ${config.NoOverrideExternalGlobalCflags}"
-	}
-
 	// Multiple source files have build rules usually share the same cFlags or tidyFlags.
 	// Define only one version in this module and share it in multiple build rules.
 	// To simplify the code, the shared variables are all named as $flags<nnn>.
diff --git a/cc/cc.go b/cc/cc.go
index 90185ea..fb5d096 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -215,7 +215,8 @@
 	// Local flags (which individual modules are responsible for). These may override global flags.
 	Local LocalOrGlobalFlags
 	// Global flags (which build system or toolchain is responsible for).
-	Global LocalOrGlobalFlags
+	Global          LocalOrGlobalFlags
+	NoOverrideFlags []string // Flags applied to the end of list of flags so they are not overridden
 
 	aidlFlags     []string // Flags that apply to aidl source files
 	rsFlags       []string // Flags that apply to renderscript source files
@@ -1896,9 +1897,6 @@
 		vndkVersion = ctx.DeviceConfig().VndkVersion()
 		nameSuffix = VendorSuffix
 	}
-	if vndkVersion == "current" {
-		vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
-	}
 	if c.VndkVersion() != vndkVersion && c.VndkVersion() != "" {
 		// add version suffix only if the module is using different vndk version than the
 		// version in product or vendor partition.
diff --git a/cc/compdb.go b/cc/compdb.go
index 617be1a..da28183 100644
--- a/cc/compdb.go
+++ b/cc/compdb.go
@@ -164,6 +164,7 @@
 		args = append(args, expandAllVars(ctx, ccModule.flags.Local.ConlyFlags)...)
 	}
 	args = append(args, expandAllVars(ctx, ccModule.flags.SystemIncludeFlags)...)
+	args = append(args, expandAllVars(ctx, ccModule.flags.NoOverrideFlags)...)
 	args = append(args, src.String())
 	return args
 }
diff --git a/cc/compiler.go b/cc/compiler.go
index de1ae71..9a961cf 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -539,7 +539,6 @@
 		flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainCflags())
 	}
 
-
 	cStd := parseCStd(compiler.Properties.C_std)
 	cppStd := parseCppStd(compiler.Properties.Cpp_std)
 
@@ -671,6 +670,16 @@
 		flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES")
 	}
 
+	flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverrideGlobalCflags}")
+
+	if flags.Toolchain.Is64Bit() {
+		flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverride64GlobalCflags}")
+	}
+
+	if android.IsThirdPartyPath(ctx.ModuleDir()) {
+		flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverrideExternalGlobalCflags}")
+	}
+
 	return flags
 }
 
diff --git a/cc/genrule.go b/cc/genrule.go
index 0fb3e2d..23e97d0 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -121,18 +121,7 @@
 		}
 	} else {
 		if vendorVariantRequired {
-			// If vndkVersion is current, we can always use PlatformVndkVersion.
-			// If not, we assume modules under proprietary paths are compatible for
-			// BOARD_VNDK_VERSION. The other modules are regarded as AOSP, that is
-			// PLATFORM_VNDK_VERSION.
-			if vndkVersion == "current" || !snapshot.IsVendorProprietaryModule(ctx) {
-				variants = append(variants, VendorVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
-			} else {
-				variants = append(variants, VendorVariationPrefix+vndkVersion)
-			}
-		}
-		if productVariantRequired {
-			variants = append(variants, ProductVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
+			variants = append(variants, VendorVariationPrefix+vndkVersion)
 		}
 	}
 
diff --git a/cc/image.go b/cc/image.go
index d02a2f3..50d1b23 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -429,7 +429,6 @@
 	var vendorVariants []string
 	var productVariants []string
 
-	platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
 	boardVndkVersion := mctx.DeviceConfig().VndkVersion()
 	recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
 	usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
@@ -444,17 +443,13 @@
 			needVndkVersionVendorVariantForLlndk = boardVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, "30"))
 		}
 	}
-	if boardVndkVersion == "current" {
-		boardVndkVersion = platformVndkVersion
-	}
-
 	if m.NeedsLlndkVariants() {
 		// This is an LLNDK library.  The implementation of the library will be on /system,
 		// and vendor and product variants will be created with LLNDK stubs.
 		// The LLNDK libraries need vendor variants even if there is no VNDK.
 		coreVariantNeeded = true
-		vendorVariants = append(vendorVariants, platformVndkVersion)
-		productVariants = append(productVariants, platformVndkVersion)
+		vendorVariants = append(vendorVariants, "")
+		productVariants = append(productVariants, "")
 		// Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not
 		// provide the LLNDK stub libraries.
 		if needVndkVersionVendorVariantForLlndk {
@@ -465,7 +460,7 @@
 		// for system and product.
 		coreVariantNeeded = true
 		vendorVariants = append(vendorVariants, boardVndkVersion)
-		productVariants = append(productVariants, platformVndkVersion)
+		productVariants = append(productVariants, "")
 	} else if m.IsSnapshotPrebuilt() {
 		// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
 		// PRODUCT_EXTRA_VNDK_VERSIONS.
@@ -486,13 +481,13 @@
 			if snapshot.IsVendorProprietaryModule(mctx) {
 				vendorVariants = append(vendorVariants, boardVndkVersion)
 			} else {
-				vendorVariants = append(vendorVariants, platformVndkVersion)
+				vendorVariants = append(vendorVariants, "")
 			}
 		}
 
 		// product_available modules are available to /product.
 		if m.HasProductVariant() {
-			productVariants = append(productVariants, platformVndkVersion)
+			productVariants = append(productVariants, "")
 		}
 	} else if vendorSpecific && m.SdkVersion() == "" {
 		// This will be available in /vendor (or /odm) only
@@ -505,13 +500,13 @@
 		// are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
 		if m.KernelHeadersDecorator() {
 			vendorVariants = append(vendorVariants,
-				platformVndkVersion,
+				"",
 				boardVndkVersion,
 			)
 		} else if snapshot.IsVendorProprietaryModule(mctx) {
 			vendorVariants = append(vendorVariants, boardVndkVersion)
 		} else {
-			vendorVariants = append(vendorVariants, platformVndkVersion)
+			vendorVariants = append(vendorVariants, "")
 		}
 	} else {
 		// This is either in /system (or similar: /data), or is a
@@ -523,7 +518,7 @@
 	if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
 		// The module has "product_specific: true" that does not create core variant.
 		coreVariantNeeded = false
-		productVariants = append(productVariants, platformVndkVersion)
+		productVariants = append(productVariants, "")
 	}
 
 	if m.RamdiskAvailable() {
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index e769fe9..7d003a9 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -324,7 +324,7 @@
 
 	variations = append(ctx.Target().Variations(), blueprint.Variation{
 		Mutator:   "image",
-		Variation: ProductVariationPrefix + ctx.DeviceConfig().PlatformVndkVersion()})
+		Variation: ProductVariation})
 
 	if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) {
 		p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix()
diff --git a/cc/util.go b/cc/util.go
index c93646b..d6089ab 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -56,18 +56,19 @@
 		localCppFlags:        strings.Join(in.Local.CppFlags, " "),
 		localLdFlags:         strings.Join(in.Local.LdFlags, " "),
 
-		aidlFlags:     strings.Join(in.aidlFlags, " "),
-		rsFlags:       strings.Join(in.rsFlags, " "),
-		libFlags:      strings.Join(in.libFlags, " "),
-		extraLibFlags: strings.Join(in.extraLibFlags, " "),
-		tidyFlags:     strings.Join(in.TidyFlags, " "),
-		sAbiFlags:     strings.Join(in.SAbiFlags, " "),
-		toolchain:     in.Toolchain,
-		gcovCoverage:  in.GcovCoverage,
-		tidy:          in.Tidy,
-		needTidyFiles: in.NeedTidyFiles,
-		sAbiDump:      in.SAbiDump,
-		emitXrefs:     in.EmitXrefs,
+		noOverrideFlags: strings.Join(in.NoOverrideFlags, " "),
+		aidlFlags:       strings.Join(in.aidlFlags, " "),
+		rsFlags:         strings.Join(in.rsFlags, " "),
+		libFlags:        strings.Join(in.libFlags, " "),
+		extraLibFlags:   strings.Join(in.extraLibFlags, " "),
+		tidyFlags:       strings.Join(in.TidyFlags, " "),
+		sAbiFlags:       strings.Join(in.SAbiFlags, " "),
+		toolchain:       in.Toolchain,
+		gcovCoverage:    in.GcovCoverage,
+		tidy:            in.Tidy,
+		needTidyFiles:   in.NeedTidyFiles,
+		sAbiDump:        in.SAbiDump,
+		emitXrefs:       in.EmitXrefs,
 
 		systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "),
 
diff --git a/cc/vndk.go b/cc/vndk.go
index 2b2ea64..ad0dcf3 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -42,28 +42,6 @@
 )
 
 func VndkLibrariesTxtModules(vndkVersion string, ctx android.BaseModuleContext) []string {
-	// Return the list of vndk txt files for the vndk apex of the vndkVersion.
-	if vndkVersion == "current" {
-		// We can assume all txt files are snapshotted if we find one of them.
-		currentVndkSnapshotted := ctx.OtherModuleExists(insertVndkVersion(llndkLibrariesTxt, ctx.DeviceConfig().PlatformVndkVersion()))
-		if currentVndkSnapshotted {
-			// If the current VNDK is already snapshotted (which can happen with
-			// the `next` config), use the prebuilt txt files in the snapshot.
-			// This is because the txt files built from source are probably be
-			// for the in-development version.
-			vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
-		} else {
-			// Use the txt files generated from the source
-			return []string{
-				llndkLibrariesTxtForApex,
-				vndkCoreLibrariesTxt,
-				vndkSpLibrariesTxt,
-				vndkPrivateLibrariesTxt,
-				vndkProductLibrariesTxt,
-			}
-		}
-	}
-
 	// Snapshot vndks have their own *.libraries.VER.txt files.
 	// Note that snapshots don't have "vndkcorevariant.libraries.VER.txt"
 	result := []string{
@@ -376,15 +354,6 @@
 		if !p.MatchesWithDevice(mctx.DeviceConfig()) {
 			return false
 		}
-
-		platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
-		if platformVndkVersion != "" {
-			// ignore prebuilt vndk modules that are newer than or equal to the platform vndk version
-			platformVndkApiLevel := android.ApiLevelOrPanic(mctx, platformVndkVersion)
-			if platformVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, p.Version())) {
-				return false
-			}
-		}
 	}
 
 	if lib, ok := m.linker.(libraryInterface); ok {
@@ -392,8 +361,7 @@
 		if lib.buildStubs() {
 			return false
 		}
-		useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
-			mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
+		useCoreVariant := mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
 		return lib.shared() && m.InVendor() && m.IsVndk() && !m.IsVndkExt() && !useCoreVariant
 	}
 	return false
@@ -548,22 +516,9 @@
 	return filename
 }
 
-func (txt *vndkLibrariesTxt) DepsMutator(mctx android.BottomUpMutatorContext) {
-	versionedName := insertVndkVersion(txt.Name(), mctx.DeviceConfig().PlatformVndkVersion())
-	if mctx.OtherModuleExists(versionedName) {
-		// If the prebuilt vndk libraries txt files exist, install them instead.
-		txt.HideFromMake()
-		mctx.AddDependency(txt, nil, versionedName)
-	}
-}
-
 func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	filename := proptools.StringDefault(txt.properties.Stem, txt.Name())
 
-	if Bool(txt.properties.Insert_vndk_version) {
-		filename = insertVndkVersion(filename, ctx.DeviceConfig().PlatformVndkVersion())
-	}
-
 	txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath
 
 	installPath := android.PathForModuleInstall(ctx, "etc")
@@ -639,34 +594,6 @@
 
 func isVndkSnapshotAware(config android.DeviceConfig, m LinkableInterface,
 	apexInfo android.ApexInfo) (vndkType string, isVndkSnapshotLib bool) {
-
-	if m.Target().NativeBridge == android.NativeBridgeEnabled {
-		return "", false
-	}
-	// !inVendor: There's product/vendor variants for VNDK libs. We only care about vendor variants.
-	// !installable: Snapshot only cares about "installable" modules.
-	// !m.IsLlndk: llndk stubs are required for building against snapshots.
-	// IsSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense.
-	// !outputFile.Valid: Snapshot requires valid output file.
-	if !m.InVendor() || (!installable(m, apexInfo) && !m.IsLlndk()) || m.IsSnapshotPrebuilt() || !m.OutputFile().Valid() {
-		return "", false
-	}
-	if !m.IsSnapshotLibrary() || !m.Shared() {
-		return "", false
-	}
-	if m.VndkVersion() == config.PlatformVndkVersion() {
-		if m.IsVndk() && !m.IsVndkExt() {
-			if m.IsVndkSp() {
-				return "vndk-sp", true
-			} else {
-				return "vndk-core", true
-			}
-		} else if m.HasLlndkStubs() && m.StubsVersion() == "" {
-			// Use default version for the snapshot.
-			return "llndk-stub", true
-		}
-	}
-
 	return "", false
 }
 
@@ -679,10 +606,6 @@
 		return
 	}
 
-	if ctx.DeviceConfig().PlatformVndkVersion() == "" {
-		return
-	}
-
 	var snapshotOutputs android.Paths
 
 	/*
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 43030b8..f4ba163 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -131,16 +131,6 @@
 
 func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
 	flags Flags, deps PathDeps, objs Objects) android.Path {
-	platformVndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
-	if platformVndkVersion != "" {
-		platformVndkApiLevel := android.ApiLevelOrPanic(ctx, platformVndkVersion)
-		if platformVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(ctx, p.Version())) {
-			// This prebuilt VNDK module is not required for the current build
-			ctx.Module().HideFromMake()
-			return nil
-		}
-	}
-
 	if !p.MatchesWithDevice(ctx.DeviceConfig()) {
 		ctx.Module().HideFromMake()
 		return nil
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index e346bd7..dd9958c 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -15,7 +15,6 @@
 package etc
 
 import (
-	"fmt"
 	"os"
 	"path/filepath"
 	"testing"
@@ -23,7 +22,6 @@
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
-	"android/soong/snapshot"
 )
 
 func TestMain(m *testing.M) {
@@ -40,18 +38,6 @@
 	}),
 )
 
-var prepareForPrebuiltEtcSnapshotTest = android.GroupFixturePreparers(
-	prepareForPrebuiltEtcTest,
-	android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
-		snapshot.VendorSnapshotImageSingleton.Init(ctx)
-		snapshot.RecoverySnapshotImageSingleton.Init(ctx)
-	}),
-	android.FixtureModifyConfig(func(config android.Config) {
-		config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
-		config.TestProductVariables.RecoverySnapshotVersion = proptools.StringPtr("current")
-	}),
-)
-
 func TestPrebuiltEtcVariants(t *testing.T) {
 	result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
 		prebuilt_etc {
@@ -415,110 +401,3 @@
 		})
 	}
 }
-
-func checkIfSnapshotTaken(t *testing.T, result *android.TestResult, image string, moduleName string) {
-	checkIfSnapshotExistAsExpected(t, result, image, moduleName, true)
-}
-
-func checkIfSnapshotNotTaken(t *testing.T, result *android.TestResult, image string, moduleName string) {
-	checkIfSnapshotExistAsExpected(t, result, image, moduleName, false)
-}
-
-func checkIfSnapshotExistAsExpected(t *testing.T, result *android.TestResult, image string, moduleName string, expectToExist bool) {
-	snapshotSingleton := result.SingletonForTests(image + "-snapshot")
-	archType := "arm64"
-	archVariant := "armv8-a"
-	archDir := fmt.Sprintf("arch-%s", archType)
-
-	snapshotDir := fmt.Sprintf("%s-snapshot", image)
-	snapshotVariantPath := filepath.Join(snapshotDir, archType)
-	outputDir := filepath.Join(snapshotVariantPath, archDir, "etc")
-	imageVariant := ""
-	if image == "recovery" {
-		imageVariant = "recovery_"
-	}
-	mod := result.ModuleForTests(moduleName, fmt.Sprintf("android_%s%s_%s", imageVariant, archType, archVariant))
-	outputFiles := mod.OutputFiles(t, "")
-	if len(outputFiles) != 1 {
-		t.Errorf("%q must have single output\n", moduleName)
-		return
-	}
-	snapshotPath := filepath.Join(outputDir, moduleName)
-
-	if expectToExist {
-		out := snapshotSingleton.Output(snapshotPath)
-
-		if out.Input.String() != outputFiles[0].String() {
-			t.Errorf("The input of snapshot %q must be %q, but %q", "prebuilt_vendor", out.Input.String(), outputFiles[0])
-		}
-
-		snapshotJsonPath := snapshotPath + ".json"
-
-		if snapshotSingleton.MaybeOutput(snapshotJsonPath).Rule == nil {
-			t.Errorf("%q expected but not found", snapshotJsonPath)
-		}
-	} else {
-		out := snapshotSingleton.MaybeOutput(snapshotPath)
-		if out.Rule != nil {
-			t.Errorf("There must be no rule for module %q output file %q", moduleName, outputFiles[0])
-		}
-	}
-}
-
-func TestPrebuiltTakeSnapshot(t *testing.T) {
-	var testBp = `
-	prebuilt_etc {
-		name: "prebuilt_vendor",
-		src: "foo.conf",
-		vendor: true,
-	}
-
-	prebuilt_etc {
-		name: "prebuilt_vendor_indirect",
-		src: "foo.conf",
-		vendor: true,
-	}
-
-	prebuilt_etc {
-		name: "prebuilt_recovery",
-		src: "bar.conf",
-		recovery: true,
-	}
-
-	prebuilt_etc {
-		name: "prebuilt_recovery_indirect",
-		src: "bar.conf",
-		recovery: true,
-	}
-	`
-
-	t.Run("prebuilt: vendor and recovery snapshot", func(t *testing.T) {
-		result := prepareForPrebuiltEtcSnapshotTest.RunTestWithBp(t, testBp)
-
-		checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor")
-		checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor_indirect")
-		checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery")
-		checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery_indirect")
-	})
-
-	t.Run("prebuilt: directed snapshot", func(t *testing.T) {
-		prepareForPrebuiltEtcDirectedSnapshotTest := android.GroupFixturePreparers(
-			prepareForPrebuiltEtcSnapshotTest,
-			android.FixtureModifyConfig(func(config android.Config) {
-				config.TestProductVariables.DirectedVendorSnapshot = true
-				config.TestProductVariables.VendorSnapshotModules = make(map[string]bool)
-				config.TestProductVariables.VendorSnapshotModules["prebuilt_vendor"] = true
-				config.TestProductVariables.DirectedRecoverySnapshot = true
-				config.TestProductVariables.RecoverySnapshotModules = make(map[string]bool)
-				config.TestProductVariables.RecoverySnapshotModules["prebuilt_recovery"] = true
-			}),
-		)
-
-		result := prepareForPrebuiltEtcDirectedSnapshotTest.RunTestWithBp(t, testBp)
-
-		checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor")
-		checkIfSnapshotNotTaken(t, result, "vendor", "prebuilt_vendor_indirect")
-		checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery")
-		checkIfSnapshotNotTaken(t, result, "recovery", "prebuilt_recovery_indirect")
-	})
-}
diff --git a/filesystem/Android.bp b/filesystem/Android.bp
index cead5fc..18dd553 100644
--- a/filesystem/Android.bp
+++ b/filesystem/Android.bp
@@ -18,6 +18,7 @@
         "avb_gen_vbmeta_image.go",
         "bootimg.go",
         "filesystem.go",
+        "fsverity_metadata.go",
         "logical_partition.go",
         "raw_binary.go",
         "system_image.go",
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index efc889c..e640c5d 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -36,6 +36,7 @@
 func registerBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("android_filesystem", filesystemFactory)
 	ctx.RegisterModuleType("android_system_image", systemImageFactory)
+	ctx.RegisterModuleType("android_system_image_defaults", systemImageDefaultsFactory)
 	ctx.RegisterModuleType("avb_add_hash_footer", avbAddHashFooterFactory)
 	ctx.RegisterModuleType("avb_add_hash_footer_defaults", avbAddHashFooterDefaultsFactory)
 	ctx.RegisterModuleType("avb_gen_vbmeta_image", avbGenVbmetaImageFactory)
@@ -57,7 +58,7 @@
 	output     android.OutputPath
 	installDir android.InstallPath
 
-	// For testing. Keeps the result of CopyDepsToZip()
+	// For testing. Keeps the result of CopySpecsToDir()
 	entries []string
 }
 
@@ -120,6 +121,8 @@
 	// modules would be installed to the same location as a make module, they will overwrite
 	// the make version.
 	Include_make_built_files string
+
+	Fsverity fsverityProperties
 }
 
 // android_filesystem packages a set of modules and their transitive dependencies into a filesystem
@@ -176,6 +179,10 @@
 	return f.BaseModuleName() + ".img"
 }
 
+func (f *filesystem) partitionName() string {
+	return proptools.StringDefault(f.properties.Partition_name, f.Name())
+}
+
 var pctx = android.NewPackageContext("android/soong/filesystem")
 
 func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -255,10 +262,12 @@
 	builder := android.NewRuleBuilder(pctx, ctx)
 	// Wipe the root dir to get rid of leftover files from prior builds
 	builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir)
-	f.entries = f.CopySpecsToDir(ctx, builder, f.gatherFilteredPackagingSpecs(ctx), rebasedDir)
+	specs := f.gatherFilteredPackagingSpecs(ctx)
+	f.entries = f.CopySpecsToDir(ctx, builder, specs, rebasedDir)
 
 	f.buildNonDepsFiles(ctx, builder, rootDir)
 	f.addMakeBuiltFiles(ctx, builder, rootDir)
+	f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir)
 
 	// run host_init_verifier
 	// Ideally we should have a concept of pluggable linters that verify the generated image.
@@ -338,13 +347,12 @@
 		addStr("avb_algorithm", algorithm)
 		key := android.PathForModuleSrc(ctx, proptools.String(f.properties.Avb_private_key))
 		addPath("avb_key_path", key)
-		partitionName := proptools.StringDefault(f.properties.Partition_name, f.Name())
-		addStr("partition_name", partitionName)
+		addStr("partition_name", f.partitionName())
 		avb_add_hashtree_footer_args := "--do_not_generate_fec"
 		if hashAlgorithm := proptools.String(f.properties.Avb_hash_algorithm); hashAlgorithm != "" {
 			avb_add_hashtree_footer_args += " --hash_algorithm " + hashAlgorithm
 		}
-		securityPatchKey := "com.android.build." + partitionName + ".security_patch"
+		securityPatchKey := "com.android.build." + f.partitionName() + ".security_patch"
 		securityPatchValue := ctx.Config().PlatformSecurityPatch()
 		avb_add_hashtree_footer_args += " --prop " + securityPatchKey + ":" + securityPatchValue
 		addStr("avb_add_hashtree_footer_args", avb_add_hashtree_footer_args)
@@ -388,9 +396,11 @@
 	builder := android.NewRuleBuilder(pctx, ctx)
 	// Wipe the root dir to get rid of leftover files from prior builds
 	builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir)
-	f.entries = f.CopySpecsToDir(ctx, builder, f.gatherFilteredPackagingSpecs(ctx), rebasedDir)
+	specs := f.gatherFilteredPackagingSpecs(ctx)
+	f.entries = f.CopySpecsToDir(ctx, builder, specs, rebasedDir)
 
 	f.buildNonDepsFiles(ctx, builder, rootDir)
+	f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir)
 
 	output := android.PathForModuleOut(ctx, f.installFileName()).OutputPath
 	cmd := builder.Command().
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index d5ea2bc..5c780f8 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -364,3 +364,72 @@
 		t.Error("prebuilt should use cov variant of filesystem")
 	}
 }
+
+func TestSystemImageDefaults(t *testing.T) {
+	result := fixture.RunTestWithBp(t, `
+		android_system_image_defaults {
+			name: "defaults",
+			multilib: {
+				common: {
+					deps: [
+						"phony",
+					],
+				},
+				lib64: {
+					deps: [
+						"libbar",
+					],
+				},
+			},
+			compile_multilib: "both",
+		}
+
+		android_system_image {
+			name: "system",
+			defaults: ["defaults"],
+			multilib: {
+				lib32: {
+					deps: [
+						"foo",
+						"libbar",
+					],
+				},
+			},
+		}
+
+		cc_binary {
+			name: "foo",
+			compile_multilib: "prefer32",
+		}
+
+		cc_library {
+			name: "libbar",
+			required: ["libbaz"],
+		}
+
+		cc_library {
+			name: "libbaz",
+		}
+
+		phony {
+			name: "phony",
+			required: ["libquz"],
+		}
+
+		cc_library {
+			name: "libquz",
+		}
+	`)
+
+	fs := result.ModuleForTests("system", "android_common").Module().(*systemImage)
+	expected := []string{
+		"bin/foo",
+		"lib/libbar.so",
+		"lib64/libbar.so",
+		"lib64/libbaz.so",
+		"lib64/libquz.so",
+	}
+	for _, e := range expected {
+		android.AssertStringListContains(t, "missing entry", fs.entries, e)
+	}
+}
diff --git a/filesystem/fsverity_metadata.go b/filesystem/fsverity_metadata.go
new file mode 100644
index 0000000..70f94e0
--- /dev/null
+++ b/filesystem/fsverity_metadata.go
@@ -0,0 +1,166 @@
+// Copyright (C) 2024 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 filesystem
+
+import (
+	"path/filepath"
+	"strings"
+
+	"android/soong/android"
+)
+
+type fsverityProperties struct {
+	// Patterns of files for fsverity metadata generation.  For each matched file, a .fsv_meta file
+	// will be generated and included to the filesystem image.
+	// etc/security/fsverity/BuildManifest.apk will also be generated which contains information
+	// about generated .fsv_meta files.
+	Inputs []string
+}
+
+func (f *filesystem) writeManifestGeneratorListFile(ctx android.ModuleContext, outputPath android.OutputPath, matchedSpecs []android.PackagingSpec, rebasedDir android.OutputPath) {
+	var buf strings.Builder
+	for _, spec := range matchedSpecs {
+		buf.WriteString(rebasedDir.Join(ctx, spec.RelPathInPackage()).String())
+		buf.WriteRune('\n')
+	}
+	android.WriteFileRuleVerbatim(ctx, outputPath, buf.String())
+}
+
+func (f *filesystem) buildFsverityMetadataFiles(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, rootDir android.OutputPath, rebasedDir android.OutputPath) {
+	match := func(path string) bool {
+		for _, pattern := range f.properties.Fsverity.Inputs {
+			if matched, err := filepath.Match(pattern, path); matched {
+				return true
+			} else if err != nil {
+				ctx.PropertyErrorf("fsverity.inputs", "bad pattern %q", pattern)
+				return false
+			}
+		}
+		return false
+	}
+
+	var matchedSpecs []android.PackagingSpec
+	for _, relPath := range android.SortedKeys(specs) {
+		if match(relPath) {
+			matchedSpecs = append(matchedSpecs, specs[relPath])
+		}
+	}
+
+	if len(matchedSpecs) == 0 {
+		return
+	}
+
+	fsverityBuilderPath := android.PathForModuleOut(ctx, "fsverity_builder.sh")
+	metadataGeneratorPath := ctx.Config().HostToolPath(ctx, "fsverity_metadata_generator")
+	fsverityPath := ctx.Config().HostToolPath(ctx, "fsverity")
+
+	cmd := builder.Command().Tool(fsverityBuilderPath)
+
+	// STEP 1: generate .fsv_meta
+	var sb strings.Builder
+	sb.WriteString("set -e\n")
+	cmd.Implicit(metadataGeneratorPath).Implicit(fsverityPath)
+	for _, spec := range matchedSpecs {
+		// srcPath is copied by CopySpecsToDir()
+		srcPath := rebasedDir.Join(ctx, spec.RelPathInPackage())
+		destPath := rebasedDir.Join(ctx, spec.RelPathInPackage()+".fsv_meta")
+		sb.WriteString(metadataGeneratorPath.String())
+		sb.WriteString(" --fsverity-path ")
+		sb.WriteString(fsverityPath.String())
+		sb.WriteString(" --signature none --hash-alg sha256 --output ")
+		sb.WriteString(destPath.String())
+		sb.WriteRune(' ')
+		sb.WriteString(srcPath.String())
+		sb.WriteRune('\n')
+	}
+
+	// STEP 2: generate signed BuildManifest.apk
+	// STEP 2-1: generate build_manifest.pb
+	assetsPath := android.PathForModuleOut(ctx, "fsverity_manifest/assets")
+	manifestPbPath := assetsPath.Join(ctx, "build_manifest.pb")
+	manifestGeneratorPath := ctx.Config().HostToolPath(ctx, "fsverity_manifest_generator")
+	cmd.Implicit(manifestGeneratorPath)
+	sb.WriteString("rm -rf ")
+	sb.WriteString(assetsPath.String())
+	sb.WriteString(" && mkdir -p ")
+	sb.WriteString(assetsPath.String())
+	sb.WriteRune('\n')
+	sb.WriteString(manifestGeneratorPath.String())
+	sb.WriteString(" --fsverity-path ")
+	sb.WriteString(fsverityPath.String())
+	sb.WriteString(" --base-dir ")
+	sb.WriteString(rootDir.String())
+	sb.WriteString(" --output ")
+	sb.WriteString(manifestPbPath.String())
+	sb.WriteRune(' ')
+
+	manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity_manifest.list")
+	f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath.OutputPath, matchedSpecs, rebasedDir)
+	sb.WriteRune('@')
+	sb.WriteString(manifestGeneratorListPath.String())
+	sb.WriteRune('\n')
+	cmd.Implicit(manifestGeneratorListPath)
+
+	// STEP 2-2: generate BuildManifest.apk (unsigned)
+	aapt2Path := ctx.Config().HostToolPath(ctx, "aapt2")
+	apkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", "BuildManifest.apk")
+	manifestTemplatePath := android.PathForSource(ctx, "system/security/fsverity/AndroidManifest.xml")
+	// package-export is currently generated by Makefile.
+	// TODO(b/330282551): fully migrate into Soong
+	frameworkResPath := android.PathForArbitraryOutput(ctx, "target/common/obj/APPS/framework-res_intermediates/package-export.apk")
+	cmd.Implicit(aapt2Path)
+	cmd.Implicit(manifestTemplatePath)
+	cmd.Implicit(frameworkResPath)
+
+	sb.WriteString(aapt2Path.String())
+	sb.WriteString(" link -o ")
+	sb.WriteString(apkPath.String())
+	sb.WriteString(" -A ")
+	sb.WriteString(assetsPath.String())
+	sb.WriteString(" -I ")
+	sb.WriteString(frameworkResPath.String())
+	minSdkVersion := ctx.Config().PlatformSdkCodename()
+	if minSdkVersion == "REL" {
+		minSdkVersion = ctx.Config().PlatformSdkVersion().String()
+	}
+	sb.WriteString(" --min-sdk-version ")
+	sb.WriteString(minSdkVersion)
+	sb.WriteString(" --version-code ")
+	sb.WriteString(ctx.Config().PlatformSdkVersion().String())
+	sb.WriteString(" --version-name ")
+	sb.WriteString(ctx.Config().AppsDefaultVersionName())
+	sb.WriteString(" --manifest ")
+	sb.WriteString(manifestTemplatePath.String())
+	sb.WriteString(" --rename-manifest-package com.android.security.fsverity_metadata.")
+	sb.WriteString(f.partitionName())
+	sb.WriteRune('\n')
+
+	// STEP 2-3: sign BuildManifest.apk
+	apksignerPath := ctx.Config().HostToolPath(ctx, "apksigner")
+	pemPath, keyPath := ctx.Config().DefaultAppCertificate(ctx)
+	cmd.Implicit(apksignerPath)
+	cmd.Implicit(pemPath)
+	cmd.Implicit(keyPath)
+	sb.WriteString(apksignerPath.String())
+	sb.WriteString(" sign --in ")
+	sb.WriteString(apkPath.String())
+	sb.WriteString(" --cert ")
+	sb.WriteString(pemPath.String())
+	sb.WriteString(" --key ")
+	sb.WriteString(keyPath.String())
+	sb.WriteRune('\n')
+
+	android.WriteExecutableFileRuleVerbatim(ctx, fsverityBuilderPath, sb.String())
+}
diff --git a/filesystem/system_image.go b/filesystem/system_image.go
index 5028a49..92bb206 100644
--- a/filesystem/system_image.go
+++ b/filesystem/system_image.go
@@ -21,6 +21,7 @@
 
 type systemImage struct {
 	filesystem
+	android.DefaultableModuleBase
 
 	properties systemImageProperties
 }
@@ -39,6 +40,7 @@
 	module.filesystem.buildExtraFiles = module.buildExtraFiles
 	module.filesystem.filterPackagingSpec = module.filterPackagingSpec
 	initFilesystemModule(&module.filesystem)
+	android.InitDefaultableModule(module)
 	return module
 }
 
@@ -100,3 +102,17 @@
 func (s *systemImage) filterPackagingSpec(ps android.PackagingSpec) bool {
 	return ps.Partition() == "system"
 }
+
+type systemImageDefaults struct {
+	android.ModuleBase
+	android.DefaultsModuleBase
+}
+
+// android_system_image_defaults is a default module for android_system_image module.
+func systemImageDefaultsFactory() android.Module {
+	module := &systemImageDefaults{}
+	module.AddProperties(&android.PackagingProperties{})
+	module.AddProperties(&systemImageProperties{})
+	android.InitDefaultsModule(module)
+	return module
+}
diff --git a/java/aar.go b/java/aar.go
index 3ac77fa..fef0d8c 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -1156,7 +1156,7 @@
 	}
 
 	extractedAARDir := android.PathForModuleOut(ctx, "aar")
-	classpathFile := extractedAARDir.Join(ctx, "classes-combined.jar")
+	classpathFile := extractedAARDir.Join(ctx, ctx.ModuleName()+".jar")
 	a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
 	a.rTxt = extractedAARDir.Join(ctx, "R.txt")
 	a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
@@ -1284,14 +1284,18 @@
 		addCLCFromDep(ctx, module, a.classLoaderContexts)
 	})
 
+	var implementationJarFile android.OutputPath
 	if len(staticJars) > 0 {
 		combineJars := append(android.Paths{classpathFile}, staticJars...)
-		a.implementationJarFile = android.PathForModuleOut(ctx, "combined", ctx.ModuleName()+".jar")
-		TransformJarsToJar(ctx, a.implementationJarFile, "combine", combineJars, android.OptionalPath{}, false, nil, nil)
+		implementationJarFile = android.PathForModuleOut(ctx, "combined", ctx.ModuleName()+".jar").OutputPath
+		TransformJarsToJar(ctx, implementationJarFile, "combine", combineJars, android.OptionalPath{}, false, nil, nil)
 	} else {
-		a.implementationJarFile = classpathFile
+		implementationJarFile = classpathFile
 	}
 
+	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
+	a.implementationJarFile = implementationJarFile.WithoutRel()
+
 	if len(staticHeaderJars) > 0 {
 		combineJars := append(android.Paths{classpathFile}, staticHeaderJars...)
 		a.headerJarFile = android.PathForModuleOut(ctx, "turbine-combined", ctx.ModuleName()+".jar")
diff --git a/java/aar_test.go b/java/aar_test.go
index 6bd53f2..3361bf9 100644
--- a/java/aar_test.go
+++ b/java/aar_test.go
@@ -128,3 +128,48 @@
 		"--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
 	)
 }
+
+func TestAndroidLibraryOutputFilesRel(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		PrepareForTestWithJavaDefaultModules,
+	).RunTestWithBp(t, `
+		android_library {
+			name: "foo",
+			srcs: ["a.java"],
+		}
+
+		android_library_import {
+			name: "bar",
+			aars: ["bar.aar"],
+
+		}
+
+		android_library_import {
+			name: "baz",
+			aars: ["baz.aar"],
+			static_libs: ["bar"],
+		}
+	`)
+
+	foo := result.ModuleForTests("foo", "android_common")
+	bar := result.ModuleForTests("bar", "android_common")
+	baz := result.ModuleForTests("baz", "android_common")
+
+	fooOutputPath := android.OutputFileForModule(android.PathContext(nil), foo.Module(), "")
+	barOutputPath := android.OutputFileForModule(android.PathContext(nil), bar.Module(), "")
+	bazOutputPath := android.OutputFileForModule(android.PathContext(nil), baz.Module(), "")
+
+	android.AssertPathRelativeToTopEquals(t, "foo output path",
+		"out/soong/.intermediates/foo/android_common/javac/foo.jar", fooOutputPath)
+	android.AssertPathRelativeToTopEquals(t, "bar output path",
+		"out/soong/.intermediates/bar/android_common/aar/bar.jar", barOutputPath)
+	android.AssertPathRelativeToTopEquals(t, "baz output path",
+		"out/soong/.intermediates/baz/android_common/combined/baz.jar", bazOutputPath)
+
+	android.AssertStringEquals(t, "foo relative output path",
+		"foo.jar", fooOutputPath.Rel())
+	android.AssertStringEquals(t, "bar relative output path",
+		"bar.jar", barOutputPath.Rel())
+	android.AssertStringEquals(t, "baz relative output path",
+		"baz.jar", bazOutputPath.Rel())
+}
diff --git a/java/base.go b/java/base.go
index 9bb133d..e2f20ce 100644
--- a/java/base.go
+++ b/java/base.go
@@ -94,9 +94,6 @@
 	// if not blank, used as prefix to generate repackage rule
 	Jarjar_prefix *string
 
-	// if set to true, skip the jarjar repackaging
-	Skip_jarjar_repackage *bool
-
 	// If not blank, set the java version passed to javac as -source and -target
 	Java_version *string
 
@@ -1103,13 +1100,11 @@
 	jarjarProviderData := j.collectJarJarRules(ctx)
 	if jarjarProviderData != nil {
 		android.SetProvider(ctx, JarJarProvider, *jarjarProviderData)
-		if !proptools.Bool(j.properties.Skip_jarjar_repackage) {
-			text := getJarJarRuleText(jarjarProviderData)
-			if text != "" {
-				ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt")
-				android.WriteFileRule(ctx, ruleTextFile, text)
-				j.repackageJarjarRules = ruleTextFile
-			}
+		text := getJarJarRuleText(jarjarProviderData)
+		if text != "" {
+			ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt")
+			android.WriteFileRule(ctx, ruleTextFile, text)
+			j.repackageJarjarRules = ruleTextFile
 		}
 	}
 
@@ -1294,10 +1289,12 @@
 			return
 		}
 
+		kotlinJarPath := j.repackageFlagsIfNecessary(ctx, kotlinJar.OutputPath, jarName, "kotlinc")
+
 		// Make javac rule depend on the kotlinc rule
 		flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...)
 
-		kotlinJars = append(kotlinJars, kotlinJar)
+		kotlinJars = append(kotlinJars, kotlinJarPath)
 		kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)
 
 		// Jar kotlin classes into the final jar after javac
@@ -1377,6 +1374,7 @@
 				for idx, shardSrc := range shardSrcs {
 					classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
 						nil, flags, extraJarDeps)
+					classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx))
 					jars = append(jars, classes)
 				}
 			}
@@ -1389,11 +1387,13 @@
 				for idx, shardSrcJars := range shardSrcJarsList {
 					classes := j.compileJavaClasses(ctx, jarName, startIdx+idx,
 						nil, shardSrcJars, flags, extraJarDeps)
+					classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx))
 					jars = append(jars, classes)
 				}
 			}
 		} else {
 			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
+			classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
 			jars = append(jars, classes)
 		}
 		if ctx.Failed() {
@@ -1552,16 +1552,6 @@
 		}
 	}
 
-	// Automatic jarjar rules propagation
-	if j.repackageJarjarRules != nil {
-		repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", jarName).OutputPath
-		TransformJarJar(ctx, repackagedJarjarFile, outputFile, j.repackageJarjarRules)
-		outputFile = repackagedJarjarFile
-		if ctx.Failed() {
-			return
-		}
-	}
-
 	// Check package restrictions if necessary.
 	if len(j.properties.Permitted_packages) > 0 {
 		// Time stamp file created by the package check rule.
@@ -2686,6 +2676,16 @@
 	return result
 }
 
+// Repackage the flags if the jarjar rule txt for the flags is generated
+func (j *Module) repackageFlagsIfNecessary(ctx android.ModuleContext, infile android.WritablePath, jarName, info string) android.WritablePath {
+	if j.repackageJarjarRules == nil {
+		return infile
+	}
+	repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info+jarName)
+	TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules)
+	return repackagedJarjarFile
+}
+
 func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
 	deps.processorPath = append(deps.processorPath, pluginJars...)
 	deps.processorClasses = append(deps.processorClasses, pluginClasses...)
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 9556e95..02b81a4 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -687,6 +687,23 @@
 	}
 }
 
+func (d *Droidstubs) apiCompatibilityFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType) {
+	if len(d.Javadoc.properties.Out) > 0 {
+		ctx.PropertyErrorf("out", "out property may not be combined with check_api")
+	}
+
+	apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
+	removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
+
+	cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
+	cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
+
+	baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
+	if baselineFile.Valid() {
+		cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
+	}
+}
+
 func metalavaUseRbe(ctx android.ModuleContext) bool {
 	return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
 }
@@ -831,6 +848,10 @@
 	d.inclusionAnnotationsFlags(ctx, cmd)
 	d.apiLevelsAnnotationsFlags(ctx, cmd, params.stubConfig.stubsType, params.apiVersionsXml)
 
+	if params.stubConfig.doCheckReleased {
+		d.apiCompatibilityFlags(ctx, cmd, params.stubConfig.stubsType)
+	}
+
 	d.expandArgs(ctx, cmd)
 
 	for _, o := range d.Javadoc.properties.Out {
@@ -989,25 +1010,12 @@
 
 	// Add "check released" options. (Detect incompatible API changes from the last public release)
 	if doCheckReleased {
-		if len(d.Javadoc.properties.Out) > 0 {
-			ctx.PropertyErrorf("out", "out property may not be combined with check_api")
-		}
-
-		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
-		removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
 		baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
-		updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
-
 		d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
-
-		cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
-		cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
-
 		if baselineFile.Valid() {
-			cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
+			updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
 			cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
 		}
-
 		// Note this string includes quote ($' ... '), which decodes the "\n"s.
 		msg := `$'\n******************************\n` +
 			`You have tried to change the API from what has been previously released in\n` +
diff --git a/phony/phony.go b/phony/phony.go
index 68fbf48..5469238 100644
--- a/phony/phony.go
+++ b/phony/phony.go
@@ -29,6 +29,7 @@
 func registerPhonyModuleTypes(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("phony", PhonyFactory)
 	ctx.RegisterModuleType("phony_rule", PhonyRuleFactory)
+	ctx.RegisterModuleType("phony_rule_defaults", PhonyRuleDefaultsFactory)
 }
 
 var PrepareForTestWithPhony = android.FixtureRegisterWithContext(registerPhonyModuleTypes)
@@ -85,6 +86,7 @@
 
 type PhonyRule struct {
 	android.ModuleBase
+	android.DefaultableModuleBase
 
 	properties PhonyProperties
 }
@@ -102,6 +104,7 @@
 	module := &PhonyRule{}
 	android.InitAndroidModule(module)
 	module.AddProperties(&module.properties)
+	android.InitDefaultableModule(module)
 	return module
 }
 
@@ -119,3 +122,45 @@
 		},
 	}
 }
+
+// PhonyRuleDefaults
+type PhonyRuleDefaults struct {
+	android.ModuleBase
+	android.DefaultsModuleBase
+}
+
+// phony_rule_defaults provides a set of properties that can be inherited by other phony_rules.
+//
+// A module can use the properties from a phony_rule_defaults module using `defaults: ["defaults_module_name"]`.  Each
+// property in the defaults module that exists in the depending module will be prepended to the depending module's
+// value for that property.
+//
+// Example:
+//
+//	phony_rule_defaults {
+//	    name: "add_module1_defaults",
+//	    phony_deps: [
+//	        "module1",
+//	    ],
+//	}
+//
+//	phony_rule {
+//	    name: "example",
+//	    defaults: ["add_module1_defaults"],
+//	}
+//
+// is functionally identical to:
+//
+//	phony_rule {
+//	    name: "example",
+//	    phony_deps: [
+//	        "module1",
+//	    ],
+//	}
+func PhonyRuleDefaultsFactory() android.Module {
+	module := &PhonyRuleDefaults{}
+	module.AddProperties(&PhonyProperties{})
+	android.InitDefaultsModule(module)
+
+	return module
+}
diff --git a/rust/image_test.go b/rust/image_test.go
index fb4d9c1..ba94906 100644
--- a/rust/image_test.go
+++ b/rust/image_test.go
@@ -24,7 +24,7 @@
 
 // Test that cc modules can link against vendor_available rust_ffi_static libraries.
 func TestVendorLinkage(t *testing.T) {
-	ctx := testRustVndk(t, `
+	ctx := testRust(t, `
 			cc_binary {
 				name: "fizz_vendor",
 				static_libs: ["libfoo_vendor"],
@@ -38,7 +38,7 @@
 			}
 		`)
 
-	vendorBinary := ctx.ModuleForTests("fizz_vendor", "android_vendor.29_arm64_armv8-a").Module().(*cc.Module)
+	vendorBinary := ctx.ModuleForTests("fizz_vendor", "android_vendor_arm64_armv8-a").Module().(*cc.Module)
 
 	if !android.InList("libfoo_vendor.vendor", vendorBinary.Properties.AndroidMkStaticLibs) {
 		t.Errorf("vendorBinary should have a dependency on libfoo_vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs)
@@ -46,8 +46,8 @@
 }
 
 // Test that variants which use the vndk emit the appropriate cfg flag.
-func TestImageVndkCfgFlag(t *testing.T) {
-	ctx := testRustVndk(t, `
+func TestImageCfgFlag(t *testing.T) {
+	ctx := testRust(t, `
 			rust_ffi_static {
 				name: "libfoo",
 				crate_name: "foo",
@@ -57,7 +57,7 @@
 			}
 		`)
 
-	vendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_static").Rule("rustc")
+	vendor := ctx.ModuleForTests("libfoo", "android_vendor_arm64_armv8-a_static").Rule("rustc")
 
 	if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") {
 		t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
@@ -69,7 +69,7 @@
 		t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
 	}
 
-	product := ctx.ModuleForTests("libfoo", "android_product.29_arm64_armv8-a_static").Rule("rustc")
+	product := ctx.ModuleForTests("libfoo", "android_product_arm64_armv8-a_static").Rule("rustc")
 	if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") {
 		t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
 	}
@@ -95,7 +95,7 @@
 
 // Test that cc modules can link against vendor_ramdisk_available rust_ffi_static libraries.
 func TestVendorRamdiskLinkage(t *testing.T) {
-	ctx := testRustVndk(t, `
+	ctx := testRust(t, `
 			cc_library_static {
 				name: "libcc_vendor_ramdisk",
 				static_libs: ["libfoo_vendor_ramdisk"],
@@ -119,7 +119,7 @@
 
 // Test that prebuilt libraries cannot be made vendor available.
 func TestForbiddenVendorLinkage(t *testing.T) {
-	testRustVndkError(t, "Rust prebuilt modules not supported for non-system images.", `
+	testRustError(t, "Rust prebuilt modules not supported for non-system images.", `
 		rust_prebuilt_library {
 			name: "librust_prebuilt",
 			crate_name: "rust_prebuilt",
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 295a734..6d083f6 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -37,11 +37,7 @@
 
 	genrule.PrepareForTestWithGenRuleBuildComponents,
 
-	PrepareForTestWithRustIncludeVndk,
-	android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
-		variables.DeviceVndkVersion = StringPtr("current")
-		variables.Platform_vndk_version = StringPtr("29")
-	}),
+	PrepareForIntegrationTestWithRust,
 )
 
 var rustMockedFiles = android.MockFS{
@@ -73,60 +69,21 @@
 	return result.TestContext
 }
 
-func testRustVndk(t *testing.T, bp string) *android.TestContext {
-	return testRustVndkFs(t, bp, rustMockedFiles)
-}
-
 const (
-	sharedVendorVariant        = "android_vendor.29_arm64_armv8-a_shared"
-	rlibVendorVariant          = "android_vendor.29_arm64_armv8-a_rlib_rlib-std"
-	rlibDylibStdVendorVariant  = "android_vendor.29_arm64_armv8-a_rlib_rlib-std"
-	dylibVendorVariant         = "android_vendor.29_arm64_armv8-a_dylib"
+	sharedVendorVariant        = "android_vendor_arm64_armv8-a_shared"
+	rlibVendorVariant          = "android_vendor_arm64_armv8-a_rlib_rlib-std"
+	rlibDylibStdVendorVariant  = "android_vendor_arm64_armv8-a_rlib_rlib-std"
+	dylibVendorVariant         = "android_vendor_arm64_armv8-a_dylib"
 	sharedRecoveryVariant      = "android_recovery_arm64_armv8-a_shared"
 	rlibRecoveryVariant        = "android_recovery_arm64_armv8-a_rlib_dylib-std"
 	rlibRlibStdRecoveryVariant = "android_recovery_arm64_armv8-a_rlib_rlib-std"
 	dylibRecoveryVariant       = "android_recovery_arm64_armv8-a_dylib"
 	binaryCoreVariant          = "android_arm64_armv8-a"
-	binaryVendorVariant        = "android_vendor.29_arm64_armv8-a"
-	binaryProductVariant       = "android_product.29_arm64_armv8-a"
+	binaryVendorVariant        = "android_vendor_arm64_armv8-a"
+	binaryProductVariant       = "android_product_arm64_armv8-a"
 	binaryRecoveryVariant      = "android_recovery_arm64_armv8-a"
 )
 
-func testRustVndkFs(t *testing.T, bp string, fs android.MockFS) *android.TestContext {
-	return testRustVndkFsVersions(t, bp, fs, "current", "current", "29")
-}
-
-func testRustVndkFsVersions(t *testing.T, bp string, fs android.MockFS, device_version, product_version, vndk_version string) *android.TestContext {
-	skipTestIfOsNotSupported(t)
-	result := android.GroupFixturePreparers(
-		prepareForRustTest,
-		fs.AddToFixture(),
-		android.FixtureModifyProductVariables(
-			func(variables android.FixtureProductVariables) {
-				variables.DeviceVndkVersion = StringPtr(device_version)
-				variables.Platform_vndk_version = StringPtr(vndk_version)
-			},
-		),
-	).RunTestWithBp(t, bp)
-	return result.TestContext
-}
-
-func testRustRecoveryFsVersions(t *testing.T, bp string, fs android.MockFS, device_version, vndk_version, recovery_version string) *android.TestContext {
-	skipTestIfOsNotSupported(t)
-	result := android.GroupFixturePreparers(
-		prepareForRustTest,
-		fs.AddToFixture(),
-		android.FixtureModifyProductVariables(
-			func(variables android.FixtureProductVariables) {
-				variables.DeviceVndkVersion = StringPtr(device_version)
-				variables.RecoverySnapshotVersion = StringPtr(recovery_version)
-				variables.Platform_vndk_version = StringPtr(vndk_version)
-			},
-		),
-	).RunTestWithBp(t, bp)
-	return result.TestContext
-}
-
 // testRustCov returns a TestContext in which a basic environment has been
 // setup. This environment explicitly enables coverage.
 func testRustCov(t *testing.T, bp string) *android.TestContext {
@@ -158,27 +115,6 @@
 		RunTestWithBp(t, bp)
 }
 
-// testRustVndkError is similar to testRustError, but can be used to test VNDK-related errors.
-func testRustVndkError(t *testing.T, pattern string, bp string) {
-	testRustVndkFsError(t, pattern, bp, rustMockedFiles)
-}
-
-func testRustVndkFsError(t *testing.T, pattern string, bp string, fs android.MockFS) {
-	skipTestIfOsNotSupported(t)
-	android.GroupFixturePreparers(
-		prepareForRustTest,
-		fs.AddToFixture(),
-		android.FixtureModifyProductVariables(
-			func(variables android.FixtureProductVariables) {
-				variables.DeviceVndkVersion = StringPtr("current")
-				variables.Platform_vndk_version = StringPtr("VER")
-			},
-		),
-	).
-		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
-		RunTestWithBp(t, bp)
-}
-
 // testRustCtx is used to build a particular test environment. Unless your
 // tests requires a specific setup, prefer the wrapping functions: testRust,
 // testRustCov or testRustError.
diff --git a/rust/testing.go b/rust/testing.go
index 986e34e..4e9a6c6 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -43,10 +43,6 @@
 // Preparer that will allow use of all rust modules fully.
 var PrepareForIntegrationTestWithRust = android.GroupFixturePreparers(
 	PrepareForTestWithRustDefaultModules,
-)
-
-var PrepareForTestWithRustIncludeVndk = android.GroupFixturePreparers(
-	PrepareForIntegrationTestWithRust,
 	cc.PrepareForIntegrationTestWithCc,
 )
 
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index dfbbe7d..7d4e69d 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -134,8 +134,6 @@
 		PrepareForTestWithSyspropBuildComponents,
 		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
 			variables.DeviceSystemSdkVersions = []string{"28"}
-			variables.DeviceVndkVersion = proptools.StringPtr("current")
-			variables.Platform_vndk_version = proptools.StringPtr("29")
 			variables.DeviceCurrentApiLevelForVendorModules = proptools.StringPtr("28")
 		}),
 		java.FixtureWithPrebuiltApis(map[string][]string{
@@ -258,10 +256,10 @@
 
 	// Check for generated cc_library
 	for _, variant := range []string{
-		"android_vendor.29_arm_armv7-a-neon_shared",
-		"android_vendor.29_arm_armv7-a-neon_static",
-		"android_vendor.29_arm64_armv8-a_shared",
-		"android_vendor.29_arm64_armv8-a_static",
+		"android_vendor_arm_armv7-a-neon_shared",
+		"android_vendor_arm_armv7-a-neon_static",
+		"android_vendor_arm64_armv8-a_shared",
+		"android_vendor_arm64_armv8-a_static",
 	} {
 		result.ModuleForTests("libsysprop-platform", variant)
 		result.ModuleForTests("libsysprop-vendor", variant)
@@ -270,10 +268,10 @@
 
 	// product variant of vendor-owned sysprop_library
 	for _, variant := range []string{
-		"android_product.29_arm_armv7-a-neon_shared",
-		"android_product.29_arm_armv7-a-neon_static",
-		"android_product.29_arm64_armv8-a_shared",
-		"android_product.29_arm64_armv8-a_static",
+		"android_product_arm_armv7-a-neon_shared",
+		"android_product_arm_armv7-a-neon_static",
+		"android_product_arm64_armv8-a_shared",
+		"android_product_arm64_armv8-a_static",
 	} {
 		result.ModuleForTests("libsysprop-vendor-on-product", variant)
 	}
@@ -296,16 +294,16 @@
 
 	// Check for exported includes
 	coreVariant := "android_arm64_armv8-a_static"
-	vendorVariant := "android_vendor.29_arm64_armv8-a_static"
-	productVariant := "android_product.29_arm64_armv8-a_static"
+	vendorVariant := "android_vendor_arm64_armv8-a_static"
+	productVariant := "android_product_arm64_armv8-a_static"
 
 	platformInternalPath := "libsysprop-platform/android_arm64_armv8-a_static/gen/sysprop/include"
-	platformPublicVendorPath := "libsysprop-platform/android_vendor.29_arm64_armv8-a_static/gen/sysprop/public/include"
+	platformPublicVendorPath := "libsysprop-platform/android_vendor_arm64_armv8-a_static/gen/sysprop/public/include"
 
-	platformOnProductPath := "libsysprop-platform-on-product/android_product.29_arm64_armv8-a_static/gen/sysprop/public/include"
+	platformOnProductPath := "libsysprop-platform-on-product/android_product_arm64_armv8-a_static/gen/sysprop/public/include"
 
-	vendorInternalPath := "libsysprop-vendor/android_vendor.29_arm64_armv8-a_static/gen/sysprop/include"
-	vendorOnProductPath := "libsysprop-vendor-on-product/android_product.29_arm64_armv8-a_static/gen/sysprop/public/include"
+	vendorInternalPath := "libsysprop-vendor/android_vendor_arm64_armv8-a_static/gen/sysprop/include"
+	vendorOnProductPath := "libsysprop-vendor-on-product/android_product_arm64_armv8-a_static/gen/sysprop/public/include"
 
 	platformClient := result.ModuleForTests("cc-client-platform", coreVariant)
 	platformFlags := platformClient.Rule("cc").Args["cFlags"]
diff --git a/tests/androidmk_test.sh b/tests/androidmk_test.sh
index b81828b..aecc4e8 100755
--- a/tests/androidmk_test.sh
+++ b/tests/androidmk_test.sh
@@ -5,7 +5,7 @@
 # How to run: bash path-to-script/androidmk_test.sh
 # Tests of converting license functionality of the androidmk tool
 REAL_TOP="$(readlink -f "$(dirname "$0")"/../../..)"
-"$REAL_TOP/build/soong/soong_ui.bash" --make-mode androidmk
+"$REAL_TOP/build/soong/soong_ui.bash" --make-mode TARGET_RELEASE=trunk_staging androidmk
 
 source "$(dirname "$0")/lib.sh"
 
diff --git a/tests/apex_cc_module_arch_variant_tests.sh b/tests/apex_cc_module_arch_variant_tests.sh
deleted file mode 100755
index 1f5e003..0000000
--- a/tests/apex_cc_module_arch_variant_tests.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-set -uo pipefail
-
-# Integration test for verifying arch variant cflags set on cc modules included
-# in Bazel-built apexes in the real source tree.
-
-if [ ! -e "build/make/core/Makefile" ]; then
-  echo "$0 must be run from the top of the Android source tree."
-  exit 1
-fi
-
-############
-# Test Setup
-############
-
-OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)"
-BAZEL_OUTPUT_DIR="$OUTPUT_DIR/bazel"
-
-export TARGET_PRODUCT="aosp_arm64"
-[ "$#" -ge 1 ] && export TARGET_PRODUCT="$1"
-ARCH_VARIANT_CFLAG="armv8-a"
-[ "$#" -ge 2 ] && ARCH_VARIANT_CFLAG="$2"
-CPU_VARIANT_CFLAG=""
-[ "$#" -ge 3 ] && CPU_VARIANT_CFLAG="$3"
-
-function call_bazel() {
-  build/bazel/bin/bazel --output_base="$BAZEL_OUTPUT_DIR" $@
-}
-
-function cleanup {
-  # call bazel clean because some bazel outputs don't have w bits.
-  call_bazel clean
-  rm -rf "${OUTPUT_DIR}"
-}
-trap cleanup EXIT
-
-######################
-# Run bp2build / Bazel
-######################
-build/soong/soong_ui.bash --make-mode BP2BUILD_VERBOSE=1 --skip-soong-tests bp2build
-
-# Number of CppCompile actions with arch variant flag
-actions_with_arch_variant_num=$(call_bazel aquery --config=bp2build --config=ci --config=android \
-  'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))' | grep -c \'-march=$ARCH_VARIANT_CFLAG\')
-
-# Number of all CppCompile actions
-all_cppcompile_actions_num=0
-aquery_summary=$(call_bazel aquery --config=bp2build --config=ci --config=android --output=summary \
-  'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))' \
-  | egrep -o '.*opt-ST.*: ([0-9]+)$' \
-  | cut -d: -f2 -)
-
-while read -r num;
-do
-  all_cppcompile_actions_num=$(($all_cppcompile_actions_num + $num))
-done <<< "$aquery_summary"
-
-if [ $actions_with_arch_variant_num -eq $all_cppcompile_actions_num ]
-then
-  echo "Pass: arch variant is set."
-else
-  echo "Error: number of CppCompile actions with arch variant set: actual=$actions_with_arch_variant_num, expected=$all_cppcompile_actions_num"
-  exit 1
-fi
-
-if [ $CPU_VARIANT_CFLAG ]
-then
-  # Number of CppCompiler actions with cpu variant flag
-  actions_with_cpu_variant_num=$(call_bazel aquery --config=bp2build --config=ci --config=android \
-    'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))' | grep -c "\-mcpu=$CPU_VARIANT_CFLAG")
-
-  if [ $actions_with_cpu_variant_num -eq $all_cppcompile_actions_num ]
-  then
-    echo "Pass: cpu variant is set."
-  else
-    echo "Error: number of CppCompile actions with cpu variant set: actual=$actions_with_cpu_variant_num, expected=$all_cppcompile_actions_num"
-    exit 1
-  fi
-fi
diff --git a/tests/apex_comparison_tests.sh b/tests/apex_comparison_tests.sh
deleted file mode 100755
index 8893060..0000000
--- a/tests/apex_comparison_tests.sh
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-set -euo pipefail
-
-# Soong/Bazel integration test for building unbundled apexes in the real source tree.
-#
-# These tests build artifacts from head and compares their contents.
-
-if [ ! -e "build/make/core/Makefile" ]; then
-  echo "$0 must be run from the top of the Android source tree."
-  exit 1
-fi
-
-############
-# Test Setup
-############
-
-OUTPUT_DIR="$(mktemp -d $(pwd)/tmp.XXXXXX)"
-SOONG_OUTPUT_DIR="$OUTPUT_DIR/soong"
-BAZEL_OUTPUT_DIR="$OUTPUT_DIR/bazel"
-
-export TARGET_PRODUCT="module_arm"
-[ "$#" -eq 1 ] && export TARGET_PRODUCT="$1"
-
-function call_bazel() {
-  build/bazel/bin/bazel --output_base="$BAZEL_OUTPUT_DIR" $@
-}
-
-function cleanup {
-  # call bazel clean because some bazel outputs don't have w bits.
-  call_bazel clean
-  rm -rf "${OUTPUT_DIR}"
-}
-
-function deapexer() {
-  DEBUGFS_PATH="$(realpath $(call_bazel cquery --config=bp2build --config=linux_x86_64 --config=ci --output=files //external/e2fsprogs/debugfs))"
-  call_bazel run --config=bp2build //system/apex/tools:deapexer -- --debugfs_path=$DEBUGFS_PATH $@
-}
-
-trap cleanup EXIT
-
-###########
-# Run Soong
-###########
-export UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true # don't rely on prebuilts
-export TARGET_BUILD_APPS="com.android.adbd com.android.tzdata build.bazel.examples.apex.minimal"
-packages/modules/common/build/build_unbundled_mainline_module.sh \
-  --product "$TARGET_PRODUCT" \
-  --dist_dir "$SOONG_OUTPUT_DIR"
-
-######################
-# Run bp2build / Bazel
-######################
-build/soong/soong_ui.bash --make-mode BP2BUILD_VERBOSE=1 --skip-soong-tests bp2build
-
-BAZEL_OUT="$(call_bazel info --config=bp2build output_path)"
-
-call_bazel build --config=bp2build --config=ci --config=android \
-  //packages/modules/adb/apex:com.android.adbd \
-  //system/timezone/apex:com.android.tzdata \
-  //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal
-BAZEL_ADBD="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //packages/modules/adb/apex:com.android.adbd))"
-BAZEL_TZDATA="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //system/timezone/apex:com.android.tzdata))"
-BAZEL_MINIMAL="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))"
-
-# # Build debugfs separately, as it's not a dep of apexer, but needs to be an explicit arg.
-call_bazel build --config=bp2build --config=linux_x86_64 //external/e2fsprogs/debugfs
-
-#######
-# Tests
-#######
-
-function compare_deapexer_list() {
-  local BAZEL_APEX=$1; shift
-  local APEX=$1; shift
-
-  # Compare the outputs of `deapexer list`, which lists the contents of the apex filesystem image.
-  local SOONG_APEX="$SOONG_OUTPUT_DIR/$APEX"
-
-  local SOONG_LIST="$OUTPUT_DIR/soong.list"
-  local BAZEL_LIST="$OUTPUT_DIR/bazel.list"
-
-  deapexer list "$SOONG_APEX" > "$SOONG_LIST"
-  deapexer list "$BAZEL_APEX" > "$BAZEL_LIST"
-
-  if cmp -s "$SOONG_LIST" "$BAZEL_LIST"
-  then
-    echo "ok: $APEX"
-  else
-    echo "contents of $APEX are different between Soong and Bazel:"
-    echo
-    echo expected
-    echo
-    cat "$SOONG_LIST"
-    echo
-    echo got
-    echo
-    cat "$BAZEL_LIST"
-    exit 1
-  fi
-}
-
-compare_deapexer_list "${BAZEL_ADBD}" com.android.adbd.apex
-compare_deapexer_list "${BAZEL_TZDATA}" com.android.tzdata.apex
-compare_deapexer_list "${BAZEL_MINIMAL}" build.bazel.examples.apex.minimal.apex
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index 5fc05f8..2e40950 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -9,6 +9,8 @@
 
 readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel"
 
+readonly target_product="${TARGET_PRODUCT:-aosp_arm}"
+
 function test_smoke {
   setup
   run_soong
@@ -18,10 +20,10 @@
   setup
   run_soong
   local -r bootstrap_mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
-  local -r output_mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r output_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
   run_soong
   local -r bootstrap_mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
-  local -r output_mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r output_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   if [[ "$bootstrap_mtime1" == "$bootstrap_mtime2" ]]; then
     # Bootstrapping is always done. It doesn't take a measurable amount of time.
@@ -60,7 +62,7 @@
   touch a/my_little_binary_host.py
   run_soong
 
-  grep -q "^# Module:.*my_little_binary_host" out/soong/build.ninja || fail "module not found"
+  grep -q "^# Module:.*my_little_binary_host" out/soong/build."${target_product}".ninja || fail "module not found"
 
   cat > a/Android.bp <<'EOF'
 python_binary_host {
@@ -71,14 +73,14 @@
   touch a/my_great_binary_host.py
   run_soong
 
-  grep -q "^# Module:.*my_little_binary_host" out/soong/build.ninja && fail "old module found"
-  grep -q "^# Module:.*my_great_binary_host" out/soong/build.ninja || fail "new module not found"
+  grep -q "^# Module:.*my_little_binary_host" out/soong/build."${target_product}".ninja && fail "old module found"
+  grep -q "^# Module:.*my_great_binary_host" out/soong/build."${target_product}".ninja || fail "new module not found"
 }
 
 function test_add_android_bp() {
   setup
   run_soong
-  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   mkdir -p a
   cat > a/Android.bp <<'EOF'
@@ -90,12 +92,12 @@
   touch a/my_little_binary_host.py
   run_soong
 
-  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
   if [[ "$mtime1" == "$mtime2" ]]; then
     fail "Output Ninja file did not change"
   fi
 
-  grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja || fail "New module not in output"
+  grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".ninja || fail "New module not in output"
 
   run_soong
 }
@@ -112,12 +114,12 @@
   touch a/my_little_binary_host.py
   run_soong
 
-  grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja || fail "Module not in output"
+  grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".ninja || fail "Module not in output"
 
   rm a/Android.bp
   run_soong
 
-  if grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja; then
+  if grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".ninja; then
     fail "Old module in output"
   fi
 }
@@ -141,16 +143,12 @@
 EOF
   touch a/my_little_binary_host.py
   run_soong
-  local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
-  local glob_deps_file=out/soong/globs/build/0.d
-
-  if [ -e "$glob_deps_file" ]; then
-    fail "Glob deps file unexpectedly written on first build"
-  fi
+  local glob_deps_file=out/soong/globs/"${target_product}"/0.d
 
   run_soong
-  local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   # There is an ineffiencency in glob that requires bpglob to rerun once for each glob to update
   # the entry in the .ninja_log.  It doesn't update the output file, but we can detect the rerun
@@ -166,7 +164,7 @@
   fi
 
   run_soong
-  local -r ninja_mtime3=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja)
   local -r glob_deps_mtime3=$(stat -c "%y" "$glob_deps_file")
 
   if [[ "$ninja_mtime2" != "$ninja_mtime3" ]]; then
@@ -191,17 +189,17 @@
 EOF
   touch a/my_little_binary_host.py
   run_soong
-  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   touch a/my_little_library.py
   run_soong
 
-  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
   if [[ "$mtime1" == "$mtime2" ]]; then
     fail "Output Ninja file did not change"
   fi
 
-  grep -q my_little_library.py out/soong/build.ninja || fail "new file is not in output"
+  grep -q my_little_library.py out/soong/build."${target_product}".ninja || fail "new file is not in output"
 }
 
 function test_soong_build_rerun_iff_environment_changes() {
@@ -267,17 +265,17 @@
 
   export CHERRY=TASTY
   run_soong
-  grep -q "CHERRY IS TASTY" out/soong/build.ninja \
+  grep -q "CHERRY IS TASTY" out/soong/build."${target_product}".ninja \
     || fail "first value of environment variable is not used"
 
   export CHERRY=RED
   run_soong
-  grep -q "CHERRY IS RED" out/soong/build.ninja \
+  grep -q "CHERRY IS RED" out/soong/build."${target_product}".ninja \
     || fail "second value of environment variable not used"
-  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   run_soong
-  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
   if [[ "$mtime1" != "$mtime2" ]]; then
     fail "Output Ninja file changed when environment variable did not"
   fi
@@ -287,7 +285,7 @@
 function test_create_global_include_directory() {
   setup
   run_soong
-  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   # Soong needs to know if top level directories like hardware/ exist for use
   # as global include directories.  Make sure that doesn't cause regens for
@@ -295,7 +293,7 @@
   mkdir -p system/core
 
   run_soong
-  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
   if [[ "$mtime1" != "$mtime2" ]]; then
     fail "Output Ninja file changed when top level directory changed"
   fi
@@ -305,7 +303,7 @@
   mkdir -p system/core/include
 
   run_soong
-  local -r mtime3=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja)
   if [[ "$mtime2" = "$mtime3" ]]; then
     fail "Output Ninja file did not change when global include directory created"
   fi
@@ -315,7 +313,7 @@
 function test_add_file_to_soong_build() {
   setup
   run_soong
-  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   mkdir -p vendor/foo/picard
   cat > vendor/foo/picard/Android.bp <<'EOF'
@@ -377,12 +375,12 @@
 EOF
 
   run_soong
-  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
   if [[ "$mtime1" == "$mtime2" ]]; then
     fail "Output Ninja file did not change"
   fi
 
-  grep -q "Make it so" out/soong/build.ninja || fail "New action not present"
+  grep -q "Make it so" out/soong/build."${target_product}".ninja || fail "New action not present"
 }
 
 # Tests a glob in a build= statement in an Android.bp file, which is interpreted
@@ -455,9 +453,9 @@
 EOF
 
   run_soong
-  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
-  grep -q "Make it so" out/soong/build.ninja || fail "Original action not present"
+  grep -q "Make it so" out/soong/build."${target_product}".ninja || fail "Original action not present"
 
   cat > build/soong/picard/foob.bp <<'EOF'
 bootstrap_go_package {
@@ -487,14 +485,14 @@
 EOF
 
   run_soong
-  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
   if [[ "$mtime1" == "$mtime2" ]]; then
     fail "Output Ninja file did not change"
   fi
 
-  grep -q "Engage" out/soong/build.ninja || fail "New action not present"
+  grep -q "Engage" out/soong/build."${target_product}".ninja || fail "New action not present"
 
-  if grep -q "Make it so" out/soong/build.ninja; then
+  if grep -q "Make it so" out/soong/build."${target_product}".ninja; then
     fail "Original action still present"
   fi
 }
@@ -512,7 +510,7 @@
   setup
 
   run_soong
-  local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   run_soong soong_docs
   local -r docs_mtime1=$(stat -c "%y" out/soong/docs/soong_build.html)
@@ -525,7 +523,7 @@
   fi
 
   run_soong
-  local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
     fail "Output Ninja file changed on null build"
@@ -565,144 +563,6 @@
   fi
 }
 
-function test_bp2build_smoke {
-  setup
-  run_soong bp2build
-  [[ -e out/soong/bp2build_workspace_marker ]] || fail "bp2build marker file not created"
-  [[ -e out/soong/workspace ]] || fail "Bazel workspace not created"
-}
-
-function test_bp2build_generates_marker_file {
-  setup
-
-  run_soong bp2build
-
-  if [[ ! -f "./out/soong/bp2build_files_marker" ]]; then
-    fail "bp2build marker file was not generated"
-  fi
-
-  if [[ ! -f "./out/soong/bp2build_workspace_marker" ]]; then
-    fail "symlink forest marker file was not generated"
-  fi
-}
-
-function test_bp2build_add_irrelevant_file {
-  setup
-
-  mkdir -p a/b
-  touch a/b/c.txt
-  cat > a/b/Android.bp <<'EOF'
-filegroup {
-  name: "c",
-  srcs: ["c.txt"],
-  bazel_module: { bp2build_available: true },
-}
-EOF
-
-  run_soong bp2build
-  if [[ ! -e out/soong/bp2build/a/b/BUILD.bazel ]]; then
-    fail "BUILD file in symlink forest was not created";
-  fi
-
-  local -r mtime1=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
-
-  touch a/irrelevant.txt
-  run_soong bp2build
-  local -r mtime2=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
-
-  if [[ "$mtime1" != "$mtime2" ]]; then
-    fail "BUILD.bazel file was regenerated"
-  fi
-
-  if [[ ! -e "out/soong/workspace/a/irrelevant.txt" ]]; then
-    fail "New file was not symlinked into symlink forest"
-  fi
-}
-
-function test_bp2build_add_android_bp {
-  setup
-
-  mkdir -p a
-  touch a/a.txt
-  cat > a/Android.bp <<'EOF'
-filegroup {
-  name: "a",
-  srcs: ["a.txt"],
-  bazel_module: { bp2build_available: true },
-}
-EOF
-
-  run_soong bp2build
-  [[ -e out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not created"
-  [[ -L out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not symlinked"
-
-  mkdir -p b
-  touch b/b.txt
-  cat > b/Android.bp <<'EOF'
-filegroup {
-  name: "b",
-  srcs: ["b.txt"],
-  bazel_module: { bp2build_available: true },
-}
-EOF
-
-  run_soong bp2build
-  [[ -e out/soong/bp2build/b/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not created"
-  [[ -L out/soong/workspace/b/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not symlinked"
-}
-
-function test_bp2build_null_build {
-  setup
-
-  run_soong bp2build
-  local -r mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
-  run_soong bp2build
-  local -r mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
-  if [[ "$mtime1" != "$mtime2" ]]; then
-    fail "Output Ninja file changed on null build"
-  fi
-}
-
-function test_bp2build_add_to_glob {
-  setup
-
-  mkdir -p a
-  touch a/a1.txt
-  cat > a/Android.bp <<'EOF'
-filegroup {
-  name: "a",
-  srcs: ["*.txt"],
-  bazel_module: { bp2build_available: true },
-}
-EOF
-
-  run_soong bp2build
-  grep -q a1.txt "out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME}" || fail "a1.txt not in ${GENERATED_BUILD_FILE_NAME} file"
-
-  touch a/a2.txt
-  run_soong bp2build
-  grep -q a2.txt "out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME}" || fail "a2.txt not in ${GENERATED_BUILD_FILE_NAME} file"
-}
-
-function test_multiple_soong_build_modes() {
-  setup
-  run_soong json-module-graph bp2build nothing
-  if [[ ! -f "out/soong/bp2build_workspace_marker" ]]; then
-    fail "bp2build marker file was not generated"
-  fi
-
-
-  if [[ ! -f "out/soong/module-graph.json" ]]; then
-    fail "JSON file was not created"
-  fi
-
-  if [[ ! -f "out/soong/build.ninja" ]]; then
-    fail "Main build.ninja file was not created"
-  fi
-}
-
 function test_dump_json_module_graph() {
   setup
   run_soong json-module-graph
@@ -715,13 +575,13 @@
   setup
 
   run_soong
-  local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   run_soong json-module-graph
   local -r json_mtime1=$(stat -c "%y" out/soong/module-graph.json)
 
   run_soong
-  local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
   if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
     fail "Output Ninja file changed after writing JSON module graph"
   fi
@@ -734,143 +594,6 @@
 
 }
 
-function test_bp2build_bazel_workspace_structure {
-  setup
-
-  mkdir -p a/b
-  touch a/a.txt
-  touch a/b/b.txt
-  cat > a/b/Android.bp <<'EOF'
-filegroup {
-  name: "b",
-  srcs: ["b.txt"],
-  bazel_module: { bp2build_available: true },
-}
-EOF
-
-  run_soong bp2build
-  [[ -e out/soong/workspace ]] || fail "Bazel workspace not created"
-  [[ -d out/soong/workspace/a/b ]] || fail "module directory not a directory"
-  [[ -L "out/soong/workspace/a/b/${GENERATED_BUILD_FILE_NAME}" ]] || fail "${GENERATED_BUILD_FILE_NAME} file not symlinked"
-  [[ "$(readlink -f out/soong/workspace/a/b/${GENERATED_BUILD_FILE_NAME})" =~ "bp2build/a/b/${GENERATED_BUILD_FILE_NAME}"$ ]] \
-    || fail "BUILD files symlinked at the wrong place"
-  [[ -L out/soong/workspace/a/b/b.txt ]] || fail "a/b/b.txt not symlinked"
-  [[ -L out/soong/workspace/a/a.txt ]] || fail "a/b/a.txt not symlinked"
-  [[ ! -e out/soong/workspace/out ]] || fail "out directory symlinked"
-}
-
-function test_bp2build_bazel_workspace_add_file {
-  setup
-
-  mkdir -p a
-  touch a/a.txt
-  cat > a/Android.bp <<EOF
-filegroup {
-  name: "a",
-  srcs: ["a.txt"],
-  bazel_module: { bp2build_available: true },
-}
-EOF
-
-  run_soong bp2build
-
-  touch a/a2.txt  # No reference in the .bp file needed
-  run_soong bp2build
-  [[ -L out/soong/workspace/a/a2.txt ]] || fail "a/a2.txt not symlinked"
-}
-
-function test_bp2build_build_file_precedence {
-  setup
-
-  mkdir -p a
-  touch a/a.txt
-  touch a/${GENERATED_BUILD_FILE_NAME}
-  cat > a/Android.bp <<EOF
-filegroup {
-  name: "a",
-  srcs: ["a.txt"],
-  bazel_module: { bp2build_available: true },
-}
-EOF
-
-  run_soong bp2build
-  [[ -L "out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME}" ]] || fail "${GENERATED_BUILD_FILE_NAME} file not symlinked"
-  [[ "$(readlink -f out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME})" =~ "bp2build/a/${GENERATED_BUILD_FILE_NAME}"$ ]] \
-    || fail "${GENERATED_BUILD_FILE_NAME} files symlinked to the wrong place"
-}
-
-function test_bp2build_fails_fast {
-  setup
-
-  mkdir -p "a/${GENERATED_BUILD_FILE_NAME}"
-  cat > a/Android.bp <<EOF
-filegroup {
-  name: "a",
-  srcs: ["a.txt"],
-  bazel_module: { bp2build_available: true },
-}
-EOF
-
-  mkdir -p "b/${GENERATED_BUILD_FILE_NAME}"
-  cat > b/Android.bp <<EOF
-filegroup {
-  name: "b",
-  srcs: ["b.txt"],
-  bazel_module: { bp2build_available: true },
-}
-EOF
-
-  if run_soong bp2build >& "$MOCK_TOP/errors"; then
-    fail "Build should have failed"
-  fi
-
-  # we should expect at least one error
-  grep -q -E "(a|b)/${GENERATED_BUILD_FILE_NAME}' exist" "$MOCK_TOP/errors" || fail "Error for ${GENERATED_BUILD_FILE_NAME} not found"
-}
-
-function test_bp2build_back_and_forth_null_build {
-  setup
-
-  run_soong
-  local -r output_mtime1=$(stat -c "%y" out/soong/build.ninja)
-
-  run_soong bp2build
-  local -r output_mtime2=$(stat -c "%y" out/soong/build.ninja)
-  if [[ "$output_mtime1" != "$output_mtime2" ]]; then
-    fail "Output Ninja file changed when switching to bp2build"
-  fi
-
-  local -r marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
-  run_soong
-  local -r output_mtime3=$(stat -c "%y" out/soong/build.ninja)
-  local -r marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-  if [[ "$output_mtime1" != "$output_mtime3" ]]; then
-    fail "Output Ninja file changed when switching to regular build from bp2build"
-  fi
-  if [[ "$marker_mtime1" != "$marker_mtime2" ]]; then
-    fail "bp2build marker file changed when switching to regular build from bp2build"
-  fi
-
-  run_soong bp2build
-  local -r output_mtime4=$(stat -c "%y" out/soong/build.ninja)
-  local -r marker_mtime3=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-  if [[ "$output_mtime1" != "$output_mtime4" ]]; then
-    fail "Output Ninja file changed when switching back to bp2build"
-  fi
-  if [[ "$marker_mtime1" != "$marker_mtime3" ]]; then
-    fail "bp2build marker file changed when switching back to bp2build"
-  fi
-}
-
-function test_queryview_smoke() {
-  setup
-
-  run_soong queryview
-  [[ -e out/soong/queryview/WORKSPACE ]] || fail "queryview WORKSPACE file not created"
-
-}
-
 function test_queryview_null_build() {
   setup
 
@@ -886,14 +609,14 @@
 }
 
 # This test verifies that adding a new glob to a blueprint file only
-# causes build.ninja to be regenerated on the *next* build, and *not*
+# causes build."${target_product}".ninja to be regenerated on the *next* build, and *not*
 # the build after. (This is a regression test for a bug where globs
 # resulted in two successive regenerations.)
 function test_new_glob_incrementality {
   setup
 
   run_soong nothing
-  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   mkdir -p globdefpkg/
   cat > globdefpkg/Android.bp <<'EOF'
@@ -904,14 +627,14 @@
 EOF
 
   run_soong nothing
-  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   if [[ "$mtime1" == "$mtime2" ]]; then
     fail "Ninja file was not regenerated, despite a new bp file"
   fi
 
   run_soong nothing
-  local -r mtime3=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja)
 
   if [[ "$mtime2" != "$mtime3" ]]; then
     fail "Ninja file was regenerated despite no previous bp changes"
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
deleted file mode 100755
index 8a64a56..0000000
--- a/tests/bp2build_bazel_test.sh
+++ /dev/null
@@ -1,445 +0,0 @@
-#!/bin/bash -eu
-
-set -o pipefail
-
-# Test that bp2build and Bazel can play nicely together
-
-source "$(dirname "$0")/lib.sh"
-
-readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel"
-
-function test_bp2build_null_build {
-  setup
-  run_soong bp2build
-  local -r output_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
-  run_soong bp2build
-  local -r output_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
-  if [[ "$output_mtime1" != "$output_mtime2" ]]; then
-    fail "Output bp2build marker file changed on null build"
-  fi
-}
-
-# Tests that, if bp2build reruns due to a blueprint file changing, that
-# BUILD files whose contents are unchanged are not regenerated.
-function test_bp2build_unchanged {
-  setup
-
-  mkdir -p pkg
-  touch pkg/x.txt
-  cat > pkg/Android.bp <<'EOF'
-filegroup {
-    name: "x",
-    srcs: ["x.txt"],
-    bazel_module: {bp2build_available: true},
-  }
-EOF
-
-  run_soong bp2build
-  local -r buildfile_mtime1=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
-  local -r marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
-  # Force bp2build to rerun by updating the timestamp of a blueprint file.
-  touch pkg/Android.bp
-
-  run_soong bp2build
-  local -r buildfile_mtime2=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
-  local -r marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
-  if [[ "$marker_mtime1" == "$marker_mtime2" ]]; then
-    fail "Expected bp2build marker file to change"
-  fi
-  if [[ "$buildfile_mtime1" != "$buildfile_mtime2" ]]; then
-    fail "BUILD.bazel was updated even though contents are same"
-  fi
-
-  # Force bp2build to rerun by updating the timestamp of the constants_exported_to_soong.bzl file.
-  touch build/bazel/constants_exported_to_soong.bzl
-
-  run_soong bp2build
-  local -r buildfile_mtime3=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
-  local -r marker_mtime3=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
-  if [[ "$marker_mtime2" == "$marker_mtime3" ]]; then
-    fail "Expected bp2build marker file to change"
-  fi
-  if [[ "$buildfile_mtime2" != "$buildfile_mtime3" ]]; then
-    fail "BUILD.bazel was updated even though contents are same"
-  fi
-}
-
-# Tests that blueprint files that are deleted are not present when the
-# bp2build tree is regenerated.
-function test_bp2build_deleted_blueprint {
-  setup
-
-  mkdir -p pkg
-  touch pkg/x.txt
-  cat > pkg/Android.bp <<'EOF'
-filegroup {
-    name: "x",
-    srcs: ["x.txt"],
-    bazel_module: {bp2build_available: true},
-  }
-EOF
-
-  run_soong bp2build
-  if [[ ! -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
-    fail "Expected pkg/BUILD.bazel to be generated"
-  fi
-
-  rm pkg/Android.bp
-
-  run_soong bp2build
-  if [[ -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
-    fail "Expected pkg/BUILD.bazel to be deleted"
-  fi
-}
-
-function test_bp2build_null_build_with_globs {
-  setup
-
-  mkdir -p foo/bar
-  cat > foo/bar/Android.bp <<'EOF'
-filegroup {
-    name: "globs",
-    srcs: ["*.txt"],
-  }
-EOF
-  touch foo/bar/a.txt foo/bar/b.txt
-
-  run_soong bp2build
-  local -r output_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
-  run_soong bp2build
-  local -r output_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
-  if [[ "$output_mtime1" != "$output_mtime2" ]]; then
-    fail "Output bp2build marker file changed on null build"
-  fi
-}
-
-function test_different_relative_outdir {
-  setup
-
-  mkdir -p a
-  touch a/g.txt
-  cat > a/Android.bp <<'EOF'
-filegroup {
-    name: "g",
-    srcs: ["g.txt"],
-    bazel_module: {bp2build_available: true},
-  }
-EOF
-
-  # A directory under $MOCK_TOP
-  outdir=out2
-  trap "rm -rf $outdir" EXIT
-  # Modify OUT_DIR in a subshell so it doesn't affect the top level one.
-  (export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
-}
-
-function test_different_absolute_outdir {
-  setup
-
-  mkdir -p a
-  touch a/g.txt
-  cat > a/Android.bp <<'EOF'
-filegroup {
-    name: "g",
-    srcs: ["g.txt"],
-    bazel_module: {bp2build_available: true},
-  }
-EOF
-
-  # A directory under /tmp/...
-  outdir=$(mktemp -t -d st.XXXXX)
-  trap 'rm -rf $outdir' EXIT
-  # Modify OUT_DIR in a subshell so it doesn't affect the top level one.
-  (export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
-}
-
-function _bp2build_generates_all_buildfiles {
-  setup
-
-  mkdir -p foo/convertible_soong_module
-  cat > foo/convertible_soong_module/Android.bp <<'EOF'
-genrule {
-    name: "the_answer",
-    cmd: "echo '42' > $(out)",
-    out: [
-        "the_answer.txt",
-    ],
-    bazel_module: {
-        bp2build_available: true,
-    },
-  }
-EOF
-
-  mkdir -p foo/unconvertible_soong_module
-  cat > foo/unconvertible_soong_module/Android.bp <<'EOF'
-genrule {
-    name: "not_the_answer",
-    cmd: "echo '43' > $(out)",
-    out: [
-        "not_the_answer.txt",
-    ],
-    bazel_module: {
-        bp2build_available: false,
-    },
-  }
-EOF
-
-  run_soong bp2build
-
-  if [[ ! -f "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
-    fail "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
-  fi
-
-  if [[ ! -f "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
-    fail "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
-  fi
-
-  if ! grep "the_answer" "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
-    fail "missing BUILD target the_answer in convertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
-  fi
-
-  if grep "not_the_answer" "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
-    fail "found unexpected BUILD target not_the_answer in unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
-  fi
-
-  if ! grep "filegroup" "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
-    fail "missing filegroup in unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
-  fi
-
-  # NOTE: We don't actually use the extra BUILD file for anything here
-  run_bazel build --config=android --config=bp2build --config=ci //foo/...
-
-  local -r the_answer_file="$(find -L bazel-out -name the_answer.txt)"
-  if [[ ! -f "${the_answer_file}" ]]; then
-    fail "Expected the_answer.txt to be generated, but was missing"
-  fi
-  if ! grep 42 "${the_answer_file}"; then
-    fail "Expected to find 42 in '${the_answer_file}'"
-  fi
-}
-
-function test_bp2build_generates_all_buildfiles {
-  _save_trap=$(trap -p EXIT)
-  trap '[[ $? -ne 0 ]] && echo Are you running this locally? Try changing --sandbox_tmpfs_path to something other than /tmp/ in build/bazel/linux.bazelrc.' EXIT
-  _bp2build_generates_all_buildfiles
-  eval "${_save_trap}"
-}
-
-function test_build_files_take_precedence {
-  _save_trap=$(trap -p EXIT)
-  trap '[[ $? -ne 0 ]] && echo Are you running this locally? Try changing --sandbox_tmpfs_path to something other than /tmp/ in build/bazel/linux.bazelrc.' EXIT
-  _build_files_take_precedence
-  eval "${_save_trap}"
-}
-
-function _build_files_take_precedence {
-  setup
-
-  # This specific directory is hardcoded in bp2build as being one
-  # where the BUILD file should be intentionally kept.
-  mkdir -p testpkg/keep_build_file
-  cat > testpkg/keep_build_file/Android.bp <<'EOF'
-genrule {
-    name: "print_origin",
-    cmd: "echo 'from_soong' > $(out)",
-    out: [
-        "origin.txt",
-    ],
-    bazel_module: {
-        bp2build_available: true,
-    },
-  }
-EOF
-
-  run_soong bp2build
-  run_bazel build --config=android --config=bp2build --config=ci //testpkg/keep_build_file:print_origin
-
-  local -r output_file="$(find -L bazel-out -name origin.txt)"
-  if [[ ! -f "${output_file}" ]]; then
-    fail "Expected origin.txt to be generated, but was missing"
-  fi
-  if ! grep from_soong "${output_file}"; then
-    fail "Expected to find 'from_soong' in '${output_file}'"
-  fi
-
-  cat > testpkg/keep_build_file/BUILD.bazel <<'EOF'
-genrule(
-    name = "print_origin",
-    outs = ["origin.txt"],
-    cmd = "echo 'from_bazel' > $@",
-)
-EOF
-
-  # Clean the workspace. There is a test infrastructure bug where run_bazel
-  # will symlink Android.bp files in the source directory again and thus
-  # pollute the workspace.
-  # TODO: b/286059878 - Remove this clean after the underlying bug is fixed.
-  run_soong clean
-  run_soong bp2build
-  run_bazel build --config=android --config=bp2build --config=ci //testpkg/keep_build_file:print_origin
-  if ! grep from_bazel "${output_file}"; then
-    fail "Expected to find 'from_bazel' in '${output_file}'"
-  fi
-}
-
-function test_bp2build_symlinks_files {
-  setup
-  mkdir -p foo
-  touch foo/BLANK1
-  touch foo/BLANK2
-  touch foo/F2D
-  touch foo/BUILD
-
-  run_soong bp2build
-
-  if [[ -e "./out/soong/workspace/foo/BUILD" ]]; then
-    fail "./out/soong/workspace/foo/BUILD should be omitted"
-  fi
-  for file in BLANK1 BLANK2 F2D
-  do
-    if [[ ! -L "./out/soong/workspace/foo/$file" ]]; then
-      fail "./out/soong/workspace/foo/$file should exist"
-    fi
-  done
-  local -r BLANK1_BEFORE=$(stat -c %y "./out/soong/workspace/foo/BLANK1")
-
-  rm foo/BLANK2
-  rm foo/F2D
-  mkdir foo/F2D
-  touch foo/F2D/BUILD
-
-  run_soong bp2build
-
-  if [[ -e "./out/soong/workspace/foo/BUILD" ]]; then
-    fail "./out/soong/workspace/foo/BUILD should be omitted"
-  fi
-  local -r BLANK1_AFTER=$(stat -c %y "./out/soong/workspace/foo/BLANK1")
-  if [[ "$BLANK1_AFTER" != "$BLANK1_BEFORE" ]]; then
-    fail "./out/soong/workspace/foo/BLANK1 should be untouched"
-  fi
-  if [[  -e "./out/soong/workspace/foo/BLANK2" ]]; then
-    fail "./out/soong/workspace/foo/BLANK2 should be removed"
-  fi
-  if [[ -L "./out/soong/workspace/foo/F2D" ]] || [[ ! -d "./out/soong/workspace/foo/F2D" ]]; then
-    fail "./out/soong/workspace/foo/F2D should be a dir"
-  fi
-}
-
-function test_cc_correctness {
-  setup
-
-  mkdir -p a
-  cat > a/Android.bp <<EOF
-cc_object {
-  name: "qq",
-  srcs: ["qq.cc"],
-  bazel_module: {
-    bp2build_available: true,
-  },
-  stl: "none",
-  system_shared_libs: [],
-}
-EOF
-
-  cat > a/qq.cc <<EOF
-#include "qq.h"
-int qq() {
-  return QQ;
-}
-EOF
-
-  cat > a/qq.h <<EOF
-#define QQ 1
-EOF
-
-  run_soong bp2build
-
-  run_bazel build --config=android --config=bp2build --config=ci //a:qq
-  local -r output_mtime1=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
-
-  run_bazel build --config=android --config=bp2build --config=ci //a:qq
-  local -r output_mtime2=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
-
-  if [[ "$output_mtime1" != "$output_mtime2" ]]; then
-    fail "output changed on null build"
-  fi
-
-  cat > a/qq.h <<EOF
-#define QQ 2
-EOF
-
-  run_bazel build --config=android --config=bp2build --config=ci //a:qq
-  local -r output_mtime3=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
-
-  if [[ "$output_mtime1" == "$output_mtime3" ]]; then
-    fail "output not changed when included header changed"
-  fi
-}
-
-# Regression test for the following failure during symlink forest creation:
-#
-#   Cannot stat '/tmp/st.rr054/foo/bar/unresolved_symlink': stat /tmp/st.rr054/foo/bar/unresolved_symlink: no such file or directory
-#
-function test_bp2build_null_build_with_unresolved_symlink_in_source() {
-  setup
-
-  mkdir -p foo/bar
-  ln -s /tmp/non-existent foo/bar/unresolved_symlink
-  cat > foo/bar/Android.bp <<'EOF'
-filegroup {
-    name: "fg",
-    srcs: ["unresolved_symlink/non-existent-file.txt"],
-  }
-EOF
-
-  run_soong bp2build
-
-  dest=$(readlink -f out/soong/workspace/foo/bar/unresolved_symlink)
-  if [[ "$dest" != "/tmp/non-existent" ]]; then
-    fail "expected to plant an unresolved symlink out/soong/workspace/foo/bar/unresolved_symlink that resolves to /tmp/non-existent"
-  fi
-}
-
-function test_bazel_standalone_output_paths_contain_product_name {
-  setup
-  mkdir -p a
-  cat > a/Android.bp <<EOF
-cc_object {
-  name: "qq",
-  srcs: ["qq.cc"],
-  bazel_module: {
-    bp2build_available: true,
-  },
-  stl: "none",
-  system_shared_libs: [],
-}
-EOF
-
-  cat > a/qq.cc <<EOF
-#include "qq.h"
-int qq() {
-  return QQ;
-}
-EOF
-
-  cat > a/qq.h <<EOF
-#define QQ 1
-EOF
-
-  export TARGET_PRODUCT=aosp_arm; run_soong bp2build
-  local -r output=$(run_bazel cquery //a:qq --output=files --config=android --config=bp2build --config=ci)
-  if [[ ! $(echo ${output} | grep "bazel-out/aosp_arm") ]]; then
-    fail "Did not find the product name '${TARGET_PRODUCT}' in the output path. This can cause " \
-      "unnecessary rebuilds when toggling between products as bazel outputs for different products will " \
-      "clobber each other. Output paths are: \n${output}"
-  fi
-}
-
-scan_and_run_tests
diff --git a/tests/dcla_apex_comparison_test.sh b/tests/dcla_apex_comparison_test.sh
deleted file mode 100755
index e3c189f..0000000
--- a/tests/dcla_apex_comparison_test.sh
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/bin/bash
-
-# Copyright (C) 2023 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.
-
-set -euo pipefail
-
-# Soong/Bazel integration test to build the mainline modules in mixed build and
-# compare the DCLA libs extracted from those modules to ensure they are identical.
-
-if [ ! -e "build/make/core/Makefile" ]; then
-  echo "$0 must be run from the top of the Android source tree."
-  exit 1
-fi
-
-TARGET_PRODUCTS=(
-  module_arm64
-  module_x86_64
-)
-
-MODULES=(
-  # These modules depend on the DCLA libs
-  com.android.adbd
-  com.android.art
-  com.android.art.debug
-  com.android.art.testing
-  com.android.btservices
-  com.android.conscrypt
-  com.android.i18n
-  com.android.media
-  com.android.media.swcodec
-  com.android.resolv
-  com.android.runtime
-  com.android.tethering
-)
-
-BAZEL_TARGETS=(
-  //packages/modules/adb/apex:com.android.adbd
-  //frameworks/av/apex:com.android.media.swcodec
-)
-
-DCLA_LIBS=(
-  libbase.so
-  libc++.so
-  libcrypto.so
-  libcutils.so
-  libstagefright_flacdec.so
-  libutils.so
-)
-
-if [[ -z ${OUT_DIR+x} ]]; then
-  OUT_DIR="out"
-fi
-
-if [[ -z ${ANDROID_HOST_OUT+x} ]]; then
-  export ANDROID_HOST_OUT="out/host/linux-x86"
-fi
-
-######################
-# Build deapexer and debugfs
-######################
-DEAPEXER="${ANDROID_HOST_OUT}/bin/deapexer"
-DEBUGFS="${ANDROID_HOST_OUT}/bin/debugfs"
-if [[ ! -f "${DEAPEXER}" ]] || [[ ! -f "${DEBUGFS}" ]]; then
-  build/soong/soong_ui.bash --make-mode --skip-soong-tests deapexer debugfs
-fi
-
-DEAPEXER="${DEAPEXER} --debugfs_path=${DEBUGFS}"
-
-############
-# Test Setup
-############
-OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)"
-
-function call_bazel() {
-  build/bazel/bin/bazel $@
-}
-
-function cleanup {
-  rm -rf "${OUTPUT_DIR}"
-}
-trap cleanup EXIT
-
-#######
-# Tests
-#######
-
-function extract_dcla_libs() {
-  local product=$1; shift
-  local modules=("$@"); shift
-
-  for module in "${modules[@]}"; do
-    local apex="${OUTPUT_DIR}/${product}/${module}.apex"
-    local extract_dir="${OUTPUT_DIR}/${product}/${module}/extract"
-
-    $DEAPEXER extract "${apex}" "${extract_dir}"
-  done
-}
-
-function compare_dcla_libs() {
-  local product=$1; shift
-  local modules=("$@"); shift
-
-  for lib in "${DCLA_LIBS[@]}"; do
-    for arch in lib lib64; do
-      local prev_sha=""
-      for module in "${modules[@]}"; do
-        local file="${OUTPUT_DIR}/${product}/${module}/extract/${arch}/${lib}"
-        if [[ ! -f "${file}" ]]; then
-          # not all libs are present in a module
-          echo "file doesn't exist: ${file}"
-          continue
-        fi
-        sha=$(sha1sum ${file})
-        sha="${sha% *}"
-        if [ "${prev_sha}" == "" ]; then
-          prev_sha="${sha}"
-        elif [ "${sha}" != "${prev_sha}" ] && { [ "${lib}" != "libcrypto.so" ] || [[ "${module}" != *"com.android.tethering" ]]; }; then
-          echo "Test failed, ${lib} has different hash value"
-          exit 1
-        fi
-      done
-    done
-  done
-}
-
-export UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true # don't rely on prebuilts
-export TARGET_BUILD_APPS="${MODULES[@]}"
-for product in "${TARGET_PRODUCTS[@]}"; do
-  ###########
-  # Build the mainline modules
-  ###########
-  packages/modules/common/build/build_unbundled_mainline_module.sh \
-    --product "${product}" \
-    --dist_dir "${OUTPUT_DIR}/${product}"
-
-  bazel_apexes=()
-  if [[ -n ${TEST_BAZEL+x} ]] && [ "${TEST_BAZEL}" = true ]; then
-    export TARGET_PRODUCT="${product/module/aosp}"
-    call_bazel build --config=bp2build --config=ci --config=android "${BAZEL_TARGETS[@]}"
-    for target in "${BAZEL_TARGETS[@]}"; do
-      apex_path="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files $target))"
-      mkdir -p ${OUTPUT_DIR}/${product}
-      bazel_apex="bazel_$(basename $apex_path)"
-      mv $apex_path ${OUTPUT_DIR}/${product}/${bazel_apex}
-      bazel_apexes+=(${bazel_apex%".apex"})
-    done
-  fi
-
-  all_modeuls=(${MODULES[@]} ${bazel_apexes[@]})
-  extract_dcla_libs "${product}" "${all_modeuls[@]}"
-  compare_dcla_libs "${product}" "${all_modeuls[@]}"
-done
-
-echo "Test passed"
diff --git a/tests/lib.sh b/tests/lib.sh
index e0b319e..4c320d0 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -140,7 +140,7 @@
 
 # shellcheck disable=SC2120
 function run_soong {
-  USE_RBE=false build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
+  USE_RBE=false TARGET_PRODUCT=aosp_arm TARGET_RELEASE=trunk_staging TARGET_BUILD_VARIANT=userdebug build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
 }
 
 function create_mock_bazel {
diff --git a/tests/mixed_mode_test.sh b/tests/mixed_mode_test.sh
deleted file mode 100755
index ca63fdf..0000000
--- a/tests/mixed_mode_test.sh
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/bin/bash
-
-set -o pipefail
-
-# This test exercises mixed builds where Soong and Bazel cooperate in building
-# Android.
-#
-# When the execroot is deleted, the Bazel server process will automatically
-# terminate itself.
-
-source "$(dirname "$0")/lib.sh"
-
-function test_bazel_smoke {
-  setup
-
-  run_soong bp2build
-
-  run_bazel info --config=bp2build
-}
-
-function test_add_irrelevant_file {
-  setup
-
-  mkdir -p soong_tests/a/b
-  touch soong_tests/a/b/c.txt
-  cat > soong_tests/a/b/Android.bp <<'EOF'
-filegroup {
-  name: "c",
-  srcs: ["c.txt"],
-  bazel_module: { bp2build_available: true },
-}
-EOF
-
-  run_soong --bazel-mode-staging nothing
-
-  if [[ ! -e out/soong/bp2build/soong_tests/a/b/BUILD.bazel ]]; then
-    fail "BUILD.bazel not created"
-  fi
-
-  if [[ ! -e out/soong/build.ninja ]]; then
-    fail "build.ninja not created"
-  fi
-
-  local mtime_build1=$(stat -c "%y" out/soong/bp2build/soong_tests/a/b/BUILD.bazel)
-  local mtime_ninja1=$(stat -c "%y" out/soong/build.ninja)
-
-  touch soong_tests/a/irrelevant.txt
-
-  run_soong --bazel-mode-staging nothing
-  local mtime_build2=$(stat -c "%y" out/soong/bp2build/soong_tests/a/b/BUILD.bazel)
-  local mtime_ninja2=$(stat -c "%y" out/soong/build.ninja)
-
-  if [[ "$mtime_build1" != "$mtime_build2" ]]; then
-    fail "BUILD.bazel was generated"
-  fi
-
-  if [[ "$mtime_ninja1" != "$mtime_ninja2" ]]; then
-    fail "build.ninja was regenerated"
-  fi
-
-  if [[ ! -e out/soong/workspace/soong_tests/a/irrelevant.txt ]]; then
-    fail "new file was not symlinked"
-  fi
-}
-
-function test_force_enabled_modules {
-  setup
-  # b/273910287 - test force enable modules
-  mkdir -p soong_tests/a/b
-  cat > soong_tests/a/b/Android.bp <<'EOF'
-genrule {
-    name: "touch-file",
-    out: ["fake-out.txt"],
-    cmd: "touch $(out)",
-    bazel_module: { bp2build_available: true },
-}
-
-genrule {
-    name: "unenabled-touch-file",
-    out: ["fake-out2.txt"],
-    cmd: "touch $(out)",
-    bazel_module: { bp2build_available: false },
-}
-EOF
-  run_soong --bazel-mode-staging --bazel-force-enabled-modules=touch-file nothing
-  local bazel_contained=`grep out/soong/.intermediates/soong_tests/a/b/touch-file/gen/fake-out.txt out/soong/build.ninja`
-  if [[ $bazel_contained == '' ]]; then
-    fail "Bazel actions not found for force-enabled module"
-  fi
-
-  unused=`run_soong --bazel-force-enabled-modules=unenabled-touch-file --ensure-allowlist-integrity nothing >/dev/null`
-
-  if [[ $? -ne 1 ]]; then
-    fail "Expected failure due to force-enabling an unenabled module "
-  fi
-}
-
-
-scan_and_run_tests
diff --git a/tests/persistent_bazel_test.sh b/tests/persistent_bazel_test.sh
deleted file mode 100755
index 9b7b58f..0000000
--- a/tests/persistent_bazel_test.sh
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/bin/bash -eu
-
-# Copyright (C) 2023 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.
-
-set -o pipefail
-
-source "$(dirname "$0")/lib.sh"
-
-# This test verifies that adding USE_PERSISTENT_BAZEL creates a Bazel process
-# that outlasts the build process.
-# This test should only be run in sandboxed environments (because this test
-# verifies a Bazel process using global process list, and may spawn lingering
-# Bazel processes).
-function test_persistent_bazel {
-  setup
-
-  # Ensure no existing Bazel process.
-  if [[ -e out/bazel/output/server/server.pid.txt ]]; then
-    kill $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null || true
-    if kill -0 $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null ; then
-      fail "Error killing pre-setup bazel"
-    fi
-  fi
-
-  USE_PERSISTENT_BAZEL=1 run_soong nothing
-
-  if ! kill -0 $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null ; then
-    fail "Persistent bazel process expected, but not found after first build"
-  fi
-  BAZEL_PID=$(cat out/bazel/output/server/server.pid.txt)
-
-  USE_PERSISTENT_BAZEL=1 run_soong nothing
-
-  if ! kill -0 $BAZEL_PID 2>/dev/null ; then
-    fail "Bazel pid $BAZEL_PID was killed after second build"
-  fi
-
-  kill $BAZEL_PID 2>/dev/null
-  if ! kill -0 $BAZEL_PID 2>/dev/null ; then
-    fail "Error killing bazel on shutdown"
-  fi
-}
-
-# Verifies that USE_PERSISTENT_BAZEL mode operates as expected in the event
-# that there are Bazel failures.
-function test_bazel_failure {
-  setup
-
-  # Ensure no existing Bazel process.
-  if [[ -e out/bazel/output/server/server.pid.txt ]]; then
-    kill $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null || true
-    if kill -0 $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null ; then
-      fail "Error killing pre-setup bazel"
-    fi
-  fi
-
-  # Introduce a syntax error in a BUILD file which is used in every build
-  # (Note this is a BUILD file which is copied as part of test setup, so this
-  # has no effect on sources outside of this test.
-  rm -rf  build/bazel/rules
-
-  USE_PERSISTENT_BAZEL=1 run_soong nothing 1>out/failurelog.txt 2>&1 && fail "Expected build failure" || true
-
-  if ! grep -sq "cannot load //build/bazel/rules/common/api_constants.bzl" out/failurelog.txt ; then
-    fail "Expected error to contain 'cannot load //build/bazel/rules/common/api_constants.bzl', instead got:\n$(cat out/failurelog.txt)"
-  fi
-
-  kill $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null || true
-}
-
-scan_and_run_tests
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index 231e18b..0235f2b 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -4,25 +4,6 @@
 
 TOP="$(readlink -f "$(dirname "$0")"/../../..)"
 "$TOP/build/soong/tests/androidmk_test.sh"
-"$TOP/build/soong/tests/b_args_test.sh"
 "$TOP/build/soong/tests/bootstrap_test.sh"
-"$TOP/build/soong/tests/mixed_mode_test.sh"
-"$TOP/build/soong/tests/bp2build_bazel_test.sh"
-"$TOP/build/soong/tests/persistent_bazel_test.sh"
 "$TOP/build/soong/tests/soong_test.sh"
-"$TOP/build/soong/tests/stale_metrics_files_test.sh"
-"$TOP/build/soong/tests/symlink_forest_rerun_test.sh"
 "$TOP/prebuilts/build-tools/linux-x86/bin/py3-cmd" "$TOP/build/bazel/ci/rbc_dashboard.py" aosp_arm64-userdebug
-
-# The following tests build against the full source tree and don't rely on the
-# mock client.
-"$TOP/build/soong/tests/apex_comparison_tests.sh"
-"$TOP/build/soong/tests/apex_comparison_tests.sh" "module_arm64only"
-TEST_BAZEL=true extra_build_params=--bazel-mode-staging "$TOP/build/soong/tests/dcla_apex_comparison_test.sh"
-#BUILD_BROKEN_DISABLE_BAZEL=true "$TOP/build/soong/tests/dcla_apex_comparison_test.sh"
-"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh"
-"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_arm" "armv7-a"
-"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_cf_arm64_phone" "armv8-a" "cortex-a53"
-
-"$TOP/build/bazel/ci/b_test.sh"
-"$TOP/build/soong/tests/symlinks_path_test.sh"
diff --git a/tests/stale_metrics_files_test.sh b/tests/stale_metrics_files_test.sh
deleted file mode 100755
index 0da89c3..0000000
--- a/tests/stale_metrics_files_test.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash -e
-
-# This test ensures that stale metrics files are deleted after each run
-
-# Run bazel
-# Note - bp2build metrics are present after clean runs, only
-build/soong/soong_ui.bash --make-mode clean
-build/bazel/bin/b build libcore:all
-soong_build_metrics_files=("out/soong_build_metrics.pb" "out/build_progress.pb" "out/soong_metrics" "out/bp2build_metrics.pb")
-bazel_build_metrics_files=("out/bazel_metrics.pb" "out/build_progress.pb" "out/soong_metrics" "out/bp2build_metrics.pb")
-
-# Ensure bazel metrics files are present
-for i in ${!bazel_build_metrics_files[@]};
-do
-  file=${bazel_build_metrics_files[$i]}
-  if [[ ! -f $file ]]; then
-     echo "Missing metrics file for Bazel build " $file
-     exit 1
-  fi
-done
-
-
-# Run a soong build
-build/soong/soong_ui.bash --make-mode nothing
-
-for i in ${!soong_build_metrics_files[@]};
-do
-  file=${soong_build_metrics_files[$i]}
-  if [[ ! -f $file ]]; then
-     echo "Missing metrics file for Soong build " $file
-     exit 1
-  fi
-done
-
-# Ensure that bazel_metrics.pb is deleted
-if [[ -f out/bazel_metrics.pb ]]; then
-   echo "Stale out/bazel_metrics.pb file detected"
-   exit 1
-fi
-
-# Run bazel again - to make sure that soong_build_metrics.pb gets deleted
-build/bazel/bin/b build libcore:all
-
-if [[ -f out/soong_build_metrics.pb ]]; then
-   echo "Stale out/soong_build_metrics.pb file detected"
-   exit 1
-fi
diff --git a/tests/symlink_forest_rerun_test.sh b/tests/symlink_forest_rerun_test.sh
deleted file mode 100755
index 74e779e..0000000
--- a/tests/symlink_forest_rerun_test.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash -eu
-
-set -o pipefail
-
-# Tests that symlink forest will replant if soong_build has changed
-# Any change to the build system should trigger a rerun
-
-source "$(dirname "$0")/lib.sh"
-
-function test_symlink_forest_reruns {
-  setup
-
-  mkdir -p a
-  touch a/g.txt
-  cat > a/Android.bp <<'EOF'
-filegroup {
-    name: "g",
-    srcs: ["g.txt"],
-  }
-EOF
-
-  run_soong g
-
-  mtime=`cat out/soong/workspace/soong_build_mtime`
-  # rerun with no changes - ensure that it hasn't changed
-  run_soong g
-  newmtime=`cat out/soong/workspace/soong_build_mtime`
-  if [[ ! "$mtime" == "$mtime" ]]; then
-     fail "symlink forest reran when it shouldn't have"
-  fi
-
-  # change exit codes to force a soong_build rebuild.
-  sed -i 's/os.Exit(1)/os.Exit(2)/g' build/soong/bp2build/symlink_forest.go
-
-  run_soong g
-  newmtime=`cat out/soong/workspace/soong_build_mtime`
-  if [[ "$mtime" == "$newmtime" ]]; then
-     fail "symlink forest did not rerun when it should have"
-  fi
-
-}
-
-scan_and_run_tests
diff --git a/tests/symlinks_path_test.sh b/tests/symlinks_path_test.sh
deleted file mode 100755
index ed42911..0000000
--- a/tests/symlinks_path_test.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/bash -eu
-
-set -o pipefail
-
-# Test that relative symlinks work by recreating the bug in b/259191764
-# In some cases, developers prefer to move their checkouts. This causes
-# issues in that symlinked files (namely, the bazel wrapper script)
-# cannot be found. As such, we implemented relative symlinks so that a
-# moved checkout doesn't need a full clean before rebuilding.
-# The bazel output base will still need to be removed, as Starlark
-# doesn't seem to support relative symlinks yet.
-
-source "$(dirname "$0")/lib.sh"
-
-function check_link_has_mock_top_prefix {
-  input_link=$1
-  link_target=`readlink $input_link`
-  if [[ $link_target != "$MOCK_TOP"* ]]; then
-    echo "Symlink for file $input_link -> $link_target doesn't start with $MOCK_TOP"
-    exit 1
-  fi
-}
-
-function test_symlinks_updated_when_top_dir_changed {
-  setup
-
-  mkdir -p a
-  touch a/g.txt
-  cat > a/Android.bp <<'EOF'
-filegroup {
-    name: "g",
-    srcs: ["g.txt"],
-    bazel_module: {bp2build_available: true},
-}
-EOF
-  # A directory under $MOCK_TOP
-  outdir=out2
-
-  # Modify OUT_DIR in a subshell so it doesn't affect the top level one.
-  (export OUT_DIR=$MOCK_TOP/$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
-
-  g_txt="out2/soong/workspace/a/g.txt"
-  check_link_has_mock_top_prefix "$g_txt"
-
-  move_mock_top
-
-  (export OUT_DIR=$MOCK_TOP/$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
-  check_link_has_mock_top_prefix "$g_txt"
-}
-
-scan_and_run_tests
\ No newline at end of file
diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go
index e7896ab..a29f413 100644
--- a/ui/build/androidmk_denylist.go
+++ b/ui/build/androidmk_denylist.go
@@ -23,6 +23,7 @@
 	"cts/",
 	"dalvik/",
 	"developers/",
+	"frameworks/",
 	// Do not block other directories in kernel/, see b/319658303.
 	"kernel/configs/",
 	"kernel/prebuilts/",