Add code coverage support to android_app JNI libs.

This is a cherry-pick change.

Test: Built mainline module coverage data
Bug: 152117890
Change-Id: I47bf3e5d6e78c4518729bdb52616e248156d3cec
Merged-In: I47bf3e5d6e78c4518729bdb52616e248156d3cec
diff --git a/java/androidmk.go b/java/androidmk.go
index a220cce..ee2437a 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -275,7 +275,7 @@
 }
 
 func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
-	if !app.IsForPlatform() {
+	if !app.IsForPlatform() || app.appProperties.HideFromMake {
 		return []android.AndroidMkEntries{android.AndroidMkEntries{
 			Disabled: true,
 		}}
@@ -288,6 +288,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)
@@ -347,6 +348,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 dc0b272..55ad8b0 100644
--- a/java/java.go
+++ b/java/java.go
@@ -538,9 +538,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 {