Merge "Add support for including py_binary and *_go_binary in apexs"
diff --git a/Android.bp b/Android.bp
index e9597f4..4d73049 100644
--- a/Android.bp
+++ b/Android.bp
@@ -375,6 +375,7 @@
         "soong-android",
         "soong-cc",
         "soong-java",
+        "soong-python",
     ],
     srcs: [
         "apex/apex.go",
diff --git a/android/module.go b/android/module.go
index f2f1af1..2fa7d31 100644
--- a/android/module.go
+++ b/android/module.go
@@ -154,6 +154,7 @@
 	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
 	VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
 	WalkDeps(visit func(Module, Module) bool)
+	WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
 
 	Variable(pctx PackageContext, name, value string)
 	Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
@@ -1067,6 +1068,10 @@
 		})
 }
 
+func (a *androidModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
+	a.ModuleContext.WalkDeps(visit)
+}
+
 func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
 	a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
 		childAndroidModule := a.validateAndroidModule(child)
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 {