Export stub sources as part of the java_sdk_library

Minor refactoring of checkMergeZip(string) -> checkMergeZips(...string)
to allow testing of multiple merge zips.

Bug: 153443117
Test: m nothing
Merged-In: I8db00f611ced15f8476ba16f2834a72e8c913596
Change-Id: I8db00f611ced15f8476ba16f2834a72e8c913596
(cherry picked from commit 3d1248ceb6d8c1ce7d2f3f2e62f98700f668e4dc)
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 62675c4..90f143a 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -331,10 +331,17 @@
 	apiToCheck.Removed_api_file = nil
 }
 
+// Used by xsd_config
 type ApiFilePath interface {
 	ApiFilePath() android.Path
 }
 
+// Provider of information about API stubs, used by java_sdk_library.
+type ApiStubsProvider interface {
+	ApiFilePath
+	StubsSrcJar() android.Path
+}
+
 //
 // Javadoc
 //
@@ -1180,6 +1187,10 @@
 	return d.apiFilePath
 }
 
+func (d *Droidstubs) StubsSrcJar() android.Path {
+	return d.stubsSrcJar
+}
+
 func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
 	d.Javadoc.addDeps(ctx)
 
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 1ad5132..85d5bd3 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -243,6 +243,7 @@
 	stubsHeaderPath android.Paths
 	stubsImplPath   android.Paths
 	apiFilePath     android.Path
+	stubsSrcJar     android.Path
 }
 
 // Common code between sdk library and sdk library import
@@ -329,11 +330,12 @@
 				scopePaths.stubsImplPath = lib.ImplementationJars()
 			}
 		}
-		if doc, ok := to.(ApiFilePath); ok {
+		if doc, ok := to.(ApiStubsProvider); ok {
 			if scopeTag, ok := tag.(scopeDependencyTag); ok {
 				apiScope := scopeTag.apiScope
 				scopePaths := module.getScopePaths(apiScope)
 				scopePaths.apiFilePath = doc.ApiFilePath()
+				scopePaths.stubsSrcJar = doc.StubsSrcJar()
 			} else {
 				ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
 			}
@@ -821,6 +823,9 @@
 
 	// List of shared java libs that this module has dependencies to
 	Libs []string
+
+	// The stub sources.
+	Stub_srcs []string `android:"path"`
 }
 
 type sdkLibraryImportProperties struct {
@@ -922,6 +927,8 @@
 		}
 
 		module.createJavaImportForStubs(mctx, apiScope, scopeProperties)
+
+		module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties)
 	}
 
 	javaSdkLibraries := javaSdkLibraries(mctx.Config())
@@ -966,6 +973,16 @@
 	mctx.CreateModule(ImportFactory, &props)
 }
 
+func (module *sdkLibraryImport) createPrebuiltStubsSources(mctx android.LoadHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
+	props := struct {
+		Name *string
+		Srcs []string
+	}{}
+	props.Name = proptools.StringPtr(apiScope.docsModuleName(module.BaseModuleName()))
+	props.Srcs = scopeProperties.Stub_srcs
+	mctx.CreateModule(PrebuiltStubsSourcesFactory, &props)
+}
+
 func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
 	for apiScope, scopeProperties := range module.scopeProperties {
 		if len(scopeProperties.Jars) == 0 {
@@ -1164,11 +1181,15 @@
 
 	// Additional libraries that the exported stubs libraries depend upon.
 	Libs []string
+
+	// The Java stubs source files.
+	Stub_srcs []string
 }
 
 type scopeProperties struct {
-	Jars       android.Paths
-	SdkVersion string
+	Jars        android.Paths
+	StubsSrcJar android.Path
+	SdkVersion  string
 }
 
 func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
@@ -1182,6 +1203,7 @@
 			properties := scopeProperties{}
 			properties.Jars = jars
 			properties.SdkVersion = apiScope.sdkVersion
+			properties.StubsSrcJar = paths.stubsSrcJar
 			s.Scopes[apiScope] = properties
 		}
 	}
@@ -1194,14 +1216,22 @@
 		if properties, ok := s.Scopes[apiScope]; ok {
 			scopeSet := propertySet.AddPropertySet(apiScope.name)
 
+			scopeDir := filepath.Join("sdk_library", s.OsPrefix(), apiScope.name)
+
 			var jars []string
 			for _, p := range properties.Jars {
-				dest := filepath.Join("sdk_library", s.OsPrefix(), apiScope.name, ctx.Name()+"-stubs.jar")
+				dest := filepath.Join(scopeDir, ctx.Name()+"-stubs.jar")
 				ctx.SnapshotBuilder().CopyToSnapshot(p, dest)
 				jars = append(jars, dest)
 			}
 			scopeSet.AddProperty("jars", jars)
 
+			// Merge the stubs source jar into the snapshot zip so that when it is unpacked
+			// the source files are also unpacked.
+			snapshotRelativeDir := filepath.Join(scopeDir, ctx.Name()+"_stub_sources")
+			ctx.SnapshotBuilder().UnzipToSnapshot(properties.StubsSrcJar, snapshotRelativeDir)
+			scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir})
+
 			if properties.SdkVersion != "" {
 				scopeSet.AddProperty("sdk_version", properties.SdkVersion)
 			}