Propagate <uses-library> dependencies from `java_library` to apps.

Automatically add `uses_libs`/`optional_uses_libs` properties specified
in `java_library` modules to the apps that transitively depend on these
libraries.

Note that a library may choose to specify its <uses-library> deps as
either optional or required. If this is not the right choice for an app,
it should be able to override it by specifying its own `uses_libs`/
`optional_uses_libs` properties.

Add Soong tests to cover the new cases.

Bug: 196377222
Test: lunch aosp_cf_x86_64_phone-userdebug && m
Change-Id: I601f3e2830ed9699b78d911966ee70812d32b4f6
diff --git a/java/app_test.go b/java/app_test.go
index 8de6691..c14c65d 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2285,6 +2285,49 @@
 			sdk_version: "current",
 		}
 
+		java_library {
+			name: "runtime-required-x",
+			srcs: ["a.java"],
+			installable: true,
+			sdk_version: "current",
+		}
+
+		java_library {
+			name: "runtime-optional-x",
+			srcs: ["a.java"],
+			installable: true,
+			sdk_version: "current",
+		}
+
+		android_library {
+			name: "static-x",
+			uses_libs: ["runtime-required-x"],
+			optional_uses_libs: ["runtime-optional-x"],
+			sdk_version: "current",
+		}
+
+		java_library {
+			name: "runtime-required-y",
+			srcs: ["a.java"],
+			installable: true,
+			sdk_version: "current",
+		}
+
+		java_library {
+			name: "runtime-optional-y",
+			srcs: ["a.java"],
+			installable: true,
+			sdk_version: "current",
+		}
+
+		java_library {
+			name: "static-y",
+			srcs: ["a.java"],
+			uses_libs: ["runtime-required-y"],
+			optional_uses_libs: ["runtime-optional-y"],
+			sdk_version: "current",
+		}
+
 		// A library that has to use "provides_uses_lib", because:
 		//    - it is not an SDK library
 		//    - its library name is different from its module name
@@ -2307,6 +2350,8 @@
 				// statically linked component libraries should not pull their SDK libraries,
 				// so "fred" should not be added to class loader context
 				"fred.stubs",
+				"static-x",
+				"static-y",
 			],
 			uses_libs: [
 				"foo",
@@ -2356,7 +2401,11 @@
 		`--uses-library foo ` + // TODO(b/132357300): "foo" should not be passed to manifest_fixer
 		`--uses-library com.non.sdk.lib ` + // TODO(b/132357300): "com.non.sdk.lib" should not be passed to manifest_fixer
 		`--uses-library runtime-library ` +
-		`--optional-uses-library bar` // TODO(b/132357300): "bar" should not be passed to manifest_fixer
+		`--uses-library runtime-required-x ` + // TODO(b/132357300): "runtime-required-x" should not be passed to manifest_fixer
+		`--uses-library runtime-required-y ` + // TODO(b/132357300): "runtime-required-y" should not be passed to manifest_fixer
+		`--optional-uses-library bar ` + // TODO(b/132357300): "bar" should not be passed to manifest_fixer
+		`--optional-uses-library runtime-optional-x ` + // TODO(b/132357300): "runtime-optional-x" should not be passed to manifest_fixer
+		`--optional-uses-library runtime-optional-y` // TODO(b/132357300): "runtime-optional-y" should not be passed to manifest_fixer
 	android.AssertStringEquals(t, "manifest_fixer args", expectManifestFixerArgs, actualManifestFixerArgs)
 
 	// Test that all libraries are verified (library order matters).
@@ -2366,8 +2415,12 @@
 		`--uses-library qux ` +
 		`--uses-library quuz ` +
 		`--uses-library runtime-library ` +
+		`--uses-library runtime-required-x ` +
+		`--uses-library runtime-required-y ` +
 		`--optional-uses-library bar ` +
-		`--optional-uses-library baz `
+		`--optional-uses-library baz ` +
+		`--optional-uses-library runtime-optional-x ` +
+		`--optional-uses-library runtime-optional-y `
 	android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
 
 	// Test that all libraries are verified for an APK (library order matters).
@@ -2387,7 +2440,11 @@
 		`PCL[/system/framework/foo.jar]#` +
 		`PCL[/system/framework/non-sdk-lib.jar]#` +
 		`PCL[/system/framework/bar.jar]#` +
-		`PCL[/system/framework/runtime-library.jar]`
+		`PCL[/system/framework/runtime-library.jar]#` +
+		`PCL[/system/framework/runtime-required-x.jar]#` +
+		`PCL[/system/framework/runtime-optional-x.jar]#` +
+		`PCL[/system/framework/runtime-required-y.jar]#` +
+		`PCL[/system/framework/runtime-optional-y.jar] `
 	android.AssertStringDoesContain(t, "dexpreopt app cmd args", cmd, w)
 
 	// Test conditional context for target SDK version 28.
diff --git a/java/java.go b/java/java.go
index 5bf3d79..b46324f 100644
--- a/java/java.go
+++ b/java/java.go
@@ -511,7 +511,7 @@
 		j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
 	}
 	j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
-	j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
+	j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
 	j.compile(ctx, nil)
 
 	// Collect the module directory for IDE info in java/jdeps.go.
@@ -530,6 +530,7 @@
 
 func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
 	j.deps(ctx)
+	j.usesLibrary.deps(ctx, false)
 }
 
 const (
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index eeec504..938bb28 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -157,7 +157,7 @@
 	qux := result.ModuleForTests("qux", "android_common")
 	if quxLib, ok := qux.Module().(*Library); ok {
 		requiredSdkLibs, optionalSdkLibs := quxLib.ClassLoaderContexts().UsesLibs()
-		android.AssertDeepEquals(t, "qux exports (required)", []string{"foo", "bar", "fred", "quuz"}, requiredSdkLibs)
+		android.AssertDeepEquals(t, "qux exports (required)", []string{"fred", "quuz", "foo", "bar"}, requiredSdkLibs)
 		android.AssertDeepEquals(t, "qux exports (optional)", []string{}, optionalSdkLibs)
 	}
 }