Convert sdk mutator to TransitionMutator

Replace cc.sdkMutator with a TransitionMutator.

Bug: 319288033
Flag: EXEMPT refactor
Test: all soong tests pass
Change-Id: If9034ff73e02f1e6ee08bc3afc9a0576e0641651
diff --git a/cc/sdk.go b/cc/sdk.go
index 4925ce1..dc1261d 100644
--- a/cc/sdk.go
+++ b/cc/sdk.go
@@ -19,12 +19,86 @@
 	"android/soong/genrule"
 )
 
-// sdkMutator sets a creates a platform and an SDK variant for modules
+// sdkTransitionMutator creates a platform and an SDK variant for modules
 // that set sdk_version, and ignores sdk_version for the platform
 // variant.  The SDK variant will be used for embedding in APKs
 // that may be installed on older platforms.  Apexes use their own
 // variants that enforce backwards compatibility.
-func sdkMutator(ctx android.BottomUpMutatorContext) {
+type sdkTransitionMutator struct{}
+
+func (sdkTransitionMutator) Split(ctx android.BaseModuleContext) []string {
+	if ctx.Os() != android.Android {
+		return []string{""}
+	}
+
+	switch m := ctx.Module().(type) {
+	case LinkableInterface:
+		if m.AlwaysSdk() {
+			if !m.UseSdk() && !m.SplitPerApiLevel() {
+				ctx.ModuleErrorf("UseSdk() must return true when AlwaysSdk is set, did the factory forget to set Sdk_version?")
+			}
+			return []string{"sdk"}
+		} else if m.UseSdk() || m.SplitPerApiLevel() {
+			return []string{"", "sdk"}
+		} else {
+			return []string{""}
+		}
+	case *genrule.Module:
+		if p, ok := m.Extra.(*GenruleExtraProperties); ok {
+			if String(p.Sdk_version) != "" {
+				return []string{"", "sdk"}
+			} else {
+				return []string{""}
+			}
+		}
+	case *CcApiVariant:
+		ccApiVariant, _ := ctx.Module().(*CcApiVariant)
+		if String(ccApiVariant.properties.Variant) == "ndk" {
+			return []string{"sdk"}
+		} else {
+			return []string{""}
+		}
+	}
+
+	return []string{""}
+}
+
+func (sdkTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+	return sourceVariation
+}
+
+func (sdkTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
+	if ctx.Os() != android.Android {
+		return ""
+	}
+	switch m := ctx.Module().(type) {
+	case LinkableInterface:
+		if m.AlwaysSdk() {
+			return "sdk"
+		} else if m.UseSdk() || m.SplitPerApiLevel() {
+			return incomingVariation
+		}
+	case *genrule.Module:
+		if p, ok := m.Extra.(*GenruleExtraProperties); ok {
+			if String(p.Sdk_version) != "" {
+				return incomingVariation
+			}
+		}
+	case *CcApiVariant:
+		ccApiVariant, _ := ctx.Module().(*CcApiVariant)
+		if String(ccApiVariant.properties.Variant) == "ndk" {
+			return "sdk"
+		}
+	}
+
+	if ctx.IsAddingDependency() {
+		return incomingVariation
+	} else {
+		return ""
+	}
+}
+
+func (sdkTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
 	if ctx.Os() != android.Android {
 		return
 	}
@@ -33,59 +107,45 @@
 	case LinkableInterface:
 		ccModule, isCcModule := ctx.Module().(*Module)
 		if m.AlwaysSdk() {
-			if !m.UseSdk() && !m.SplitPerApiLevel() {
-				ctx.ModuleErrorf("UseSdk() must return true when AlwaysSdk is set, did the factory forget to set Sdk_version?")
+			if variation != "sdk" {
+				ctx.ModuleErrorf("tried to create variation %q for module with AlwaysSdk set, expected \"sdk\"", variation)
 			}
-			modules := ctx.CreateVariations("sdk")
-			modules[0].(*Module).Properties.IsSdkVariant = true
+
+			ccModule.Properties.IsSdkVariant = true
 		} else if m.UseSdk() || m.SplitPerApiLevel() {
-			modules := ctx.CreateVariations("", "sdk")
+			if variation == "" {
+				// Clear the sdk_version property for the platform (non-SDK) variant so later code
+				// doesn't get confused by it.
+				ccModule.Properties.Sdk_version = nil
+			} else {
+				// Mark the SDK variant.
+				ccModule.Properties.IsSdkVariant = true
 
-			// Clear the sdk_version property for the platform (non-SDK) variant so later code
-			// doesn't get confused by it.
-			modules[0].(*Module).Properties.Sdk_version = nil
-
-			// Mark the SDK variant.
-			modules[1].(*Module).Properties.IsSdkVariant = true
+				// SDK variant never gets installed because the variant is to be embedded in
+				// APKs, not to be installed to the platform.
+				ccModule.Properties.PreventInstall = true
+			}
 
 			if ctx.Config().UnbundledBuildApps() {
-				// For an unbundled apps build, hide the platform variant from Make
-				// so that other Make modules don't link against it, but against the
-				// SDK variant.
-				modules[0].(*Module).Properties.HideFromMake = true
+				if variation == "" {
+					// For an unbundled apps build, hide the platform variant from Make
+					// so that other Make modules don't link against it, but against the
+					// SDK variant.
+					ccModule.Properties.HideFromMake = true
+				}
 			} else {
-				// For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when
-				// exposed to Make.
-				modules[1].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
+				if variation == "sdk" {
+					// For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when
+					// exposed to Make.
+					ccModule.Properties.SdkAndPlatformVariantVisibleToMake = true
+				}
 			}
-			// SDK variant never gets installed because the variant is to be embedded in
-			// APKs, not to be installed to the platform.
-			modules[1].(*Module).Properties.PreventInstall = true
-			ctx.AliasVariation("")
 		} else {
 			if isCcModule {
 				// Clear the sdk_version property for modules that don't have an SDK variant so
 				// later code doesn't get confused by it.
 				ccModule.Properties.Sdk_version = nil
 			}
-			ctx.CreateVariations("")
-			ctx.AliasVariation("")
-		}
-	case *genrule.Module:
-		if p, ok := m.Extra.(*GenruleExtraProperties); ok {
-			if String(p.Sdk_version) != "" {
-				ctx.CreateVariations("", "sdk")
-			} else {
-				ctx.CreateVariations("")
-			}
-			ctx.AliasVariation("")
-		}
-	case *CcApiVariant:
-		ccApiVariant, _ := ctx.Module().(*CcApiVariant)
-		if String(ccApiVariant.properties.Variant) == "ndk" {
-			ctx.CreateVariations("sdk")
-		} else {
-			ctx.CreateVariations("")
 		}
 	}
 }