Make java binaries common instead of common-first

Previously, java binaries had both common and the first arch variants.
This was origionally added in aosp/556843. The reasoning there was so
that a java binary could be used as the dependency of a genrule.

However, now with transition mutators, we can make the incoming
transition redirect the arch variant to the common variant if the module
only has a common variant. This allows genrules to depend on the common
arch variant easily. That change is also included in this cl.

Bug: 372091092
Test: m nothing --no-skip-soong-tests
Change-Id: Iea612d050bff608d661f81566884653239015213
diff --git a/java/androidmk.go b/java/androidmk.go
index 2dff6cd..bacd925 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -281,50 +281,24 @@
 		return nil
 	}
 
-	if !binary.isWrapperVariant {
-		return []android.AndroidMkEntries{android.AndroidMkEntries{
-			Class:      "JAVA_LIBRARIES",
-			OutputFile: android.OptionalPathForPath(binary.outputFile),
-			Include:    "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
-			ExtraEntries: []android.AndroidMkExtraEntriesFunc{
-				func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
-					entries.SetPath("LOCAL_SOONG_HEADER_JAR", binary.headerJarFile)
-					entries.SetPath("LOCAL_SOONG_CLASSES_JAR", binary.implementationAndResourcesJar)
-					if binary.dexJarFile.IsSet() {
-						entries.SetPath("LOCAL_SOONG_DEX_JAR", binary.dexJarFile.Path())
-					}
-					if len(binary.dexpreopter.builtInstalled) > 0 {
-						entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled)
-					}
-				},
+	return []android.AndroidMkEntries{{
+		Class:      "JAVA_LIBRARIES",
+		OutputFile: android.OptionalPathForPath(binary.outputFile),
+		Include:    "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
+		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+				entries.SetPath("LOCAL_SOONG_HEADER_JAR", binary.headerJarFile)
+				entries.SetPath("LOCAL_SOONG_CLASSES_JAR", binary.implementationAndResourcesJar)
+				if binary.dexJarFile.IsSet() {
+					entries.SetPath("LOCAL_SOONG_DEX_JAR", binary.dexJarFile.Path())
+				}
+				if len(binary.dexpreopter.builtInstalled) > 0 {
+					entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled)
+				}
+				entries.AddStrings("LOCAL_REQUIRED_MODULES", binary.androidMkNamesOfJniLibs...)
 			},
-			ExtraFooters: []android.AndroidMkExtraFootersFunc{
-				func(w io.Writer, name, prefix, moduleDir string) {
-					fmt.Fprintln(w, "jar_installed_module := $(LOCAL_INSTALLED_MODULE)")
-				},
-			},
-		}}
-	} else {
-		outputFile := binary.wrapperFile
-
-		return []android.AndroidMkEntries{android.AndroidMkEntries{
-			Class:      "EXECUTABLES",
-			OutputFile: android.OptionalPathForPath(outputFile),
-			ExtraEntries: []android.AndroidMkExtraEntriesFunc{
-				func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
-					entries.SetBool("LOCAL_STRIP_MODULE", false)
-					entries.AddStrings("LOCAL_REQUIRED_MODULES", binary.androidMkNamesOfJniLibs...)
-				},
-			},
-			ExtraFooters: []android.AndroidMkExtraFootersFunc{
-				func(w io.Writer, name, prefix, moduleDir string) {
-					// Ensure that the wrapper script timestamp is always updated when the jar is updated
-					fmt.Fprintln(w, "$(LOCAL_INSTALLED_MODULE): $(jar_installed_module)")
-					fmt.Fprintln(w, "jar_installed_module :=")
-				},
-			},
-		}}
-	}
+		},
+	}}
 }
 
 func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/java/java.go b/java/java.go
index 018850f..d972887 100644
--- a/java/java.go
+++ b/java/java.go
@@ -450,7 +450,6 @@
 	javaApiContributionTag  = dependencyTag{name: "java-api-contribution"}
 	aconfigDeclarationTag   = dependencyTag{name: "aconfig-declaration"}
 	jniInstallTag           = dependencyTag{name: "jni install", runtimeLinked: true, installable: true}
-	binaryInstallTag        = dependencyTag{name: "binary install", runtimeLinked: true, installable: true}
 	usesLibReqTag           = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
 	usesLibOptTag           = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true)
 	usesLibCompat28OptTag   = makeUsesLibraryDependencyTag(28, true)
@@ -1004,13 +1003,7 @@
 	}
 	j.compile(ctx, nil, nil, nil, nil)
 
-	// If this module is an impl library created from java_sdk_library,
-	// install the files under the java_sdk_library module outdir instead of this module outdir.
-	if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") {
-		j.setInstallRules(ctx, proptools.String(j.SdkLibraryName()))
-	} else {
-		j.setInstallRules(ctx, ctx.ModuleName())
-	}
+	j.setInstallRules(ctx)
 
 	android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
 		TestOnly:       Bool(j.sourceProperties.Test_only),
@@ -1020,7 +1013,27 @@
 	setOutputFiles(ctx, j.Module)
 }
 
-func (j *Library) setInstallRules(ctx android.ModuleContext, installModuleName string) {
+func (j *Library) getJarInstallDir(ctx android.ModuleContext) android.InstallPath {
+	var installDir android.InstallPath
+	if ctx.InstallInTestcases() {
+		var archDir string
+		if !ctx.Host() {
+			archDir = ctx.DeviceConfig().DeviceArch()
+		}
+		installModuleName := ctx.ModuleName()
+		// If this module is an impl library created from java_sdk_library,
+		// install the files under the java_sdk_library module outdir instead of this module outdir.
+		if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") {
+			installModuleName = proptools.String(j.SdkLibraryName())
+		}
+		installDir = android.PathForModuleInstall(ctx, installModuleName, archDir)
+	} else {
+		installDir = android.PathForModuleInstall(ctx, "framework")
+	}
+	return installDir
+}
+
+func (j *Library) setInstallRules(ctx android.ModuleContext) {
 	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
 
 	if (Bool(j.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() {
@@ -1034,17 +1047,7 @@
 				android.PathForHostDexInstall(ctx, "framework"),
 				j.Stem()+"-hostdex.jar", j.outputFile)
 		}
-		var installDir android.InstallPath
-		if ctx.InstallInTestcases() {
-			var archDir string
-			if !ctx.Host() {
-				archDir = ctx.DeviceConfig().DeviceArch()
-			}
-			installDir = android.PathForModuleInstall(ctx, installModuleName, archDir)
-		} else {
-			installDir = android.PathForModuleInstall(ctx, "framework")
-		}
-		j.installFile = ctx.InstallFileWithoutCheckbuild(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...)
+		j.installFile = ctx.InstallFileWithoutCheckbuild(j.getJarInstallDir(ctx), j.Stem()+".jar", j.outputFile, extraInstallDeps...)
 	}
 }
 
@@ -1804,8 +1807,6 @@
 
 	binaryProperties binaryProperties
 
-	isWrapperVariant bool
-
 	wrapperFile android.Path
 	binaryFile  android.InstallPath
 
@@ -1819,97 +1820,94 @@
 func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName())
 
-	if ctx.Arch().ArchType == android.Common {
-		// Compile the jar
-		if j.binaryProperties.Main_class != nil {
-			if j.properties.Manifest != nil {
-				ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set")
-			}
-			manifestFile := android.PathForModuleOut(ctx, "manifest.txt")
-			GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class))
-			j.overrideManifest = android.OptionalPathForPath(manifestFile)
-		}
-
-		j.Library.GenerateAndroidBuildActions(ctx)
+	// Handle the binary wrapper. This comes before compiling the jar so that the wrapper
+	// is the first PackagingSpec
+	if j.binaryProperties.Wrapper != nil {
+		j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper)
 	} else {
-		// Handle the binary wrapper
-		j.isWrapperVariant = true
-
-		if j.binaryProperties.Wrapper != nil {
-			j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper)
-		} else {
-			if ctx.Windows() {
-				ctx.PropertyErrorf("wrapper", "wrapper is required for Windows")
-			}
-
-			if ctx.Device() {
-				// device binary should have a main_class property if it does not
-				// have a specific wrapper, so that a default wrapper can
-				// be generated for it.
-				if j.binaryProperties.Main_class == nil {
-					ctx.PropertyErrorf("main_class", "main_class property "+
-						"is required for device binary if no default wrapper is assigned")
-				} else {
-					wrapper := android.PathForModuleOut(ctx, ctx.ModuleName()+".sh")
-					jarName := j.Stem() + ".jar"
-					partition := j.PartitionTag(ctx.DeviceConfig())
-					ctx.Build(pctx, android.BuildParams{
-						Rule:   deviceBinaryWrapper,
-						Output: wrapper,
-						Args: map[string]string{
-							"jar_name":   jarName,
-							"partition":  partition,
-							"main_class": String(j.binaryProperties.Main_class),
-						},
-					})
-					j.wrapperFile = wrapper
-				}
-			} else {
-				j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
-			}
-		}
-
-		ext := ""
 		if ctx.Windows() {
-			ext = ".bat"
+			ctx.PropertyErrorf("wrapper", "wrapper is required for Windows")
 		}
 
-		// The host installation rules make the installed wrapper depend on all the dependencies
-		// of the wrapper variant, which will include the common variant's jar file and any JNI
-		// libraries.  This is verified by TestBinary.
-		j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
-			ctx.ModuleName()+ext, j.wrapperFile)
-
-		setOutputFiles(ctx, j.Library.Module)
-
-		// Set the jniLibs of this binary.
-		// These will be added to `LOCAL_REQUIRED_MODULES`, and the kati packaging system will
-		// install these alongside the java binary.
-		ctx.VisitDirectDepsWithTag(jniInstallTag, func(jni android.Module) {
-			// Use the BaseModuleName of the dependency (without any prebuilt_ prefix)
-			bmn, _ := jni.(interface{ BaseModuleName() string })
-			j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, bmn.BaseModuleName()+":"+jni.Target().Arch.ArchType.Bitness())
-		})
-		// Check that native libraries are not listed in `required`. Prompt users to use `jni_libs` instead.
-		ctx.VisitDirectDepsWithTag(android.RequiredDepTag, func(dep android.Module) {
-			if _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider); hasSharedLibraryInfo {
-				ctx.ModuleErrorf("cc_library %s is no longer supported in `required` of java_binary modules. Please use jni_libs instead.", dep.Name())
+		if ctx.Device() {
+			// device binary should have a main_class property if it does not
+			// have a specific wrapper, so that a default wrapper can
+			// be generated for it.
+			if j.binaryProperties.Main_class == nil {
+				ctx.PropertyErrorf("main_class", "main_class property "+
+					"is required for device binary if no default wrapper is assigned")
+			} else {
+				wrapper := android.PathForModuleOut(ctx, ctx.ModuleName()+".sh")
+				jarName := j.Stem() + ".jar"
+				partition := j.PartitionTag(ctx.DeviceConfig())
+				ctx.Build(pctx, android.BuildParams{
+					Rule:   deviceBinaryWrapper,
+					Output: wrapper,
+					Args: map[string]string{
+						"jar_name":   jarName,
+						"partition":  partition,
+						"main_class": String(j.binaryProperties.Main_class),
+					},
+				})
+				j.wrapperFile = wrapper
 			}
-		})
+		} else {
+			j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
+		}
 	}
+
+	ext := ""
+	if ctx.Windows() {
+		ext = ".bat"
+	}
+
+	// The host installation rules make the installed wrapper depend on all the dependencies
+	// of the wrapper variant, which will include the common variant's jar file and any JNI
+	// libraries.  This is verified by TestBinary. Also make it depend on the jar file so that
+	// the binary file timestamp will update when the jar file timestamp does. The jar file is
+	// built later on, in j.Library.GenerateAndroidBuildActions, so we have to create an identical
+	// installpath representing it here.
+	j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
+		ctx.ModuleName()+ext, j.wrapperFile, j.getJarInstallDir(ctx).Join(ctx, j.Stem()+".jar"))
+
+	// Set the jniLibs of this binary.
+	// These will be added to `LOCAL_REQUIRED_MODULES`, and the kati packaging system will
+	// install these alongside the java binary.
+	ctx.VisitDirectDepsWithTag(jniInstallTag, func(jni android.Module) {
+		// Use the BaseModuleName of the dependency (without any prebuilt_ prefix)
+		bmn, _ := jni.(interface{ BaseModuleName() string })
+		j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, bmn.BaseModuleName()+":"+jni.Target().Arch.ArchType.Bitness())
+	})
+	// Check that native libraries are not listed in `required`. Prompt users to use `jni_libs` instead.
+	ctx.VisitDirectDepsWithTag(android.RequiredDepTag, func(dep android.Module) {
+		if _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider); hasSharedLibraryInfo {
+			ctx.ModuleErrorf("cc_library %s is no longer supported in `required` of java_binary modules. Please use jni_libs instead.", dep.Name())
+		}
+	})
+
+	// Compile the jar
+	if j.binaryProperties.Main_class != nil {
+		if j.properties.Manifest != nil {
+			ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set")
+		}
+		manifestFile := android.PathForModuleOut(ctx, "manifest.txt")
+		GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class))
+		j.overrideManifest = android.OptionalPathForPath(manifestFile)
+	}
+
+	j.Library.GenerateAndroidBuildActions(ctx)
 }
 
 func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
-	if ctx.Arch().ArchType == android.Common {
-		j.deps(ctx)
-	}
+	j.deps(ctx)
 	// These dependencies ensure the installation rules will install the jar file when the
 	// wrapper is installed, and the jni libraries when the wrapper is installed.
-	if ctx.Arch().ArchType != android.Common {
-		ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...)
-		ctx.AddVariationDependencies(
-			[]blueprint.Variation{{Mutator: "arch", Variation: android.CommonArch.String()}},
-			binaryInstallTag, ctx.ModuleName())
+	if ctx.Os().Class == android.Host {
+		ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniInstallTag, j.binaryProperties.Jni_libs...)
+	} else if ctx.Os().Class == android.Device {
+		ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), jniInstallTag, j.binaryProperties.Jni_libs...)
+	} else {
+		ctx.ModuleErrorf("Unknown os class")
 	}
 }
 
@@ -1929,7 +1927,7 @@
 
 	module.Module.properties.Installable = proptools.BoolPtr(true)
 
-	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst)
+	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
 	android.InitDefaultableModule(module)
 
 	return module
@@ -1947,7 +1945,7 @@
 
 	module.Module.properties.Installable = proptools.BoolPtr(true)
 
-	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst)
+	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
 	android.InitDefaultableModule(module)
 	return module
 }
diff --git a/java/java_test.go b/java/java_test.go
index 24dabdb..51cfdab 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -569,8 +569,7 @@
 
 	bar := ctx.ModuleForTests("bar", buildOS+"_common")
 	barJar := bar.Output("bar.jar").Output.String()
-	barWrapper := ctx.ModuleForTests("bar", buildOS+"_x86_64")
-	barWrapperDeps := barWrapper.Output("bar").Implicits.Strings()
+	barWrapperDeps := bar.Output("bar").Implicits.Strings()
 
 	libjni := ctx.ModuleForTests("libjni", buildOS+"_x86_64_shared")
 	libjniSO := libjni.Rule("Cp").Output.String()
@@ -1931,7 +1930,7 @@
 			main_class: "foo.bar.jb",
 		}
 	`)
-	wrapperPath := fmt.Sprint(ctx.ModuleForTests("foo", "android_arm64_armv8-a").AllOutputs())
+	wrapperPath := fmt.Sprint(ctx.ModuleForTests("foo", "android_common").AllOutputs())
 	if !strings.Contains(wrapperPath, "foo.sh") {
 		t.Errorf("wrapper file foo.sh is not generated")
 	}
@@ -3125,13 +3124,6 @@
 }
 `
 	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))
+	deps := findDepsOfModule(res, res.ModuleForTests("myjavabin", "android_common").Module(), "mynativelib")
+	android.AssertIntEquals(t, "Create a dep on the first variant", 1, len(deps))
 }