Enforce bcp/sscp stubs do not compile against apps

This ensures that we do not run into circular depencies when
UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT=true. When this variable
is true, apps compile with a min_sdk_version equivalent to the sha of
the apis (i.e. the java_genrule `api_fingerprint`). If the api stubs are
allowed to depend on android apps, we will run into circular deps

Implementation details
1. Modify the deps mutator of combined_apis to add a dependency on the
   stub java modules
2. Do a graph walk in GenerateAndroidBuildActions and ensure that no
   child is an android_app. This will be determined by casting to
AndroidLibraryDependency.

Re (2): this does a graph walk via ctx.WalkDeps, but should not be
computationally intensive because
(a) We do this for a single module (i.e. combined_apis)
(b) The transitive closure is shallow since it starts from stubs

Test: presubmits
Test: locally, added an app to libs of `service-sdksandbox` and verified
that the error is raised

Bug: 315016205
Change-Id: Iaf35f03171d13d75e75de6e0e744fcf34e3294fd
diff --git a/api/api.go b/api/api.go
index c733f5b..e885823 100644
--- a/api/api.go
+++ b/api/api.go
@@ -79,7 +79,45 @@
 
 var PrepareForCombinedApisTest = android.FixtureRegisterWithContext(registerBuildComponents)
 
+func (a *CombinedApis) apiFingerprintStubDeps() []string {
+	ret := []string{}
+	ret = append(
+		ret,
+		transformArray(a.properties.Bootclasspath, "", ".stubs")...,
+	)
+	ret = append(
+		ret,
+		transformArray(a.properties.Bootclasspath, "", ".stubs.system")...,
+	)
+	ret = append(
+		ret,
+		transformArray(a.properties.Bootclasspath, "", ".stubs.module_lib")...,
+	)
+	ret = append(
+		ret,
+		transformArray(a.properties.System_server_classpath, "", ".stubs.system_server")...,
+	)
+	return ret
+}
+
+func (a *CombinedApis) DepsMutator(ctx android.BottomUpMutatorContext) {
+	ctx.AddDependency(ctx.Module(), nil, a.apiFingerprintStubDeps()...)
+}
+
 func (a *CombinedApis) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	ctx.WalkDeps(func(child, parent android.Module) bool {
+		if _, ok := child.(java.AndroidLibraryDependency); ok && child.Name() != "framework-res" {
+			// Stubs of BCP and SSCP libraries should not have any dependencies on apps
+			// This check ensures that we do not run into circular dependencies when UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT=true
+			ctx.ModuleErrorf(
+				"Module %s is not a valid dependency of the stub library %s\n."+
+					"If this dependency has been added via `libs` of java_sdk_library, please move it to `impl_only_libs`\n",
+				child.Name(), parent.Name())
+			return false // error detected
+		}
+		return true
+	})
+
 }
 
 type genruleProps struct {