Refactor for preliminary Rust vendor image support

Refactors parts of CC to prepare for preliminary support for using Rust
static libraries in vendor images. Some previously private functions are
made public, and additional functions are added to LinkableInterface so
GetMakeLinkType can be passed a LinkableInterface.

Bug: 172525289
Test: m
Change-Id: I5fda48e79532fe9ceab255e18d910af58048a123
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 320e69b..3619fd8 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -113,7 +113,7 @@
 						entries.SetString("LOCAL_SOONG_VNDK_VERSION", c.VndkVersion())
 						// VNDK libraries available to vendor are not installed because
 						// they are packaged in VNDK APEX and installed by APEX packages (apex/apex.go)
-						if !c.isVndkExt() {
+						if !c.IsVndkExt() {
 							entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
 						}
 					}
diff --git a/cc/cc.go b/cc/cc.go
index b1c1264..ffba579 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -401,7 +401,7 @@
 	isVndkPrivate(config android.Config) bool
 	isVndk() bool
 	isVndkSp() bool
-	isVndkExt() bool
+	IsVndkExt() bool
 	inProduct() bool
 	inVendor() bool
 	inRamdisk() bool
@@ -1024,7 +1024,7 @@
 	return isLlndkLibrary(name, config) && !isVndkPrivateLibrary(name, config)
 }
 
-func (c *Module) isVndkPrivate(config android.Config) bool {
+func (c *Module) IsVndkPrivate(config android.Config) bool {
 	// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private.
 	return isVndkPrivateLibrary(c.BaseModuleName(), config)
 }
@@ -1057,7 +1057,7 @@
 	return false
 }
 
-func (c *Module) isVndkExt() bool {
+func (c *Module) IsVndkExt() bool {
 	if vndkdep := c.vndkdep; vndkdep != nil {
 		return vndkdep.isVndkExt()
 	}
@@ -1241,7 +1241,7 @@
 }
 
 func (ctx *moduleContextImpl) isVndkPrivate(config android.Config) bool {
-	return ctx.mod.isVndkPrivate(config)
+	return ctx.mod.IsVndkPrivate(config)
 }
 
 func (ctx *moduleContextImpl) isVndk() bool {
@@ -1260,8 +1260,8 @@
 	return ctx.mod.isVndkSp()
 }
 
-func (ctx *moduleContextImpl) isVndkExt() bool {
-	return ctx.mod.isVndkExt()
+func (ctx *moduleContextImpl) IsVndkExt() bool {
+	return ctx.mod.IsVndkExt()
 }
 
 func (ctx *moduleContextImpl) mustUseVendorVariant() bool {
@@ -1414,7 +1414,7 @@
 	// "current", it will append the VNDK version to the name suffix.
 	var vndkVersion string
 	var nameSuffix string
-	if c.inProduct() {
+	if c.InProduct() {
 		vndkVersion = ctx.DeviceConfig().ProductVndkVersion()
 		nameSuffix = productSuffix
 	} else {
@@ -1448,7 +1448,7 @@
 		c.hideApexVariantFromMake = true
 	}
 
-	c.makeLinkType = c.getMakeLinkType(actx)
+	c.makeLinkType = GetMakeLinkType(actx, c)
 
 	c.Properties.SubName = ""
 
@@ -2097,7 +2097,7 @@
 		return
 	}
 
-	if from.Module().Target().Os != android.Android {
+	if from.Target().Os != android.Android {
 		// Host code is not restricted
 		return
 	}
@@ -2111,6 +2111,11 @@
 			if ccFrom.vndkdep != nil {
 				ccFrom.vndkdep.vndkCheckLinkType(ctx, ccTo, tag)
 			}
+		} else if linkableMod, ok := to.(LinkableInterface); ok {
+			// Static libraries from other languages can be linked
+			if !linkableMod.Static() {
+				ctx.ModuleErrorf("Attempting to link VNDK cc.Module with unsupported module type")
+			}
 		} else {
 			ctx.ModuleErrorf("Attempting to link VNDK cc.Module with unsupported module type")
 		}
@@ -2762,7 +2767,7 @@
 		return libName + vendorRamdiskSuffix
 	} else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() {
 		return libName + recoverySuffix
-	} else if ccDep.Module().Target().NativeBridge == android.NativeBridgeEnabled {
+	} else if ccDep.Target().NativeBridge == android.NativeBridgeEnabled {
 		return libName + nativeBridgeSuffix
 	} else {
 		return libName
@@ -2874,22 +2879,24 @@
 	return false
 }
 
-func (c *Module) getMakeLinkType(actx android.ModuleContext) string {
+func GetMakeLinkType(actx android.ModuleContext, c LinkableInterface) string {
 	if c.UseVndk() {
-		if lib, ok := c.linker.(*llndkStubDecorator); ok {
-			if Bool(lib.Properties.Vendor_available) {
-				return "native:vndk"
+		if ccModule, ok := c.Module().(*Module); ok {
+			// Only CC modules provide stubs at the moment.
+			if lib, ok := ccModule.linker.(*llndkStubDecorator); ok {
+				if Bool(lib.Properties.Vendor_available) {
+					return "native:vndk"
+				}
+				return "native:vndk_private"
 			}
-			return "native:vndk_private"
 		}
-		if c.IsVndk() && !c.isVndkExt() {
-			// Product_available, if defined, must have the same value with Vendor_available.
-			if Bool(c.VendorProperties.Vendor_available) {
-				return "native:vndk"
+		if c.IsVndk() && !c.IsVndkExt() {
+			if c.IsVndkPrivate(actx.Config()) {
+				return "native:vndk_private"
 			}
-			return "native:vndk_private"
+			return "native:vndk"
 		}
-		if c.inProduct() {
+		if c.InProduct() {
 			return "native:product"
 		}
 		return "native:vendor"
@@ -2899,7 +2906,7 @@
 		return "native:vendor_ramdisk"
 	} else if c.InRecovery() {
 		return "native:recovery"
-	} else if c.Target().Os == android.Android && String(c.Properties.Sdk_version) != "" {
+	} else if c.Target().Os == android.Android && c.SdkVersion() != "" {
 		return "native:ndk:none:none"
 		// TODO(b/114741097): use the correct ndk stl once build errors have been fixed
 		//family, link := getNdkStlFamilyAndLinkType(c)
diff --git a/cc/cc_test.go b/cc/cc_test.go
index af9b943..456ce53 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -250,8 +250,8 @@
 
 	// Check VNDK extension properties.
 	isVndkExt := extends != ""
-	if mod.isVndkExt() != isVndkExt {
-		t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
+	if mod.IsVndkExt() != isVndkExt {
+		t.Errorf("%q IsVndkExt() must equal to %t", name, isVndkExt)
 	}
 
 	if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
diff --git a/cc/image.go b/cc/image.go
index 3d6769e..32325b9 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -41,7 +41,7 @@
 		return hostImageVariant
 	} else if c.inVendor() {
 		return vendorImageVariant
-	} else if c.inProduct() {
+	} else if c.InProduct() {
 		return productImageVariant
 	} else if c.InRamdisk() {
 		return ramdiskImageVariant
@@ -67,7 +67,7 @@
 func (ctx *moduleContext) ProductSpecific() bool {
 	//TODO(b/150902910): Replace HasNonSystemVariants() with HasProductVariant()
 	return ctx.ModuleContext.ProductSpecific() ||
-		(ctx.mod.HasNonSystemVariants() && ctx.mod.inProduct())
+		(ctx.mod.HasNonSystemVariants() && ctx.mod.InProduct())
 }
 
 func (ctx *moduleContext) SocSpecific() bool {
@@ -76,7 +76,7 @@
 }
 
 func (ctx *moduleContextImpl) inProduct() bool {
-	return ctx.mod.inProduct()
+	return ctx.mod.InProduct()
 }
 
 func (ctx *moduleContextImpl) inVendor() bool {
@@ -111,7 +111,7 @@
 }
 
 // Returns true if the module is "product" variant. Usually these modules are installed in /product
-func (c *Module) inProduct() bool {
+func (c *Module) InProduct() bool {
 	return c.Properties.ImageVariationPrefix == ProductVariationPrefix
 }
 
@@ -265,7 +265,7 @@
 		} else {
 			mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
 		}
-	} else if m.HasNonSystemVariants() && !m.isVndkExt() {
+	} else if m.HasNonSystemVariants() && !m.IsVndkExt() {
 		// This will be available to /system unless it is product_specific
 		// which will be handled later.
 		coreVariantNeeded = true
diff --git a/cc/library.go b/cc/library.go
index c626b03..00bb4bc 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -575,13 +575,13 @@
 	}
 	if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate(ctx.Config()) {
 		if ctx.isVndkSp() {
-			if ctx.isVndkExt() {
+			if ctx.IsVndkExt() {
 				return "VNDK-SP-ext"
 			} else {
 				return "VNDK-SP"
 			}
 		} else {
-			if ctx.isVndkExt() {
+			if ctx.IsVndkExt() {
 				return "VNDK-ext"
 			} else {
 				return "VNDK-core"
@@ -730,7 +730,7 @@
 func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string {
 	name := library.getLibNameHelper(ctx.baseModuleName(), ctx.useVndk())
 
-	if ctx.isVndkExt() {
+	if ctx.IsVndkExt() {
 		// vndk-ext lib should have the same name with original lib
 		ctx.VisitDirectDepsWithTag(vndkExtDepTag, func(module android.Module) {
 			originalName := module.(*Module).outputFile.Path()
@@ -1153,7 +1153,7 @@
 			library.sAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
 				refAbiDumpFile, fileName, exportedHeaderFlags,
 				Bool(library.Properties.Header_abi_checker.Check_all_apis),
-				ctx.isLlndk(ctx.Config()), ctx.isNdk(ctx.Config()), ctx.isVndkExt())
+				ctx.isLlndk(ctx.Config()), ctx.isNdk(ctx.Config()), ctx.IsVndkExt())
 		}
 	}
 }
@@ -1269,7 +1269,7 @@
 	if library.shared() {
 		if ctx.Device() && ctx.useVndk() {
 			// set subDir for VNDK extensions
-			if ctx.isVndkExt() {
+			if ctx.IsVndkExt() {
 				if ctx.isVndkSp() {
 					library.baseInstaller.subDir = "vndk-sp"
 				} else {
@@ -1278,7 +1278,7 @@
 			}
 
 			// In some cases we want to use core variant for VNDK-Core libs
-			if ctx.isVndk() && !ctx.isVndkSp() && !ctx.isVndkExt() {
+			if ctx.isVndk() && !ctx.isVndkSp() && !ctx.IsVndkExt() {
 				mayUseCoreVariant := true
 
 				if ctx.mustUseVendorVariant() {
@@ -1299,7 +1299,7 @@
 
 			// do not install vndk libs
 			// vndk libs are packaged into VNDK APEX
-			if ctx.isVndk() && !ctx.isVndkExt() {
+			if ctx.isVndk() && !ctx.IsVndkExt() {
 				return
 			}
 		} else if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.directlyInAnyApex() {
diff --git a/cc/linkable.go b/cc/linkable.go
index 0609b28..e5dc2b3 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -7,6 +7,8 @@
 )
 
 type LinkableInterface interface {
+	android.Module
+
 	Module() android.Module
 	CcLibrary() bool
 	CcLibraryInterface() bool
@@ -41,7 +43,10 @@
 	UseVndk() bool
 	MustUseVendorVariant() bool
 	IsVndk() bool
+	IsVndkExt() bool
+	IsVndkPrivate(config android.Config) bool
 	HasVendorVariant() bool
+	InProduct() bool
 
 	SdkVersion() string
 	AlwaysSdk() bool
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index 3ef0b62..7f7a1fd 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -842,7 +842,7 @@
 				if !m.IsVndk() {
 					return true
 				}
-				return m.isVndkExt()
+				return m.IsVndkExt()
 			}
 		}
 		return true
@@ -944,7 +944,7 @@
 
 		// Common properties among snapshots.
 		prop.ModuleName = ctx.ModuleName(m)
-		if c.supportsVndkExt && m.isVndkExt() {
+		if c.supportsVndkExt && m.IsVndkExt() {
 			// vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
 			if m.isVndkSp() {
 				prop.RelativeInstallPath = "vndk-sp"
diff --git a/cc/vndk.go b/cc/vndk.go
index d57cdf7..cdd66a8 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -389,7 +389,7 @@
 
 		useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
 			mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
-		return lib.shared() && m.inVendor() && m.IsVndk() && !m.isVndkExt() && !useCoreVariant
+		return lib.shared() && m.inVendor() && m.IsVndk() && !m.IsVndkExt() && !useCoreVariant
 	}
 	return false
 }
@@ -549,7 +549,7 @@
 	if !ok || !l.shared() {
 		return nil, "", false
 	}
-	if m.VndkVersion() == config.PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() {
+	if m.VndkVersion() == config.PlatformVndkVersion() && m.IsVndk() && !m.IsVndkExt() {
 		if m.isVndkSp() {
 			return l, "vndk-sp", true
 		} else {
diff --git a/rust/rust.go b/rust/rust.go
index 38caad3..4094094 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -208,6 +208,18 @@
 	return false
 }
 
+func (mod *Module) IsVndkExt() bool {
+	return false
+}
+
+func (c *Module) IsVndkPrivate(config android.Config) bool {
+	return false
+}
+
+func (mod *Module) InProduct() bool {
+	return false
+}
+
 func (mod *Module) SdkVersion() string {
 	return ""
 }