From 031d8693b3dae7edaca2e5fef3d017ac2e67424d Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Fri, 12 Feb 2021 11:46:42 +0000 Subject: [PATCH] Allow explicitly specified additional annotations for hiddenapi Adds the hiddenapi_additional_annotations to allow a library to list the libraries that provided additional hiddenapi related annotations for a library. Modifies merge_csv.py so it can process multiple zip files at the same time and uses that to merge the embedded .uau files from a module and those it depends upon. Bug: 180102243 Test: m droid Verified that hiddenapi files (both aggregated ones and for the individual modules) are not affected by this change. Change-Id: I796520021c7357398a9e2a09f1029e4a578b05b3 --- java/hiddenapi.go | 28 ++++++++++++++++++++++++---- java/hiddenapi_singleton_test.go | 19 +++++++++++++++++++ java/java.go | 6 ++++++ scripts/hiddenapi/merge_csv.py | 21 +++++++++------------ 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/java/hiddenapi.go b/java/hiddenapi.go index 1651c1c6d..f8e41c458 100644 --- a/java/hiddenapi.go +++ b/java/hiddenapi.go @@ -221,13 +221,19 @@ func (h *hiddenAPI) hiddenAPIExtractInformation(ctx android.ModuleContext, dexJa return } + classesJars := android.Paths{classesJar} + ctx.VisitDirectDepsWithTag(hiddenApiAnnotationsTag, func(dep android.Module) { + javaInfo := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) + classesJars = append(classesJars, javaInfo.ImplementationJars...) + }) + stubFlagsCSV := hiddenAPISingletonPaths(ctx).stubFlags flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv") ctx.Build(pctx, android.BuildParams{ Rule: hiddenAPIGenerateCSVRule, Description: "hiddenapi flags", - Input: classesJar, + Inputs: classesJars, Output: flagsCSV, Implicit: stubFlagsCSV, Args: map[string]string{ @@ -241,7 +247,7 @@ func (h *hiddenAPI) hiddenAPIExtractInformation(ctx android.ModuleContext, dexJa ctx.Build(pctx, android.BuildParams{ Rule: hiddenAPIGenerateCSVRule, Description: "hiddenapi metadata", - Input: classesJar, + Inputs: classesJars, Output: metadataCSV, Implicit: stubFlagsCSV, Args: map[string]string{ @@ -255,8 +261,9 @@ func (h *hiddenAPI) hiddenAPIExtractInformation(ctx android.ModuleContext, dexJa rule := android.NewRuleBuilder(pctx, ctx) rule.Command(). BuiltTool("merge_csv"). - FlagWithInput("--zip_input=", classesJar). - FlagWithOutput("--output=", indexCSV) + Flag("--zip_input"). + FlagWithOutput("--output=", indexCSV). + Inputs(classesJars) rule.Build("merged-hiddenapi-index", "Merged Hidden API index") h.indexCSVPath = indexCSV @@ -335,3 +342,16 @@ func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, TransformZipAlign(ctx, output, tmpOutput) } } + +type hiddenApiAnnotationsDependencyTag struct { + blueprint.BaseDependencyTag +} + +// Tag used to mark dependencies on java_library instances that contains Java source files whose +// sole purpose is to provide additional hiddenapi annotations. +var hiddenApiAnnotationsTag hiddenApiAnnotationsDependencyTag + +// Mark this tag so dependencies that use it are excluded from APEX contents. +func (t hiddenApiAnnotationsDependencyTag) ExcludeFromApexContents() {} + +var _ android.ExcludeFromApexContentsTag = hiddenApiAnnotationsTag diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go index df825bb3a..4670d0311 100644 --- a/java/hiddenapi_singleton_test.go +++ b/java/hiddenapi_singleton_test.go @@ -82,6 +82,10 @@ func TestHiddenAPIIndexSingleton(t *testing.T) { name: "foo", srcs: ["a.java"], compile_dex: true, + + hiddenapi_additional_annotations: [ + "foo-hiddenapi-annotations", + ], } java_library { @@ -90,6 +94,12 @@ func TestHiddenAPIIndexSingleton(t *testing.T) { compile_dex: true, } + java_library { + name: "foo-hiddenapi-annotations", + srcs: ["a.java"], + compile_dex: true, + } + java_import { name: "foo", jars: ["a.jar"], @@ -112,6 +122,15 @@ func TestHiddenAPIIndexSingleton(t *testing.T) { .intermediates/foo/android_common/hiddenapi/index.csv `, indexRule) + + // Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that + // creates the index.csv file. + foo := ctx.ModuleForTests("foo", "android_common") + indexParams := foo.Output("hiddenapi/index.csv") + CheckHiddenAPIRuleInputs(t, ` +.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar +.intermediates/foo/android_common/javac/foo.jar +`, indexParams) } func TestHiddenAPISingletonWithPrebuilt(t *testing.T) { diff --git a/java/java.go b/java/java.go index 338140bbf..e14815e92 100644 --- a/java/java.go +++ b/java/java.go @@ -298,6 +298,9 @@ type CompilerProperties struct { // If true, package the kotlin stdlib into the jar. Defaults to true. Static_kotlin_stdlib *bool `android:"arch_variant"` + + // A list of java_library instances that provide additional hiddenapi annotations for the library. + Hiddenapi_additional_annotations []string } type CompilerDeviceProperties struct { @@ -840,6 +843,9 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { libDeps := ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...) ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...) + // Add dependency on libraries that provide additional hidden api annotations. + ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...) + if ctx.DeviceConfig().VndkVersion() != "" && ctx.Config().EnforceInterPartitionJavaSdkLibrary() { // Require java_sdk_library at inter-partition java dependency to ensure stable // interface between partitions. If inter-partition java_library dependency is detected, diff --git a/scripts/hiddenapi/merge_csv.py b/scripts/hiddenapi/merge_csv.py index 6a5b0e134..5ad61b2f6 100755 --- a/scripts/hiddenapi/merge_csv.py +++ b/scripts/hiddenapi/merge_csv.py @@ -26,7 +26,8 @@ from zipfile import ZipFile args_parser = argparse.ArgumentParser(description='Merge given CSV files into a single one.') args_parser.add_argument('--header', help='Comma separated field names; ' 'if missing determines the header from input files.') -args_parser.add_argument('--zip_input', help='ZIP archive with all CSV files to merge.') +args_parser.add_argument('--zip_input', help='Treat files as ZIP archives containing CSV files to merge.', + action="store_true") args_parser.add_argument('--output', help='Output file for merged CSV.', default='-', type=argparse.FileType('w')) args_parser.add_argument('files', nargs=argparse.REMAINDER) @@ -36,20 +37,16 @@ args = args_parser.parse_args() def dict_reader(input): return csv.DictReader(input, delimiter=',', quotechar='|') - -if args.zip_input and len(args.files) > 0: - raise ValueError('Expecting either a single ZIP with CSV files' - ' or a list of CSV files as input; not both.') - csv_readers = [] -if len(args.files) > 0: +if not(args.zip_input): for file in args.files: csv_readers.append(dict_reader(open(file, 'r'))) -elif args.zip_input: - with ZipFile(args.zip_input) as zip: - for entry in zip.namelist(): - if entry.endswith('.uau'): - csv_readers.append(dict_reader(io.TextIOWrapper(zip.open(entry, 'r')))) +else: + for file in args.files: + with ZipFile(file) as zip: + for entry in zip.namelist(): + if entry.endswith('.uau'): + csv_readers.append(dict_reader(io.TextIOWrapper(zip.open(entry, 'r')))) headers = set() if args.header: