Convert sdk_library to use ModuleProxy.

Bug: 377723687
Test: Unit tests and compare the ninja and mk files generated.
Change-Id: Ifa759a5894c55a2a1485b61fb6752a74df589aec
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 0c6bab3..d65e29e 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -28,18 +28,28 @@
 	"android/soong/remoteexec"
 )
 
-type StubsArtifactsInfo struct {
-	ApiVersionsXml android.WritablePath
+type StubsInfo struct {
+	ApiVersionsXml android.Path
+	AnnotationsZip android.Path
+	ApiFile        android.Path
+	RemovedApiFile android.Path
 }
 
 type DroidStubsInfo struct {
 	CurrentApiTimestamp android.Path
-	EverythingArtifacts StubsArtifactsInfo
-	ExportableArtifacts StubsArtifactsInfo
+	EverythingStubsInfo StubsInfo
+	ExportableStubsInfo StubsInfo
 }
 
 var DroidStubsInfoProvider = blueprint.NewProvider[DroidStubsInfo]()
 
+type StubsSrcInfo struct {
+	EverythingStubsSrcJar android.Path
+	ExportableStubsSrcJar android.Path
+}
+
+var StubsSrcInfoProvider = blueprint.NewProvider[StubsSrcInfo]()
+
 // The values allowed for Droidstubs' Api_levels_sdk_type
 var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib", "system-server"}
 
@@ -541,9 +551,9 @@
 		ctx.VisitDirectDepsProxyWithTag(metalavaAPILevelsModuleTag, func(m android.ModuleProxy) {
 			if s, ok := android.OtherModuleProvider(ctx, m, DroidStubsInfoProvider); ok {
 				if stubsType == Everything {
-					apiVersions = s.EverythingArtifacts.ApiVersionsXml
+					apiVersions = s.EverythingStubsInfo.ApiVersionsXml
 				} else if stubsType == Exportable {
-					apiVersions = s.ExportableArtifacts.ApiVersionsXml
+					apiVersions = s.ExportableStubsInfo.ApiVersionsXml
 				} else {
 					ctx.ModuleErrorf("%s stubs type does not generate api-versions.xml file", stubsType.String())
 				}
@@ -1390,14 +1400,18 @@
 		rule.Build("metalavaCurrentApiUpdate", "update current API")
 	}
 
-	android.SetProvider(ctx, DroidStubsInfoProvider, DroidStubsInfo{
+	droidInfo := DroidStubsInfo{
 		CurrentApiTimestamp: d.CurrentApiTimestamp(),
-		EverythingArtifacts: StubsArtifactsInfo{
-			ApiVersionsXml: d.everythingArtifacts.apiVersionsXml,
-		},
-		ExportableArtifacts: StubsArtifactsInfo{
-			ApiVersionsXml: d.exportableArtifacts.apiVersionsXml,
-		},
+		EverythingStubsInfo: StubsInfo{},
+		ExportableStubsInfo: StubsInfo{},
+	}
+	setDroidInfo(ctx, d, &droidInfo.EverythingStubsInfo, Everything)
+	setDroidInfo(ctx, d, &droidInfo.ExportableStubsInfo, Exportable)
+	android.SetProvider(ctx, DroidStubsInfoProvider, droidInfo)
+
+	android.SetProvider(ctx, StubsSrcInfoProvider, StubsSrcInfo{
+		EverythingStubsSrcJar: d.stubsSrcJar,
+		ExportableStubsSrcJar: d.exportableStubsSrcJar,
 	})
 
 	d.setOutputFiles(ctx)
@@ -1405,6 +1419,22 @@
 	d.setPhonyRules(ctx)
 }
 
+func setDroidInfo(ctx android.ModuleContext, d *Droidstubs, info *StubsInfo, typ StubsType) {
+	if typ == Everything {
+		info.ApiFile = d.apiFile
+		info.RemovedApiFile = d.removedApiFile
+		info.AnnotationsZip = d.everythingArtifacts.annotationsZip
+		info.ApiVersionsXml = d.everythingArtifacts.apiVersionsXml
+	} else if typ == Exportable {
+		info.ApiFile = d.exportableApiFile
+		info.RemovedApiFile = d.exportableRemovedApiFile
+		info.AnnotationsZip = d.exportableArtifacts.annotationsZip
+		info.ApiVersionsXml = d.exportableArtifacts.apiVersionsXml
+	} else {
+		ctx.ModuleErrorf("failed to set ApiVersionsXml, stubs type not supported: %d", typ)
+	}
+}
+
 // This method sets the outputFiles property, which is used to set the
 // OutputFilesProvider later.
 // Droidstubs' tag supports specifying with the stubs type.
@@ -1570,6 +1600,11 @@
 		p.stubsSrcJar = outPath
 	}
 
+	android.SetProvider(ctx, StubsSrcInfoProvider, StubsSrcInfo{
+		EverythingStubsSrcJar: p.stubsSrcJar,
+		ExportableStubsSrcJar: p.stubsSrcJar,
+	})
+
 	ctx.SetOutputFiles(android.Paths{p.stubsSrcJar}, "")
 	// prebuilt droidstubs does not output "exportable" stubs.
 	// Output the "everything" stubs srcjar file if the tag is ".exportable".
diff --git a/java/java.go b/java/java.go
index 66550d5..98e2e64 100644
--- a/java/java.go
+++ b/java/java.go
@@ -363,6 +363,8 @@
 	// output file of the module, which may be a classes jar or a dex jar
 	OutputFile android.Path
 
+	ExtraOutputFiles android.Paths
+
 	AndroidLibraryDependencyInfo *AndroidLibraryDependencyInfo
 
 	UsesLibraryDependencyInfo *UsesLibraryDependencyInfo
@@ -374,6 +376,62 @@
 	ModuleWithUsesLibraryInfo *ModuleWithUsesLibraryInfo
 
 	ModuleWithSdkDepInfo *ModuleWithSdkDepInfo
+
+	// output file containing classes.dex and resources
+	DexJarFile OptionalDexJarPath
+
+	// installed file for binary dependency
+	InstallFile android.Path
+
+	// The path to the dex jar that is in the boot class path. If this is unset then the associated
+	// module is not a boot jar, but could be one of the <x>-hiddenapi modules that provide additional
+	// annotations for the <x> boot dex jar but which do not actually provide a boot dex jar
+	// themselves.
+	//
+	// This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on
+	// this file so using the encoded dex jar here would result in a cycle in the ninja rules.
+	BootDexJarPath OptionalDexJarPath
+
+	// The compressed state of the dex file being encoded. This is used to ensure that the encoded
+	// dex file has the same state.
+	UncompressDexState *bool
+
+	// True if the module containing this structure contributes to the hiddenapi information or has
+	// that information encoded within it.
+	Active bool
+
+	BuiltInstalled string
+
+	BuiltInstalledForApex []dexpreopterInstall
+
+	// The config is used for two purposes:
+	// - Passing dexpreopt information about libraries from Soong to Make. This is needed when
+	//   a <uses-library> is defined in Android.bp, but used in Android.mk (see dex_preopt_config_merger.py).
+	//   Note that dexpreopt.config might be needed even if dexpreopt is disabled for the library itself.
+	// - Dexpreopt post-processing (using dexpreopt artifacts from a prebuilt system image to incrementally
+	//   dexpreopt another partition).
+	ConfigPath android.WritablePath
+
+	// The path to the profile on host that dexpreopter generates. This is used as the input for
+	// dex2oat.
+	OutputProfilePathOnHost android.Path
+
+	LogtagsSrcs android.Paths
+
+	ProguardDictionary android.OptionalPath
+
+	ProguardUsageZip android.OptionalPath
+
+	LinterReports android.Paths
+
+	// installed file for hostdex copy
+	HostdexInstallFile android.InstallPath
+
+	// Additional srcJars tacked in by GeneratedJavaLibraryModule
+	GeneratedSrcjars []android.Path
+
+	// True if profile-guided optimization is actually enabled.
+	ProfileGuided bool
 }
 
 var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]()
@@ -1065,6 +1123,24 @@
 
 	if javaInfo != nil {
 		setExtraJavaInfo(ctx, j, javaInfo)
+		javaInfo.ExtraOutputFiles = j.extraOutputFiles
+		javaInfo.DexJarFile = j.dexJarFile
+		javaInfo.InstallFile = j.installFile
+		javaInfo.BootDexJarPath = j.bootDexJarPath
+		javaInfo.UncompressDexState = j.uncompressDexState
+		javaInfo.Active = j.active
+		javaInfo.BuiltInstalledForApex = j.builtInstalledForApex
+		javaInfo.BuiltInstalled = j.builtInstalled
+		javaInfo.ConfigPath = j.configPath
+		javaInfo.OutputProfilePathOnHost = j.outputProfilePathOnHost
+		javaInfo.LogtagsSrcs = j.logtagsSrcs
+		javaInfo.ProguardDictionary = j.proguardDictionary
+		javaInfo.ProguardUsageZip = j.proguardUsageZip
+		javaInfo.LinterReports = j.reports
+		javaInfo.HostdexInstallFile = j.hostdexInstallFile
+		javaInfo.GeneratedSrcjars = j.properties.Generated_srcjars
+		javaInfo.ProfileGuided = j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided
+
 		android.SetProvider(ctx, JavaInfoProvider, javaInfo)
 	}
 
diff --git a/java/sdk_library.go b/java/sdk_library.go
index fda87f8..05a5b49 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -693,9 +693,9 @@
 		paths.stubsHeaderPath = lib.HeaderJars
 		paths.stubsImplPath = lib.ImplementationJars
 
-		libDep := dep.(UsesLibraryDependency)
-		paths.stubsDexJarPath = libDep.DexJarBuildPath(ctx)
-		paths.exportableStubsDexJarPath = libDep.DexJarBuildPath(ctx)
+		libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider).UsesLibraryDependencyInfo
+		paths.stubsDexJarPath = libDep.DexJarBuildPath
+		paths.exportableStubsDexJarPath = libDep.DexJarBuildPath
 		return nil
 	} else {
 		return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
@@ -709,8 +709,8 @@
 			paths.stubsImplPath = lib.ImplementationJars
 		}
 
-		libDep := dep.(UsesLibraryDependency)
-		paths.stubsDexJarPath = libDep.DexJarBuildPath(ctx)
+		libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider).UsesLibraryDependencyInfo
+		paths.stubsDexJarPath = libDep.DexJarBuildPath
 		return nil
 	} else {
 		return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
@@ -723,58 +723,67 @@
 			paths.stubsImplPath = lib.ImplementationJars
 		}
 
-		libDep := dep.(UsesLibraryDependency)
-		paths.exportableStubsDexJarPath = libDep.DexJarBuildPath(ctx)
+		libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider).UsesLibraryDependencyInfo
+		paths.exportableStubsDexJarPath = libDep.DexJarBuildPath
 		return nil
 	} else {
 		return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
 	}
 }
 
-func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action func(provider ApiStubsProvider) error) error {
-	if apiStubsProvider, ok := dep.(ApiStubsProvider); ok {
-		err := action(apiStubsProvider)
+func (paths *scopePaths) treatDepAsApiStubsProvider(ctx android.ModuleContext, dep android.Module,
+	action func(*DroidStubsInfo, *StubsSrcInfo) error) error {
+	apiStubsProvider, ok := android.OtherModuleProvider(ctx, dep, DroidStubsInfoProvider)
+	if !ok {
+		return fmt.Errorf("expected module that provides DroidStubsInfo, e.g. droidstubs")
+	}
+
+	apiStubsSrcProvider, ok := android.OtherModuleProvider(ctx, dep, StubsSrcInfoProvider)
+	if !ok {
+		return fmt.Errorf("expected module that provides StubsSrcInfo, e.g. droidstubs")
+	}
+	return action(&apiStubsProvider, &apiStubsSrcProvider)
+}
+
+func (paths *scopePaths) treatDepAsApiStubsSrcProvider(
+	ctx android.ModuleContext, dep android.Module, action func(provider *StubsSrcInfo) error) error {
+	if apiStubsProvider, ok := android.OtherModuleProvider(ctx, dep, StubsSrcInfoProvider); ok {
+		err := action(&apiStubsProvider)
 		if err != nil {
 			return err
 		}
 		return nil
 	} else {
-		return fmt.Errorf("expected module that implements ExportableApiStubsSrcProvider, e.g. droidstubs")
+		return fmt.Errorf("expected module that provides DroidStubsInfo, e.g. droidstubs")
 	}
 }
 
-func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider) error) error {
-	if apiStubsProvider, ok := dep.(ApiStubsSrcProvider); ok {
-		err := action(apiStubsProvider)
-		if err != nil {
-			return err
-		}
-		return nil
-	} else {
-		return fmt.Errorf("expected module that implements ApiStubsSrcProvider, e.g. droidstubs")
+func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider *DroidStubsInfo, stubsType StubsType) error {
+	var currentApiFilePathErr, removedApiFilePathErr error
+	info, err := getStubsInfoForType(provider, stubsType)
+	if err != nil {
+		return err
 	}
-}
-
-func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider, stubsType StubsType) error {
-	var annotationsZip, currentApiFilePath, removedApiFilePath android.Path
-	annotationsZip, annotationsZipErr := provider.AnnotationsZip(stubsType)
-	currentApiFilePath, currentApiFilePathErr := provider.ApiFilePath(stubsType)
-	removedApiFilePath, removedApiFilePathErr := provider.RemovedApiFilePath(stubsType)
-
-	combinedError := errors.Join(annotationsZipErr, currentApiFilePathErr, removedApiFilePathErr)
+	if info.ApiFile == nil {
+		currentApiFilePathErr = fmt.Errorf("expected module that provides ApiFile")
+	}
+	if info.RemovedApiFile == nil {
+		removedApiFilePathErr = fmt.Errorf("expected module that provides RemovedApiFile")
+	}
+	combinedError := errors.Join(currentApiFilePathErr, removedApiFilePathErr)
 
 	if combinedError == nil {
-		paths.annotationsZip = android.OptionalPathForPath(annotationsZip)
-		paths.currentApiFilePath = android.OptionalPathForPath(currentApiFilePath)
-		paths.removedApiFilePath = android.OptionalPathForPath(removedApiFilePath)
+		paths.annotationsZip = android.OptionalPathForPath(info.AnnotationsZip)
+		paths.currentApiFilePath = android.OptionalPathForPath(info.ApiFile)
+		paths.removedApiFilePath = android.OptionalPathForPath(info.RemovedApiFile)
 	}
 	return combinedError
 }
 
-func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider, stubsType StubsType) error {
-	stubsSrcJar, err := provider.StubsSrcJar(stubsType)
+func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider *StubsSrcInfo, stubsType StubsType) error {
+	path, err := getStubsSrcInfoForType(provider, stubsType)
 	if err == nil {
-		paths.stubsSrcJar = android.OptionalPathForPath(stubsSrcJar)
+		paths.stubsSrcJar = android.OptionalPathForPath(path)
 	}
 	return err
 }
@@ -784,7 +793,7 @@
 	if ctx.Config().ReleaseHiddenApiExportableStubs() {
 		stubsType = Exportable
 	}
-	return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) error {
+	return paths.treatDepAsApiStubsSrcProvider(ctx, dep, func(provider *StubsSrcInfo) error {
 		return paths.extractStubsSourceInfoFromApiStubsProviders(provider, stubsType)
 	})
 }
@@ -794,17 +803,17 @@
 	if ctx.Config().ReleaseHiddenApiExportableStubs() {
 		stubsType = Exportable
 	}
-	return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) error {
-		extractApiInfoErr := paths.extractApiInfoFromApiStubsProvider(provider, stubsType)
-		extractStubsSourceInfoErr := paths.extractStubsSourceInfoFromApiStubsProviders(provider, stubsType)
+	return paths.treatDepAsApiStubsProvider(ctx, dep, func(apiStubsProvider *DroidStubsInfo, apiStubsSrcProvider *StubsSrcInfo) error {
+		extractApiInfoErr := paths.extractApiInfoFromApiStubsProvider(apiStubsProvider, stubsType)
+		extractStubsSourceInfoErr := paths.extractStubsSourceInfoFromApiStubsProviders(apiStubsSrcProvider, stubsType)
 		return errors.Join(extractApiInfoErr, extractStubsSourceInfoErr)
 	})
 }
 
-func extractOutputPaths(dep android.Module) (android.Paths, error) {
+func extractOutputPaths(ctx android.ModuleContext, dep android.Module) (android.Paths, error) {
 	var paths android.Paths
-	if sourceFileProducer, ok := dep.(android.SourceFileProducer); ok {
-		paths = sourceFileProducer.Srcs()
+	if sourceFileProducer, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoProvider); ok {
+		paths = sourceFileProducer.Srcs
 		return paths, nil
 	} else {
 		return nil, fmt.Errorf("module %q does not produce source files", dep)
@@ -812,17 +821,47 @@
 }
 
 func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.Module) error {
-	outputPaths, err := extractOutputPaths(dep)
+	outputPaths, err := extractOutputPaths(ctx, dep)
 	paths.latestApiPaths = outputPaths
 	return err
 }
 
 func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.Module) error {
-	outputPaths, err := extractOutputPaths(dep)
+	outputPaths, err := extractOutputPaths(ctx, dep)
 	paths.latestRemovedApiPaths = outputPaths
 	return err
 }
 
+func getStubsInfoForType(info *DroidStubsInfo, stubsType StubsType) (ret *StubsInfo, err error) {
+	switch stubsType {
+	case Everything:
+		ret, err = &info.EverythingStubsInfo, nil
+	case Exportable:
+		ret, err = &info.ExportableStubsInfo, nil
+	default:
+		ret, err = nil, fmt.Errorf("stubs info not supported for the stub type %s", stubsType.String())
+	}
+	if ret == nil && err == nil {
+		err = fmt.Errorf("stubs info is null for the stub type %s", stubsType.String())
+	}
+	return ret, err
+}
+
+func getStubsSrcInfoForType(info *StubsSrcInfo, stubsType StubsType) (ret android.Path, err error) {
+	switch stubsType {
+	case Everything:
+		ret, err = info.EverythingStubsSrcJar, nil
+	case Exportable:
+		ret, err = info.ExportableStubsSrcJar, nil
+	default:
+		ret, err = nil, fmt.Errorf("stubs src info not supported for the stub type %s", stubsType.String())
+	}
+	if ret == nil && err == nil {
+		err = fmt.Errorf("stubs src info is null for the stub type %s", stubsType.String())
+	}
+	return ret, err
+}
+
 type commonToSdkLibraryAndImportProperties struct {
 	// Specifies whether this module can be used as an Android shared library; defaults
 	// to true.
@@ -911,9 +950,9 @@
 	// This is non-empty only when api_only is false.
 	implLibraryHeaderJars android.Paths
 
-	// The reference to the implementation library created by the source module.
-	// Is nil if the source module does not exist.
-	implLibraryModule *Library
+	// The reference to the JavaInfo provided by implementation library created by
+	// the source module. Is nil if the source module does not exist.
+	implLibraryInfo *JavaInfo
 }
 
 func (c *commonToSdkLibraryAndImport) initCommon(module commonSdkLibraryAndImportModule) {
@@ -1218,16 +1257,16 @@
 
 // To satisfy the UsesLibraryDependency interface
 func (module *SdkLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
-	if module.implLibraryModule != nil {
-		return module.implLibraryModule.DexJarBuildPath(ctx)
+	if module.implLibraryInfo != nil {
+		return module.implLibraryInfo.DexJarFile
 	}
 	return makeUnsetDexJarPath()
 }
 
 // To satisfy the UsesLibraryDependency interface
 func (module *SdkLibrary) DexJarInstallPath() android.Path {
-	if module.implLibraryModule != nil {
-		return module.implLibraryModule.DexJarInstallPath()
+	if module.implLibraryInfo != nil {
+		return module.implLibraryInfo.InstallFile
 	}
 	return nil
 }
@@ -1414,11 +1453,11 @@
 	// Collate the components exported by this module. All scope specific modules are exported but
 	// the impl and xml component modules are not.
 	exportedComponents := map[string]struct{}{}
-
+	var implLib android.ModuleProxy
 	// Record the paths to the header jars of the library (stubs and impl).
 	// When this java_sdk_library is depended upon from others via "libs" property,
 	// the recorded paths will be returned depending on the link type of the caller.
-	ctx.VisitDirectDeps(func(to android.Module) {
+	ctx.VisitDirectDepsProxy(func(to android.ModuleProxy) {
 		tag := ctx.OtherModuleDependencyTag(to)
 
 		// Extract information from any of the scope specific dependencies.
@@ -1438,7 +1477,8 @@
 		if tag == implLibraryTag {
 			if dep, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok {
 				module.implLibraryHeaderJars = append(module.implLibraryHeaderJars, dep.HeaderJars...)
-				module.implLibraryModule = to.(*Library)
+				module.implLibraryInfo = dep
+				implLib = to
 			}
 		}
 	})
@@ -1449,39 +1489,39 @@
 		module.hideApexVariantFromMake = true
 	}
 
-	if module.implLibraryModule != nil {
+	if module.implLibraryInfo != nil {
 		if ctx.Device() {
-			module.classesJarPaths = android.Paths{module.implLibraryModule.implementationJarFile}
-			module.bootDexJarPath = module.implLibraryModule.bootDexJarPath
-			module.uncompressDexState = module.implLibraryModule.uncompressDexState
-			module.active = module.implLibraryModule.active
+			module.classesJarPaths = module.implLibraryInfo.ImplementationJars
+			module.bootDexJarPath = module.implLibraryInfo.BootDexJarPath
+			module.uncompressDexState = module.implLibraryInfo.UncompressDexState
+			module.active = module.implLibraryInfo.Active
 		}
 
-		module.outputFile = module.implLibraryModule.outputFile
-		module.dexJarFile = makeDexJarPathFromPath(module.implLibraryModule.dexJarFile.Path())
-		module.headerJarFile = module.implLibraryModule.headerJarFile
-		module.implementationAndResourcesJar = module.implLibraryModule.implementationAndResourcesJar
-		module.builtInstalledForApex = module.implLibraryModule.builtInstalledForApex
-		module.dexpreopter.configPath = module.implLibraryModule.dexpreopter.configPath
-		module.dexpreopter.outputProfilePathOnHost = module.implLibraryModule.dexpreopter.outputProfilePathOnHost
+		module.outputFile = module.implLibraryInfo.OutputFile
+		module.dexJarFile = makeDexJarPathFromPath(module.implLibraryInfo.DexJarFile.Path())
+		module.headerJarFile = module.implLibraryInfo.HeaderJars[0]
+		module.implementationAndResourcesJar = module.implLibraryInfo.ImplementationAndResourcesJars[0]
+		module.builtInstalledForApex = module.implLibraryInfo.BuiltInstalledForApex
+		module.dexpreopter.configPath = module.implLibraryInfo.ConfigPath
+		module.dexpreopter.outputProfilePathOnHost = module.implLibraryInfo.OutputProfilePathOnHost
 
 		// Properties required for Library.AndroidMkEntries
-		module.logtagsSrcs = module.implLibraryModule.logtagsSrcs
-		module.dexpreopter.builtInstalled = module.implLibraryModule.dexpreopter.builtInstalled
-		module.jacocoReportClassesFile = module.implLibraryModule.jacocoReportClassesFile
-		module.dexer.proguardDictionary = module.implLibraryModule.dexer.proguardDictionary
-		module.dexer.proguardUsageZip = module.implLibraryModule.dexer.proguardUsageZip
-		module.linter.reports = module.implLibraryModule.linter.reports
+		module.logtagsSrcs = module.implLibraryInfo.LogtagsSrcs
+		module.dexpreopter.builtInstalled = module.implLibraryInfo.BuiltInstalled
+		module.jacocoReportClassesFile = module.implLibraryInfo.JacocoReportClassesFile
+		module.dexer.proguardDictionary = module.implLibraryInfo.ProguardDictionary
+		module.dexer.proguardUsageZip = module.implLibraryInfo.ProguardUsageZip
+		module.linter.reports = module.implLibraryInfo.LinterReports
 
-		if lintInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, LintProvider); ok {
+		if lintInfo, ok := android.OtherModuleProvider(ctx, implLib, LintProvider); ok {
 			android.SetProvider(ctx, LintProvider, lintInfo)
 		}
 
 		if !module.Host() {
-			module.hostdexInstallFile = module.implLibraryModule.hostdexInstallFile
+			module.hostdexInstallFile = module.implLibraryInfo.HostdexInstallFile
 		}
 
-		if installFilesInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, android.InstallFilesProvider); ok {
+		if installFilesInfo, ok := android.OtherModuleProvider(ctx, implLib, android.InstallFilesProvider); ok {
 			if installFilesInfo.CheckbuildTarget != nil {
 				ctx.CheckbuildFile(installFilesInfo.CheckbuildTarget)
 			}
@@ -1524,15 +1564,26 @@
 		}
 	}
 
-	if module.requiresRuntimeImplementationLibrary() && module.implLibraryModule != nil {
+	if module.requiresRuntimeImplementationLibrary() && module.implLibraryInfo != nil {
 		generatingLibs = append(generatingLibs, module.implLibraryModuleName())
-		setOutputFiles(ctx, module.implLibraryModule.Module)
+		setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo)
 	}
 
 	sdkLibInfo.GeneratingLibs = generatingLibs
 	android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo)
 }
 
+func setOutputFilesFromJavaInfo(ctx android.ModuleContext, info *JavaInfo) {
+	ctx.SetOutputFiles(append(android.PathsIfNonNil(info.OutputFile), info.ExtraOutputFiles...), "")
+	ctx.SetOutputFiles(android.PathsIfNonNil(info.OutputFile), android.DefaultDistTag)
+	ctx.SetOutputFiles(info.ImplementationAndResourcesJars, ".jar")
+	ctx.SetOutputFiles(info.HeaderJars, ".hjar")
+	if info.ProguardDictionary.Valid() {
+		ctx.SetOutputFiles(android.Paths{info.ProguardDictionary.Path()}, ".proguard_map")
+	}
+	ctx.SetOutputFiles(info.GeneratedSrcjars, ".generated_srcjars")
+}
+
 func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall {
 	return module.builtInstalledForApex
 }
@@ -1906,10 +1957,6 @@
 
 	commonToSdkLibraryAndImport
 
-	// The reference to the xml permissions module created by the source module.
-	// Is nil if the source module does not exist.
-	xmlPermissionsFileModule *sdkLibraryXml
-
 	// Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
 	dexJarFile    OptionalDexJarPath
 	dexJarFileErr error
@@ -2098,7 +2145,7 @@
 	module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar")
 
 	// Record the paths to the prebuilt stubs library and stubs source.
-	ctx.VisitDirectDeps(func(to android.Module) {
+	ctx.VisitDirectDepsProxy(func(to android.ModuleProxy) {
 		tag := ctx.OtherModuleDependencyTag(to)
 
 		// Extract information from any of the scope specific dependencies.
@@ -2110,17 +2157,11 @@
 			// is determined by the nature of the dependency which is determined by the tag.
 			scopeTag.extractDepInfo(ctx, to, scopePaths)
 		} else if tag == implLibraryTag {
-			if implLibrary, ok := to.(*Library); ok {
-				module.implLibraryModule = implLibrary
+			if implInfo, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok {
+				module.implLibraryInfo = implInfo
 			} else {
 				ctx.ModuleErrorf("implementation library must be of type *java.Library but was %T", to)
 			}
-		} else if tag == xmlPermissionsFileTag {
-			if xmlPermissionsFileModule, ok := to.(*sdkLibraryXml); ok {
-				module.xmlPermissionsFileModule = xmlPermissionsFileModule
-			} else {
-				ctx.ModuleErrorf("xml permissions file module must be of type *sdkLibraryXml but was %T", to)
-			}
 		}
 	})
 	sdkLibInfo := module.generateCommonBuildActions(ctx)
@@ -2160,9 +2201,9 @@
 	}
 
 	module.setOutputFiles(ctx)
-	if module.implLibraryModule != nil {
+	if module.implLibraryInfo != nil {
 		generatingLibs = append(generatingLibs, module.implLibraryModuleName())
-		setOutputFiles(ctx, module.implLibraryModule.Module)
+		setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo)
 	}
 
 	sdkLibInfo.GeneratingLibs = generatingLibs
@@ -2181,10 +2222,10 @@
 	if module.dexJarFile.IsSet() {
 		return module.dexJarFile
 	}
-	if module.implLibraryModule == nil {
+	if module.implLibraryInfo == nil {
 		return makeUnsetDexJarPath()
 	} else {
-		return module.implLibraryModule.DexJarBuildPath(ctx)
+		return module.implLibraryInfo.DexJarFile
 	}
 }
 
@@ -2200,10 +2241,10 @@
 
 // to satisfy apex.javaDependency interface
 func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path {
-	if module.implLibraryModule == nil {
+	if module.implLibraryInfo == nil {
 		return nil
 	} else {
-		return module.implLibraryModule.JacocoReportClassesFile()
+		return module.implLibraryInfo.JacocoReportClassesFile
 	}
 }
 
@@ -2216,19 +2257,19 @@
 
 // to satisfy java.ApexDependency interface
 func (module *SdkLibraryImport) HeaderJars() android.Paths {
-	if module.implLibraryModule == nil {
+	if module.implLibraryInfo == nil {
 		return nil
 	} else {
-		return module.implLibraryModule.HeaderJars()
+		return module.implLibraryInfo.HeaderJars
 	}
 }
 
 // to satisfy java.ApexDependency interface
 func (module *SdkLibraryImport) ImplementationAndResourcesJars() android.Paths {
-	if module.implLibraryModule == nil {
+	if module.implLibraryInfo == nil {
 		return nil
 	} else {
-		return module.implLibraryModule.ImplementationAndResourcesJars()
+		return module.implLibraryInfo.ImplementationAndResourcesJars
 	}
 }
 
@@ -2393,8 +2434,7 @@
 	s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk
 	s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk
 
-	implLibrary := sdk.implLibraryModule
-	if implLibrary != nil && implLibrary.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
+	if sdk.implLibraryInfo != nil && sdk.implLibraryInfo.ProfileGuided {
 		s.DexPreoptProfileGuided = proptools.BoolPtr(true)
 	}
 }