Merge changes from topics "add_AddReverseVariationDependency", "use_AddReverseVariationDependency" into main

* changes:
  Use AddReverseVariationDependency to avoid 1-variant fallback
  Add AddReverseVariationDependency
diff --git a/android/arch.go b/android/arch.go
index d9ecb50..1ec971d 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -142,7 +142,10 @@
 	if a.Multilib == "lib32" {
 		return "32"
 	}
-	return "64"
+	if a.Multilib == "lib64" {
+		return "64"
+	}
+	panic("Bitness is not defined for the common variant")
 }
 
 const COMMON_VARIANT = "common"
diff --git a/android/module.go b/android/module.go
index 1866d7a..20caae2 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1005,6 +1005,14 @@
 			return
 		}
 
+		// Do not create a dependency from common variant to arch variant for `common_first` modules
+		if multilib, _ := decodeMultilib(ctx, ctx.Module().base()); multilib == string(MultilibCommonFirst) {
+			commonVariant := ctx.Arch().ArchType.Multilib == ""
+			if bothInAndroid && commonVariant && InList(target.Arch.ArchType.Multilib, []string{"lib32", "lib64"}) {
+				return
+			}
+		}
+
 		variation := target.Variations()
 		if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
 			ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
@@ -2288,6 +2296,8 @@
 		}
 		variable := condition.Arg(0)
 		switch variable {
+		case "build_from_text_stub":
+			return proptools.ConfigurableValueBool(ctx.Config().BuildFromTextStub())
 		case "debuggable":
 			return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
 		case "use_debug_art":
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 577c6cc..5b1ae54 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -375,6 +375,7 @@
 	ctx.Register()
 	finalOutputFile, ninjaDeps := runSoongOnlyBuild(ctx)
 
+	ninjaDeps = append(ninjaDeps, configuration.ProductVariablesFileName)
 	ninjaDeps = append(ninjaDeps, usedEnvFile)
 	if shared.IsDebugging() {
 		// Add a non-existent file to the dependencies so that soong_build will rerun when the debugger is
diff --git a/java/fuzz.go b/java/fuzz.go
index d37c558..e5f1f04 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -85,10 +85,11 @@
 
 func (j *JavaFuzzTest) DepsMutator(ctx android.BottomUpMutatorContext) {
 	if j.Os().Class.String() == deviceString {
-		j.testProperties.Jni_libs = append(j.testProperties.Jni_libs, artDeps...)
+		j.testProperties.Jni_libs.AppendSimpleValue(artDeps)
 	}
 
-	if len(j.testProperties.Jni_libs) > 0 {
+	jniLibs := j.testProperties.Jni_libs.GetOrDefault(ctx, nil)
+	if len(jniLibs) > 0 {
 		if j.fuzzPackagedModule.FuzzProperties.Fuzz_config == nil {
 			config := &fuzz.FuzzConfig{}
 			j.fuzzPackagedModule.FuzzProperties.Fuzz_config = config
@@ -98,7 +99,7 @@
 		j.fuzzPackagedModule.FuzzProperties.Fuzz_config.IsJni = proptools.BoolPtr(true)
 		for _, target := range ctx.MultiTargets() {
 			sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
-			ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...)
+			ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, jniLibs...)
 		}
 	}
 
diff --git a/java/java.go b/java/java.go
index 92dcc63..661422b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1301,7 +1301,7 @@
 	Test_options TestOptions
 
 	// Names of modules containing JNI libraries that should be installed alongside the test.
-	Jni_libs []string
+	Jni_libs proptools.Configurable[[]string]
 
 	// Install the test into a folder named for the module in all test suites.
 	Per_testcase_directory *bool
@@ -1485,10 +1485,11 @@
 		}
 	}
 
-	if len(j.testProperties.Jni_libs) > 0 {
+	jniLibs := j.testProperties.Jni_libs.GetOrDefault(ctx, nil)
+	if len(jniLibs) > 0 {
 		for _, target := range ctx.MultiTargets() {
 			sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
-			ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...)
+			ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, jniLibs...)
 		}
 	}
 
diff --git a/java/java_test.go b/java/java_test.go
index 641bf40..e976b08 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -3132,3 +3132,37 @@
 		t.Errorf("top-level: Expected but not found: %v, Found but not expected: %v", left, right)
 	}
 }
+
+// Test that a dependency edge is created to the "first" variant of a native library listed in `required` of java_binary
+func TestNativeRequiredDepOfJavaBinary(t *testing.T) {
+	findDepsOfModule := func(ctx *android.TestContext, module android.Module, depName string) []blueprint.Module {
+		var ret []blueprint.Module
+		ctx.VisitDirectDeps(module, func(dep blueprint.Module) {
+			if dep.Name() == depName {
+				ret = append(ret, dep)
+			}
+		})
+		return ret
+	}
+
+	bp := cc.GatherRequiredDepsForTest(android.Android) + `
+java_binary {
+	name: "myjavabin",
+	main_class: "com.android.MyJava",
+	required: ["mynativelib"],
+}
+cc_library_shared {
+	name: "mynativelib",
+}
+`
+	res, _ := testJava(t, bp)
+	// The first variant installs the native library via the common variant, so check the deps of both variants.
+	nativeVariantDepsWithDups := findDepsOfModule(res, res.ModuleForTests("myjavabin", "android_arm64_armv8-a").Module(), "mynativelib")
+	nativeVariantDepsWithDups = append(nativeVariantDepsWithDups, findDepsOfModule(res, res.ModuleForTests("myjavabin", "android_common").Module(), "mynativelib")...)
+
+	nativeVariantDepsUnique := map[blueprint.Module]bool{}
+	for _, dep := range nativeVariantDepsWithDups {
+		nativeVariantDepsUnique[dep] = true
+	}
+	android.AssertIntEquals(t, "Create a dep on the first variant", 1, len(nativeVariantDepsUnique))
+}