Merge "Use module-lib system modules when building from prebuilts"
diff --git a/android/api_levels.go b/android/api_levels.go
index 93583bc..c1b3ba2 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -177,6 +177,10 @@
 // libandroid_support.
 var FirstNonLibAndroidSupportVersion = uncheckedFinalApiLevel(21)
 
+// LastWithoutModuleLibCoreSystemModules is the last API level where prebuilts/sdk does not contain
+// a core-for-system-modules.jar for the module-lib API scope.
+var LastWithoutModuleLibCoreSystemModules = uncheckedFinalApiLevel(31)
+
 // If the `raw` input is the codename of an API level has been finalized, this
 // function returns the API level number associated with that API level. If the
 // input is *not* a finalized codename, the input is returned unmodified.
@@ -236,6 +240,27 @@
 	return apiLevel, nil
 }
 
+// ApiLevelForTest returns an ApiLevel constructed from the supplied raw string.
+//
+// This only supports "current" and numeric levels, code names are not supported.
+func ApiLevelForTest(raw string) ApiLevel {
+	if raw == "" {
+		panic("API level string must be non-empty")
+	}
+
+	if raw == "current" {
+		return FutureApiLevel
+	}
+
+	asInt, err := strconv.Atoi(raw)
+	if err != nil {
+		panic(fmt.Errorf("%q could not be parsed as an integer and is not a recognized codename", raw))
+	}
+
+	apiLevel := uncheckedFinalApiLevel(asInt)
+	return apiLevel
+}
+
 // Converts an API level string `raw` into an ApiLevel in the same method as
 // `ApiLevelFromUser`, but the input is assumed to have no errors and any errors
 // will panic instead of returning an error.
diff --git a/java/prebuilt_apis_test.go b/java/prebuilt_apis_test.go
index 7c2e526..79f4225 100644
--- a/java/prebuilt_apis_test.go
+++ b/java/prebuilt_apis_test.go
@@ -28,6 +28,7 @@
 		prepareForJavaTest,
 		FixtureWithPrebuiltApis(map[string][]string{
 			"31":      {},
+			"32":      {},
 			"current": {},
 		}),
 	).RunTest(t)
@@ -44,8 +45,11 @@
 		// 31 only has public system modules.
 		"sdk_public_31_system_modules",
 
-		// current only has public system modules.
+		// 32 and current both have public and module-lib system modules.
+		"sdk_public_32_system_modules",
+		"sdk_module-lib_32_system_modules",
 		"sdk_public_current_system_modules",
+		"sdk_module-lib_current_system_modules",
 	}
 	sort.Strings(expected)
 	android.AssertArrayString(t, "sdk system modules", expected, sdkSystemModules)
diff --git a/java/sdk.go b/java/sdk.go
index 42ed14f..34d68ae 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -60,10 +60,28 @@
 	}
 }
 
-// systemModuleKind returns the kind of system modules to use.
-func systemModuleKind() android.SdkKind {
-	// Currently, every sdk version uses the system modules for the public API.
-	return android.SdkPublic
+// systemModuleKind returns the kind of system modules to use for the supplied combination of sdk
+// kind and API level.
+func systemModuleKind(sdkKind android.SdkKind, apiLevel android.ApiLevel) android.SdkKind {
+	systemModuleKind := sdkKind
+	if apiLevel.LessThanOrEqualTo(android.LastWithoutModuleLibCoreSystemModules) {
+		// API levels less than or equal to 31 did not provide a core-for-system-modules.jar
+		// specifically for the module-lib API. So, always use the public system modules for them.
+		systemModuleKind = android.SdkPublic
+	} else if systemModuleKind == android.SdkCore {
+		// Core is by definition what is included in the system module for the public API so should
+		// just use its system modules.
+		systemModuleKind = android.SdkPublic
+	} else if systemModuleKind == android.SdkSystem || systemModuleKind == android.SdkTest {
+		// The core system and test APIs are currently the same as the public API so they should use
+		// its system modules.
+		systemModuleKind = android.SdkPublic
+	} else if systemModuleKind == android.SdkSystemServer {
+		// The core system server API is the same as the core module-lib API.
+		systemModuleKind = android.SdkModule
+	}
+
+	return systemModuleKind
 }
 
 func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) sdkDep {
@@ -111,7 +129,7 @@
 
 		var systemModules string
 		if defaultJavaLanguageVersion(ctx, sdkVersion).usesJavaModules() {
-			systemModuleKind := systemModuleKind()
+			systemModuleKind := systemModuleKind(sdkVersion.Kind, sdkVersion.ApiLevel)
 			systemModules = fmt.Sprintf("sdk_%s_%s_system_modules", systemModuleKind, sdkVersion.ApiLevel)
 		}
 
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 9a71192..5c4a6d2 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -304,7 +304,7 @@
 			name:           "module_current",
 			properties:     `sdk_version: "module_current",`,
 			bootclasspath:  []string{`""`},
-			system:         "sdk_public_current_system_modules",
+			system:         "sdk_module-lib_current_system_modules",
 			java8classpath: []string{"prebuilts/sdk/current/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
 			java9classpath: []string{"prebuilts/sdk/current/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
 			aidl:           "-pprebuilts/sdk/current/public/framework.aidl",
@@ -331,7 +331,7 @@
 			name:           "module_32",
 			properties:     `sdk_version: "module_32",`,
 			bootclasspath:  []string{`""`},
-			system:         "sdk_public_32_system_modules",
+			system:         "sdk_module-lib_32_system_modules",
 			java8classpath: []string{"prebuilts/sdk/32/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
 			java9classpath: []string{"prebuilts/sdk/32/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
 			aidl:           "-pprebuilts/sdk/32/public/framework.aidl",
@@ -354,7 +354,7 @@
 			name:           "system_server_current",
 			properties:     `sdk_version: "system_server_current",`,
 			bootclasspath:  []string{`""`},
-			system:         "sdk_public_current_system_modules",
+			system:         "sdk_module-lib_current_system_modules",
 			java8classpath: []string{"prebuilts/sdk/current/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
 			java9classpath: []string{"prebuilts/sdk/current/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
 			aidl:           "-pprebuilts/sdk/current/public/framework.aidl",
@@ -381,7 +381,7 @@
 			name:           "system_server_32",
 			properties:     `sdk_version: "system_server_32",`,
 			bootclasspath:  []string{`""`},
-			system:         "sdk_public_32_system_modules",
+			system:         "sdk_module-lib_32_system_modules",
 			java8classpath: []string{"prebuilts/sdk/32/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
 			java9classpath: []string{"prebuilts/sdk/32/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
 			aidl:           "-pprebuilts/sdk/32/public/framework.aidl",
diff --git a/java/testing.go b/java/testing.go
index fafc8d7..3397e46 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -172,9 +172,10 @@
 
 	fs := make(map[string][]byte)
 	for _, level := range apiLevels {
+		apiLevel := android.ApiLevelForTest(level)
 		for _, sdkKind := range []android.SdkKind{android.SdkPublic, android.SdkSystem, android.SdkModule, android.SdkSystemServer, android.SdkTest} {
 			// A core-for-system-modules file must only be created for the sdk kind that supports it.
-			if sdkKind == systemModuleKind() {
+			if sdkKind == systemModuleKind(sdkKind, apiLevel) {
 				fs[fmt.Sprintf("prebuilts/sdk/%s/%s/core-for-system-modules.jar", level, sdkKind)] = nil
 			}