Fix hidden API flags in com.android.i18n

Change 70cfdff3da2ea07cd5cb7f7b91474f6fa0c248e5 changed the hidden API
flags in com.android.i18n as it stopped the i18n-bootclasspath-fragment
from making the hidden API flag files available for use by
platform-bootclasspath.

This change fixes that by exporting the flag files even if hidden API
flag generation is skipped.

Bug: 179354495
Test: m com.android.i18 out/soong/hiddenapi/hiddenapi-flags.csv
      - make sure that the flags in
        packages/modules/RuntimeI18n/apex/hiddenapi/hiddenapi-max-target-o-low-priority.txt
        are reflected in the core-icu4j dex files in the apex.
Merged-In: I9b5c7c74bd996ab447bc0e0452da5fd49191a35d
Change-Id: I9b5c7c74bd996ab447bc0e0452da5fd49191a35d
(cherry picked from commit 62370923911827d0a9cf6103e47652f40ca2cd25)
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index cc4b0dd..1807ce7 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -501,73 +501,48 @@
 	return imageConfig
 }
 
-// canPerformHiddenAPIProcessing determines whether hidden API processing should be performed.
-//
-// A temporary workaround to avoid existing bootclasspath_fragments that do not provide the
-// appropriate information needed for hidden API processing breaking the build.
-// TODO(b/179354495): Remove this workaround.
-func (b *BootclasspathFragmentModule) canPerformHiddenAPIProcessing(ctx android.ModuleContext) bool {
-	// Hidden API processing is always enabled in tests.
-	if ctx.Config().TestProductVariables != nil {
-		return true
-	}
-	// A module that has fragments should have access to the information it needs in order to perform
-	// hidden API processing.
-	if len(b.properties.Fragments) != 0 {
-		return true
-	}
-
-	// The art bootclasspath fragment does not depend on any other fragments but already supports
-	// hidden API processing.
-	imageName := proptools.String(b.properties.Image_name)
-	if imageName == "art" {
-		return true
-	}
-
-	// Disable it for everything else.
-	return false
-}
-
 // generateHiddenAPIBuildActions generates all the hidden API related build rules.
 func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module) *HiddenAPIFlagOutput {
 
-	// A temporary workaround to avoid existing bootclasspath_fragments that do not provide the
-	// appropriate information needed for hidden API processing breaking the build.
-	if !b.canPerformHiddenAPIProcessing(ctx) {
-		// Nothing to do.
-		return nil
-	}
-
 	// Create hidden API input structure.
 	input := b.createHiddenAPIFlagInput(ctx, contents)
 
-	// Performing hidden API processing without stubs is not supported and it is unlikely to ever be
-	// required as the whole point of adding something to the bootclasspath fragment is to add it to
-	// the bootclasspath in order to be used by something else in the system. Without any stubs it
-	// cannot do that.
-	if len(input.StubDexJarsByKind) == 0 {
-		return nil
-	}
-
 	// Store the information for use by other modules.
 	bootclasspathApiInfo := bootclasspathApiInfo{stubJarsByKind: input.StubDexJarsByKind}
 	ctx.SetProvider(bootclasspathApiInfoProvider, bootclasspathApiInfo)
 
-	hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, contents)
+	var output *HiddenAPIFlagOutput
 
-	// Delegate the production of the hidden API all-flags.csv file to a module type specific method.
-	common := ctx.Module().(commonBootclasspathFragment)
-	output := common.produceHiddenAPIAllFlagsFile(ctx, hiddenAPIModules, input)
+	// Hidden API processing is conditional as a temporary workaround as not all
+	// bootclasspath_fragments provide the appropriate information needed for hidden API processing
+	// which leads to breakages of the build.
+	// TODO(b/179354495): Stop hidden API processing being conditional once all bootclasspath_fragment
+	//  modules have been updated to support it.
+	if input.canPerformHiddenAPIProcessing(ctx, b.properties) {
+		// Get the content modules that contribute to the hidden API processing.
+		hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, contents)
 
-	// Initialize a HiddenAPIInfo structure and provide it for use by other modules.
+		// Delegate the production of the hidden API all-flags.csv file to a module type specific method.
+		common := ctx.Module().(commonBootclasspathFragment)
+		output = common.produceHiddenAPIAllFlagsFile(ctx, hiddenAPIModules, input)
+	}
+
+	// Initialize a HiddenAPIInfo structure.
 	hiddenAPIInfo := HiddenAPIInfo{
-		// The monolithic hidden API processing needs access to the flag files from all the fragments.
+		// The monolithic hidden API processing needs access to the flag files that override the default
+		// flags from all the fragments whether or not they actually perform their own hidden API flag
+		// generation. That is because the monolithic hidden API processing uses those flag files to
+		// perform its own flag generation.
 		FlagFilesByCategory: input.FlagFilesByCategory,
+	}
 
+	if output != nil {
 		// The monolithic hidden API processing also needs access to all the output files produced by
 		// hidden API processing of this fragment.
-		HiddenAPIFlagOutput: *output,
+		hiddenAPIInfo.HiddenAPIFlagOutput = *output
 	}
+
+	//  Provide it for use by other modules.
 	ctx.SetProvider(HiddenAPIInfoProvider, hiddenAPIInfo)
 
 	return output
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index b8ffdd6..0bf39ff 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -20,6 +20,7 @@
 
 	"android/soong/android"
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/proptools"
 )
 
 // Contains support for processing hiddenAPI in a modular fashion.
@@ -395,6 +396,42 @@
 	return input
 }
 
+// canPerformHiddenAPIProcessing determines whether hidden API processing should be performed.
+//
+// A temporary workaround to avoid existing bootclasspath_fragments that do not provide the
+// appropriate information needed for hidden API processing breaking the build.
+// TODO(b/179354495): Remove this workaround.
+func (i *HiddenAPIFlagInput) canPerformHiddenAPIProcessing(ctx android.ModuleContext, properties bootclasspathFragmentProperties) bool {
+	// Performing hidden API processing without stubs is not supported and it is unlikely to ever be
+	// required as the whole point of adding something to the bootclasspath fragment is to add it to
+	// the bootclasspath in order to be used by something else in the system. Without any stubs it
+	// cannot do that.
+	if len(i.StubDexJarsByKind) == 0 {
+		return false
+	}
+
+	// Hidden API processing is always enabled in tests.
+	if ctx.Config().TestProductVariables != nil {
+		return true
+	}
+
+	// A module that has fragments should have access to the information it needs in order to perform
+	// hidden API processing.
+	if len(properties.Fragments) != 0 {
+		return true
+	}
+
+	// The art bootclasspath fragment does not depend on any other fragments but already supports
+	// hidden API processing.
+	imageName := proptools.String(properties.Image_name)
+	if imageName == "art" {
+		return true
+	}
+
+	// Disable it for everything else.
+	return false
+}
+
 // gatherStubLibInfo gathers information from the stub libs needed by hidden API processing from the
 // dependencies added in hiddenAPIAddStubLibDependencies.
 //
diff --git a/java/hiddenapi_monolithic.go b/java/hiddenapi_monolithic.go
index 147afce..a6bf8c7 100644
--- a/java/hiddenapi_monolithic.go
+++ b/java/hiddenapi_monolithic.go
@@ -70,11 +70,22 @@
 // append appends all the files from the supplied info to the corresponding files in this struct.
 func (i *MonolithicHiddenAPIInfo) append(other *HiddenAPIInfo) {
 	i.FlagsFilesByCategory.append(other.FlagFilesByCategory)
-	i.StubFlagsPaths = append(i.StubFlagsPaths, other.StubFlagsPath)
-	i.AnnotationFlagsPaths = append(i.AnnotationFlagsPaths, other.AnnotationFlagsPath)
-	i.MetadataPaths = append(i.MetadataPaths, other.MetadataPath)
-	i.IndexPaths = append(i.IndexPaths, other.IndexPath)
-	i.AllFlagsPaths = append(i.AllFlagsPaths, other.AllFlagsPath)
+
+	// The output may not be set if the bootclasspath_fragment has not yet been updated to support
+	// hidden API processing.
+	// TODO(b/179354495): Switch back to append once all bootclasspath_fragment modules have been
+	//  updated to support hidden API processing properly.
+	appendIfNotNil := func(paths android.Paths, path android.Path) android.Paths {
+		if path == nil {
+			return paths
+		}
+		return append(paths, path)
+	}
+	i.StubFlagsPaths = appendIfNotNil(i.StubFlagsPaths, other.StubFlagsPath)
+	i.AnnotationFlagsPaths = appendIfNotNil(i.AnnotationFlagsPaths, other.AnnotationFlagsPath)
+	i.MetadataPaths = appendIfNotNil(i.MetadataPaths, other.MetadataPath)
+	i.IndexPaths = appendIfNotNil(i.IndexPaths, other.IndexPath)
+	i.AllFlagsPaths = appendIfNotNil(i.AllFlagsPaths, other.AllFlagsPath)
 }
 
 // dedup removes duplicates in all the paths, while maintaining the order in which they were