Move validation from FindDeapexerProviderForModule to rdeps

FindDeapexerProviderForModule raises an exception if multiple apexes in
the tree has an export dep on the java module. In prepartation to
support multiple prebuilts, move this error check out of
FindDeapexerProviderForModule and into rdeps. i.e. raise an exception
only if an rdep calls DexJarBuildPath

- This should be a no-op for now.
- In the short-term future, a java import module will be allowed to have
  multiple deapexers. An error will be raised if anyone actually tries
  to depend on the dexjar
- In the long-term future, this function will be removed. All processing
  will be done at the prebuilt apex level and not at the prebuilt java
  library level

Since this check now happens in the moduleCtx of rdeps, add some
additional props to unit tests to ensure that it does not exit early on
unrelated validation checks (e.g. hidden_api prop is not set)

Test: go test ./apex ./java
Bug: 308790457

Change-Id: I3323d993c1ea8f43305834cae8e65b6fe41dfefd
diff --git a/android/deapexer.go b/android/deapexer.go
index de933d1..fb2073d 100644
--- a/android/deapexer.go
+++ b/android/deapexer.go
@@ -15,6 +15,7 @@
 package android
 
 import (
+	"fmt"
 	"strings"
 
 	"github.com/google/blueprint"
@@ -146,10 +147,16 @@
 
 // FindDeapexerProviderForModule searches through the direct dependencies of the current context
 // module for a DeapexerTag dependency and returns its DeapexerInfo. If a single nonambiguous
-// deapexer module isn't found then errors are reported with ctx.ModuleErrorf and nil is returned.
-func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo {
+// deapexer module isn't found then it returns it an error
+// clients should check the value of error and call ctx.ModuleErrof if a non nil error is received
+func FindDeapexerProviderForModule(ctx ModuleContext) (*DeapexerInfo, error) {
 	var di *DeapexerInfo
+	var err error
 	ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) {
+		if err != nil {
+			// An err has been found. Do not visit further.
+			return
+		}
 		c, _ := OtherModuleProvider(ctx, m, DeapexerProvider)
 		p := &c
 		if di != nil {
@@ -159,17 +166,18 @@
 				di = selected
 				return
 			}
-			ctx.ModuleErrorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s",
-				di.ApexModuleName(), p.ApexModuleName())
+			err = fmt.Errorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s", di.ApexModuleName(), p.ApexModuleName())
 		}
 		di = p
 	})
+	if err != nil {
+		return nil, err
+	}
 	if di != nil {
-		return di
+		return di, nil
 	}
 	ai, _ := ModuleProvider(ctx, ApexInfoProvider)
-	ctx.ModuleErrorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName)
-	return nil
+	return nil, fmt.Errorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName)
 }
 
 // removeCompressedApexSuffix removes the _compressed suffix from the name if present.
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 1ced393..6c7dabc 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -8432,6 +8432,13 @@
 		prebuilt_bootclasspath_fragment {
 			name: "my-bootclasspath-fragment",
 			apex_available: ["com.android.myapex"],
+			hidden_api: {
+				annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+				metadata: "my-bootclasspath-fragment/metadata.csv",
+				index: "my-bootclasspath-fragment/index.csv",
+				stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+				all_flags: "my-bootclasspath-fragment/all-flags.csv",
+			},
 			%s
 		}
 	`
@@ -8453,6 +8460,7 @@
 				public: {
 					jars: ["libbar.jar"],
 				},
+				shared_library: false,
 				apex_available: ["com.android.myapex"],
 			}
 		`)
@@ -8468,6 +8476,7 @@
 				public: {
 					jars: ["libbar.jar"],
 				},
+				shared_library: false,
 				apex_available: ["com.android.myapex"],
 			}
 		`)
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 4c44678..b13ecc2 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -193,7 +193,10 @@
 	}
 	// Use apex_name to determine the api domain of this prebuilt apex
 	apexName := p.ApexVariationName()
-	di := android.FindDeapexerProviderForModule(ctx)
+	di, err := android.FindDeapexerProviderForModule(ctx)
+	if err != nil {
+		ctx.ModuleErrorf(err.Error())
+	}
 	dc := dexpreopt.GetGlobalConfig(ctx)
 	systemServerJarList := dc.AllApexSystemServerJars(ctx)
 
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index d2bb523..83030b5 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -240,7 +240,8 @@
 	sourceOnlyProperties SourceOnlyBootclasspathProperties
 
 	// Path to the boot image profile.
-	profilePath android.WritablePath
+	profilePath    android.WritablePath
+	profilePathErr error
 }
 
 // commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
@@ -1065,8 +1066,11 @@
 		return nil
 	}
 
-	di := android.FindDeapexerProviderForModule(ctx)
-	if di == nil {
+	di, err := android.FindDeapexerProviderForModule(ctx)
+	if err != nil {
+		// An error was found, possibly due to multiple apexes in the tree that export this library
+		// Defer the error till a client tries to call getProfilePath
+		module.profilePathErr = err
 		return nil // An error has been reported by FindDeapexerProviderForModule.
 	}
 
@@ -1074,6 +1078,9 @@
 }
 
 func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path {
+	if b.profilePathErr != nil {
+		panic(b.profilePathErr.Error())
+	}
 	return b.profilePath
 }
 
diff --git a/java/java.go b/java/java.go
index 630318e..51e8c34 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2100,6 +2100,7 @@
 
 	// output file containing classes.dex and resources
 	dexJarFile        OptionalDexJarPath
+	dexJarFileErr     error
 	dexJarInstallFile android.Path
 
 	combinedClasspathFile android.Path
@@ -2250,9 +2251,12 @@
 		ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
 		if ai.ForPrebuiltApex {
 			// Get the path of the dex implementation jar from the `deapexer` module.
-			di := android.FindDeapexerProviderForModule(ctx)
-			if di == nil {
-				return // An error has been reported by FindDeapexerProviderForModule.
+			di, err := android.FindDeapexerProviderForModule(ctx)
+			if err != nil {
+				// An error was found, possibly due to multiple apexes in the tree that export this library
+				// Defer the error till a client tries to call DexJarBuildPath
+				j.dexJarFileErr = err
+				return
 			}
 			dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(j.BaseModuleName())
 			if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
@@ -2375,6 +2379,9 @@
 }
 
 func (j *Import) DexJarBuildPath() OptionalDexJarPath {
+	if j.dexJarFileErr != nil {
+		panic(j.dexJarFileErr.Error())
+	}
 	return j.dexJarFile
 }
 
diff --git a/java/sdk_library.go b/java/sdk_library.go
index a634b17..38bd301 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -2378,7 +2378,8 @@
 	xmlPermissionsFileModule *sdkLibraryXml
 
 	// Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
-	dexJarFile OptionalDexJarPath
+	dexJarFile    OptionalDexJarPath
+	dexJarFileErr error
 
 	// Expected install file path of the source module(sdk_library)
 	// or dex implementation jar obtained from the prebuilt_apex, if any.
@@ -2687,9 +2688,12 @@
 		ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
 		if ai.ForPrebuiltApex {
 			// Get the path of the dex implementation jar from the `deapexer` module.
-			di := android.FindDeapexerProviderForModule(ctx)
-			if di == nil {
-				return // An error has been reported by FindDeapexerProviderForModule.
+			di, err := android.FindDeapexerProviderForModule(ctx)
+			if err != nil {
+				// An error was found, possibly due to multiple apexes in the tree that export this library
+				// Defer the error till a client tries to call DexJarBuildPath
+				module.dexJarFileErr = err
+				return
 			}
 			dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(module.BaseModuleName())
 			if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
@@ -2751,6 +2755,9 @@
 func (module *SdkLibraryImport) DexJarBuildPath() OptionalDexJarPath {
 	// The dex implementation jar extracted from the .apex file should be used in preference to the
 	// source.
+	if module.dexJarFileErr != nil {
+		panic(module.dexJarFileErr.Error())
+	}
 	if module.dexJarFile.IsSet() {
 		return module.dexJarFile
 	}