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

Commit 3adf3c52 authored by Anton Hansson's avatar Anton Hansson
Browse files

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
Merged-In: I955cae720e6f1382936836ee1d8fb11003f51b7d
Change-Id: I955cae720e6f1382936836ee1d8fb11003f51b7d
parent d446d282
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -153,6 +153,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

@@ -207,6 +208,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
}
+28 −4
Original line number Diff line number Diff line
@@ -550,6 +550,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 {
@@ -585,6 +588,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())
}
@@ -739,6 +743,8 @@ const (
	apiTxtComponentName = "api.txt"

	removedApiTxtComponentName = "removed-api.txt"

	annotationsComponentName = "annotations.zip"
)

// A regular expression to match tags that reference a specific stubs component.
@@ -757,7 +763,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))
@@ -765,9 +771,7 @@ var tagSplitter = func() *regexp.Regexp {

// For OutputFileProducer interface
//
// .<scope>.stubs.source
// .<scope>.api.txt
// .<scope>.removed-api.txt
// .<scope>.<component name>, 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]
@@ -794,6 +798,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)
@@ -1888,6 +1897,9 @@ type sdkLibraryScopeProperties struct {

	// The removed.txt
	Removed_api *string `android:"path"`

	// Annotation zip
	Annotations *string `android:"path"`
}

type sdkLibraryImportProperties struct {
@@ -2189,6 +2201,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)
	}
@@ -2529,6 +2542,7 @@ type scopeProperties struct {
	StubsSrcJar    android.Path
	CurrentApiFile android.Path
	RemovedApiFile android.Path
	AnnotationsZip android.Path
	SdkVersion     string
}

@@ -2554,6 +2568,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
		}
	}
@@ -2618,6 +2636,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)
			}
+29 −1
Original line number Diff line number Diff line
@@ -247,12 +247,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"],
@@ -265,6 +290,7 @@ func TestJavaSdkLibrary_UseSourcesFromAnotherSdkLibrary(t *testing.T) {
		java_library {
			name: "bar",
			srcs: ["b.java", ":foo{.public.stubs.source}"],
			java_resources: [":foo{.public.annotations.zip}"],
		}
		`)
}
@@ -328,6 +354,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",
			},
		}

@@ -337,6 +364,7 @@ func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) {
			java_resources: [
				":foo{.public.api.txt}",
				":foo{.public.removed-api.txt}",
				":foo{.public.annotations.zip}",
			],
		}
		`)
+1 −0
Original line number Diff line number Diff line
@@ -280,6 +280,7 @@ func gatherRequiredDepsForTest() string {
		"kotlin-stdlib-jdk7",
		"kotlin-stdlib-jdk8",
		"kotlin-annotations",
		"stub-annotations",
	}

	for _, extra := range extraModules {
+49 −0
Original line number Diff line number Diff line
@@ -1204,6 +1204,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 {