Merge "Extend RegistrationContext to support pre/post deps mutators"
diff --git a/android/module.go b/android/module.go
index ffcbf32..a14e575 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1803,6 +1803,49 @@
 	OutputFiles(tag string) (Paths, error)
 }
 
+// OutputFilesForModule returns the paths from an OutputFileProducer with the given tag.  On error, including if the
+// module produced zero paths, it reports errors to the ctx and returns nil.
+func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths {
+	paths, err := outputFilesForModule(ctx, module, tag)
+	if err != nil {
+		reportPathError(ctx, err)
+		return nil
+	}
+	return paths
+}
+
+// OutputFileForModule returns the path from an OutputFileProducer with the given tag.  On error, including if the
+// module produced zero or multiple paths, it reports errors to the ctx and returns nil.
+func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path {
+	paths, err := outputFilesForModule(ctx, module, tag)
+	if err != nil {
+		reportPathError(ctx, err)
+		return nil
+	}
+	if len(paths) > 1 {
+		reportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
+			pathContextName(ctx, module))
+		return nil
+	}
+	return paths[0]
+}
+
+func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
+	if outputFileProducer, ok := module.(OutputFileProducer); ok {
+		paths, err := outputFileProducer.OutputFiles(tag)
+		if err != nil {
+			return nil, fmt.Errorf("failed to get output file from module %q: %s",
+				pathContextName(ctx, module), err.Error())
+		}
+		if len(paths) == 0 {
+			return nil, fmt.Errorf("failed to get output files from module %q", pathContextName(ctx, module))
+		}
+		return paths, nil
+	} else {
+		return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module))
+	}
+}
+
 type HostToolProvider interface {
 	HostToolPath() OptionalPath
 }
diff --git a/android/paths.go b/android/paths.go
index a04dc6b..d181b75 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -89,6 +89,15 @@
 	}
 }
 
+func pathContextName(ctx PathContext, module blueprint.Module) string {
+	if x, ok := ctx.(interface{ ModuleName(blueprint.Module) string }); ok {
+		return x.ModuleName(module)
+	} else if x, ok := ctx.(interface{ OtherModuleName(blueprint.Module) string }); ok {
+		return x.OtherModuleName(module)
+	}
+	return "unknown"
+}
+
 type Path interface {
 	// Returns the path in string form
 	String() string
diff --git a/android/sh_binary.go b/android/sh_binary.go
index 3293d4f..7d9dc67 100644
--- a/android/sh_binary.go
+++ b/android/sh_binary.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"path/filepath"
 	"strings"
 )
 
@@ -74,8 +75,11 @@
 
 	sourceFilePath Path
 	outputFilePath OutputPath
+	installedFile  InstallPath
 }
 
+var _ HostToolProvider = (*ShBinary)(nil)
+
 type ShTest struct {
 	ShBinary
 
@@ -84,16 +88,16 @@
 	data Paths
 }
 
+func (s *ShBinary) HostToolPath() OptionalPath {
+	return OptionalPathForPath(s.installedFile)
+}
+
 func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) {
 	if s.properties.Src == nil {
 		ctx.PropertyErrorf("src", "missing prebuilt source file")
 	}
 }
 
-func (s *ShBinary) SourceFilePath(ctx ModuleContext) Path {
-	return PathForModuleSrc(ctx, String(s.properties.Src))
-}
-
 func (s *ShBinary) OutputFile() OutputPath {
 	return s.outputFilePath
 }
@@ -110,7 +114,7 @@
 	return s.properties.Symlinks
 }
 
-func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
+func (s *ShBinary) generateAndroidBuildActions(ctx ModuleContext) {
 	s.sourceFilePath = PathForModuleSrc(ctx, String(s.properties.Src))
 	filename := String(s.properties.Filename)
 	filename_from_src := Bool(s.properties.Filename_from_src)
@@ -135,6 +139,12 @@
 	})
 }
 
+func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
+	s.generateAndroidBuildActions(ctx)
+	installDir := PathForModuleInstall(ctx, "bin", String(s.properties.Sub_dir))
+	s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
+}
+
 func (s *ShBinary) AndroidMkEntries() []AndroidMkEntries {
 	return []AndroidMkEntries{AndroidMkEntries{
 		Class:      "EXECUTABLES",
@@ -158,11 +168,26 @@
 }
 
 func (s *ShTest) GenerateAndroidBuildActions(ctx ModuleContext) {
-	s.ShBinary.GenerateAndroidBuildActions(ctx)
+	s.ShBinary.generateAndroidBuildActions(ctx)
+	testDir := "nativetest"
+	if ctx.Target().Arch.ArchType.Multilib == "lib64" {
+		testDir = "nativetest64"
+	}
+	if ctx.Target().NativeBridge == NativeBridgeEnabled {
+		testDir = filepath.Join(testDir, ctx.Target().NativeBridgeRelativePath)
+	} else if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
+		testDir = filepath.Join(testDir, ctx.Arch().ArchType.String())
+	}
+	installDir := PathForModuleInstall(ctx, testDir, String(s.properties.Sub_dir))
+	s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
 
 	s.data = PathsForModuleSrc(ctx, s.testProperties.Data)
 }
 
+func (s *ShTest) InstallInData() bool {
+	return true
+}
+
 func (s *ShTest) AndroidMkEntries() []AndroidMkEntries {
 	return []AndroidMkEntries{AndroidMkEntries{
 		Class:      "NATIVE_TESTS",
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 0d3cc74..8b84be8 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -27,9 +27,10 @@
 type FuzzConfig struct {
 	// Email address of people to CC on bugs or contact about this fuzz target.
 	Cc []string `json:"cc,omitempty"`
-	// Boolean specifying whether to disable the fuzz target from running
-	// automatically in continuous fuzzing infrastructure.
-	Disable *bool `json:"disable,omitempty"`
+	// Specify whether to enable continuous fuzzing on devices. Defaults to true.
+	Fuzz_on_haiku_device *bool `json:"fuzz_on_haiku_device,omitempty"`
+	// Specify whether to enable continuous fuzzing on host. Defaults to true.
+	Fuzz_on_haiku_host *bool `json:"fuzz_on_haiku_host,omitempty"`
 	// Component in Google's bug tracking system that bugs should be filed to.
 	Componentid *int64 `json:"componentid,omitempty"`
 	// Hotlists in Google's bug tracking system that bugs should be marked with.