Convert hasCode and aaptLibs to use ModuleProxy.

Bug: 377723687
Test: Unit tests and compare the ninja and mk files generated.
Change-Id: Ie937a236f3c286fb5b2cd439614f09f7a85e884f
diff --git a/java/aar.go b/java/aar.go
index ed2fb7a..7c63a29 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -876,13 +876,15 @@
 	rroDirsDepSetBuilder := depset.NewBuilder[rroDir](depset.TOPOLOGICAL)
 	manifestsDepSetBuilder := depset.NewBuilder[android.Path](depset.TOPOLOGICAL)
 
-	ctx.VisitDirectDeps(func(module android.Module) {
+	ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
 		depTag := ctx.OtherModuleDependencyTag(module)
 
 		var exportPackage android.Path
-		aarDep, _ := module.(AndroidLibraryDependency)
-		if aarDep != nil {
-			exportPackage = aarDep.ExportPackage()
+		var aarDep *AndroidLibraryDependencyInfo
+		javaInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider)
+		if ok && javaInfo.AndroidLibraryDependencyInfo != nil {
+			aarDep = javaInfo.AndroidLibraryDependencyInfo
+			exportPackage = aarDep.ExportPackage
 		}
 
 		switch depTag {
@@ -890,7 +892,7 @@
 			// Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
 		case sdkLibTag, libTag, rroDepTag:
 			if exportPackage != nil {
-				sharedResourcesNodeDepSets = append(sharedResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
+				sharedResourcesNodeDepSets = append(sharedResourcesNodeDepSets, aarDep.ResourcesNodeDepSet)
 				sharedLibs = append(sharedLibs, exportPackage)
 			}
 		case frameworkResTag:
@@ -899,9 +901,9 @@
 			}
 		case staticLibTag:
 			if exportPackage != nil {
-				staticResourcesNodeDepSets = append(staticResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
-				rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet())
-				manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet())
+				staticResourcesNodeDepSets = append(staticResourcesNodeDepSets, aarDep.ResourcesNodeDepSet)
+				rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet)
+				manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet)
 			}
 		}
 
@@ -1023,7 +1025,7 @@
 		extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
 	}
 
-	a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
+	javaInfo := a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
 
 	a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
 	var res android.Paths
@@ -1049,6 +1051,11 @@
 
 	android.SetProvider(ctx, AndroidLibraryInfoProvider, AndroidLibraryInfo{})
 
+	if javaInfo != nil {
+		setExtraJavaInfo(ctx, a, javaInfo)
+		android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+	}
+
 	a.setOutputFiles(ctx)
 }
 
@@ -1537,7 +1544,7 @@
 		ctx.CheckbuildFile(a.implementationJarFile)
 	}
 
-	android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+	javaInfo := &JavaInfo{
 		HeaderJars:                             android.PathsIfNonNil(a.headerJarFile),
 		LocalHeaderJars:                        android.PathsIfNonNil(classpathFile),
 		TransitiveStaticLibsHeaderJars:         completeStaticLibsHeaderJars,
@@ -1550,7 +1557,9 @@
 		ImplementationJars:                     android.PathsIfNonNil(a.implementationJarFile),
 		StubsLinkType:                          Implementation,
 		// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
-	})
+	}
+	setExtraJavaInfo(ctx, a, javaInfo)
+	android.SetProvider(ctx, JavaInfoProvider, javaInfo)
 
 	if proptools.Bool(a.properties.Extract_jni) {
 		for _, t := range ctx.MultiTargets() {
diff --git a/java/app.go b/java/app.go
index 0abeaf4..12705b0 100644
--- a/java/app.go
+++ b/java/app.go
@@ -575,7 +575,7 @@
 }
 
 func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
-	ctx.VisitDirectDeps(func(dep android.Module) {
+	ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
 		tag := ctx.OtherModuleDependencyTag(dep)
 		switch tag {
 		case staticLibTag:
@@ -730,6 +730,7 @@
 
 	var packageResources = a.exportPackage
 
+	javaInfo := &JavaInfo{}
 	if ctx.ModuleName() != "framework-res" {
 		if a.dexProperties.resourceShrinkingEnabled(ctx) {
 			protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
@@ -753,13 +754,17 @@
 			extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
 		}
 
-		a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
+		javaInfo = a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
 		if a.dexProperties.resourceShrinkingEnabled(ctx) {
 			binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
 			aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
 			packageResources = binaryResources
 		}
 	}
+	if javaInfo != nil {
+		setExtraJavaInfo(ctx, a, javaInfo)
+		android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+	}
 
 	return a.dexJarFile.PathOrNil(), packageResources
 }
diff --git a/java/base.go b/java/base.go
index 1aef37c..ac8619e 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1153,7 +1153,7 @@
 	j.properties.Generated_srcjars = append(j.properties.Generated_srcjars, path)
 }
 
-func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars, extraDepCombinedJars android.Paths) {
+func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars, extraDepCombinedJars android.Paths) *JavaInfo {
 	// Auto-propagating jarjar rules
 	jarjarProviderData := j.collectJarJarRules(ctx)
 	if jarjarProviderData != nil {
@@ -1287,7 +1287,7 @@
 			transitiveStaticLibsHeaderJars = nil
 		}
 		if ctx.Failed() {
-			return
+			return nil
 		}
 		j.headerJarFile = combinedHeaderJarFile
 
@@ -1302,7 +1302,8 @@
 			ctx.CheckbuildFile(j.headerJarFile)
 		}
 
-		android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+		j.outputFile = j.headerJarFile
+		return &JavaInfo{
 			HeaderJars:                          android.PathsIfNonNil(j.headerJarFile),
 			LocalHeaderJars:                     localHeaderJars,
 			TransitiveStaticLibsHeaderJars:      depset.New(depset.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
@@ -1315,10 +1316,7 @@
 			StubsLinkType:                       j.stubsLinkType,
 			AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
 			SdkVersion:                          j.SdkVersion(ctx),
-		})
-
-		j.outputFile = j.headerJarFile
-		return
+		}
 	}
 
 	if srcFiles.HasExt(".kt") {
@@ -1375,7 +1373,7 @@
 		kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
 		j.kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
 		if ctx.Failed() {
-			return
+			return nil
 		}
 
 		kotlinJarPath, _ := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc")
@@ -1502,7 +1500,7 @@
 			localImplementationJars = append(localImplementationJars, classes)
 		}
 		if ctx.Failed() {
-			return
+			return nil
 		}
 	}
 
@@ -1542,7 +1540,7 @@
 		resourceJar := android.PathForModuleOut(ctx, "res", jarName)
 		TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
 		if ctx.Failed() {
-			return
+			return nil
 		}
 		localResourceJars = append(localResourceJars, resourceJar)
 	}
@@ -1664,7 +1662,7 @@
 	}
 
 	if ctx.Failed() {
-		return
+		return nil
 	}
 
 	if j.ravenizer.enabled {
@@ -1728,7 +1726,7 @@
 		CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
 
 		if ctx.Failed() {
-			return
+			return nil
 		}
 	}
 
@@ -1753,7 +1751,7 @@
 	// enforce syntax check to jacoco filters for any build (http://b/183622051)
 	specs := j.jacocoModuleToZipCommand(ctx)
 	if ctx.Failed() {
-		return
+		return nil
 	}
 
 	completeStaticLibsImplementationJarsToCombine := completeStaticLibsImplementationJars
@@ -1821,7 +1819,7 @@
 			}
 			dexOutputFile, dexArtProfileOutput := j.dexer.compileDex(ctx, params)
 			if ctx.Failed() {
-				return
+				return nil
 			}
 
 			// If r8/d8 provides a profile that matches the optimized dex, use that for dexpreopt.
@@ -1880,7 +1878,7 @@
 		}
 
 		if ctx.Failed() {
-			return
+			return nil
 		}
 	}
 
@@ -1927,7 +1925,10 @@
 		ctx.CheckbuildFile(j.headerJarFile)
 	}
 
-	android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
+	j.outputFile = outputFile.WithoutRel()
+
+	return &JavaInfo{
 		HeaderJars:           android.PathsIfNonNil(j.headerJarFile),
 		RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile),
 
@@ -1952,10 +1953,7 @@
 		StubsLinkType:                       j.stubsLinkType,
 		AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
 		SdkVersion:                          j.SdkVersion(ctx),
-	})
-
-	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
-	j.outputFile = outputFile.WithoutRel()
+	}
 }
 
 func (j *Module) useCompose(ctx android.BaseModuleContext) bool {
@@ -2220,7 +2218,7 @@
 
 func (j *Module) hasCode(ctx android.ModuleContext) bool {
 	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
-	return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0
+	return len(srcFiles) > 0 || len(ctx.GetDirectDepsProxyWithTag(staticLibTag)) > 0
 }
 
 // Implements android.ApexModule
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index bfacea6..04def3e 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -140,7 +140,7 @@
 		d.combinedHeaderJar = d.headerJars[0]
 	}
 
-	android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+	javaInfo := &JavaInfo{
 		HeaderJars:                             d.headerJars,
 		LocalHeaderJars:                        d.headerJars,
 		TransitiveStaticLibsHeaderJars:         depset.New(depset.PREORDER, nil, transitiveHeaderJars),
@@ -154,7 +154,9 @@
 		StubsLinkType:                          Implementation,
 		// TODO: Not sure if aconfig flags that have been moved between device and host variants
 		// make sense.
-	})
+	}
+	setExtraJavaInfo(ctx, d, javaInfo)
+	android.SetProvider(ctx, JavaInfoProvider, javaInfo)
 
 }
 
diff --git a/java/java.go b/java/java.go
index 0ab3440..25be93b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -250,6 +250,32 @@
 
 var ProguardSpecInfoProvider = blueprint.NewProvider[ProguardSpecInfo]()
 
+type AndroidLibraryDependencyInfo struct {
+	ExportPackage       android.Path
+	ResourcesNodeDepSet depset.DepSet[*resourcesNode]
+	RRODirsDepSet       depset.DepSet[rroDir]
+	ManifestsDepSet     depset.DepSet[android.Path]
+}
+
+type UsesLibraryDependencyInfo struct {
+	DexJarBuildPath     OptionalDexJarPath
+	DexJarInstallPath   android.Path
+	ClassLoaderContexts dexpreopt.ClassLoaderContextMap
+}
+
+type SdkLibraryComponentDependencyInfo struct {
+	// The name of the implementation library for the optional SDK library or nil, if there isn't one.
+	OptionalSdkLibraryImplementation *string
+}
+
+type ProvidesUsesLibInfo struct {
+	ProvidesUsesLib *string
+}
+
+type ModuleWithUsesLibraryInfo struct {
+	UsesLibrary *usesLibrary
+}
+
 // JavaInfo contains information about a java module for use by modules that depend on it.
 type JavaInfo struct {
 	// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
@@ -328,6 +354,16 @@
 	AconfigIntermediateCacheOutputPaths android.Paths
 
 	SdkVersion android.SdkSpec
+
+	AndroidLibraryDependencyInfo *AndroidLibraryDependencyInfo
+
+	UsesLibraryDependencyInfo *UsesLibraryDependencyInfo
+
+	SdkLibraryComponentDependencyInfo *SdkLibraryComponentDependencyInfo
+
+	ProvidesUsesLibInfo *ProvidesUsesLibInfo
+
+	ModuleWithUsesLibraryInfo *ModuleWithUsesLibraryInfo
 }
 
 var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]()
@@ -1002,7 +1038,7 @@
 			j.dexpreopter.disableDexpreopt()
 		}
 	}
-	j.compile(ctx, nil, nil, nil, nil)
+	javaInfo := j.compile(ctx, nil, nil, nil, nil)
 
 	j.setInstallRules(ctx)
 
@@ -1011,6 +1047,11 @@
 		TopLevelTarget: j.sourceProperties.Top_level_test_target,
 	})
 
+	if javaInfo != nil {
+		setExtraJavaInfo(ctx, j, javaInfo)
+		android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+	}
+
 	setOutputFiles(ctx, j.Module)
 }
 
@@ -2427,7 +2468,7 @@
 
 	ctx.Phony(ctx.ModuleName(), al.stubsJar)
 
-	android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+	javaInfo := &JavaInfo{
 		HeaderJars:                             android.PathsIfNonNil(al.stubsJar),
 		LocalHeaderJars:                        android.PathsIfNonNil(al.stubsJar),
 		TransitiveStaticLibsHeaderJars:         depset.New(depset.PREORDER, android.PathsIfNonNil(al.stubsJar), nil),
@@ -2437,7 +2478,9 @@
 		AidlIncludeDirs:                        android.Paths{},
 		StubsLinkType:                          Stubs,
 		// No aconfig libraries on api libraries
-	})
+	}
+	setExtraJavaInfo(ctx, al, javaInfo)
+	android.SetProvider(ctx, JavaInfoProvider, javaInfo)
 }
 
 func (al *ApiLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
@@ -2912,7 +2955,7 @@
 		}
 	}
 
-	android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+	javaInfo := &JavaInfo{
 		HeaderJars:                             android.PathsIfNonNil(j.combinedHeaderFile),
 		LocalHeaderJars:                        android.PathsIfNonNil(j.combinedHeaderFile),
 		TransitiveLibsHeaderJarsForR8:          j.transitiveLibsHeaderJarsForR8,
@@ -2926,7 +2969,9 @@
 		AidlIncludeDirs:                        j.exportAidlIncludeDirs,
 		StubsLinkType:                          j.stubsLinkType,
 		// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
-	})
+	}
+	setExtraJavaInfo(ctx, j, javaInfo)
+	android.SetProvider(ctx, JavaInfoProvider, javaInfo)
 
 	ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "")
 	ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar")
@@ -3340,8 +3385,8 @@
 func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
 	clcMap dexpreopt.ClassLoaderContextMap) {
 
-	dep, ok := depModule.(UsesLibraryDependency)
-	if !ok {
+	dep, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
+	if !ok || dep.UsesLibraryDependencyInfo == nil {
 		return
 	}
 
@@ -3351,14 +3396,14 @@
 	if lib, ok := android.OtherModuleProvider(ctx, depModule, SdkLibraryInfoProvider); ok && lib.SharedLibrary {
 		// A shared SDK library. This should be added as a top-level CLC element.
 		sdkLib = &depName
-	} else if lib, ok := depModule.(SdkLibraryComponentDependency); ok && lib.OptionalSdkLibraryImplementation() != nil {
-		if depModule.Name() == proptools.String(lib.OptionalSdkLibraryImplementation())+".impl" {
-			sdkLib = lib.OptionalSdkLibraryImplementation()
+	} else if lib := dep.SdkLibraryComponentDependencyInfo; lib != nil && lib.OptionalSdkLibraryImplementation != nil {
+		if depModule.Name() == proptools.String(lib.OptionalSdkLibraryImplementation)+".impl" {
+			sdkLib = lib.OptionalSdkLibraryImplementation
 		}
-	} else if ulib, ok := depModule.(ProvidesUsesLib); ok {
+	} else if ulib := dep.ProvidesUsesLibInfo; ulib != nil {
 		// A non-SDK library disguised as an SDK library by the means of `provides_uses_lib`
 		// property. This should be handled in the same way as a shared SDK library.
-		sdkLib = ulib.ProvidesUsesLib()
+		sdkLib = ulib.ProvidesUsesLib
 	}
 
 	depTag := ctx.OtherModuleDependencyTag(depModule)
@@ -3390,21 +3435,22 @@
 			}
 		}
 		clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional,
-			dep.DexJarBuildPath(ctx).PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
+			dep.UsesLibraryDependencyInfo.DexJarBuildPath.PathOrNil(),
+			dep.UsesLibraryDependencyInfo.DexJarInstallPath, dep.UsesLibraryDependencyInfo.ClassLoaderContexts)
 	} else {
-		clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
+		clcMap.AddContextMap(dep.UsesLibraryDependencyInfo.ClassLoaderContexts, depName)
 	}
 }
 
 func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.Module,
 	usesLibrary *usesLibrary) {
 
-	dep, ok := depModule.(ModuleWithUsesLibrary)
-	if !ok {
+	dep, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
+	if !ok || dep.ModuleWithUsesLibraryInfo == nil {
 		return
 	}
 
-	for _, lib := range dep.UsesLibrary().usesLibraryProperties.Missing_optional_uses_libs {
+	for _, lib := range dep.ModuleWithUsesLibraryInfo.UsesLibrary.usesLibraryProperties.Missing_optional_uses_libs {
 		if !android.InList(lib, usesLibrary.usesLibraryProperties.Missing_optional_uses_libs) {
 			usesLibrary.usesLibraryProperties.Missing_optional_uses_libs =
 				append(usesLibrary.usesLibraryProperties.Missing_optional_uses_libs, lib)
@@ -3460,3 +3506,40 @@
 func (ap *JavaApiContributionImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	ap.JavaApiContribution.GenerateAndroidBuildActions(ctx)
 }
+
+func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo *JavaInfo) {
+	if alDep, ok := module.(AndroidLibraryDependency); ok {
+		javaInfo.AndroidLibraryDependencyInfo = &AndroidLibraryDependencyInfo{
+			ExportPackage:       alDep.ExportPackage(),
+			ResourcesNodeDepSet: alDep.ResourcesNodeDepSet(),
+			RRODirsDepSet:       alDep.RRODirsDepSet(),
+			ManifestsDepSet:     alDep.ManifestsDepSet(),
+		}
+	}
+
+	if ulDep, ok := module.(UsesLibraryDependency); ok {
+		javaInfo.UsesLibraryDependencyInfo = &UsesLibraryDependencyInfo{
+			DexJarBuildPath:     ulDep.DexJarBuildPath(ctx),
+			DexJarInstallPath:   ulDep.DexJarInstallPath(),
+			ClassLoaderContexts: ulDep.ClassLoaderContexts(),
+		}
+	}
+
+	if slcDep, ok := module.(SdkLibraryComponentDependency); ok {
+		javaInfo.SdkLibraryComponentDependencyInfo = &SdkLibraryComponentDependencyInfo{
+			OptionalSdkLibraryImplementation: slcDep.OptionalSdkLibraryImplementation(),
+		}
+	}
+
+	if pul, ok := module.(ProvidesUsesLib); ok {
+		javaInfo.ProvidesUsesLibInfo = &ProvidesUsesLibInfo{
+			ProvidesUsesLib: pul.ProvidesUsesLib(),
+		}
+	}
+
+	if mwul, ok := module.(ModuleWithUsesLibrary); ok {
+		javaInfo.ModuleWithUsesLibraryInfo = &ModuleWithUsesLibraryInfo{
+			UsesLibrary: mwul.UsesLibrary(),
+		}
+	}
+}
diff --git a/java/robolectric.go b/java/robolectric.go
index 6c137ba..8c76ac7 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -104,8 +104,6 @@
 
 var _ android.TestSuiteModule = (*robolectricTest)(nil)
 
-
-
 func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
 	r.Library.DepsMutator(ctx)
 
@@ -207,7 +205,7 @@
 	r.stem = proptools.StringDefault(r.overridableProperties.Stem, ctx.ModuleName())
 	r.classLoaderContexts = r.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
 	r.dexpreopter.disableDexpreopt()
-	r.compile(ctx, nil, nil, nil, extraCombinedJars)
+	javaInfo := r.compile(ctx, nil, nil, nil, extraCombinedJars)
 
 	installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
 	var installDeps android.InstallPaths
@@ -244,6 +242,11 @@
 	}
 
 	r.installFile = ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
+
+	if javaInfo != nil {
+		setExtraJavaInfo(ctx, r, javaInfo)
+		android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+	}
 }
 
 func generateSameDirRoboTestConfigJar(ctx android.ModuleContext, outputFile android.ModuleOutPath) {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index a0affe0..155bea4 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -964,6 +964,10 @@
 		removedApiFilePaths[kind] = removedApiFilePath
 	}
 
+	javaInfo := &JavaInfo{}
+	setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
+	android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
 	return SdkLibraryInfo{
 		EverythingStubDexJarPaths: everythingStubPaths,
 		ExportableStubDexJarPaths: exportableStubPaths,