soong: fix wrong link type for VNDKs

Do not rely on 'module.Name()' to decide VNDK link type.
Some prebuilt modules such as libclang_rt_prebuilt_library_shared and
vndk_prebuilt may have different naming schemes.(prefix/suffix)
And llndk_library module has '.llndk' suffix.

Instead, use VNDK-related properties (e.g. vndk.enabled,
vendor_available, etc.).

Bug: 132800095
Test: m & check LOCAL_SOONG_LINK_TYPE for prebuilts
Change-Id: I06b0c182aeab16969c44a86397f02be4beb80bbd
diff --git a/cc/cc.go b/cc/cc.go
index 786e4fd..de108b4 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -919,7 +919,7 @@
 }
 
 func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
-	c.makeLinkType = c.getMakeLinkType(actx.Config())
+	c.makeLinkType = c.getMakeLinkType(actx)
 
 	ctx := &moduleContext{
 		ModuleContext: actx,
@@ -1940,19 +1940,22 @@
 	return false
 }
 
-func (c *Module) getMakeLinkType(config android.Config) string {
+func (c *Module) getMakeLinkType(actx android.ModuleContext) string {
+	name := actx.ModuleName()
 	if c.useVndk() {
-		if inList(c.Name(), *vndkCoreLibraries(config)) ||
-			inList(c.Name(), *vndkSpLibraries(config)) ||
-			inList(c.Name(), *llndkLibraries(config)) {
-			if inList(c.Name(), *vndkPrivateLibraries(config)) {
-				return "native:vndk_private"
-			} else {
+		if lib, ok := c.linker.(*llndkStubDecorator); ok {
+			if Bool(lib.Properties.Vendor_available) {
 				return "native:vndk"
 			}
-		} else {
-			return "native:vendor"
+			return "native:vndk_private"
 		}
+		if c.isVndk() && !c.isVndkExt() {
+			if Bool(c.VendorProperties.Vendor_available) {
+				return "native:vndk"
+			}
+			return "native:vndk_private"
+		}
+		return "native:vendor"
 	} else if c.inRecovery() {
 		return "native:recovery"
 	} else if c.Target().Os == android.Android && String(c.Properties.Sdk_version) != "" {
@@ -1960,7 +1963,7 @@
 		// TODO(b/114741097): use the correct ndk stl once build errors have been fixed
 		//family, link := getNdkStlFamilyAndLinkType(c)
 		//return fmt.Sprintf("native:ndk:%s:%s", family, link)
-	} else if inList(c.Name(), *vndkUsingCoreVariantLibraries(config)) {
+	} else if inList(name, *vndkUsingCoreVariantLibraries(actx.Config())) {
 		return "native:platform_vndk"
 	} else {
 		return "native:platform"
diff --git a/cc/cc_test.go b/cc/cc_test.go
index f5bb12c..997e11e 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -1263,6 +1263,110 @@
 	`)
 }
 
+func TestMakeLinkType(t *testing.T) {
+	config := android.TestArchConfig(buildDir, nil)
+	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+	// native:vndk
+	ctx := testCcWithConfig(t, `
+	cc_library {
+		name: "libvndk",
+		vendor_available: true,
+		vndk: {
+			enabled: true,
+		},
+	}
+	cc_library {
+		name: "libvndksp",
+		vendor_available: true,
+		vndk: {
+			enabled: true,
+			support_system_process: true,
+		},
+	}
+	cc_library {
+		name: "libvndkprivate",
+		vendor_available: false,
+		vndk: {
+			enabled: true,
+		},
+	}
+	cc_library {
+		name: "libvendor",
+		vendor: true,
+	}
+	cc_library {
+		name: "libvndkext",
+		vendor: true,
+		vndk: {
+			enabled: true,
+			extends: "libvndk",
+		},
+	}
+	vndk_prebuilt_shared {
+		name: "prevndk",
+		version: "27",
+		target_arch: "arm",
+		binder32bit: true,
+		vendor_available: true,
+		vndk: {
+			enabled: true,
+		},
+		arch: {
+			arm: {
+				srcs: ["liba.so"],
+			},
+		},
+	}
+	cc_library {
+		name: "libllndk",
+	}
+	llndk_library {
+		name: "libllndk",
+		symbol_file: "",
+	}
+	cc_library {
+		name: "libllndkprivate",
+	}
+	llndk_library {
+		name: "libllndkprivate",
+		vendor_available: false,
+		symbol_file: "",
+	}`, config)
+
+	assertArrayString(t, *vndkCoreLibraries(config),
+		[]string{"libvndk", "libvndkprivate"})
+	assertArrayString(t, *vndkSpLibraries(config),
+		[]string{"libc++", "libvndksp"})
+	assertArrayString(t, *llndkLibraries(config),
+		[]string{"libc", "libdl", "libllndk", "libllndkprivate", "libm"})
+	assertArrayString(t, *vndkPrivateLibraries(config),
+		[]string{"libllndkprivate", "libvndkprivate"})
+
+	tests := []struct {
+		variant  string
+		name     string
+		expected string
+	}{
+		{vendorVariant, "libvndk", "native:vndk"},
+		{vendorVariant, "libvndksp", "native:vndk"},
+		{vendorVariant, "libvndkprivate", "native:vndk_private"},
+		{vendorVariant, "libvendor", "native:vendor"},
+		{vendorVariant, "libvndkext", "native:vendor"},
+		{vendorVariant, "prevndk.vndk.27.arm.binder32", "native:vndk"},
+		{vendorVariant, "libllndk.llndk", "native:vndk"},
+		{coreVariant, "libvndk", "native:platform"},
+		{coreVariant, "libvndkprivate", "native:platform"},
+		{coreVariant, "libllndk", "native:platform"},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
+			assertString(t, module.makeLinkType, test.expected)
+		})
+	}
+}
+
 var (
 	str11 = "01234567891"
 	str10 = str11[:10]
@@ -2159,3 +2263,25 @@
 		)
 	}
 }
+
+func assertString(t *testing.T, got, expected string) {
+	t.Helper()
+	if got != expected {
+		t.Errorf("expected %q got %q", expected, got)
+	}
+}
+
+func assertArrayString(t *testing.T, got, expected []string) {
+	t.Helper()
+	if len(got) != len(expected) {
+		t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
+		return
+	}
+	for i := range got {
+		if got[i] != expected[i] {
+			t.Errorf("expected %d-th %q (%q) got %q (%q)",
+				i, expected[i], expected, got[i], got)
+			return
+		}
+	}
+}
diff --git a/cc/testing.go b/cc/testing.go
index 259fb19..d9be900 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -207,6 +207,7 @@
 	ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
 	ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory))
 	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
+	ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(vndkPrebuiltSharedFactory))
 	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("image", ImageMutator).Parallel()
 		ctx.BottomUp("link", LinkageMutator).Parallel()