Move LLNDK and NDK versionSelectorMutator special cases into versionedInterface

Implement stubsVersions on *llndkStubDecorator and *stubDecorator to
handle the special cases in versionSelectorMutator.

Test: m checkbuild
Change-Id: Idc985c52f91450df42c0275b2b2acef3f2ed8868
diff --git a/cc/cc.go b/cc/cc.go
index 73fe762..dbe6346 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -717,9 +717,9 @@
 	return c.Properties.AlwaysSdk || Bool(c.Properties.Sdk_variant_only)
 }
 
-func (c *Module) StubsVersions() []string {
+func (c *Module) StubsVersions(ctx android.BaseMutatorContext) []string {
 	if versioned, ok := c.linker.(versionedInterface); ok {
-		return versioned.stubsVersions()
+		return versioned.stubsVersions(ctx)
 	}
 	panic(fmt.Errorf("StubsVersions called on non-library module: %q", c.BaseModuleName()))
 }
diff --git a/cc/library.go b/cc/library.go
index b131a16..780d104 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -660,6 +660,8 @@
 }
 
 type libraryInterface interface {
+	versionedInterface
+
 	static() bool
 	shared() bool
 	objs() Objects
@@ -687,7 +689,7 @@
 	setStubsVersion(string)
 	stubsVersion() string
 
-	stubsVersions() []string
+	stubsVersions(ctx android.BaseMutatorContext) []string
 	setAllStubsVersions([]string)
 	allStubsVersions() []string
 }
@@ -1371,7 +1373,7 @@
 	return len(library.Properties.Stubs.Versions) > 0
 }
 
-func (library *libraryDecorator) stubsVersions() []string {
+func (library *libraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
 	return library.Properties.Stubs.Versions
 }
 
@@ -1650,47 +1652,19 @@
 // and propagates the value from implementation libraries to llndk libraries with the same name.
 func versionSelectorMutator(mctx android.BottomUpMutatorContext) {
 	if library, ok := mctx.Module().(LinkableInterface); ok && CanBeVersionVariant(library) {
-		if c, ok := library.(*Module); ok {
-			if _, ok := c.linker.(*llndkStubDecorator); ok {
-				// Get the versions from the implementation module.
-				impls := mctx.GetDirectDepsWithTag(llndkImplDep)
-				if len(impls) > 1 {
-					panic(fmt.Errorf("Expected single implmenetation library, got %d", len(impls)))
-				} else if len(impls) == 1 {
-					c.SetAllStubsVersions(impls[0].(*Module).AllStubsVersions())
-				}
-				return
-			}
-
-			if compiler, ok := c.linker.(*stubDecorator); ok {
-				if mctx.Os() != android.Android {
-					// These modules are always android.DeviceEnabled only, but
-					// those include Fuchsia devices, which we don't support.
-					mctx.Module().Disable()
+		if library.CcLibraryInterface() && library.BuildSharedVariant() {
+			versions := library.StubsVersions(mctx)
+			if len(versions) > 0 {
+				normalizeVersions(mctx, versions)
+				if mctx.Failed() {
 					return
 				}
-				firstVersion, err := nativeApiLevelFromUser(mctx,
-					String(compiler.properties.First_version))
-				if err != nil {
-					mctx.PropertyErrorf("first_version", err.Error())
-					return
-				}
-				c.SetAllStubsVersions(ndkLibraryVersions(mctx, firstVersion))
+				// Set the versions on the pre-mutated module so they can be read by any llndk modules that
+				// depend on the implementation library and haven't been mutated yet.
+				library.SetAllStubsVersions(versions)
 				return
 			}
 		}
-
-		if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 && !library.UseSdk() {
-			versions := library.StubsVersions()
-			normalizeVersions(mctx, versions)
-			if mctx.Failed() {
-				return
-			}
-			// Set the versions on the pre-mutated module so they can be read by any llndk modules that
-			// depend on the implementation library and haven't been mutated yet.
-			library.SetAllStubsVersions(versions)
-			return
-		}
 	}
 }
 
diff --git a/cc/linkable.go b/cc/linkable.go
index 21e6f9b..4eb7220 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -16,7 +16,7 @@
 
 	NonCcVariants() bool
 
-	StubsVersions() []string
+	StubsVersions(android.BaseMutatorContext) []string
 	BuildStubs() bool
 	SetBuildStubs()
 	SetStubsVersion(string)
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index e50da9a..4425a10 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -15,6 +15,7 @@
 package cc
 
 import (
+	"fmt"
 	"path/filepath"
 	"strings"
 
@@ -170,6 +171,17 @@
 	return true
 }
 
+func (stub *llndkStubDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
+	// Get the versions from the implementation module.
+	impls := ctx.GetDirectDepsWithTag(llndkImplDep)
+	if len(impls) > 1 {
+		panic(fmt.Errorf("Expected single implmenetation library, got %d", len(impls)))
+	} else if len(impls) == 1 {
+		return impls[0].(*Module).AllStubsVersions()
+	}
+	return nil
+}
+
 func NewLLndkStubLibrary() *Module {
 	module, library := NewLibrary(android.DeviceSupported)
 	library.BuildOnlyShared()
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index bb0f2e8..f2ad652 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -104,7 +104,7 @@
 	return stub.apiLevel.GreaterThanOrEqualTo(stub.unversionedUntil)
 }
 
-func ndkLibraryVersions(ctx android.BottomUpMutatorContext, from android.ApiLevel) []string {
+func ndkLibraryVersions(ctx android.BaseMutatorContext, from android.ApiLevel) []string {
 	var versions []android.ApiLevel
 	versionStrs := []string{}
 	for _, version := range ctx.Config().AllSupportedApiLevels() {
@@ -118,6 +118,19 @@
 	return versionStrs
 }
 
+func (this *stubDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
+	if !ctx.Module().Enabled() {
+		return nil
+	}
+	firstVersion, err := nativeApiLevelFromUser(ctx,
+		String(this.properties.First_version))
+	if err != nil {
+		ctx.PropertyErrorf("first_version", err.Error())
+		return nil
+	}
+	return ndkLibraryVersions(ctx, firstVersion)
+}
+
 func (this *stubDecorator) initializeProperties(ctx BaseModuleContext) bool {
 	this.apiLevel = nativeApiLevelOrPanic(ctx, this.stubsVersion())