Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37ca4a1e authored by Jaewoong Jung's avatar Jaewoong Jung
Browse files

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
parent 0ed9a7d6
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import (

	"android/soong/android"
	"android/soong/cc"
	"android/soong/java"

	"github.com/google/blueprint/proptools"
)
@@ -181,6 +182,9 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, mo
			// 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())
+5 −1
Original line number Diff line number Diff line
@@ -275,7 +275,7 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries {
}

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 (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
			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 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
				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)
				}
+38 −4
Original line number Diff line number Diff line
@@ -105,6 +105,11 @@ type appProperties struct {
	// 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
@@ -134,6 +139,7 @@ type AndroidApp struct {
	overridableAppProperties overridableAppProperties

	installJniLibs     []jniLib
	jniCoverageOutputs android.Paths

	bundleFile android.Path

@@ -171,6 +177,10 @@ func (a *AndroidApp) Certificate() Certificate {
	return a.certificate
}

func (a *AndroidApp) JniCoverageOutputs() android.Paths {
	return a.jniCoverageOutputs
}

var _ AndroidLibraryDependency = (*AndroidApp)(nil)

type Certificate struct {
@@ -373,6 +383,11 @@ func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, ctx android.ModuleContext
		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
		}
@@ -575,6 +590,7 @@ func collectAppDeps(ctx android.ModuleContext, shouldCollectRecursiveNativeDeps
						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 @@ func (a *AndroidApp) Privileged() bool {
	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{}
+4 −3
Original line number Diff line number Diff line
@@ -541,6 +541,7 @@ type jniLib struct {
	name         string
	path         android.Path
	target       android.Target
	coverageFile android.OptionalPath
}

func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {