Merge "Avoid creating APEX variant for sdk member"
diff --git a/apex/apex.go b/apex/apex.go
index f9c902c..e3a95fa 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -704,7 +704,7 @@
 		if !ok || !am.CanHaveApexVariants() {
 			return false
 		}
-		if !parent.(android.DepIsInSameApex).DepIsInSameApex(mctx, child) && !inAnySdk(child) {
+		if !parent.(android.DepIsInSameApex).DepIsInSameApex(mctx, child) {
 			return false
 		}
 		if excludeVndkLibs {
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index a2198e9..931ca3c 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -204,8 +204,8 @@
 		}
 	`)
 
-	sdkMemberV1 := result.ctx.ModuleForTests("sdkmember_mysdk_1", "android_common_myapex").Rule("combineJar").Output
-	sdkMemberV2 := result.ctx.ModuleForTests("sdkmember_mysdk_2", "android_common_myapex2").Rule("combineJar").Output
+	sdkMemberV1 := result.ctx.ModuleForTests("sdkmember_mysdk_1", "android_common").Rule("combineJar").Output
+	sdkMemberV2 := result.ctx.ModuleForTests("sdkmember_mysdk_2", "android_common").Rule("combineJar").Output
 
 	javalibForMyApex := result.ctx.ModuleForTests("myjavalib", "android_common_myapex")
 	javalibForMyApex2 := result.ctx.ModuleForTests("myjavalib", "android_common_myapex2")
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 3e76008..7591020 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -406,13 +406,17 @@
 // Step 4: transitively ripple down the SDK requirements from the root modules like APEX to its
 // descendants
 func sdkDepsMutator(mctx android.TopDownMutatorContext) {
-	if m, ok := mctx.Module().(android.SdkAware); ok {
+	if parent, ok := mctx.Module().(interface {
+		android.DepIsInSameApex
+		android.RequiredSdks
+	}); ok {
 		// Module types for Mainline modules (e.g. APEX) are expected to implement RequiredSdks()
 		// by reading its own properties like `uses_sdks`.
-		requiredSdks := m.RequiredSdks()
+		requiredSdks := parent.RequiredSdks()
 		if len(requiredSdks) > 0 {
 			mctx.VisitDirectDeps(func(m android.Module) {
-				if dep, ok := m.(android.SdkAware); ok {
+				// Only propagate required sdks from the apex onto its contents.
+				if dep, ok := m.(android.SdkAware); ok && parent.DepIsInSameApex(mctx, dep) {
 					dep.BuildWithSdks(requiredSdks)
 				}
 			})
@@ -423,15 +427,28 @@
 // Step 5: if libfoo.mysdk.11 is in the context where version 11 of mysdk is requested, the
 // versioned module is used instead of the un-versioned (in-development) module libfoo
 func sdkDepsReplaceMutator(mctx android.BottomUpMutatorContext) {
-	if m, ok := mctx.Module().(android.SdkAware); ok && m.IsInAnySdk() {
-		if sdk := m.ContainingSdk(); !sdk.Unversioned() {
-			if m.RequiredSdks().Contains(sdk) {
-				// Note that this replacement is done only for the modules that have the same
-				// variations as the current module. Since current module is already mutated for
-				// apex references in other APEXes are not affected by this replacement.
-				memberName := m.MemberName()
-				mctx.ReplaceDependencies(memberName)
-			}
+	if versionedSdkMember, ok := mctx.Module().(android.SdkAware); ok && versionedSdkMember.IsInAnySdk() {
+		if sdk := versionedSdkMember.ContainingSdk(); !sdk.Unversioned() {
+			// Only replace dependencies to <sdkmember> with <sdkmember@required-version>
+			// if the depending module requires it. e.g.
+			//      foo -> sdkmember
+			// will be transformed to:
+			//      foo -> sdkmember@1
+			// if and only if foo is a member of an APEX that requires version 1 of the
+			// sdk containing sdkmember.
+			memberName := versionedSdkMember.MemberName()
+
+			// Replace dependencies on sdkmember with a dependency on the current module which
+			// is a versioned prebuilt of the sdkmember if required.
+			mctx.ReplaceDependenciesIf(memberName, func(from blueprint.Module, tag blueprint.DependencyTag, to blueprint.Module) bool {
+				// from - foo
+				// to - sdkmember
+				replace := false
+				if parent, ok := from.(android.RequiredSdks); ok {
+					replace = parent.RequiredSdks().Contains(sdk)
+				}
+				return replace
+			})
 		}
 	}
 }