Propagate min and max sdk versions to classpaths.proto configs.

These attributed define a range for dessert releases where the jars
should be active, and included in corresponding CLASSPATH varibles by
derive_classpath.

Bug: 190818041
Test: presubmit
Change-Id: Ieb9aef29657ad0694d48a63019f93faca2678252
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index f63d81d..92e01a2 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -84,11 +84,10 @@
 
 // Matches definition of Jar in packages/modules/SdkExtensions/proto/classpaths.proto
 type classpathJar struct {
-	path      string
-	classpath classpathType
-	// TODO(satayev): propagate min/max sdk versions for the jars
-	minSdkVersion int32
-	maxSdkVersion int32
+	path          string
+	classpath     classpathType
+	minSdkVersion string
+	maxSdkVersion string
 }
 
 // gatherPossibleApexModuleNamesAndStems returns a set of module and stem names from the
@@ -120,10 +119,32 @@
 	jars := make([]classpathJar, 0, len(paths)*len(classpaths))
 	for i := 0; i < len(paths); i++ {
 		for _, classpathType := range classpaths {
-			jars = append(jars, classpathJar{
+			jar := classpathJar{
 				classpath: classpathType,
 				path:      paths[i],
+			}
+			ctx.VisitDirectDepsIf(func(m android.Module) bool {
+				return m.Name() == configuredJars.Jar(i)
+			}, func(m android.Module) {
+				if s, ok := m.(*SdkLibrary); ok {
+					// TODO(208456999): instead of mapping "current" to latest, min_sdk_version should never be set to "current"
+					if s.minSdkVersion.Specified() {
+						if s.minSdkVersion.ApiLevel.IsCurrent() {
+							jar.minSdkVersion = ctx.Config().LatestPreviewApiLevel().String()
+						} else {
+							jar.minSdkVersion = s.minSdkVersion.ApiLevel.String()
+						}
+					}
+					if s.maxSdkVersion.Specified() {
+						if s.maxSdkVersion.ApiLevel.IsCurrent() {
+							jar.maxSdkVersion = ctx.Config().LatestPreviewApiLevel().String()
+						} else {
+							jar.maxSdkVersion = s.maxSdkVersion.ApiLevel.String()
+						}
+					}
+				}
 			})
+			jars = append(jars, jar)
 		}
 	}
 	return jars
@@ -161,6 +182,7 @@
 
 func writeClasspathsJson(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) {
 	var content strings.Builder
+
 	fmt.Fprintf(&content, "{\n")
 	fmt.Fprintf(&content, "\"jars\": [\n")
 	for idx, jar := range jars {
@@ -169,6 +191,20 @@
 		fmt.Fprintf(&content, "\"path\": \"%s\",\n", jar.path)
 		fmt.Fprintf(&content, "\"classpath\": \"%s\"\n", jar.classpath)
 
+		if jar.minSdkVersion != "" {
+			fmt.Fprintf(&content, ",\n")
+			fmt.Fprintf(&content, "\"minSdkVersion\": \"%s\"\n", jar.minSdkVersion)
+		} else {
+			fmt.Fprintf(&content, "\n")
+		}
+
+		if jar.maxSdkVersion != "" {
+			fmt.Fprintf(&content, ",\n")
+			fmt.Fprintf(&content, "\"maxSdkVersion\": \"%s\"\n", jar.maxSdkVersion)
+		} else {
+			fmt.Fprintf(&content, "\n")
+		}
+
 		if idx < len(jars)-1 {
 			fmt.Fprintf(&content, "},\n")
 		} else {
@@ -177,6 +213,7 @@
 	}
 	fmt.Fprintf(&content, "]\n")
 	fmt.Fprintf(&content, "}\n")
+
 	android.WriteFileRule(ctx, output, content.String())
 }