Revert "Remove java_sdk_library "magic""

Revert submission 3271699

Reason for revert: DroidMonitor: Potential culprit for http://b/368606825 - verifying through ABTD before submission. 

Reverted changes: /q/submissionid:3271699

Change-Id: If40f7956e699246cf1d72ffc50ffffa4696504df
diff --git a/java/sdk_library.go b/java/sdk_library.go
index c3ffb46..7daaca7 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -268,6 +268,10 @@
 	return baseName + ".stubs.source" + scope.moduleSuffix
 }
 
+func (scope *apiScope) apiModuleName(baseName string) string {
+	return baseName + ".api" + scope.moduleSuffix
+}
+
 func (scope *apiScope) String() string {
 	return scope.name
 }
@@ -1078,6 +1082,21 @@
 	return nil
 }
 
+func (c *commonToSdkLibraryAndImport) selectHeaderJarsForSdkVersion(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
+
+	// If a specific numeric version has been requested then use prebuilt versions of the sdk.
+	if !sdkVersion.ApiLevel.IsPreview() {
+		return PrebuiltJars(ctx, c.module.RootLibraryName(), sdkVersion)
+	}
+
+	paths := c.selectScopePaths(ctx, sdkVersion.Kind)
+	if paths == nil {
+		return nil
+	}
+
+	return paths.stubsHeaderPath
+}
+
 // selectScopePaths returns the *scopePaths appropriate for the specific kind.
 //
 // If the module does not support the specific kind then it will return the *scopePaths for the
@@ -1244,6 +1263,12 @@
 type SdkLibraryDependency interface {
 	SdkLibraryComponentDependency
 
+	// Get the header jars appropriate for the supplied sdk_version.
+	//
+	// These are turbine generated jars so they only change if the externals of the
+	// class changes but it does not contain and implementation or JavaDoc.
+	SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths
+
 	// SdkApiStubDexJar returns the dex jar for the stubs for the prebuilt
 	// java_sdk_library_import module. It is needed by the hiddenapi processing tool which
 	// processes dex files.
@@ -2207,6 +2232,72 @@
 	mctx.CreateModule(sdkLibraryXmlFactory, &props)
 }
 
+func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s android.SdkSpec) android.Paths {
+	var ver android.ApiLevel
+	var kind android.SdkKind
+	if s.UsePrebuilt(ctx) {
+		ver = s.ApiLevel
+		kind = s.Kind
+	} else {
+		// We don't have prebuilt SDK for the specific sdkVersion.
+		// Instead of breaking the build, fallback to use "system_current"
+		ver = android.FutureApiLevel
+		kind = android.SdkSystem
+	}
+
+	dir := filepath.Join("prebuilts", "sdk", ver.String(), kind.String())
+	jar := filepath.Join(dir, baseName+".jar")
+	jarPath := android.ExistentPathForSource(ctx, jar)
+	if !jarPath.Valid() {
+		if ctx.Config().AllowMissingDependencies() {
+			return android.Paths{android.PathForSource(ctx, jar)}
+		} else {
+			ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", s.Raw, jar)
+		}
+		return nil
+	}
+	return android.Paths{jarPath.Path()}
+}
+
+// Check to see if the other module is within the same set of named APEXes as this module.
+//
+// If either this or the other module are on the platform then this will return
+// false.
+func withinSameApexesAs(ctx android.BaseModuleContext, other android.Module) bool {
+	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
+	otherApexInfo, _ := android.OtherModuleProvider(ctx, other, android.ApexInfoProvider)
+	return len(otherApexInfo.InApexVariants) > 0 && reflect.DeepEqual(apexInfo.InApexVariants, otherApexInfo.InApexVariants)
+}
+
+func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
+	// If the client doesn't set sdk_version, but if this library prefers stubs over
+	// the impl library, let's provide the widest API surface possible. To do so,
+	// force override sdk_version to module_current so that the closest possible API
+	// surface could be found in selectHeaderJarsForSdkVersion
+	if module.defaultsToStubs() && !sdkVersion.Specified() {
+		sdkVersion = android.SdkSpecFrom(ctx, "module_current")
+	}
+
+	// Only provide access to the implementation library if it is actually built.
+	if module.requiresRuntimeImplementationLibrary() {
+		// Check any special cases for java_sdk_library.
+		//
+		// Only allow access to the implementation library in the following condition:
+		// * No sdk_version specified on the referencing module.
+		// * The referencing module is in the same apex as this.
+		if sdkVersion.Kind == android.SdkPrivate || withinSameApexesAs(ctx, module) {
+			return module.implLibraryHeaderJars
+		}
+	}
+
+	return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion)
+}
+
+// to satisfy SdkLibraryDependency interface
+func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
+	return module.sdkJars(ctx, sdkVersion)
+}
+
 var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
 
 func javaSdkLibraries(config android.Config) *[]string {
@@ -2325,6 +2416,10 @@
 	return !proptools.Bool(module.sdkLibraryProperties.Api_only)
 }
 
+func (module *SdkLibrary) defaultsToStubs() bool {
+	return proptools.Bool(module.sdkLibraryProperties.Default_to_stubs)
+}
+
 func moduleStubLinkType(j *Module) (stub bool, ret sdkLinkType) {
 	kind := android.ToSdkKind(proptools.String(j.properties.Stub_contributing_api))
 	switch kind {
@@ -2826,6 +2921,28 @@
 	})
 }
 
+func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec, headerJars bool) android.Paths {
+
+	// For consistency with SdkLibrary make the implementation jar available to libraries that
+	// are within the same APEX.
+	implLibraryModule := module.implLibraryModule
+	if implLibraryModule != nil && withinSameApexesAs(ctx, module) {
+		if headerJars {
+			return implLibraryModule.HeaderJars()
+		} else {
+			return implLibraryModule.ImplementationJars()
+		}
+	}
+
+	return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion)
+}
+
+// to satisfy SdkLibraryDependency interface
+func (module *SdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
+	// This module is just a wrapper for the prebuilt stubs.
+	return module.sdkJars(ctx, sdkVersion, true)
+}
+
 // to satisfy UsesLibraryDependency interface
 func (module *SdkLibraryImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
 	// The dex implementation jar extracted from the .apex file should be used in preference to the