Convert api.xml dist rules to Soong

...from make to support dist'ing *-api.xml files in soong-only builds.

Test: m droid dist --soong-only && ls out/dist/api.xml
Bug: 395162087
Bug: 394365683
Change-Id: I98e92423a107d24b04e6f6f0f96c23c24de01fa5
diff --git a/android/sdk_version.go b/android/sdk_version.go
index a9b88fb..fa3abaa 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -123,6 +123,31 @@
 	}
 }
 
+func JavaLibraryNameToSdkKind(name string) (SdkKind, bool) {
+	if name == SdkPublic.DefaultJavaLibraryName() {
+		return SdkPublic, true
+	}
+	if name == SdkSystem.DefaultJavaLibraryName() {
+		return SdkSystem, true
+	}
+	if name == SdkTest.DefaultJavaLibraryName() {
+		return SdkTest, true
+	}
+	if name == SdkTestFrameworksCore.DefaultJavaLibraryName() {
+		return SdkTestFrameworksCore, true
+	}
+	if name == SdkCore.DefaultJavaLibraryName() {
+		return SdkCore, true
+	}
+	if name == SdkModule.DefaultJavaLibraryName() {
+		return SdkModule, true
+	}
+	if name == SdkSystemServer.DefaultJavaLibraryName() {
+		return SdkSystemServer, true
+	}
+	return SdkInvalid, false
+}
+
 func (k SdkKind) DefaultExportableJavaLibraryName() string {
 	switch k {
 	case SdkPublic, SdkSystem, SdkTest, SdkModule, SdkSystemServer:
diff --git a/java/androidmk.go b/java/androidmk.go
index 4305360..c9de7e6 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -120,6 +120,14 @@
 					}
 				},
 			},
+			ExtraFooters: []android.AndroidMkExtraFootersFunc{
+				func(w io.Writer, name, prefix, moduleDir string) {
+					if library.apiXmlFile != nil {
+						fmt.Fprintf(w, "$(call declare-1p-target,%s,)\n", library.apiXmlFile.String())
+						fmt.Fprintf(w, "$(eval $(call copy-one-file,%s,$(TARGET_OUT_COMMON_INTERMEDIATES)/%s))\n", library.apiXmlFile.String(), library.apiXmlFile.Base())
+					}
+				},
+			},
 		})
 	}
 
diff --git a/java/builder.go b/java/builder.go
index 22dad10..ade9784 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -323,6 +323,13 @@
 			Command:     `${keep-flagged-apis} ${in} > ${out}`,
 			CommandDeps: []string{"${keep-flagged-apis}"},
 		})
+
+	generateApiXMLRule = pctx.AndroidStaticRule("generateApiXMLRule",
+		blueprint.RuleParams{
+			Command:     `${config.JavaCmd} ${config.JavaVmFlags} -Xmx4g -jar ${config.MetalavaJar} jar-to-jdiff ${in} ${out}`,
+			CommandDeps: []string{"${config.JavaCmd}", "${config.MetalavaJar}"},
+			Description: "Converting API file to XML",
+		})
 )
 
 func init() {
diff --git a/java/java.go b/java/java.go
index c204476..2db7b1e 100644
--- a/java/java.go
+++ b/java/java.go
@@ -828,6 +828,8 @@
 	combinedExportedProguardFlagsFile android.Path
 
 	InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.InstallPaths)
+
+	apiXmlFile android.WritablePath
 }
 
 var _ android.ApexModule = (*Library)(nil)
@@ -1155,6 +1157,8 @@
 	j.javaLibraryModuleInfoJSON(ctx)
 
 	buildComplianceMetadata(ctx)
+
+	j.createApiXmlFile(ctx)
 }
 
 func (j *Library) javaLibraryModuleInfoJSON(ctx android.ModuleContext) *android.ModuleInfoJSON {
@@ -1259,6 +1263,35 @@
 	}
 }
 
+var apiXMLGeneratingApiSurfaces = []android.SdkKind{
+	android.SdkPublic,
+	android.SdkSystem,
+	android.SdkModule,
+	android.SdkSystemServer,
+	android.SdkTest,
+}
+
+func (j *Library) createApiXmlFile(ctx android.ModuleContext) {
+	if kind, ok := android.JavaLibraryNameToSdkKind(ctx.ModuleName()); ok && android.InList(kind, apiXMLGeneratingApiSurfaces) {
+		scopePrefix := AllApiScopes.matchingScopeFromSdkKind(kind).apiFilePrefix
+		j.apiXmlFile = android.PathForModuleOut(ctx, fmt.Sprintf("%sapi.xml", scopePrefix))
+		ctx.Build(pctx, android.BuildParams{
+			Rule: generateApiXMLRule,
+			// LOCAL_SOONG_CLASSES_JAR
+			Input:  j.implementationAndResourcesJar,
+			Output: j.apiXmlFile,
+		})
+	}
+}
+
+var _ android.ModuleMakeVarsProvider = (*Library)(nil)
+
+func (j *Library) MakeVars(ctx android.MakeVarsModuleContext) {
+	if j.apiXmlFile != nil {
+		ctx.DistForGoal("dist_files", j.apiXmlFile)
+	}
+}
+
 const (
 	aidlIncludeDir   = "aidl"
 	javaDir          = "java"
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 07f0599..b6bac2d 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -316,6 +316,15 @@
 	return name
 }
 
+func (scopes apiScopes) matchingScopeFromSdkKind(kind android.SdkKind) *apiScope {
+	for _, scope := range scopes {
+		if scope.kind == kind {
+			return scope
+		}
+	}
+	return nil
+}
+
 var (
 	scopeByName    = make(map[string]*apiScope)
 	allScopeNames  []string