Merge "Add a Tag field to dist to dist a tagged output" into rvc-dev
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 9a29687..2303efe 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -22,6 +22,7 @@
 
 	"android/soong/android"
 	"android/soong/cc"
+	"android/soong/java"
 
 	"github.com/google/blueprint/proptools"
 )
@@ -181,6 +182,9 @@
 			// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
 			// we will have foo.apk.apk
 			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.builtFile.Base(), ".apk"))
+			if app, ok := fi.module.(*java.AndroidApp); ok && len(app.JniCoverageOutputs()) > 0 {
+				fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", strings.Join(app.JniCoverageOutputs().Strings(), " "))
+			}
 			fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_app_prebuilt.mk")
 		} else if fi.class == nativeSharedLib || fi.class == nativeExecutable || fi.class == nativeTest {
 			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
diff --git a/java/androidmk.go b/java/androidmk.go
index e18fbb4..136bb36 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -276,7 +276,7 @@
 }
 
 func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
-	if !app.IsForPlatform() {
+	if !app.IsForPlatform() || app.appProperties.HideFromMake {
 		return []android.AndroidMkEntries{android.AndroidMkEntries{
 			Disabled: true,
 		}}
@@ -289,6 +289,7 @@
 			func(entries *android.AndroidMkEntries) {
 				// App module names can be overridden.
 				entries.SetString("LOCAL_MODULE", app.installApkName)
+				entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", app.appProperties.PreventInstall)
 				entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", app.exportPackage)
 				if app.dexJarFile != nil {
 					entries.SetPath("LOCAL_SOONG_DEX_JAR", app.dexJarFile)
@@ -348,6 +349,9 @@
 				for _, jniLib := range app.installJniLibs {
 					entries.AddStrings("LOCAL_SOONG_JNI_LIBS_"+jniLib.target.Arch.ArchType.String(), jniLib.name)
 				}
+				if len(app.jniCoverageOutputs) > 0 {
+					entries.AddStrings("LOCAL_PREBUILT_COVERAGE_ARCHIVE", app.jniCoverageOutputs.Strings()...)
+				}
 				if len(app.dexpreopter.builtInstalled) > 0 {
 					entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", app.dexpreopter.builtInstalled)
 				}
diff --git a/java/app.go b/java/app.go
index 7a444ca..f9992d8 100755
--- a/java/app.go
+++ b/java/app.go
@@ -105,6 +105,11 @@
 	// If set, find and merge all NOTICE files that this module and its dependencies have and store
 	// it in the APK as an asset.
 	Embed_notices *bool
+
+	// cc.Coverage related properties
+	PreventInstall    bool `blueprint:"mutated"`
+	HideFromMake      bool `blueprint:"mutated"`
+	IsCoverageVariant bool `blueprint:"mutated"`
 }
 
 // android_app properties that can be overridden by override_android_app
@@ -133,7 +138,8 @@
 
 	overridableAppProperties overridableAppProperties
 
-	installJniLibs []jniLib
+	installJniLibs     []jniLib
+	jniCoverageOutputs android.Paths
 
 	bundleFile android.Path
 
@@ -171,6 +177,10 @@
 	return a.certificate
 }
 
+func (a *AndroidApp) JniCoverageOutputs() android.Paths {
+	return a.jniCoverageOutputs
+}
+
 var _ AndroidLibraryDependency = (*AndroidApp)(nil)
 
 type Certificate struct {
@@ -373,6 +383,11 @@
 		if a.shouldEmbedJnis(ctx) {
 			jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
 			TransformJniLibsToJar(ctx, jniJarFile, jniLibs, a.useEmbeddedNativeLibs(ctx))
+			for _, jni := range jniLibs {
+				if jni.coverageFile.Valid() {
+					a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
+				}
+			}
 		} else {
 			a.installJniLibs = jniLibs
 		}
@@ -572,9 +587,10 @@
 
 				if lib.Valid() {
 					jniLibs = append(jniLibs, jniLib{
-						name:   ctx.OtherModuleName(module),
-						path:   path,
-						target: module.Target(),
+						name:         ctx.OtherModuleName(module),
+						path:         path,
+						target:       module.Target(),
+						coverageFile: dep.CoverageOutputFile(),
 					})
 				} else {
 					ctx.ModuleErrorf("dependency %q missing output file", otherName)
@@ -628,6 +644,24 @@
 	return Bool(a.appProperties.Privileged)
 }
 
+func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
+	return ctx.Device() && (ctx.DeviceConfig().NativeCoverageEnabled() || ctx.DeviceConfig().ClangCoverageEnabled())
+}
+
+func (a *AndroidApp) PreventInstall() {
+	a.appProperties.PreventInstall = true
+}
+
+func (a *AndroidApp) HideFromMake() {
+	a.appProperties.HideFromMake = true
+}
+
+func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
+	a.appProperties.IsCoverageVariant = coverage
+}
+
+var _ cc.Coverage = (*AndroidApp)(nil)
+
 // android_app compiles sources and Android resources into an Android application package `.apk` file.
 func AndroidAppFactory() android.Module {
 	module := &AndroidApp{}
diff --git a/java/java.go b/java/java.go
index edf83cf..d67ff87 100644
--- a/java/java.go
+++ b/java/java.go
@@ -540,9 +540,10 @@
 }
 
 type jniLib struct {
-	name   string
-	path   android.Path
-	target android.Target
+	name         string
+	path         android.Path
+	target       android.Target
+	coverageFile android.OptionalPath
 }
 
 func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {
diff --git a/ui/build/sandbox_linux.go b/ui/build/sandbox_linux.go
index 11ff667..2de772b 100644
--- a/ui/build/sandbox_linux.go
+++ b/ui/build/sandbox_linux.go
@@ -90,10 +90,7 @@
 			return
 		}
 
-		c.ctx.Println("Build sandboxing disabled due to nsjail error. This may become fatal in the future.")
-		c.ctx.Println("Please let us know why nsjail doesn't work in your environment at:")
-		c.ctx.Println("  https://groups.google.com/forum/#!forum/android-building")
-		c.ctx.Println("  https://issuetracker.google.com/issues/new?component=381517")
+		c.ctx.Println("Build sandboxing disabled due to nsjail error.")
 
 		for _, line := range strings.Split(strings.TrimSpace(string(data)), "\n") {
 			c.ctx.Verboseln(line)