Merge "cc: Vendor modules should NOT derive its "SDK" level from VNDK" into main
diff --git a/android/config.go b/android/config.go
index 7cb30c5..d94a86f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1309,6 +1309,10 @@
 	return String(c.productVariables.VendorApiLevel)
 }
 
+func (c *config) VendorApiLevelFrozen() bool {
+	return c.productVariables.GetBuildFlagBool("RELEASE_BOARD_API_LEVEL_FROZEN")
+}
+
 func (c *deviceConfig) Arches() []Arch {
 	var arches []Arch
 	for _, target := range c.config.Targets[Android] {
diff --git a/cc/cc.go b/cc/cc.go
index 31fa4fd..4a8baa6 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1607,9 +1607,10 @@
 
 func (ctx *moduleContextImpl) sdkVersion() string {
 	if ctx.ctx.Device() {
-		if ctx.useVndk() {
+		config := ctx.ctx.Config()
+		if !config.IsVndkDeprecated() && ctx.useVndk() {
 			vndkVer := ctx.mod.VndkVersion()
-			if inList(vndkVer, ctx.ctx.Config().PlatformVersionActiveCodenames()) {
+			if inList(vndkVer, config.PlatformVersionActiveCodenames()) {
 				return "current"
 			}
 			return vndkVer
@@ -1627,6 +1628,17 @@
 	if ver == "apex_inherit" || ver == "" {
 		ver = ctx.sdkVersion()
 	}
+
+	if ctx.ctx.Device() {
+		config := ctx.ctx.Config()
+		if config.IsVndkDeprecated() && ctx.inVendor() {
+			// If building for vendor with final API, then use the latest _stable_ API as "current".
+			if config.VendorApiLevelFrozen() && (ver == "" || ver == "current") {
+				ver = config.PlatformSdkVersion().String()
+			}
+		}
+	}
+
 	// For crt objects, the meaning of min_sdk_version is very different from other types of
 	// module. For them, min_sdk_version defines the oldest version that the build system will
 	// create versioned variants for. For example, if min_sdk_version is 16, then sdk variant of
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 321bd38..6cc500b 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -43,6 +43,7 @@
 	android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
 		variables.VendorApiLevel = StringPtr("202404")
 		variables.DeviceVndkVersion = StringPtr("current")
+		variables.KeepVndk = BoolPtr(true)
 		variables.Platform_vndk_version = StringPtr("29")
 	}),
 )
@@ -4843,3 +4844,43 @@
 	testDepWithVariant("vendor")
 	testDepWithVariant("product")
 }
+
+func TestVendorSdkVersionWithoutVndk(t *testing.T) {
+	t.Parallel()
+
+	bp := `
+		cc_library {
+			name: "libfoo",
+			srcs: ["libfoo.cc"],
+			vendor_available: true,
+		}
+
+		cc_library {
+			name: "libbar",
+			srcs: ["libbar.cc"],
+			vendor_available: true,
+			min_sdk_version: "29",
+		}
+	`
+
+	ctx := prepareForCcTestWithoutVndk.RunTestWithBp(t, bp)
+	testSdkVersionFlag := func(module, version string) {
+		flags := ctx.ModuleForTests(module, "android_vendor_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+		android.AssertStringDoesContain(t, "min sdk version", flags, "-target aarch64-linux-android"+version)
+	}
+
+	testSdkVersionFlag("libfoo", "10000")
+	testSdkVersionFlag("libbar", "29")
+
+	ctx = android.GroupFixturePreparers(
+		prepareForCcTestWithoutVndk,
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			if variables.BuildFlags == nil {
+				variables.BuildFlags = make(map[string]string)
+			}
+			variables.BuildFlags["RELEASE_BOARD_API_LEVEL_FROZEN"] = "true"
+		}),
+	).RunTestWithBp(t, bp)
+	testSdkVersionFlag("libfoo", "30")
+	testSdkVersionFlag("libbar", "29")
+}
diff --git a/cc/object_test.go b/cc/object_test.go
index e6a3fdd..c0d1331 100644
--- a/cc/object_test.go
+++ b/cc/object_test.go
@@ -22,7 +22,7 @@
 )
 
 func TestMinSdkVersionsOfCrtObjects(t *testing.T) {
-	ctx := testCc(t, `
+	bp := `
 		cc_object {
 			name: "crt_foo",
 			srcs: ["foo.c"],
@@ -30,8 +30,8 @@
 			stl: "none",
 			min_sdk_version: "28",
 			vendor_available: true,
-		}`)
-
+		}
+	`
 	variants := []struct {
 		variant string
 		num     string
@@ -43,11 +43,17 @@
 		{"android_arm64_armv8-a_sdk_current", "10000"},
 		{"android_vendor.29_arm64_armv8-a", "29"},
 	}
+
+	ctx := prepareForCcTest.RunTestWithBp(t, bp)
 	for _, v := range variants {
 		cflags := ctx.ModuleForTests("crt_foo", v.variant).Rule("cc").Args["cFlags"]
 		expected := "-target aarch64-linux-android" + v.num + " "
 		android.AssertStringDoesContain(t, "cflag", cflags, expected)
 	}
+	ctx = prepareForCcTestWithoutVndk.RunTestWithBp(t, bp)
+	android.AssertStringDoesContain(t, "cflag",
+		ctx.ModuleForTests("crt_foo", "android_vendor_arm64_armv8-a").Rule("cc").Args["cFlags"],
+		"-target aarch64-linux-android10000 ")
 }
 
 func TestUseCrtObjectOfCorrectVersion(t *testing.T) {