Merge changes from topics "revert-2897484-revert-2897682-dont_limit_systemsdk-JCOOOXGAIF-BSJGJAJAWC", "revert-2897568-revert-2894701-limit_systemsdk-WNEMOTGMRS-ROJNXPXKUV" into main

* changes:
  Revert^2 "Add BUILD_BROKEN_DONT_CHECK_SYSTEMSDK"
  Revert "Revert "Limit System SDK to 34 for Java modules in the v..."
diff --git a/aconfig/codegen/cc_aconfig_library_test.go b/aconfig/codegen/cc_aconfig_library_test.go
index c5ff6a1..d762e9b 100644
--- a/aconfig/codegen/cc_aconfig_library_test.go
+++ b/aconfig/codegen/cc_aconfig_library_test.go
@@ -148,6 +148,7 @@
 		cc_library {
 			name: "server_configurable_flags",
 			srcs: ["server_configurable_flags.cc"],
+			vendor_available: true,
 		}
 	`
 	result := android.GroupFixturePreparers(
@@ -155,7 +156,7 @@
 		cc.PrepareForTestWithCcDefaultModules).
 		ExtendWithErrorHandler(android.FixtureExpectsNoErrors).RunTestWithBp(t, bp)
 
-	module := result.ModuleForTests("my_cc_library", "android_arm64_armv8-a_shared").Module()
+	module := result.ModuleForTests("my_cc_library", "android_vendor_arm64_armv8-a_shared").Module()
 
 	entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
 
diff --git a/android/androidmk.go b/android/androidmk.go
index f65e084..235d7c0 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -276,14 +276,17 @@
 }
 
 // AddCompatibilityTestSuites adds the supplied test suites to the EntryMap, with special handling
-// for partial MTS test suites.
+// for partial MTS and MCTS test suites.
 func (a *AndroidMkEntries) AddCompatibilityTestSuites(suites ...string) {
-	// MTS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
-	// To reduce repetition, if we find a partial MTS test suite without an full MTS test suite,
+	// M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
+	// To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite,
 	// we add the full test suite to our list.
 	if PrefixInList(suites, "mts-") && !InList("mts", suites) {
 		suites = append(suites, "mts")
 	}
+	if PrefixInList(suites, "mcts-") && !InList("mcts", suites) {
+		suites = append(suites, "mcts")
+	}
 	a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...)
 }
 
diff --git a/android/arch_list.go b/android/arch_list.go
index ab644a4..801ac49 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -34,6 +34,11 @@
 		"broadwell",
 		"goldmont",
 		"goldmont-plus",
+		// Target arch is goldmont, but without xsaves support.
+		// This ensures efficient execution on a broad range of Intel/AMD CPUs used
+		// in Chromebooks, including those lacking xsaves support.
+		// (e.g. Kaby Lake, Gemini Lake, Alder Lake and AMD Zen series)
+		"goldmont-without-xsaves",
 		"haswell",
 		"icelake",
 		"ivybridge",
@@ -52,6 +57,7 @@
 		"broadwell",
 		"goldmont",
 		"goldmont-plus",
+		"goldmont-without-xsaves",
 		"haswell",
 		"icelake",
 		"ivybridge",
@@ -197,6 +203,15 @@
 			"popcnt",
 			"movbe",
 		},
+		"goldmont-without-xsaves": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"aes_ni",
+			"popcnt",
+			"movbe",
+		},
 		"haswell": {
 			"ssse3",
 			"sse4",
@@ -358,6 +373,14 @@
 			"aes_ni",
 			"popcnt",
 		},
+		"goldmont-without-xsaves": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"aes_ni",
+			"popcnt",
+		},
 		"haswell": {
 			"ssse3",
 			"sse4",
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index 79bdeb8..a6b2c51 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -376,8 +376,7 @@
 		prepareForSoongConfigTestModule,
 		FixtureWithRootAndroidBp(bp),
 	).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
-		// TODO(b/171232169): improve the error message for non-existent properties
-		`unrecognized property "soong_config_variables`,
+		`unrecognized property "soong_config_variables.feature1.made_up_property`,
 	})).RunTest(t)
 }
 
diff --git a/apex/apex.go b/apex/apex.go
index 76e78bf..42a7d73 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -719,7 +719,7 @@
 
 // getImageVariationPair returns a pair for the image variation name as its
 // prefix and suffix. The prefix indicates whether it's core/vendor/product and the
-// suffix indicates the vndk version when it's vendor or product.
+// suffix indicates the vndk version for vendor/product if vndk is enabled.
 // getImageVariation can simply join the result of this function to get the
 // image variation name.
 func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
@@ -727,8 +727,8 @@
 		return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
 	}
 
-	var prefix string
-	var vndkVersion string
+	prefix := android.CoreVariation
+	vndkVersion := ""
 	if deviceConfig.VndkVersion() != "" {
 		if a.SocSpecific() || a.DeviceSpecific() {
 			prefix = cc.VendorVariationPrefix
@@ -737,15 +737,18 @@
 			prefix = cc.ProductVariationPrefix
 			vndkVersion = deviceConfig.PlatformVndkVersion()
 		}
+	} else {
+		if a.SocSpecific() || a.DeviceSpecific() {
+			prefix = cc.VendorVariation
+		} else if a.ProductSpecific() {
+			prefix = cc.ProductVariation
+		}
 	}
 	if vndkVersion == "current" {
 		vndkVersion = deviceConfig.PlatformVndkVersion()
 	}
-	if vndkVersion != "" {
-		return prefix, vndkVersion
-	}
 
-	return android.CoreVariation, "" // The usual case
+	return prefix, vndkVersion
 }
 
 // getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
diff --git a/cc/cc.go b/cc/cc.go
index 6b64b7b..c6e21c2 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -25,6 +25,7 @@
 	"strings"
 
 	"android/soong/testing"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 
@@ -300,8 +301,8 @@
 	// Set by DepsMutator.
 	AndroidMkSystemSharedLibs []string `blueprint:"mutated"`
 
-	// The name of the image this module is built for, suffixed with a '.'
-	ImageVariationPrefix string `blueprint:"mutated"`
+	// The name of the image this module is built for
+	ImageVariation string `blueprint:"mutated"`
 
 	// The VNDK version this module is built against. If empty, the module is not
 	// build against the VNDK.
@@ -2427,9 +2428,9 @@
 		// Only retrieve the snapshot on demand in order to avoid circular dependencies
 		// between the modules in the snapshot and the snapshot itself.
 		var snapshotModule []blueprint.Module
-		if c.InVendor() && c.VndkVersion() == actx.DeviceConfig().VndkVersion() {
+		if c.InVendor() && c.VndkVersion() == actx.DeviceConfig().VndkVersion() && actx.OtherModuleExists("vendor_snapshot") {
 			snapshotModule = actx.AddVariationDependencies(nil, nil, "vendor_snapshot")
-		} else if recoverySnapshotVersion := actx.DeviceConfig().RecoverySnapshotVersion(); recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && c.InRecovery() {
+		} else if recoverySnapshotVersion := actx.DeviceConfig().RecoverySnapshotVersion(); recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && c.InRecovery() && actx.OtherModuleExists("recovery_snapshot") {
 			snapshotModule = actx.AddVariationDependencies(nil, nil, "recovery_snapshot")
 		}
 		if len(snapshotModule) > 0 && snapshotModule[0] != nil {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 5c5275e..321bd38 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -26,6 +26,8 @@
 
 	"android/soong/aidl_library"
 	"android/soong/android"
+
+	"github.com/google/blueprint"
 )
 
 func init() {
@@ -45,6 +47,14 @@
 	}),
 )
 
+// TODO(b/316829758) Update prepareForCcTest with this configuration and remove prepareForCcTestWithoutVndk
+var prepareForCcTestWithoutVndk = android.GroupFixturePreparers(
+	PrepareForIntegrationTestWithCc,
+	android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+		variables.VendorApiLevel = StringPtr("202404")
+	}),
+)
+
 var apexVariationName = "apex28"
 var apexVersion = "28"
 
@@ -2640,6 +2650,7 @@
 		name: "libexternal_headers",
 		export_include_dirs: ["include"],
 		vendor_available: true,
+		product_available: true,
 	}
 	cc_library_headers {
 		name: "libexternal_llndk_headers",
@@ -4784,3 +4795,51 @@
 		return
 	}
 }
+
+// TODO(b/316829758) Remove this test and do not set VNDK version from other tests
+func TestImageVariantsWithoutVndk(t *testing.T) {
+	t.Parallel()
+
+	bp := `
+	cc_binary {
+		name: "binfoo",
+		srcs: ["binfoo.cc"],
+		vendor_available: true,
+		product_available: true,
+		shared_libs: ["libbar"]
+	}
+	cc_library {
+		name: "libbar",
+		srcs: ["libbar.cc"],
+		vendor_available: true,
+		product_available: true,
+	}
+	`
+
+	ctx := prepareForCcTestWithoutVndk.RunTestWithBp(t, bp)
+
+	hasDep := func(m android.Module, wantDep android.Module) bool {
+		t.Helper()
+		var found bool
+		ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
+			if dep == wantDep {
+				found = true
+			}
+		})
+		return found
+	}
+
+	testDepWithVariant := func(imageVariant string) {
+		imageVariantStr := ""
+		if imageVariant != "core" {
+			imageVariantStr = "_" + imageVariant
+		}
+		binFooModule := ctx.ModuleForTests("binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module()
+		libBarModule := ctx.ModuleForTests("libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module()
+		android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule))
+	}
+
+	testDepWithVariant("core")
+	testDepWithVariant("vendor")
+	testDepWithVariant("product")
+}
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index e43848c..ff0a3b7 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -49,6 +49,10 @@
 		"goldmont-plus": []string{
 			"-march=goldmont-plus",
 		},
+		"goldmont-without-xsaves": []string{
+			"-march=goldmont",
+			"-mno-xsaves",
+		},
 		"haswell": []string{
 			"-march=core-avx2",
 		},
diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go
index c826d3c..08be869 100644
--- a/cc/config/x86_device.go
+++ b/cc/config/x86_device.go
@@ -56,6 +56,10 @@
 		"goldmont-plus": []string{
 			"-march=goldmont-plus",
 		},
+		"goldmont-without-xsaves": []string{
+			"-march=goldmont",
+			"-mno-xsaves",
+		},
 		"haswell": []string{
 			"-march=core-avx2",
 		},
diff --git a/cc/image.go b/cc/image.go
index 4c0c722..9eec255 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -42,10 +42,18 @@
 )
 
 const (
+	// VendorVariation is the variant name used for /vendor code that does not
+	// compile against the VNDK.
+	VendorVariation = "vendor"
+
 	// VendorVariationPrefix is the variant prefix used for /vendor code that compiles
 	// against the VNDK.
 	VendorVariationPrefix = "vendor."
 
+	// ProductVariation is the variant name used for /product code that does not
+	// compile against the VNDK.
+	ProductVariation = "product"
+
 	// ProductVariationPrefix is the variant prefix used for /product code that compiles
 	// against the VNDK.
 	ProductVariationPrefix = "product."
@@ -112,12 +120,12 @@
 
 // Returns true if the module is "product" variant. Usually these modules are installed in /product
 func (c *Module) InProduct() bool {
-	return c.Properties.ImageVariationPrefix == ProductVariationPrefix
+	return c.Properties.ImageVariation == ProductVariation
 }
 
 // Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
 func (c *Module) InVendor() bool {
-	return c.Properties.ImageVariationPrefix == VendorVariationPrefix
+	return c.Properties.ImageVariation == VendorVariation
 }
 
 func (c *Module) InRamdisk() bool {
@@ -439,10 +447,8 @@
 		// 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
-		if platformVndkVersion != "" {
-			vendorVariants = append(vendorVariants, platformVndkVersion)
-			productVariants = append(productVariants, platformVndkVersion)
-		}
+		vendorVariants = append(vendorVariants, platformVndkVersion)
+		productVariants = append(productVariants, platformVndkVersion)
 		// Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not
 		// provide the LLNDK stub libraries.
 		if needVndkVersionVendorVariantForLlndk {
@@ -453,13 +459,7 @@
 		// for system and product.
 		coreVariantNeeded = true
 		vendorVariants = append(vendorVariants, boardVndkVersion)
-		if platformVndkVersion != "" {
-			productVariants = append(productVariants, platformVndkVersion)
-		}
-	} else if boardVndkVersion == "" {
-		// If the device isn't compiling against the VNDK, we always
-		// use the core mode.
-		coreVariantNeeded = true
+		productVariants = append(productVariants, platformVndkVersion)
 	} else if m.IsSnapshotPrebuilt() {
 		// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
 		// PRODUCT_EXTRA_VNDK_VERSIONS.
@@ -557,11 +557,19 @@
 	}
 
 	for _, variant := range android.FirstUniqueStrings(vendorVariants) {
-		m.AppendExtraVariant(VendorVariationPrefix + variant)
+		if variant == "" {
+			m.AppendExtraVariant(VendorVariation)
+		} else {
+			m.AppendExtraVariant(VendorVariationPrefix + variant)
+		}
 	}
 
 	for _, variant := range android.FirstUniqueStrings(productVariants) {
-		m.AppendExtraVariant(ProductVariationPrefix + variant)
+		if variant == "" {
+			m.AppendExtraVariant(ProductVariation)
+		} else {
+			m.AppendExtraVariant(ProductVariationPrefix + variant)
+		}
 	}
 
 	m.SetRamdiskVariantNeeded(ramdiskVariantNeeded)
@@ -672,9 +680,12 @@
 	} else if variant == android.RecoveryVariation {
 		m.MakeAsPlatform()
 		squashRecoverySrcs(m)
-	} else if strings.HasPrefix(variant, VendorVariationPrefix) {
-		m.Properties.ImageVariationPrefix = VendorVariationPrefix
-		m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
+	} else if strings.HasPrefix(variant, VendorVariation) {
+		m.Properties.ImageVariation = VendorVariation
+
+		if strings.HasPrefix(variant, VendorVariationPrefix) {
+			m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
+		}
 		squashVendorSrcs(m)
 
 		// Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
@@ -684,9 +695,11 @@
 			m.Properties.HideFromMake = true
 			m.HideFromMake()
 		}
-	} else if strings.HasPrefix(variant, ProductVariationPrefix) {
-		m.Properties.ImageVariationPrefix = ProductVariationPrefix
-		m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
+	} else if strings.HasPrefix(variant, ProductVariation) {
+		m.Properties.ImageVariation = ProductVariation
+		if strings.HasPrefix(variant, ProductVariationPrefix) {
+			m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
+		}
 		squashProductSrcs(m)
 	}
 
diff --git a/java/aar.go b/java/aar.go
index 2ad8fdf..eb07e0f 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -544,7 +544,7 @@
 
 	if a.useResourceProcessorBusyBox() {
 		rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
-		resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary)
+		resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary, a.aaptProperties.Aaptflags)
 		aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
 		transitiveRJars = append(transitiveRJars, rJar)
 		a.rJar = rJar
@@ -604,7 +604,7 @@
 // using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
 // supports producing classes for static dependencies that only include resources from that dependency.
 func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
-	rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool) {
+	rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool, aaptFlags []string) {
 
 	var args []string
 	var deps android.Paths
@@ -621,6 +621,17 @@
 		args = append(args, "--finalFields=false")
 	}
 
+	for i, arg := range aaptFlags {
+		const AAPT_CUSTOM_PACKAGE = "--custom-package"
+		if strings.HasPrefix(arg, AAPT_CUSTOM_PACKAGE) {
+			pkg := strings.TrimSpace(strings.TrimPrefix(arg, AAPT_CUSTOM_PACKAGE))
+			if pkg == "" && i+1 < len(aaptFlags) {
+				pkg = aaptFlags[i+1]
+			}
+			args = append(args, "--packageForR "+pkg)
+		}
+	}
+
 	deps = append(deps, rTxt, manifest)
 
 	ctx.Build(pctx, android.BuildParams{
@@ -1194,7 +1205,7 @@
 		linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil, nil)
 
 	a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
-	resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true)
+	resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true, nil)
 
 	aapt2ExtractExtraPackages(ctx, a.extraAaptPackagesFile, a.rJar)
 
diff --git a/java/app_test.go b/java/app_test.go
index 861c047..3ee94d5 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2109,7 +2109,7 @@
 		Output("libjni.so").Output.String()
 	sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").
 		Output("libjni.so").Output.String()
-	vendorJNI := ctx.ModuleForTests("libvendorjni", "android_arm64_armv8-a_shared").
+	vendorJNI := ctx.ModuleForTests("libvendorjni", "android_vendor_arm64_armv8-a_shared").
 		Output("libvendorjni.so").Output.String()
 
 	for _, test := range testCases {
diff --git a/java/base.go b/java/base.go
index 0d3e4db..51471ea 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1644,30 +1644,11 @@
 	}
 
 	if ctx.Device() {
-		lintSDKVersion := func(apiLevel android.ApiLevel) int {
+		lintSDKVersion := func(apiLevel android.ApiLevel) android.ApiLevel {
 			if !apiLevel.IsPreview() {
-				return apiLevel.FinalInt()
+				return apiLevel
 			} else {
-				// When running metalava, we pass --version-codename. When that value
-				// is not REL, metalava will add 1 to the --current-version argument.
-				// On old branches, PLATFORM_SDK_VERSION is the latest version (for that
-				// branch) and the codename is REL, except potentially on the most
-				// recent non-master branch. On that branch, it goes through two other
-				// phases before it gets to the phase previously described:
-				//  - PLATFORM_SDK_VERSION has not been updated yet, and the codename
-				//    is not rel. This happens for most of the internal branch's life
-				//    while the branch has been cut but is still under active development.
-				//  - PLATFORM_SDK_VERSION has been set, but the codename is still not
-				//    REL. This happens briefly during the release process. During this
-				//    state the code to add --current-version is commented out, and then
-				//    that commenting out is reverted after the codename is set to REL.
-				// On the master branch, the PLATFORM_SDK_VERSION always represents a
-				// prior version and the codename is always non-REL.
-				//
-				// We need to add one here to match metalava adding 1. Technically
-				// this means that in the state described in the second bullet point
-				// above, this number is 1 higher than it should be.
-				return ctx.Config().PlatformSdkVersion().FinalInt() + 1
+				return ctx.Config().DefaultAppTargetSdk(ctx)
 			}
 		}
 
diff --git a/java/lint.go b/java/lint.go
index 5a684a8..c3d723b 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -17,7 +17,6 @@
 import (
 	"fmt"
 	"sort"
-	"strconv"
 	"strings"
 
 	"github.com/google/blueprint/proptools"
@@ -56,7 +55,8 @@
 		// Modules that provide extra lint checks
 		Extra_check_modules []string
 
-		// Name of the file that lint uses as the baseline. Defaults to "lint-baseline.xml".
+		// The lint baseline file to use. If specified, lint warnings listed in this file will be
+		// suppressed during lint checks.
 		Baseline_filename *string
 
 		// If true, baselining updatability lint checks (e.g. NewApi) is prohibited. Defaults to false.
@@ -84,9 +84,9 @@
 	classes                 android.Path
 	extraLintCheckJars      android.Paths
 	library                 bool
-	minSdkVersion           int
-	targetSdkVersion        int
-	compileSdkVersion       int
+	minSdkVersion           android.ApiLevel
+	targetSdkVersion        android.ApiLevel
+	compileSdkVersion       android.ApiLevel
 	compileSdkKind          android.SdkKind
 	javaLanguageLevel       string
 	kotlinLanguageLevel     string
@@ -357,33 +357,20 @@
 		Text(`echo "<?xml version='1.0' encoding='utf-8'?>" &&`).
 		Text(`echo "<manifest xmlns:android='http://schemas.android.com/apk/res/android'" &&`).
 		Text(`echo "    android:versionCode='1' android:versionName='1' >" &&`).
-		Textf(`echo "  <uses-sdk android:minSdkVersion='%d' android:targetSdkVersion='%d'/>" &&`,
-			l.minSdkVersion, l.targetSdkVersion).
+		Textf(`echo "  <uses-sdk android:minSdkVersion='%s' android:targetSdkVersion='%s'/>" &&`,
+			l.minSdkVersion.String(), l.targetSdkVersion.String()).
 		Text(`echo "</manifest>"`).
 		Text(") >").Output(manifestPath)
 
 	return manifestPath
 }
 
-func (l *linter) getBaselineFilepath(ctx android.ModuleContext) android.OptionalPath {
-	var lintBaseline android.OptionalPath
-	if lintFilename := proptools.StringDefault(l.properties.Lint.Baseline_filename, "lint-baseline.xml"); lintFilename != "" {
-		if String(l.properties.Lint.Baseline_filename) != "" {
-			// if manually specified, we require the file to exist
-			lintBaseline = android.OptionalPathForPath(android.PathForModuleSrc(ctx, lintFilename))
-		} else {
-			lintBaseline = android.ExistentPathForSource(ctx, ctx.ModuleDir(), lintFilename)
-		}
-	}
-	return lintBaseline
-}
-
 func (l *linter) lint(ctx android.ModuleContext) {
 	if !l.enabled() {
 		return
 	}
 
-	if l.minSdkVersion != l.compileSdkVersion {
+	if l.minSdkVersion.CompareTo(l.compileSdkVersion) == -1 {
 		l.extraMainlineLintErrors = append(l.extraMainlineLintErrors, updatabilityChecks...)
 		// Skip lint warning checks for NewApi warnings for libcore where they come from source
 		// files that reference the API they are adding (b/208656169).
@@ -497,7 +484,7 @@
 		FlagWithOutput("--html ", html).
 		FlagWithOutput("--text ", text).
 		FlagWithOutput("--xml ", xml).
-		FlagWithArg("--compile-sdk-version ", strconv.Itoa(l.compileSdkVersion)).
+		FlagWithArg("--compile-sdk-version ", l.compileSdkVersion.String()).
 		FlagWithArg("--java-language-level ", l.javaLanguageLevel).
 		FlagWithArg("--kotlin-language-level ", l.kotlinLanguageLevel).
 		FlagWithArg("--url ", fmt.Sprintf(".=.,%s=out", android.PathForOutput(ctx).String())).
@@ -518,9 +505,8 @@
 		cmd.FlagWithArg("--check ", checkOnly)
 	}
 
-	lintBaseline := l.getBaselineFilepath(ctx)
-	if lintBaseline.Valid() {
-		cmd.FlagWithInput("--baseline ", lintBaseline.Path())
+	if l.properties.Lint.Baseline_filename != nil {
+		cmd.FlagWithInput("--baseline ", android.PathForModuleSrc(ctx, *l.properties.Lint.Baseline_filename))
 	}
 
 	cmd.FlagWithOutput("--write-reference-baseline ", referenceBaseline)
@@ -556,6 +542,10 @@
 	if l.buildModuleReportZip {
 		l.reports = BuildModuleLintReportZips(ctx, l.LintDepSets())
 	}
+
+	// Create a per-module phony target to run the lint check.
+	phonyName := ctx.ModuleName() + "-lint"
+	ctx.Phony(phonyName, xml)
 }
 
 func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) android.Paths {
diff --git a/java/lint_test.go b/java/lint_test.go
index 5e6b8bc..b7e6aad 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -21,7 +21,7 @@
 	"android/soong/android"
 )
 
-func TestJavaLint(t *testing.T) {
+func TestJavaLintDoesntUseBaselineImplicitly(t *testing.T) {
 	ctx, _ := testJavaWithFS(t, `
 		java_library {
 			name: "foo",
@@ -40,30 +40,8 @@
 	foo := ctx.ModuleForTests("foo", "android_common")
 
 	sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
-	if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
-		t.Error("did not pass --baseline flag")
-	}
-}
-
-func TestJavaLintWithoutBaseline(t *testing.T) {
-	ctx, _ := testJavaWithFS(t, `
-		java_library {
-			name: "foo",
-			srcs: [
-				"a.java",
-				"b.java",
-				"c.java",
-			],
-			min_sdk_version: "29",
-			sdk_version: "system_current",
-		}
-       `, map[string][]byte{})
-
-	foo := ctx.ModuleForTests("foo", "android_common")
-
-	sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
-	if strings.Contains(*sboxProto.Commands[0].Command, "--baseline") {
-		t.Error("passed --baseline flag for non existent file")
+	if strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml") {
+		t.Error("Passed --baseline flag when baseline_filename was not set")
 	}
 }
 
diff --git a/rust/config/x86_64_device.go b/rust/config/x86_64_device.go
index c797eef..cc16704 100644
--- a/rust/config/x86_64_device.go
+++ b/rust/config/x86_64_device.go
@@ -28,15 +28,16 @@
 	x86_64LinkFlags            = []string{}
 
 	x86_64ArchVariantRustFlags = map[string][]string{
-		"":              []string{},
-		"broadwell":     []string{"-C target-cpu=broadwell"},
-		"goldmont":      []string{"-C target-cpu=goldmont"},
-		"goldmont-plus": []string{"-C target-cpu=goldmont-plus"},
-		"haswell":       []string{"-C target-cpu=haswell"},
-		"ivybridge":     []string{"-C target-cpu=ivybridge"},
-		"sandybridge":   []string{"-C target-cpu=sandybridge"},
-		"silvermont":    []string{"-C target-cpu=silvermont"},
-		"skylake":       []string{"-C target-cpu=skylake"},
+		"":                        []string{},
+		"broadwell":               []string{"-C target-cpu=broadwell"},
+		"goldmont":                []string{"-C target-cpu=goldmont"},
+		"goldmont-plus":           []string{"-C target-cpu=goldmont-plus"},
+		"goldmont-without-xsaves": []string{"-C target-cpu=goldmont", "-C target-feature=-xsaves"},
+		"haswell":                 []string{"-C target-cpu=haswell"},
+		"ivybridge":               []string{"-C target-cpu=ivybridge"},
+		"sandybridge":             []string{"-C target-cpu=sandybridge"},
+		"silvermont":              []string{"-C target-cpu=silvermont"},
+		"skylake":                 []string{"-C target-cpu=skylake"},
 		//TODO: Add target-cpu=stoneyridge when rustc supports it.
 		"stoneyridge": []string{""},
 		"tremont":     []string{"-C target-cpu=tremont"},
diff --git a/rust/config/x86_device.go b/rust/config/x86_device.go
index 822f281..e7b575c 100644
--- a/rust/config/x86_device.go
+++ b/rust/config/x86_device.go
@@ -26,16 +26,17 @@
 	x86LinkFlags            = []string{}
 
 	x86ArchVariantRustFlags = map[string][]string{
-		"":              []string{},
-		"atom":          []string{"-C target-cpu=atom"},
-		"broadwell":     []string{"-C target-cpu=broadwell"},
-		"goldmont":      []string{"-C target-cpu=goldmont"},
-		"goldmont-plus": []string{"-C target-cpu=goldmont-plus"},
-		"haswell":       []string{"-C target-cpu=haswell"},
-		"ivybridge":     []string{"-C target-cpu=ivybridge"},
-		"sandybridge":   []string{"-C target-cpu=sandybridge"},
-		"silvermont":    []string{"-C target-cpu=silvermont"},
-		"skylake":       []string{"-C target-cpu=skylake"},
+		"":                        []string{},
+		"atom":                    []string{"-C target-cpu=atom"},
+		"broadwell":               []string{"-C target-cpu=broadwell"},
+		"goldmont":                []string{"-C target-cpu=goldmont"},
+		"goldmont-plus":           []string{"-C target-cpu=goldmont-plus"},
+		"goldmont-without-xsaves": []string{"-C target-cpu=goldmont", "-C target-feature=-xsaves"},
+		"haswell":                 []string{"-C target-cpu=haswell"},
+		"ivybridge":               []string{"-C target-cpu=ivybridge"},
+		"sandybridge":             []string{"-C target-cpu=sandybridge"},
+		"silvermont":              []string{"-C target-cpu=silvermont"},
+		"skylake":                 []string{"-C target-cpu=skylake"},
 		//TODO: Add target-cpu=stoneyridge when rustc supports it.
 		"stoneyridge": []string{""},
 		"tremont":     []string{"-C target-cpu=tremont"},
diff --git a/rust/image.go b/rust/image.go
index d0218f0..7adf234 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -184,12 +184,12 @@
 }
 
 func (mod *Module) InProduct() bool {
-	return mod.Properties.ImageVariationPrefix == cc.ProductVariationPrefix
+	return mod.Properties.ImageVariation == cc.ProductVariation
 }
 
 // Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
 func (mod *Module) InVendor() bool {
-	return mod.Properties.ImageVariationPrefix == cc.VendorVariationPrefix
+	return mod.Properties.ImageVariation == cc.VendorVariation
 }
 
 func (mod *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
@@ -198,9 +198,11 @@
 		m.MakeAsPlatform()
 	} else if variant == android.RecoveryVariation {
 		m.MakeAsPlatform()
-	} else if strings.HasPrefix(variant, cc.VendorVariationPrefix) {
-		m.Properties.ImageVariationPrefix = cc.VendorVariationPrefix
-		m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.VendorVariationPrefix)
+	} else if strings.HasPrefix(variant, cc.VendorVariation) {
+		m.Properties.ImageVariation = cc.VendorVariation
+		if strings.HasPrefix(variant, cc.VendorVariationPrefix) {
+			m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.VendorVariationPrefix)
+		}
 
 		// Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
 		// Hide other vendor variants to avoid collision.
@@ -209,9 +211,11 @@
 			m.Properties.HideFromMake = true
 			m.HideFromMake()
 		}
-	} else if strings.HasPrefix(variant, cc.ProductVariationPrefix) {
-		m.Properties.ImageVariationPrefix = cc.ProductVariationPrefix
-		m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.ProductVariationPrefix)
+	} else if strings.HasPrefix(variant, cc.ProductVariation) {
+		m.Properties.ImageVariation = cc.ProductVariation
+		if strings.HasPrefix(variant, cc.ProductVariationPrefix) {
+			m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.ProductVariationPrefix)
+		}
 	}
 }
 
diff --git a/rust/rust.go b/rust/rust.go
index 6f4631d..34ce4c5 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -20,6 +20,7 @@
 
 	"android/soong/bloaty"
 	"android/soong/testing"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 
@@ -69,9 +70,9 @@
 	AndroidMkProcMacroLibs []string `blueprint:"mutated"`
 	AndroidMkStaticLibs    []string `blueprint:"mutated"`
 
-	ImageVariationPrefix string `blueprint:"mutated"`
-	VndkVersion          string `blueprint:"mutated"`
-	SubName              string `blueprint:"mutated"`
+	ImageVariation string `blueprint:"mutated"`
+	VndkVersion    string `blueprint:"mutated"`
+	SubName        string `blueprint:"mutated"`
 
 	// SubName is used by CC for tracking image variants / SDK versions. RustSubName is used for Rust-specific
 	// subnaming which shouldn't be visible to CC modules (such as the rlib stdlinkage subname). This should be