Add hostdex support

If hostdex: true is specified for a java library, create an extra
Make module that copies the dex jar to a module with a -hostdex
suffix in the host output directory.

Bug: 67600882
Test: m -j checkbuild
Change-Id: I859dfaabeefdca714b566de94e00f74e03c85939
diff --git a/java/androidmk.go b/java/androidmk.go
index 89d7d51..e349de4 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -19,6 +19,8 @@
 	"io"
 	"strings"
 
+	"github.com/google/blueprint/proptools"
+
 	"android/soong/android"
 )
 
@@ -38,6 +40,25 @@
 				fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", library.deviceProperties.Sdk_version)
 			},
 		},
+		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+			android.WriteAndroidMkData(w, data)
+
+			if proptools.Bool(library.deviceProperties.Hostdex) && !library.Host() {
+				fmt.Fprintln(w, "include $(CLEAR_VARS)")
+				fmt.Fprintln(w, "LOCAL_MODULE := "+name+"-hostdex")
+				fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
+				fmt.Fprintln(w, "LOCAL_MODULE_CLASS := JAVA_LIBRARIES")
+				fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", library.classpathFile.String())
+				if library.properties.Installable != nil && *library.properties.Installable == false {
+					fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+				}
+				if library.dexJarFile != nil {
+					fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", library.dexJarFile.String())
+				}
+				fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+strings.Join(data.Required, " "))
+				fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
+			}
+		},
 	}
 }
 
diff --git a/java/app.go b/java/app.go
index e40478a..490a03d 100644
--- a/java/app.go
+++ b/java/app.go
@@ -274,8 +274,6 @@
 func AndroidAppFactory() android.Module {
 	module := &AndroidApp{}
 
-	module.deviceProperties.Dex = true
-
 	module.AddProperties(
 		&module.Module.properties,
 		&module.Module.deviceProperties,
diff --git a/java/java.go b/java/java.go
index fde88e9..5393b06 100644
--- a/java/java.go
+++ b/java/java.go
@@ -125,16 +125,15 @@
 	// if not blank, set to the version of the sdk to compile against
 	Sdk_version string
 
-	// Set for device java libraries, and for host versions of device java libraries
-	// built for testing
-	Dex bool `blueprint:"mutated"`
-
 	// directories to pass to aidl tool
 	Aidl_includes []string
 
 	// directories that should be added as include directories
 	// for any aidl sources of modules that depend on this module
 	Export_aidl_include_dirs []string
+
+	// If true, export a copy of the module as a -hostdex module for host testing.
+	Hostdex *bool
 }
 
 // Module contains the properties and members used by all java module types
@@ -279,8 +278,6 @@
 			if sdkDep.useModule {
 				ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.module)
 			}
-		} else {
-			// TODO(ccross): add hostdex support
 		}
 	}
 	ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
@@ -508,7 +505,6 @@
 
 	j.classpathFile = outputFile
 
-	// TODO(ccross): handle hostdex
 	if ctx.Device() && j.installable() {
 		dxFlags := j.deviceProperties.Dxflags
 		if false /* emma enabled */ {
@@ -622,7 +618,6 @@
 		if !installable {
 			module.properties.Installable = proptools.BoolPtr(false)
 		}
-		module.deviceProperties.Dex = true
 
 		module.AddProperties(
 			&module.Module.properties,
@@ -680,8 +675,6 @@
 func BinaryFactory() android.Module {
 	module := &Binary{}
 
-	module.deviceProperties.Dex = true
-
 	module.AddProperties(
 		&module.Module.properties,
 		&module.Module.deviceProperties,