Add temporary restriction on hidden API processing

Hidden API processing of a bootclasspath_fragment requires the fragment
provides information, such as dependencies on other fragments and flag
files to override the default flags. Failing to do so will cause hidden
API generation to either fail or to generate different flags to that
generated by the hidden API processing done by platform_bootclasspath
which will cause the build to fail.

Previously, this was handled by only performing hidden API processing
for those modules that provide stub libs and relied on there only being
bootclasspath_fragments defined for ART (which already supports hidden
API processing), and Conscrypt and I18n neither of which provide stubs.
Unfortunately, that can no longer be relied upon due to a couple of
recent changes:
1. A java_sdk_library in a bootclasspath_fragment's content property is
   automatically treated a stub library. That avoids duplication for
   most bootclasspath_fragments that provide the implementation and
   stub libraries through the same java_sdk_library. It does not affect
   either ART, conscrypt or i18n as they all define the implementation
   separately to the stubs.

2. bootclasspath_fragment modules have been defined for a number of
   android modules as they are needed for reasons other than hidden API
   processing.

In combination this meant that rules to perform hidden API processing
were being created but they were not currently being used which is
good because they fail.

However, adding the fragment to the platform-bootclasspath will cause
those rules to be used as the platform_bootclasspath module performs a
consistency check on the hidden API flags generated by each of the
fragments to ensure that they are consistent with those it generates
itself.

The dynamic bootclasspath work will need to add fragments to the
platform_bootclasspath and without this change that would be blocked
until all fragments had been switched to generating hidden API flags
properly.

This change adds a new fragments property to the bootclasspath and
disables hidden API processing for everything other than ART and tests
if the fragments property or stub libs is empty.

Bug: 179354495
Test: - Before making this change.
      - Add com.android.os.statds-bootclasspath-fragment to platform-bootclasspath.fragments
      m out/soong/hiddenapi/hiddenapi-flags.csv
      - hidden API processing fails in statsd as it cannot find java.lang.Object.
      - After making this change, run the above command again and it should pass.

Change-Id: Ifbb362f8fcfb2c06595fbd5ae39421b536e329ef
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 16aa5e2..b6b877b 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -112,6 +112,11 @@
 	Coverage BootclasspathFragmentCoverageAffectedProperties
 
 	Hidden_api HiddenAPIFlagFileProperties
+
+	// Properties that allow a fragment to depend on other fragments. This is needed for hidden API
+	// processing as it needs access to all the classes used by a fragment including those provided
+	// by other fragments.
+	BootclasspathFragmentsDepsProperties
 }
 
 type BootclasspathFragmentModule struct {
@@ -448,12 +453,54 @@
 	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) {
 
+	// 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
+	}
+
 	// Convert the kind specific lists of modules into kind specific lists of jars.
 	stubJarsByKind := hiddenAPIGatherStubLibDexJarPaths(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(stubJarsByKind) == 0 {
+		return
+	}
+
 	// Store the information for use by other modules.
 	bootclasspathApiInfo := bootclasspathApiInfo{stubJarsByKind: stubJarsByKind}
 	ctx.SetProvider(bootclasspathApiInfoProvider, bootclasspathApiInfo)
@@ -474,15 +521,6 @@
 // produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files)
 // for the fragment.
 func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
-	// If no stubs have been provided then don't perform hidden API processing. This is a temporary
-	// workaround to avoid existing bootclasspath_fragments that do not provide stubs breaking the
-	// build.
-	// TODO(b/179354495): Remove this workaround.
-	if len(stubJarsByKind) == 0 {
-		// Nothing to do.
-		return
-	}
-
 	// Generate the rules to create the hidden API flags and update the supplied flagFileInfo with the
 	// paths to the created files.
 	hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx, contents, stubJarsByKind, flagFileInfo)