From d78eb76f6428b471a57451cc80574019c89d3409 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Tue, 21 Sep 2021 15:25:12 +0100 Subject: [PATCH] Add annotations.zip support to java_sdk_library The annotations zip file is produced by the "main" sdk build and is primarily consumed by android studio. In order to support building the main SDK without requiring the sources of all modules, we are adding module SDK artifacts that allows reconstructing these outputs. The annotations zip contains XML files which should be fairly easy to merge from all the individual parts. Bug: 187397779 Test: unit tests in this CL Test: m sdkextensions-sdk and inspect output Change-Id: I955cae720e6f1382936836ee1d8fb11003f51b7d --- java/droidstubs.go | 5 ++++ java/sdk_library.go | 32 ++++++++++++++++++++++---- java/sdk_library_test.go | 30 +++++++++++++++++++++++- java/testing.go | 1 + sdk/java_sdk_test.go | 49 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 5 deletions(-) diff --git a/java/droidstubs.go b/java/droidstubs.go index ec1b04a06..7fd88fceb 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -156,6 +156,7 @@ type ApiStubsSrcProvider interface { // Provider of information about API stubs, used by java_sdk_library. type ApiStubsProvider interface { + AnnotationsZip() android.Path ApiFilePath RemovedApiFilePath() android.Path @@ -210,6 +211,10 @@ func (d *Droidstubs) OutputFiles(tag string) (android.Paths, error) { } } +func (d *Droidstubs) AnnotationsZip() android.Path { + return d.annotationsZip +} + func (d *Droidstubs) ApiFilePath() android.Path { return d.apiFilePath } diff --git a/java/sdk_library.go b/java/sdk_library.go index 1d3907178..207a60033 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -547,6 +547,9 @@ type scopePaths struct { // The stubs source jar. stubsSrcJar android.OptionalPath + + // Extracted annotations. + annotationsZip android.OptionalPath } func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error { @@ -582,6 +585,7 @@ func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, actio } func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider) { + paths.annotationsZip = android.OptionalPathForPath(provider.AnnotationsZip()) paths.currentApiFilePath = android.OptionalPathForPath(provider.ApiFilePath()) paths.removedApiFilePath = android.OptionalPathForPath(provider.RemovedApiFilePath()) } @@ -736,6 +740,8 @@ const ( apiTxtComponentName = "api.txt" removedApiTxtComponentName = "removed-api.txt" + + annotationsComponentName = "annotations.zip" ) // A regular expression to match tags that reference a specific stubs component. @@ -754,7 +760,7 @@ var tagSplitter = func() *regexp.Regexp { scopesRegexp := choice(allScopeNames...) // Regular expression to match one of the components. - componentsRegexp := choice(stubsSourceComponentName, apiTxtComponentName, removedApiTxtComponentName) + componentsRegexp := choice(stubsSourceComponentName, apiTxtComponentName, removedApiTxtComponentName, annotationsComponentName) // Regular expression to match any combination of one scope and one component. return regexp.MustCompile(fmt.Sprintf(`^\.(%s)\.(%s)$`, scopesRegexp, componentsRegexp)) @@ -762,9 +768,7 @@ var tagSplitter = func() *regexp.Regexp { // For OutputFileProducer interface // -// ..stubs.source -// ..api.txt -// ..removed-api.txt +// .., for all ComponentNames (for example: .public.removed-api.txt) func (c *commonToSdkLibraryAndImport) commonOutputFiles(tag string) (android.Paths, error) { if groups := tagSplitter.FindStringSubmatch(tag); groups != nil { scopeName := groups[1] @@ -791,6 +795,11 @@ func (c *commonToSdkLibraryAndImport) commonOutputFiles(tag string) (android.Pat if paths.removedApiFilePath.Valid() { return android.Paths{paths.removedApiFilePath.Path()}, nil } + + case annotationsComponentName: + if paths.annotationsZip.Valid() { + return android.Paths{paths.annotationsZip.Path()}, nil + } } return nil, fmt.Errorf("%s not available for api scope %s", component, scopeName) @@ -1884,6 +1893,9 @@ type sdkLibraryScopeProperties struct { // The removed.txt Removed_api *string `android:"path"` + + // Annotation zip + Annotations *string `android:"path"` } type sdkLibraryImportProperties struct { @@ -2197,6 +2209,7 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo } paths := module.getScopePathsCreateIfNeeded(apiScope) + paths.annotationsZip = android.OptionalPathForModuleSrc(ctx, scopeProperties.Annotations) paths.currentApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Current_api) paths.removedApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Removed_api) } @@ -2547,6 +2560,7 @@ type scopeProperties struct { StubsSrcJar android.Path CurrentApiFile android.Path RemovedApiFile android.Path + AnnotationsZip android.Path SdkVersion string } @@ -2572,6 +2586,10 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe if paths.removedApiFilePath.Valid() { properties.RemovedApiFile = paths.removedApiFilePath.Path() } + // The annotations zip is only available for modules that set annotations_enabled: true. + if paths.annotationsZip.Valid() { + properties.AnnotationsZip = paths.annotationsZip.Path() + } s.Scopes[apiScope] = properties } } @@ -2636,6 +2654,12 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo scopeSet.AddProperty("removed_api", removedApiSnapshotPath) } + if properties.AnnotationsZip != nil { + annotationsSnapshotPath := filepath.Join(scopeDir, ctx.Name()+"_annotations.zip") + ctx.SnapshotBuilder().CopyToSnapshot(properties.AnnotationsZip, annotationsSnapshotPath) + scopeSet.AddProperty("annotations", annotationsSnapshotPath) + } + if properties.SdkVersion != "" { scopeSet.AddProperty("sdk_version", properties.SdkVersion) } diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index d6c0946b1..be23536ea 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -248,12 +248,37 @@ func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) { } } -func TestJavaSdkLibrary_UseSourcesFromAnotherSdkLibrary(t *testing.T) { +func TestJavaSdkLibrary_AccessOutputFiles(t *testing.T) { android.GroupFixturePreparers( prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("foo"), ).RunTestWithBp(t, ` + java_sdk_library { + name: "foo", + srcs: ["a.java"], + api_packages: ["foo"], + annotations_enabled: true, + public: { + enabled: true, + }, + } + java_library { + name: "bar", + srcs: ["b.java", ":foo{.public.stubs.source}"], + java_resources: [":foo{.public.annotations.zip}"], + } + `) +} + +func TestJavaSdkLibrary_AccessOutputFiles_NoAnnotations(t *testing.T) { + android.GroupFixturePreparers( + prepareForJavaTest, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + ). + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": path dependency ":foo{.public.annotations.zip}": annotations.zip not available for api scope public`)). + RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java"], @@ -266,6 +291,7 @@ func TestJavaSdkLibrary_UseSourcesFromAnotherSdkLibrary(t *testing.T) { java_library { name: "bar", srcs: ["b.java", ":foo{.public.stubs.source}"], + java_resources: [":foo{.public.annotations.zip}"], } `) } @@ -329,6 +355,7 @@ func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) { stub_srcs: ["a.java"], current_api: "api/current.txt", removed_api: "api/removed.txt", + annotations: "x/annotations.zip", }, } @@ -338,6 +365,7 @@ func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) { java_resources: [ ":foo{.public.api.txt}", ":foo{.public.removed-api.txt}", + ":foo{.public.annotations.zip}", ], } `) diff --git a/java/testing.go b/java/testing.go index a642753c4..99d55a054 100644 --- a/java/testing.go +++ b/java/testing.go @@ -300,6 +300,7 @@ func gatherRequiredDepsForTest() string { "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8", "kotlin-annotations", + "stub-annotations", } for _, extra := range extraModules { diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 9efb3a49a..43542cbdc 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -1205,6 +1205,55 @@ java_sdk_library_import { ) } +func TestSnapshotWithJavaSdkLibrary_AnnotationsZip(t *testing.T) { + result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, ` + sdk { + name: "mysdk", + java_sdk_libs: ["myjavalib"], + } + + java_sdk_library { + name: "myjavalib", + srcs: ["Test.java"], + sdk_version: "current", + shared_library: false, + annotations_enabled: true, + public: { + enabled: true, + }, + } + `) + + CheckSnapshot(t, result, "mysdk", "", + checkUnversionedAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_sdk_library_import { + name: "myjavalib", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + shared_library: false, + public: { + jars: ["sdk_library/public/myjavalib-stubs.jar"], + stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], + current_api: "sdk_library/public/myjavalib.txt", + removed_api: "sdk_library/public/myjavalib-removed.txt", + annotations: "sdk_library/public/myjavalib_annotations.zip", + sdk_version: "current", + }, +} + `), + checkAllCopyRules(` +.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar +.intermediates/myjavalib.stubs.source/android_common/metalava/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt +.intermediates/myjavalib.stubs.source/android_common/metalava/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt +.intermediates/myjavalib.stubs.source/android_common/metalava/myjavalib.stubs.source_annotations.zip -> sdk_library/public/myjavalib_annotations.zip + `), + checkMergeZips(".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip"), + ) +} + func TestSnapshotWithJavaSdkLibrary_CompileDex(t *testing.T) { result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, ` sdk {