Merge "Reorganize and cull cc_library_static denylist."
diff --git a/apex/apex.go b/apex/apex.go
index 762912e..949d80e 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1498,10 +1498,15 @@
 var _ javaModule = (*java.DexImport)(nil)
 var _ javaModule = (*java.SdkLibraryImport)(nil)
 
+// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
 func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
+	return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath())
+}
+
+// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
+func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaModule, dexImplementationJar android.Path) apexFile {
 	dirInApex := "javalib"
-	fileToCopy := module.DexJarBuildPath()
-	af := newApexFile(ctx, fileToCopy, module.BaseModuleName(), dirInApex, javaSharedLib, module)
+	af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module)
 	af.jacocoReportClassesFile = module.JacocoReportClassesFile()
 	af.lintDepSets = module.LintDepSets()
 	af.customStem = module.Stem() + ".jar"
@@ -1696,21 +1701,12 @@
 			case bcpfTag:
 				{
 					if _, ok := child.(*java.BootclasspathFragmentModule); !ok {
-						ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a boot_image module", depName)
+						ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
 						return false
 					}
-					bootImageInfo := ctx.OtherModuleProvider(child, java.BootImageInfoProvider).(java.BootImageInfo)
-					for arch, files := range bootImageInfo.AndroidBootImageFilesByArchType() {
-						dirInApex := filepath.Join("javalib", arch.String())
-						for _, f := range files {
-							androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
-							// TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
-							af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
-							filesInfo = append(filesInfo, af)
-						}
-					}
 
-					// Track transitive dependencies.
+					filesToAdd := apexBootclasspathFragmentFiles(ctx, child)
+					filesInfo = append(filesInfo, filesToAdd...)
 					return true
 				}
 			case javaLibTag:
@@ -1928,7 +1924,8 @@
 					// Add the contents of the bootclasspath fragment to the apex.
 					switch child.(type) {
 					case *java.Library, *java.SdkLibrary:
-						af := apexFileForJavaModule(ctx, child.(javaModule))
+						javaModule := child.(javaModule)
+						af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
 						if !af.ok() {
 							ctx.PropertyErrorf("bootclasspath_fragments", "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
 							return false
@@ -2083,6 +2080,41 @@
 	}
 }
 
+// apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that
+// the bootclasspath_fragment contributes to the apex.
+func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile {
+	bootclasspathFragmentInfo := ctx.OtherModuleProvider(module, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
+	var filesToAdd []apexFile
+
+	// Add the boot image files, e.g. .art, .oat and .vdex files.
+	for arch, files := range bootclasspathFragmentInfo.AndroidBootImageFilesByArchType() {
+		dirInApex := filepath.Join("javalib", arch.String())
+		for _, f := range files {
+			androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
+			// TODO(b/177892522) - consider passing in the bootclasspath fragment module here instead of nil
+			af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
+			filesToAdd = append(filesToAdd, af)
+		}
+	}
+
+	return filesToAdd
+}
+
+// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
+// content module, i.e. a library that is part of the bootclasspath.
+func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
+	bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragmentModule, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
+
+	// Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the
+	// hidden API encpding.
+	dexBootJar := bootclasspathFragmentInfo.DexBootJarPathForContentModule(javaModule)
+
+	// Create an apexFile as for a normal java module but with the dex boot jar provided by the
+	// bootclasspath_fragment.
+	af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar)
+	return af
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Factory functions
 //
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 87f0132..feda482 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -143,13 +143,13 @@
 
 	bootclasspathFragment := result.ModuleForTests(moduleName, "android_common").Module().(*java.BootclasspathFragmentModule)
 
-	bootImageInfo := result.ModuleProvider(bootclasspathFragment, java.BootImageInfoProvider).(java.BootImageInfo)
-	modules := bootImageInfo.Modules()
+	bootclasspathFragmentInfo := result.ModuleProvider(bootclasspathFragment, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
+	modules := bootclasspathFragmentInfo.Modules()
 	android.AssertStringEquals(t, "invalid modules for "+moduleName, expectedConfiguredModules, modules.String())
 
 	// Get a list of all the paths in the boot image sorted by arch type.
 	allPaths := []string{}
-	bootImageFilesByArchType := bootImageInfo.AndroidBootImageFilesByArchType()
+	bootImageFilesByArchType := bootclasspathFragmentInfo.AndroidBootImageFilesByArchType()
 	for _, archType := range android.ArchTypeList() {
 		if paths, ok := bootImageFilesByArchType[archType]; ok {
 			for _, path := range paths {
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 619d47f..90383af 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -165,24 +165,26 @@
 	}
 }
 
-var BootImageInfoProvider = blueprint.NewProvider(BootImageInfo{})
+var BootclasspathFragmentApexContentInfoProvider = blueprint.NewProvider(BootclasspathFragmentApexContentInfo{})
 
-type BootImageInfo struct {
+// BootclasspathFragmentApexContentInfo contains the bootclasspath_fragments contributions to the
+// apex contents.
+type BootclasspathFragmentApexContentInfo struct {
 	// The image config, internal to this module (and the dex_bootjars singleton).
 	//
-	// Will be nil if the BootImageInfo has not been provided for a specific module. That can occur
+	// Will be nil if the BootclasspathFragmentApexContentInfo has not been provided for a specific module. That can occur
 	// when SkipDexpreoptBootJars(ctx) returns true.
 	imageConfig *bootImageConfig
 }
 
-func (i BootImageInfo) Modules() android.ConfiguredJarList {
+func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList {
 	return i.imageConfig.modules
 }
 
 // Get a map from ArchType to the associated boot image's contents for Android.
 //
 // Extension boot images only return their own files, not the files of the boot images they extend.
-func (i BootImageInfo) AndroidBootImageFilesByArchType() map[android.ArchType]android.OutputPaths {
+func (i BootclasspathFragmentApexContentInfo) AndroidBootImageFilesByArchType() map[android.ArchType]android.OutputPaths {
 	files := map[android.ArchType]android.OutputPaths{}
 	if i.imageConfig != nil {
 		for _, variant := range i.imageConfig.variants {
@@ -196,6 +198,15 @@
 	return files
 }
 
+// DexBootJarPathForContentModule returns the path to the dex boot jar for specified module.
+//
+// The dex boot jar is one which has had hidden API encoding performed on it.
+func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.Module) android.Path {
+	j := module.(UsesLibraryDependency)
+	dexJar := j.DexJarBuildPath()
+	return dexJar
+}
+
 func (b *BootclasspathFragmentModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
 	tag := ctx.OtherModuleDependencyTag(dep)
 	if IsBootclasspathFragmentContentDepTag(tag) {
@@ -264,10 +275,10 @@
 	}
 
 	// Construct the boot image info from the config.
-	info := BootImageInfo{imageConfig: imageConfig}
+	info := BootclasspathFragmentApexContentInfo{imageConfig: imageConfig}
 
 	// Make it available for other modules.
-	ctx.SetProvider(BootImageInfoProvider, info)
+	ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info)
 }
 
 func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index b1a0ac4..05b8e2f 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -171,17 +171,6 @@
 	// Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
 	// GenerateSingletonBuildActions method as it cannot create it for itself.
 	dexpreopt.GetGlobalSoongConfig(ctx)
-
-	imageConfig := b.getImageConfig(ctx)
-	if imageConfig == nil {
-		return
-	}
-
-	// Construct the boot image info from the config.
-	info := BootImageInfo{imageConfig: imageConfig}
-
-	// Make it available for other modules.
-	ctx.SetProvider(BootImageInfoProvider, info)
 }
 
 func (b *platformBootclasspathModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {