diff --git a/java/app.go b/java/app.go index abd78b7ed..87685449a 100644 --- a/java/app.go +++ b/java/app.go @@ -1471,7 +1471,23 @@ func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig androi return testConfig } +func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) { + if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") { + // Instrument the android_test_helper target to log potential API calls at the run time. + // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER. + ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib") + a.setApiMapper(true) + } + a.AndroidApp.DepsMutator(ctx) +} + func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) { + if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") { + // Instrument the android_test_helper target to log potential API calls at the run time. + // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER. + ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib") + a.setApiMapper(true) + } a.AndroidApp.DepsMutator(ctx) } diff --git a/java/base.go b/java/base.go index e516891a3..dcf6bf55c 100644 --- a/java/base.go +++ b/java/base.go @@ -233,6 +233,10 @@ type CommonProperties struct { // Contributing api surface of the stub module. Is not visible to bp modules, and should // only be set for stub submodules generated by the java_sdk_library Stub_contributing_api *string `blueprint:"mutated"` + + // If true, enable the "ApiMapper" tool on the output jar. "ApiMapper" is a tool to inject + // bytecode to log API calls. + ApiMapper bool `blueprint:"mutated"` } // Properties that are specific to device modules. Host module factories should not add these when @@ -739,6 +743,10 @@ func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool { ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir()) } +func (j *Module) shouldApiMapper() bool { + return j.properties.ApiMapper +} + func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool { return j.properties.Supports_static_instrumentation && j.shouldInstrument(ctx) && @@ -767,6 +775,10 @@ func (j *Module) setInstrument(value bool) { j.properties.Instrument = value } +func (j *Module) setApiMapper(value bool) { + j.properties.ApiMapper = value +} + func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version)) } @@ -1598,6 +1610,18 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath outputFile = ravenizerOutput } + if j.shouldApiMapper() { + inputFile := outputFile + apiMapperFile := android.PathForModuleOut(ctx, "apimapper", jarName) + ctx.Build(pctx, android.BuildParams{ + Rule: apimapper, + Description: "apimapper", + Input: inputFile, + Output: apiMapperFile, + }) + outputFile = apiMapperFile + } + // Check package restrictions if necessary. if len(j.properties.Permitted_packages) > 0 { // Time stamp file created by the package check rule. diff --git a/java/builder.go b/java/builder.go index 49207e535..81b0feb75 100644 --- a/java/builder.go +++ b/java/builder.go @@ -265,6 +265,13 @@ var ( }, ) + apimapper = pctx.AndroidStaticRule("apimapper", + blueprint.RuleParams{ + Command: "${apimapper} --in-jar $in --out-jar $out", + CommandDeps: []string{"${apimapper}"}, + }, + ) + zipalign = pctx.AndroidStaticRule("zipalign", blueprint.RuleParams{ Command: "if ! ${config.ZipAlign} -c -p 4 $in > /dev/null; then " + @@ -315,6 +322,7 @@ func init() { pctx.HostBinToolVariable("aconfig", "aconfig") pctx.HostBinToolVariable("ravenizer", "ravenizer") + pctx.HostBinToolVariable("apimapper", "apimapper") pctx.HostBinToolVariable("keep-flagged-apis", "keep-flagged-apis") }