Support transitive dependencies through android_libary_import modules

Fix dependencies of android_library_import modules so that the -nodeps
modules created by pom2bp are no longer necessary.  Provide transitive
manifests (b/288358614), combine static dependencies into the output
jars, and propagate uses_libraries and optional_uses_libraries from
dependencies.

Bug: 288358614
Test: TestManifestMerger
Test: TestAndroidResourceProcessor
Change-Id: Ief45169d04217826fbb21ba283602b38ef0dd3f6
diff --git a/java/aar.go b/java/aar.go
index 2835792..b327531 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -386,11 +386,6 @@
 	// Add additional manifest files to transitive manifests.
 	additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
 	transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...)
-	// TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
-	// modules.  Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
-	// of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
-	// android_library_import modules.  If this is fixed, staticManifestsDepSet can be dropped completely in favor of
-	// staticResourcesNodesDepSet.manifests()
 	transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...)
 
 	if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
@@ -757,7 +752,8 @@
 	// reverse later.
 	// NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in
 	// dependencies) the highest priority dependency is listed first, but for resources the highest priority
-	// dependency has to be listed last.
+	// dependency has to be listed last.  This is also inconsistent with the way manifests from the same
+	// transitive dependencies are merged.
 	staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
 		android.ReverseSliceInPlace(staticResourcesNodeDepSets))
 	sharedResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
@@ -972,7 +968,8 @@
 
 	properties AARImportProperties
 
-	classpathFile                      android.WritablePath
+	headerJarFile                      android.WritablePath
+	implementationJarFile              android.WritablePath
 	proguardFlags                      android.WritablePath
 	exportPackage                      android.WritablePath
 	transitiveAaptResourcePackagesFile android.Path
@@ -993,6 +990,9 @@
 	sdkVersion    android.SdkSpec
 	minSdkVersion android.ApiLevel
 
+	usesLibrary
+	classLoaderContexts dexpreopt.ClassLoaderContextMap
+
 	// Single aconfig "cache file" merged from this module and all dependencies.
 	mergedAconfigFiles map[string]android.Paths
 }
@@ -1005,7 +1005,7 @@
 	case ".aar":
 		return []android.Path{a.aarPath}, nil
 	case "":
-		return []android.Path{a.classpathFile}, nil
+		return []android.Path{a.implementationJarFile}, nil
 	default:
 		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
 	}
@@ -1088,6 +1088,8 @@
 
 	ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...)
 	ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs...)
+
+	a.usesLibrary.deps(ctx, false)
 }
 
 type JniPackageInfo struct {
@@ -1146,7 +1148,7 @@
 	}
 
 	extractedAARDir := android.PathForModuleOut(ctx, "aar")
-	a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
+	classpathFile := extractedAARDir.Join(ctx, "classes-combined.jar")
 	a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
 	a.rTxt = extractedAARDir.Join(ctx, "R.txt")
 	a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
@@ -1162,11 +1164,11 @@
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        unzipAAR,
 		Input:       a.aarPath,
-		Outputs:     android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, a.rTxt},
+		Outputs:     android.WritablePaths{classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, a.rTxt},
 		Description: "unzip AAR",
 		Args: map[string]string{
 			"outDir":             extractedAARDir.String(),
-			"combinedClassesJar": a.classpathFile.String(),
+			"combinedClassesJar": classpathFile.String(),
 			"assetsPackage":      a.assetsPackage.String(),
 		},
 	})
@@ -1239,13 +1241,7 @@
 	a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build()
 
 	manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest)
-	// TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
-	// modules.  Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
-	// of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
-	// android_library_import modules.  If this is fixed, AndroidLibraryDependency.ManifestsDepSet can be dropped
-	// completely in favor of AndroidLibraryDependency.ResourceNodesDepSet.manifest
-	//manifestDepSetBuilder.Transitive(transitiveStaticDeps.manifests)
-	_ = staticManifestsDepSet
+	manifestDepSetBuilder.Transitive(staticManifestsDepSet)
 	a.manifestsDepSet = manifestDepSetBuilder.Build()
 
 	transitiveAaptResourcePackages := staticDeps.resPackages().Strings()
@@ -1257,12 +1253,45 @@
 	a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
 
 	a.collectTransitiveHeaderJars(ctx)
+
+	a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+
+	var staticJars android.Paths
+	var staticHeaderJars android.Paths
+	ctx.VisitDirectDeps(func(module android.Module) {
+		if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
+			tag := ctx.OtherModuleDependencyTag(module)
+			switch tag {
+			case staticLibTag:
+				staticJars = append(staticJars, dep.ImplementationJars...)
+				staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
+			}
+		}
+		addCLCFromDep(ctx, module, a.classLoaderContexts)
+	})
+
+	if len(staticJars) > 0 {
+		combineJars := append(android.Paths{classpathFile}, staticJars...)
+		a.implementationJarFile = android.PathForModuleOut(ctx, "combined", ctx.ModuleName()+".jar")
+		TransformJarsToJar(ctx, a.implementationJarFile, "combine", combineJars, android.OptionalPath{}, false, nil, nil)
+	} else {
+		a.implementationJarFile = classpathFile
+	}
+
+	if len(staticHeaderJars) > 0 {
+		combineJars := append(android.Paths{classpathFile}, staticHeaderJars...)
+		a.headerJarFile = android.PathForModuleOut(ctx, "turbine-combined", ctx.ModuleName()+".jar")
+		TransformJarsToJar(ctx, a.headerJarFile, "combine header jars", combineJars, android.OptionalPath{}, false, nil, nil)
+	} else {
+		a.headerJarFile = classpathFile
+	}
+
 	android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
-		HeaderJars:                     android.PathsIfNonNil(a.classpathFile),
+		HeaderJars:                     android.PathsIfNonNil(a.headerJarFile),
 		TransitiveLibsHeaderJars:       a.transitiveLibsHeaderJars,
 		TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
-		ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
-		ImplementationJars:             android.PathsIfNonNil(a.classpathFile),
+		ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationJarFile),
+		ImplementationJars:             android.PathsIfNonNil(a.implementationJarFile),
 		StubsLinkType:                  Implementation,
 		// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
 	})
@@ -1295,15 +1324,15 @@
 }
 
 func (a *AARImport) HeaderJars() android.Paths {
-	return android.Paths{a.classpathFile}
+	return android.Paths{a.headerJarFile}
 }
 
 func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
-	return android.Paths{a.classpathFile}
+	return android.Paths{a.implementationJarFile}
 }
 
-func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) android.Path {
-	return nil
+func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
+	return OptionalDexJarPath{}
 }
 
 func (a *AARImport) DexJarInstallPath() android.Path {
@@ -1311,9 +1340,11 @@
 }
 
 func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
-	return nil
+	return a.classLoaderContexts
 }
 
+var _ UsesLibraryDependency = (*AARImport)(nil)
+
 var _ android.ApexModule = (*AARImport)(nil)
 
 // Implements android.ApexModule
@@ -1322,7 +1353,7 @@
 }
 
 // Implements android.ApexModule
-func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
+func (a *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
 	sdkVersion android.ApiLevel) error {
 	return nil
 }
@@ -1336,7 +1367,10 @@
 func AARImportFactory() android.Module {
 	module := &AARImport{}
 
-	module.AddProperties(&module.properties)
+	module.AddProperties(
+		&module.properties,
+		&module.usesLibrary.usesLibraryProperties,
+	)
 
 	android.InitPrebuiltModule(module, &module.properties.Aars)
 	android.InitApexModule(module)
diff --git a/java/android_manifest_test.go b/java/android_manifest_test.go
index 5909b1e..7c91884 100644
--- a/java/android_manifest_test.go
+++ b/java/android_manifest_test.go
@@ -92,10 +92,9 @@
 			"out/soong/.intermediates/transitive/android_common/manifest_fixer/AndroidManifest.xml",
 			"transitive/AndroidManifest2.xml",
 			"out/soong/.intermediates/transitive_import/android_common/aar/AndroidManifest.xml",
+			"out/soong/.intermediates/transitive_import_dep/android_common/aar/AndroidManifest.xml",
 			"out/soong/.intermediates/direct_import/android_common/aar/AndroidManifest.xml",
-			// TODO(b/288358614): Soong has historically not merged manifests from dependencies of
-			// android_library_import modules.
-
+			"out/soong/.intermediates/direct_import_dep/android_common/aar/AndroidManifest.xml",
 		},
 		manifestMergerRule.Implicits)
 }
diff --git a/java/androidmk.go b/java/androidmk.go
index 498962f..e1b4efd 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -262,13 +262,13 @@
 	}
 	return []android.AndroidMkEntries{android.AndroidMkEntries{
 		Class:      "JAVA_LIBRARIES",
-		OutputFile: android.OptionalPathForPath(prebuilt.classpathFile),
+		OutputFile: android.OptionalPathForPath(prebuilt.implementationJarFile),
 		Include:    "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
 		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
 			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
 				entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
-				entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.classpathFile)
-				entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.classpathFile)
+				entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.headerJarFile)
+				entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.implementationJarFile)
 				entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", prebuilt.exportPackage)
 				entries.SetPath("LOCAL_SOONG_TRANSITIVE_RES_PACKAGES", prebuilt.transitiveAaptResourcePackagesFile)
 				entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", prebuilt.proguardFlags)
diff --git a/java/app_test.go b/java/app_test.go
index b75cb16..ca9d317 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -829,12 +829,12 @@
 				"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
 				"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
 				"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
-				"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
 			},
 			appCombined: []string{
 				"out/soong/.intermediates/app/android_common/javac/app.jar",
 				"out/soong/.intermediates/direct/android_common/combined/direct.jar",
-				"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
 			},
 
 			directResources: nil,
@@ -849,12 +849,12 @@
 			directClasspath: []string{
 				"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
 				"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
-				"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
 			},
 			directCombined: []string{
 				"out/soong/.intermediates/direct/android_common/javac/direct.jar",
 				"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
-				"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
 			},
 
 			transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -928,13 +928,13 @@
 				"out/soong/.intermediates/app/android_common/busybox/R.jar",
 				"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
 				"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
-				"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
 			},
 			appCombined: []string{
 				"out/soong/.intermediates/app/android_common/javac/app.jar",
 				"out/soong/.intermediates/app/android_common/busybox/R.jar",
 				"out/soong/.intermediates/direct/android_common/combined/direct.jar",
-				"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
 			},
 
 			directResources: nil,
@@ -953,12 +953,12 @@
 				"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
 				"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
 				"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
-				"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
 			},
 			directCombined: []string{
 				"out/soong/.intermediates/direct/android_common/javac/direct.jar",
 				"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
-				"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
 			},
 
 			transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -1034,13 +1034,13 @@
 				"out/soong/.intermediates/app/android_common/busybox/R.jar",
 				"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
 				"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
-				"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
 			},
 			appCombined: []string{
 				"out/soong/.intermediates/app/android_common/javac/app.jar",
 				"out/soong/.intermediates/app/android_common/busybox/R.jar",
 				"out/soong/.intermediates/direct/android_common/combined/direct.jar",
-				"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
 			},
 
 			dontVerifyDirect:           true,
@@ -1075,12 +1075,12 @@
 				"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
 				"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
 				"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
-				"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
 			},
 			appCombined: []string{
 				"out/soong/.intermediates/app/android_common/javac/app.jar",
 				"out/soong/.intermediates/direct/android_common/combined/direct.jar",
-				"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
 			},
 
 			directResources: nil,
@@ -1098,12 +1098,12 @@
 				"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
 				"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
 				"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
-				"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
 			},
 			directCombined: []string{
 				"out/soong/.intermediates/direct/android_common/javac/direct.jar",
 				"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
-				"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
 			},
 
 			dontVerifyTransitive:       true,
@@ -1137,12 +1137,12 @@
 				"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
 				"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
 				"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
-				"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
 			},
 			appCombined: []string{
 				"out/soong/.intermediates/app/android_common/javac/app.jar",
 				"out/soong/.intermediates/direct/android_common/combined/direct.jar",
-				"out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
 			},
 
 			directResources: nil,
@@ -1157,12 +1157,12 @@
 			directClasspath: []string{
 				"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
 				"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
-				"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
 			},
 			directCombined: []string{
 				"out/soong/.intermediates/direct/android_common/javac/direct.jar",
 				"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
-				"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+				"out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
 			},
 
 			transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},