Move hiddenapi singleton rules to Soong

Move the rules that build hiddenapi-stubs-flags.txt,
hiddenapi-flags.csv and hiddenapi-greylist.csv into Soong.

Bug: 123645297
Test: m checkbuild
Test: m UNSAFE_DISABLE_HIDDEN_API_FLAGS=true
Change-Id: I90bf58710f6153ee8565994f799d3ec5699bc7fa
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index c7eac73..f199051 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -16,13 +16,11 @@
 
 import (
 	"path/filepath"
-	"sort"
-	"strings"
-	"sync"
 
 	"github.com/google/blueprint"
 
 	"android/soong/android"
+	"android/soong/java/config"
 )
 
 var hiddenAPIGenerateCSVRule = pctx.AndroidStaticRule("hiddenAPIGenerateCSV", blueprint.RuleParams{
@@ -30,10 +28,60 @@
 	CommandDeps: []string{"${config.Class2Greylist}"},
 }, "outFlag", "stubAPIFlags")
 
-func hiddenAPIGenerateCSV(ctx android.ModuleContext, classesJar android.Path) {
-	flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv")
-	metadataCSV := android.PathForModuleOut(ctx, "hiddenapi", "metadata.csv")
-	stubFlagsCSV := &hiddenAPIPath{ctx.Config().HiddenAPIStubFlags()}
+type hiddenAPI struct {
+	flagsCSVPath    android.Path
+	metadataCSVPath android.Path
+	bootDexJarPath  android.Path
+}
+
+func (h *hiddenAPI) flagsCSV() android.Path {
+	return h.flagsCSVPath
+}
+
+func (h *hiddenAPI) metadataCSV() android.Path {
+	return h.metadataCSVPath
+}
+
+func (h *hiddenAPI) bootDexJar() android.Path {
+	return h.bootDexJarPath
+}
+
+type hiddenAPIIntf interface {
+	flagsCSV() android.Path
+	metadataCSV() android.Path
+	bootDexJar() android.Path
+}
+
+var _ hiddenAPIIntf = (*hiddenAPI)(nil)
+
+func (h *hiddenAPI) hiddenAPI(ctx android.ModuleContext, dexJar android.ModuleOutPath, implementationJar android.Path,
+	uncompressDex bool) android.ModuleOutPath {
+
+	if !ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+		isBootJar := inList(ctx.ModuleName(), ctx.Config().BootJars())
+		if isBootJar || inList(ctx.ModuleName(), config.HiddenAPIExtraAppUsageJars) {
+			// Derive the greylist from classes jar.
+			flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv")
+			metadataCSV := android.PathForModuleOut(ctx, "hiddenapi", "metadata.csv")
+			hiddenAPIGenerateCSV(ctx, flagsCSV, metadataCSV, implementationJar)
+			h.flagsCSVPath = flagsCSV
+			h.metadataCSVPath = metadataCSV
+		}
+		if isBootJar {
+			hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", ctx.ModuleName()+".jar")
+			h.bootDexJarPath = dexJar
+			hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex)
+			dexJar = hiddenAPIJar
+		}
+	}
+
+	return dexJar
+}
+
+func hiddenAPIGenerateCSV(ctx android.ModuleContext, flagsCSV, metadataCSV android.WritablePath,
+	classesJar android.Path) {
+
+	stubFlagsCSV := hiddenAPISingletonPaths(ctx).stubFlags
 
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        hiddenAPIGenerateCSVRule,
@@ -59,7 +107,6 @@
 		},
 	})
 
-	hiddenAPISaveCSVOutputs(ctx, flagsCSV, metadataCSV)
 }
 
 var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", blueprint.RuleParams{
@@ -78,10 +125,10 @@
 	},
 }, "flagsCsv", "hiddenapiFlags", "tmpDir", "soongZipFlags")
 
-func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, dexInput android.WritablePath,
+func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, dexInput android.Path,
 	uncompressDex bool) {
 
-	flagsCsv := &hiddenAPIPath{ctx.Config().HiddenAPIFlags()}
+	flagsCSV := hiddenAPISingletonPaths(ctx).flags
 
 	// The encode dex rule requires unzipping and rezipping the classes.dex files, ensure that if it was uncompressed
 	// in the input it stays uncompressed in the output.
@@ -105,9 +152,9 @@
 		Description: "hiddenapi encode dex",
 		Input:       dexInput,
 		Output:      tmpOutput,
-		Implicit:    flagsCsv,
+		Implicit:    flagsCSV,
 		Args: map[string]string{
-			"flagsCsv":       flagsCsv.String(),
+			"flagsCsv":       flagsCSV.String(),
 			"tmpDir":         tmpDir.String(),
 			"soongZipFlags":  soongZipFlags,
 			"hiddenapiFlags": hiddenapiFlags,
@@ -117,57 +164,6 @@
 	if uncompressDex {
 		TransformZipAlign(ctx, output, tmpOutput)
 	}
-
-	hiddenAPISaveDexInputs(ctx, dexInput)
-}
-
-var hiddenAPIOutputsKey = android.NewOnceKey("hiddenAPIOutputsKey")
-
-var hiddenAPIOutputsLock sync.Mutex
-
-func hiddenAPIGetOutputs(config android.Config) (*android.Paths, *android.Paths, *android.Paths) {
-	type threePathsPtrs [3]*android.Paths
-	s := config.Once(hiddenAPIOutputsKey, func() interface{} {
-		return threePathsPtrs{new(android.Paths), new(android.Paths), new(android.Paths)}
-	}).(threePathsPtrs)
-	return s[0], s[1], s[2]
-}
-
-func hiddenAPISaveCSVOutputs(ctx android.ModuleContext, flagsCSV, metadataCSV android.Path) {
-	flagsCSVList, metadataCSVList, _ := hiddenAPIGetOutputs(ctx.Config())
-
-	hiddenAPIOutputsLock.Lock()
-	defer hiddenAPIOutputsLock.Unlock()
-
-	*flagsCSVList = append(*flagsCSVList, flagsCSV)
-	*metadataCSVList = append(*metadataCSVList, metadataCSV)
-}
-
-func hiddenAPISaveDexInputs(ctx android.ModuleContext, dexInput android.Path) {
-	_, _, dexInputList := hiddenAPIGetOutputs(ctx.Config())
-
-	hiddenAPIOutputsLock.Lock()
-	defer hiddenAPIOutputsLock.Unlock()
-
-	*dexInputList = append(*dexInputList, dexInput)
-}
-
-func init() {
-	android.RegisterMakeVarsProvider(pctx, hiddenAPIMakeVars)
-}
-
-func hiddenAPIMakeVars(ctx android.MakeVarsContext) {
-	flagsCSVList, metadataCSVList, dexInputList := hiddenAPIGetOutputs(ctx.Config())
-
-	export := func(name string, paths *android.Paths) {
-		s := paths.Strings()
-		sort.Strings(s)
-		ctx.Strict(name, strings.Join(s, " "))
-	}
-
-	export("SOONG_HIDDENAPI_FLAGS", flagsCSVList)
-	export("SOONG_HIDDENAPI_GREYLIST_METADATA", metadataCSVList)
-	export("SOONG_HIDDENAPI_DEX_INPUTS", dexInputList)
 }
 
 type hiddenAPIPath struct {