Propagate transitive missing optional_uses_libs.

Bug: 331528424
Test: m --no-skip-soong-tests
Ignore-AOSP-First: Depends on internal changes. Will cherry-pick once merged.
Merged-In: Ied2821f11b6a5056ecf577e1e25765bc6dd212c0
Change-Id: Ied2821f11b6a5056ecf577e1e25765bc6dd212c0
diff --git a/java/aar.go b/java/aar.go
index 037342a..752d683 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -356,12 +356,13 @@
 	forceNonFinalResourceIDs       bool
 	extraLinkFlags                 []string
 	aconfigTextFiles               android.Paths
+	usesLibrary                    *usesLibrary
 }
 
 func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptions) {
 
 	staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedExportPackages, libFlags :=
-		aaptLibs(ctx, opts.sdkContext, opts.classLoaderContexts)
+		aaptLibs(ctx, opts.sdkContext, opts.classLoaderContexts, opts.usesLibrary)
 
 	// Exclude any libraries from the supplied list.
 	opts.classLoaderContexts = opts.classLoaderContexts.ExcludeLibs(opts.excludedLibs)
@@ -703,7 +704,8 @@
 }
 
 // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
-func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap) (
+func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext,
+	classLoaderContexts dexpreopt.ClassLoaderContextMap, usesLibrary *usesLibrary) (
 	staticResourcesNodes, sharedResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir],
 	staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) {
 
@@ -753,6 +755,9 @@
 		}
 
 		addCLCFromDep(ctx, module, classLoaderContexts)
+		if usesLibrary != nil {
+			addMissingOptionalUsesLibsFromDep(ctx, module, usesLibrary)
+		}
 	})
 
 	// AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later.
@@ -829,6 +834,7 @@
 			classLoaderContexts:            a.classLoaderContexts,
 			enforceDefaultTargetSdkVersion: false,
 			aconfigTextFiles:               getAconfigFilePaths(ctx),
+			usesLibrary:                    &a.usesLibrary,
 		},
 	)
 
@@ -1212,7 +1218,7 @@
 	linkDeps = append(linkDeps, a.manifest)
 
 	staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags :=
-		aaptLibs(ctx, android.SdkContext(a), nil)
+		aaptLibs(ctx, android.SdkContext(a), nil, nil)
 
 	_ = sharedResourcesNodesDepSet
 	_ = staticRRODirsDepSet
@@ -1282,6 +1288,7 @@
 			}
 		}
 		addCLCFromDep(ctx, module, a.classLoaderContexts)
+		addMissingOptionalUsesLibsFromDep(ctx, module, &a.usesLibrary)
 	})
 
 	if len(staticJars) > 0 {
diff --git a/java/app.go b/java/app.go
index a02ada1..61e3235 100755
--- a/java/app.go
+++ b/java/app.go
@@ -527,6 +527,7 @@
 			forceNonFinalResourceIDs:       nonFinalIds,
 			extraLinkFlags:                 aaptLinkFlags,
 			aconfigTextFiles:               getAconfigFilePaths(ctx),
+			usesLibrary:                    &a.usesLibrary,
 		},
 	)
 
diff --git a/java/app_test.go b/java/app_test.go
index d5c1cc7..c8bc770 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -3244,7 +3244,10 @@
 			name: "static-y",
 			srcs: ["a.java"],
 			uses_libs: ["runtime-required-y"],
-			optional_uses_libs: ["runtime-optional-y"],
+			optional_uses_libs: [
+				"runtime-optional-y",
+				"missing-lib-a",
+			],
 			sdk_version: "current",
 		}
 
@@ -3341,7 +3344,8 @@
 		`--optional-uses-library bar ` +
 		`--optional-uses-library runtime-optional-x ` +
 		`--optional-uses-library runtime-optional-y ` +
-		`--missing-optional-uses-library missing-lib-b `
+		`--missing-optional-uses-library missing-lib-b ` +
+		`--missing-optional-uses-library missing-lib-a`
 	android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
 
 	// Test that all libraries are verified for an APK (library order matters).
diff --git a/java/base.go b/java/base.go
index 241030e..abe1e69 100644
--- a/java/base.go
+++ b/java/base.go
@@ -2385,6 +2385,7 @@
 		}
 
 		addCLCFromDep(ctx, module, j.classLoaderContexts)
+		addMissingOptionalUsesLibsFromDep(ctx, module, &j.usesLibrary)
 	})
 
 	return deps
diff --git a/java/java.go b/java/java.go
index f523847..963651a 100644
--- a/java/java.go
+++ b/java/java.go
@@ -3151,6 +3151,22 @@
 	}
 }
 
+func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.Module,
+	usesLibrary *usesLibrary) {
+
+	dep, ok := depModule.(ModuleWithUsesLibrary)
+	if !ok {
+		return
+	}
+
+	for _, lib := range dep.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)
+		}
+	}
+}
+
 type JavaApiContributionImport struct {
 	JavaApiContribution