Add support for prebuilt java_sdk_library modules

Add java_sdk_library_import for use when a java_sdk_library may
be used by unbundled branches that do not have the project that
contains the original java_sdk_library module.

Bug: 130287656
Test: m checkbuild
Change-Id: I62df4bccc0da95ed6c8b31dab8f2c32cc3215e9e
diff --git a/java/java.go b/java/java.go
index bf62578..7768756 100644
--- a/java/java.go
+++ b/java/java.go
@@ -713,7 +713,7 @@
 				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
 				// names of sdk libs that are directly depended are exported
 				j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
-			default:
+			case staticLibTag:
 				ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
 			}
 		case Dependency:
diff --git a/java/java_test.go b/java/java_test.go
index 89f871c..0a1c17c 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -86,6 +86,7 @@
 	ctx.RegisterModuleType("droiddoc_host", android.ModuleFactoryAdaptor(DroiddocHostFactory))
 	ctx.RegisterModuleType("droiddoc_template", android.ModuleFactoryAdaptor(ExportedDroiddocDirFactory))
 	ctx.RegisterModuleType("java_sdk_library", android.ModuleFactoryAdaptor(SdkLibraryFactory))
+	ctx.RegisterModuleType("java_sdk_library_import", android.ModuleFactoryAdaptor(sdkLibraryImportFactory))
 	ctx.RegisterModuleType("override_android_app", android.ModuleFactoryAdaptor(OverrideAndroidAppModuleFactory))
 	ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(PrebuiltApisFactory))
 	ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
@@ -323,7 +324,7 @@
 		java_library {
 			name: "foo",
 			srcs: ["a.java"],
-			libs: ["bar"],
+			libs: ["bar", "sdklib"],
 			static_libs: ["baz"],
 		}
 
@@ -341,17 +342,27 @@
 			name: "qux",
 			jars: ["b.jar"],
 		}
+
+		java_sdk_library_import {
+			name: "sdklib",
+			jars: ["b.jar"],
+		}
 		`)
 
 	javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
 	combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
 	barJar := ctx.ModuleForTests("bar", "android_common").Rule("combineJar").Output
 	bazJar := ctx.ModuleForTests("baz", "android_common").Rule("combineJar").Output
+	sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output
 
 	if !strings.Contains(javac.Args["classpath"], barJar.String()) {
 		t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String())
 	}
 
+	if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) {
+		t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String())
+	}
+
 	if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != bazJar.String() {
 		t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String())
 	}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 3bda9c7..c60a8a0 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -75,6 +75,7 @@
 
 func init() {
 	android.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
+	android.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory)
 
 	android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
 		javaSdkLibraries := javaSdkLibraries(ctx.Config())
@@ -731,3 +732,112 @@
 	android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.CreateInternalModules(ctx) })
 	return module
 }
+
+//
+// SDK library prebuilts
+//
+
+type sdkLibraryImportProperties struct {
+	Jars []string `android:"path"`
+
+	Sdk_version *string
+
+	Installable *bool
+
+	// List of shared java libs that this module has dependencies to
+	Libs []string
+
+	// List of files to remove from the jar file(s)
+	Exclude_files []string
+
+	// List of directories to remove from the jar file(s)
+	Exclude_dirs []string
+}
+
+type sdkLibraryImport struct {
+	android.ModuleBase
+	android.DefaultableModuleBase
+	prebuilt android.Prebuilt
+
+	properties sdkLibraryImportProperties
+
+	stubsPath android.Paths
+}
+
+var _ SdkLibraryDependency = (*sdkLibraryImport)(nil)
+
+func sdkLibraryImportFactory() android.Module {
+	module := &sdkLibraryImport{}
+
+	module.AddProperties(&module.properties)
+
+	android.InitPrebuiltModule(module, &module.properties.Jars)
+	InitJavaModule(module, android.HostAndDeviceSupported)
+
+	android.AddLoadHook(module, func(mctx android.LoadHookContext) { module.createInternalModules(mctx) })
+	return module
+}
+
+func (module *sdkLibraryImport) Prebuilt() *android.Prebuilt {
+	return &module.prebuilt
+}
+
+func (module *sdkLibraryImport) Name() string {
+	return module.prebuilt.Name(module.ModuleBase.Name())
+}
+
+func (module *sdkLibraryImport) createInternalModules(mctx android.LoadHookContext) {
+	// Creates a java import for the jar with ".stubs" suffix
+	props := struct {
+		Name             *string
+		Soc_specific     *bool
+		Device_specific  *bool
+		Product_specific *bool
+	}{}
+
+	props.Name = proptools.StringPtr(module.BaseModuleName() + sdkStubsLibrarySuffix)
+
+	if module.SocSpecific() {
+		props.Soc_specific = proptools.BoolPtr(true)
+	} else if module.DeviceSpecific() {
+		props.Device_specific = proptools.BoolPtr(true)
+	} else if module.ProductSpecific() {
+		props.Product_specific = proptools.BoolPtr(true)
+	}
+
+	mctx.CreateModule(android.ModuleFactoryAdaptor(ImportFactory), &props, &module.properties)
+
+	javaSdkLibraries := javaSdkLibraries(mctx.Config())
+	javaSdkLibrariesLock.Lock()
+	defer javaSdkLibrariesLock.Unlock()
+	*javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
+}
+
+func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
+	// Add dependencies to the prebuilt stubs library
+	ctx.AddVariationDependencies(nil, publicApiStubsTag, module.BaseModuleName()+sdkStubsLibrarySuffix)
+}
+
+func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	// Record the paths to the prebuilt stubs library.
+	ctx.VisitDirectDeps(func(to android.Module) {
+		tag := ctx.OtherModuleDependencyTag(to)
+
+		switch tag {
+		case publicApiStubsTag:
+			module.stubsPath = to.(Dependency).HeaderJars()
+		}
+	})
+}
+
+// to satisfy SdkLibraryDependency interface
+func (module *sdkLibraryImport) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
+	// This module is just a wrapper for the prebuilt stubs.
+	return module.stubsPath
+}
+
+// to satisfy SdkLibraryDependency interface
+func (module *sdkLibraryImport) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
+	// This module is just a wrapper for the stubs.
+	return module.stubsPath
+}