Add support for including py_binary and *_go_binary in apexs

These additional binary types are useful for some apexs. Add the
ability to include them. Due to the nature of the resulting artifacts
only py binaries with embedded launchers and host go binaries are
supported.

Test: m com.android.support.apexer
Bug: 119332365
Bug: 119332362
Change-Id: I27c253d3647cf7bbe15896610d7a74a5f93e8bec
diff --git a/apex/apex.go b/apex/apex.go
index 9ab5187..f72eef3 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -25,8 +25,10 @@
 	"android/soong/android"
 	"android/soong/cc"
 	"android/soong/java"
+	"android/soong/python"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -289,6 +291,8 @@
 	nativeSharedLib
 	nativeExecutable
 	shBinary
+	pyBinary
+	goBinary
 	javaSharedLib
 )
 
@@ -348,7 +352,7 @@
 		return "ETC"
 	case nativeSharedLib:
 		return "SHARED_LIBRARIES"
-	case nativeExecutable, shBinary:
+	case nativeExecutable, shBinary, pyBinary, goBinary:
 		return "EXECUTABLES"
 	case javaSharedLib:
 		return "JAVA_LIBRARIES"
@@ -624,6 +628,22 @@
 	return
 }
 
+func getCopyManifestForPyBinary(py *python.Module) (fileToCopy android.Path, dirInApex string) {
+	dirInApex = "bin"
+	fileToCopy = py.HostToolPath().Path()
+	return
+}
+func getCopyManifestForGoBinary(ctx android.ModuleContext, gb bootstrap.GoBinaryTool) (fileToCopy android.Path, dirInApex string) {
+	dirInApex = "bin"
+	s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath())
+	if err != nil {
+		ctx.ModuleErrorf("Unable to use compiled binary at %s", gb.InstallPath())
+		return
+	}
+	fileToCopy = android.PathForOutput(ctx, s)
+	return
+}
+
 func getCopyManifestForShBinary(sh *android.ShBinary) (fileToCopy android.Path, dirInApex string) {
 	dirInApex = filepath.Join("bin", sh.SubDir())
 	fileToCopy = sh.OutputFile()
@@ -658,7 +678,7 @@
 
 	handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
 
-	ctx.WalkDeps(func(child, parent android.Module) bool {
+	ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
 		if _, ok := parent.(*apexBundle); ok {
 			// direct dependencies
 			depTag := ctx.OtherModuleDependencyTag(child)
@@ -685,8 +705,17 @@
 				} else if sh, ok := child.(*android.ShBinary); ok {
 					fileToCopy, dirInApex := getCopyManifestForShBinary(sh)
 					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, shBinary, sh, nil})
+				} else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() {
+					fileToCopy, dirInApex := getCopyManifestForPyBinary(py)
+					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, pyBinary, py, nil})
+				} else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() {
+					fileToCopy, dirInApex := getCopyManifestForGoBinary(ctx, gb)
+					// NB: Since go binaries are static we don't need the module for anything here, which is
+					// good since the go tool is a blueprint.Module not an android.Module like we would
+					// normally use.
+					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, goBinary, nil, nil})
 				} else {
-					ctx.PropertyErrorf("binaries", "%q is neithher cc_binary nor sh_binary", depName)
+					ctx.PropertyErrorf("binaries", "%q is neither cc_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
 				}
 			case javaLibTag:
 				if java, ok := child.(*java.Library); ok {