Merge CSV files generated by UnsupportedAppUsageProcessor.

Flow:
1. Annotation processor generates a CSV file per class as a CLASS_OUTPUT resource.
2. hiddenapi.go extracts individual .csv files and merges them into an index.csv file per module.
3. hiddenapi_singleton.go merges individual index.csv files into a combined .csv file.

In a follow up hiddenapi-index.csv would replace unsupportedappusage_index.csv

Bug: 145132366
Change-Id: I87d92f9c8d4b1cc1df526fc576ee3c2101116b58
Test: diff unsupportedappusage_index.csv hiddenapi-index.csv
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 7850193..7e7e955 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -22,13 +22,15 @@
 
 func init() {
 	android.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory)
+	android.RegisterSingletonType("hiddenapi_index", hiddenAPIIndexSingletonFactory)
 	android.RegisterModuleType("hiddenapi_flags", hiddenAPIFlagsFactory)
 }
 
 type hiddenAPISingletonPathsStruct struct {
-	stubFlags android.OutputPath
 	flags     android.OutputPath
+	index     android.OutputPath
 	metadata  android.OutputPath
+	stubFlags android.OutputPath
 }
 
 var hiddenAPISingletonPathsKey = android.NewOnceKey("hiddenAPISingletonPathsKey")
@@ -39,9 +41,10 @@
 func hiddenAPISingletonPaths(ctx android.PathContext) hiddenAPISingletonPathsStruct {
 	return ctx.Config().Once(hiddenAPISingletonPathsKey, func() interface{} {
 		return hiddenAPISingletonPathsStruct{
-			stubFlags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-stub-flags.txt"),
 			flags:     android.PathForOutput(ctx, "hiddenapi", "hiddenapi-flags.csv"),
+			index:     android.PathForOutput(ctx, "hiddenapi", "hiddenapi-index.csv"),
 			metadata:  android.PathForOutput(ctx, "hiddenapi", "hiddenapi-greylist.csv"),
+			stubFlags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-stub-flags.txt"),
 		}
 	}).(hiddenAPISingletonPathsStruct)
 }
@@ -364,3 +367,45 @@
 	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
 	return module
 }
+
+func hiddenAPIIndexSingletonFactory() android.Singleton {
+	return &hiddenAPIIndexSingleton{}
+}
+
+type hiddenAPIIndexSingleton struct {
+	index android.Path
+}
+
+func (h *hiddenAPIIndexSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+	// Don't run any hiddenapi rules if UNSAFE_DISABLE_HIDDENAPI_FLAGS=true
+	if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+		return
+	}
+
+	indexes := android.Paths{}
+	ctx.VisitAllModules(func(module android.Module) {
+		if h, ok := module.(hiddenAPIIntf); ok {
+			if h.indexCSV() != nil {
+				indexes = append(indexes, h.indexCSV())
+			}
+		}
+	})
+
+	rule := android.NewRuleBuilder()
+	rule.Command().
+		BuiltTool(ctx, "merge_csv").
+		FlagWithArg("--header=", "signature,file,startline,startcol,endline,endcol,properties").
+		FlagWithOutput("--output=", hiddenAPISingletonPaths(ctx).index).
+		Inputs(indexes)
+	rule.Build(pctx, ctx, "singleton-merged-hiddenapi-index", "Singleton merged Hidden API index")
+
+	h.index = hiddenAPISingletonPaths(ctx).index
+}
+
+func (h *hiddenAPIIndexSingleton) MakeVars(ctx android.MakeVarsContext) {
+	if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+		return
+	}
+
+	ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_INDEX", h.index.String())
+}