Merge "Use system modules for prebuilt SDKs >=30"
diff --git a/java/java.go b/java/java.go
index d943a3a..5b1dcd7 100644
--- a/java/java.go
+++ b/java/java.go
@@ -643,13 +643,15 @@
 			}
 		} else if sdkDep.useModule {
 			ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
-			ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
 			ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
 			if j.deviceProperties.EffectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
 				ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultBootclasspathLibraries...)
 				ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultLibraries...)
 			}
 		}
+		if sdkDep.systemModules != "" {
+			ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
+		}
 
 		if ctx.ModuleName() == "android_stubs_current" ||
 			ctx.ModuleName() == "android_system_stubs_current" ||
@@ -1052,19 +1054,10 @@
 }
 
 func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) javaVersion {
-	sdk, err := sdkContext.sdkVersion().effectiveVersion(ctx)
-	if err != nil {
-		ctx.PropertyErrorf("sdk_version", "%s", err)
-	}
 	if javaVersion != "" {
 		return normalizeJavaVersion(ctx, javaVersion)
-	} else if ctx.Device() && sdk <= 23 {
-		return JAVA_VERSION_7
-	} else if ctx.Device() && sdk <= 29 {
-		return JAVA_VERSION_8
-	} else if ctx.Device() && ctx.Config().UnbundledBuildUsePrebuiltSdks() {
-		// TODO(b/142896162): once we have prebuilt system modules we can use 1.9 for unbundled builds
-		return JAVA_VERSION_8
+	} else if ctx.Device() {
+		return sdkContext.sdkVersion().defaultJavaLanguageVersion(ctx)
 	} else {
 		return JAVA_VERSION_9
 	}
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 03bc76b..999c72f 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -15,11 +15,12 @@
 package java
 
 import (
-	"android/soong/android"
 	"sort"
 	"strings"
 
 	"github.com/google/blueprint/proptools"
+
+	"android/soong/android"
 )
 
 func init() {
@@ -69,6 +70,10 @@
 	return
 }
 
+func prebuiltApiModuleName(mctx android.LoadHookContext, module string, scope string, apiver string) string {
+	return mctx.ModuleName() + "_" + scope + "_" + apiver + "_" + module
+}
+
 func createImport(mctx android.LoadHookContext, module string, scope string, apiver string, path string) {
 	props := struct {
 		Name        *string
@@ -76,7 +81,7 @@
 		Sdk_version *string
 		Installable *bool
 	}{}
-	props.Name = proptools.StringPtr(mctx.ModuleName() + "_" + scope + "_" + apiver + "_" + module)
+	props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, module, scope, apiver))
 	props.Jars = append(props.Jars, path)
 	// TODO(hansson): change to scope after migration is done.
 	props.Sdk_version = proptools.StringPtr("current")
@@ -124,6 +129,27 @@
 	}
 }
 
+func createSystemModules(mctx android.LoadHookContext, apiver string) {
+	props := struct {
+		Name *string
+		Libs []string
+	}{}
+	props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, "system_modules", "public", apiver))
+	props.Libs = append(props.Libs, prebuiltApiModuleName(mctx, "core-for-system-modules", "public", apiver))
+
+	mctx.CreateModule(SystemModulesFactory, &props)
+}
+
+func prebuiltSdkSystemModules(mctx android.LoadHookContext) {
+	for _, apiver := range mctx.Module().(*prebuiltApis).properties.Api_dirs {
+		jar := android.ExistentPathForSource(mctx,
+			mctx.ModuleDir(), apiver, "public", "core-for-system-modules.jar")
+		if jar.Valid() {
+			createSystemModules(mctx, apiver)
+		}
+	}
+}
+
 func prebuiltApiFiles(mctx android.LoadHookContext) {
 	mydir := mctx.ModuleDir() + "/"
 	// <apiver>/<scope>/api/<module>.txt
@@ -178,6 +204,7 @@
 	if _, ok := mctx.Module().(*prebuiltApis); ok {
 		prebuiltApiFiles(mctx)
 		prebuiltSdkStubs(mctx)
+		prebuiltSdkSystemModules(mctx)
 	}
 }
 
@@ -191,7 +218,9 @@
 // Similarly, it generates a java_import for all API .jar files found under the
 // directory where the Android.bp is located. Specifically, an API file located
 // at ./<ver>/<scope>/api/<module>.jar generates a java_import module named
-// <prebuilt-api-module>.<scope>.<ver>.<module>.
+// <prebuilt-api-module>_<scope>_<ver>_<module>, and for SDK versions >= 30
+// a java_system_modules module named
+// <prebuilt-api-module>_public_<ver>_system_modules
 func PrebuiltApisFactory() android.Module {
 	module := &prebuiltApis{}
 	module.AddProperties(&module.properties)
diff --git a/java/sdk.go b/java/sdk.go
index 690451c..9310f78 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -252,6 +252,20 @@
 	return ver.String(), err
 }
 
+func (s sdkSpec) defaultJavaLanguageVersion(ctx android.EarlyModuleContext) javaVersion {
+	sdk, err := s.effectiveVersion(ctx)
+	if err != nil {
+		ctx.PropertyErrorf("sdk_version", "%s", err)
+	}
+	if sdk <= 23 {
+		return JAVA_VERSION_7
+	} else if sdk <= 29 {
+		return JAVA_VERSION_8
+	} else {
+		return JAVA_VERSION_9
+	}
+}
+
 func sdkSpecFrom(str string) sdkSpec {
 	switch str {
 	// special cases first
@@ -370,10 +384,16 @@
 			return sdkDep{}
 		}
 
+		var systemModules string
+		if sdkVersion.defaultJavaLanguageVersion(ctx).usesJavaModules() {
+			systemModules = "sdk_public_" + sdkVersion.version.String() + "_system_modules"
+		}
+
 		return sdkDep{
-			useFiles: true,
-			jars:     android.Paths{jarPath.Path(), lambdaStubsPath},
-			aidl:     android.OptionalPathForPath(aidlPath.Path()),
+			useFiles:      true,
+			jars:          android.Paths{jarPath.Path(), lambdaStubsPath},
+			aidl:          android.OptionalPathForPath(aidlPath.Path()),
+			systemModules: systemModules,
 		}
 	}
 
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 088db9e..fb86463 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -83,6 +83,16 @@
 		},
 		{
 
+			name:           "sdk v30",
+			properties:     `sdk_version: "30",`,
+			bootclasspath:  []string{`""`},
+			system:         "sdk_public_30_system_modules",
+			java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			aidl:           "-pprebuilts/sdk/30/public/framework.aidl",
+		},
+		{
+
 			name:           "current",
 			properties:     `sdk_version: "current",`,
 			bootclasspath:  []string{"android_stubs_current", "core-lambda-stubs"},
@@ -110,6 +120,16 @@
 		},
 		{
 
+			name:           "system_30",
+			properties:     `sdk_version: "system_30",`,
+			bootclasspath:  []string{`""`},
+			system:         "sdk_public_30_system_modules",
+			java8classpath: []string{"prebuilts/sdk/30/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			java9classpath: []string{"prebuilts/sdk/30/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			aidl:           "-pprebuilts/sdk/30/public/framework.aidl",
+		},
+		{
+
 			name:           "test_current",
 			properties:     `sdk_version: "test_current",`,
 			bootclasspath:  []string{"android_test_stubs_current", "core-lambda-stubs"},
@@ -176,12 +196,24 @@
 		},
 		{
 
+			name:           "unbundled sdk v30",
+			unbundled:      true,
+			properties:     `sdk_version: "30",`,
+			bootclasspath:  []string{`""`},
+			system:         "sdk_public_30_system_modules",
+			java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			aidl:           "-pprebuilts/sdk/30/public/framework.aidl",
+		},
+		{
+
 			name:           "unbundled current",
 			unbundled:      true,
 			properties:     `sdk_version: "current",`,
 			bootclasspath:  []string{`""`},
-			forces8:        true,
+			system:         "sdk_public_current_system_modules",
 			java8classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			java9classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
 			aidl:           "-pprebuilts/sdk/current/public/framework.aidl",
 		},
 
@@ -189,27 +221,30 @@
 			name:           "pdk default",
 			pdk:            true,
 			bootclasspath:  []string{`""`},
-			forces8:        true,
-			java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
-			aidl:           "-pprebuilts/sdk/29/public/framework.aidl",
+			system:         "sdk_public_30_system_modules",
+			java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			aidl:           "-pprebuilts/sdk/30/public/framework.aidl",
 		},
 		{
 			name:           "pdk current",
 			pdk:            true,
 			properties:     `sdk_version: "current",`,
 			bootclasspath:  []string{`""`},
-			forces8:        true,
-			java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
-			aidl:           "-pprebuilts/sdk/29/public/framework.aidl",
+			system:         "sdk_public_30_system_modules",
+			java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			aidl:           "-pprebuilts/sdk/30/public/framework.aidl",
 		},
 		{
 			name:           "pdk 29",
 			pdk:            true,
 			properties:     `sdk_version: "29",`,
 			bootclasspath:  []string{`""`},
-			forces8:        true,
-			java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
-			aidl:           "-pprebuilts/sdk/29/public/framework.aidl",
+			system:         "sdk_public_30_system_modules",
+			java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+			aidl:           "-pprebuilts/sdk/30/public/framework.aidl",
 		},
 		{
 			name:           "module_current",
@@ -292,12 +327,16 @@
 			if testcase.system == "none" {
 				system = "--system=none"
 			} else if testcase.system != "" {
-				system = "--system=" + filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system")
+				dir := ""
+				if strings.HasPrefix(testcase.system, "sdk_public_") {
+					dir = "prebuilts/sdk"
+				}
+				system = "--system=" + filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system")
 				// The module-relative parts of these paths are hardcoded in system_modules.go:
 				systemDeps = []string{
-					filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system", "lib", "modules"),
-					filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system", "lib", "jrt-fs.jar"),
-					filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system", "release"),
+					filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system", "lib", "modules"),
+					filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system", "lib", "jrt-fs.jar"),
+					filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system", "release"),
 				}
 			}
 
diff --git a/java/testing.go b/java/testing.go
index 53181a0..1967148 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -55,36 +55,54 @@
 		"assets_a/a":             nil,
 		"assets_b/b":             nil,
 
-		"prebuilts/sdk/14/public/android.jar":         nil,
-		"prebuilts/sdk/14/public/framework.aidl":      nil,
-		"prebuilts/sdk/14/system/android.jar":         nil,
-		"prebuilts/sdk/17/public/android.jar":         nil,
-		"prebuilts/sdk/17/public/framework.aidl":      nil,
-		"prebuilts/sdk/17/system/android.jar":         nil,
-		"prebuilts/sdk/29/public/android.jar":         nil,
-		"prebuilts/sdk/29/public/framework.aidl":      nil,
-		"prebuilts/sdk/29/system/android.jar":         nil,
-		"prebuilts/sdk/29/system/foo.jar":             nil,
-		"prebuilts/sdk/current/core/android.jar":      nil,
-		"prebuilts/sdk/current/public/android.jar":    nil,
-		"prebuilts/sdk/current/public/framework.aidl": nil,
-		"prebuilts/sdk/current/public/core.jar":       nil,
-		"prebuilts/sdk/current/system/android.jar":    nil,
-		"prebuilts/sdk/current/test/android.jar":      nil,
-		"prebuilts/sdk/28/public/api/foo.txt":         nil,
-		"prebuilts/sdk/28/system/api/foo.txt":         nil,
-		"prebuilts/sdk/28/test/api/foo.txt":           nil,
-		"prebuilts/sdk/28/public/api/foo-removed.txt": nil,
-		"prebuilts/sdk/28/system/api/foo-removed.txt": nil,
-		"prebuilts/sdk/28/test/api/foo-removed.txt":   nil,
-		"prebuilts/sdk/28/public/api/bar.txt":         nil,
-		"prebuilts/sdk/28/system/api/bar.txt":         nil,
-		"prebuilts/sdk/28/test/api/bar.txt":           nil,
-		"prebuilts/sdk/28/public/api/bar-removed.txt": nil,
-		"prebuilts/sdk/28/system/api/bar-removed.txt": nil,
-		"prebuilts/sdk/28/test/api/bar-removed.txt":   nil,
-		"prebuilts/sdk/tools/core-lambda-stubs.jar":   nil,
-		"prebuilts/sdk/Android.bp":                    []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "current"],}`),
+		"prebuilts/sdk/14/public/android.jar":                      nil,
+		"prebuilts/sdk/14/public/framework.aidl":                   nil,
+		"prebuilts/sdk/14/system/android.jar":                      nil,
+		"prebuilts/sdk/17/public/android.jar":                      nil,
+		"prebuilts/sdk/17/public/framework.aidl":                   nil,
+		"prebuilts/sdk/17/system/android.jar":                      nil,
+		"prebuilts/sdk/29/public/android.jar":                      nil,
+		"prebuilts/sdk/29/public/framework.aidl":                   nil,
+		"prebuilts/sdk/29/system/android.jar":                      nil,
+		"prebuilts/sdk/29/system/foo.jar":                          nil,
+		"prebuilts/sdk/30/public/android.jar":                      nil,
+		"prebuilts/sdk/30/public/framework.aidl":                   nil,
+		"prebuilts/sdk/30/system/android.jar":                      nil,
+		"prebuilts/sdk/30/system/foo.jar":                          nil,
+		"prebuilts/sdk/30/public/core-for-system-modules.jar":      nil,
+		"prebuilts/sdk/current/core/android.jar":                   nil,
+		"prebuilts/sdk/current/public/android.jar":                 nil,
+		"prebuilts/sdk/current/public/framework.aidl":              nil,
+		"prebuilts/sdk/current/public/core.jar":                    nil,
+		"prebuilts/sdk/current/public/core-for-system-modules.jar": nil,
+		"prebuilts/sdk/current/system/android.jar":                 nil,
+		"prebuilts/sdk/current/test/android.jar":                   nil,
+		"prebuilts/sdk/28/public/api/foo.txt":                      nil,
+		"prebuilts/sdk/28/system/api/foo.txt":                      nil,
+		"prebuilts/sdk/28/test/api/foo.txt":                        nil,
+		"prebuilts/sdk/28/public/api/foo-removed.txt":              nil,
+		"prebuilts/sdk/28/system/api/foo-removed.txt":              nil,
+		"prebuilts/sdk/28/test/api/foo-removed.txt":                nil,
+		"prebuilts/sdk/28/public/api/bar.txt":                      nil,
+		"prebuilts/sdk/28/system/api/bar.txt":                      nil,
+		"prebuilts/sdk/28/test/api/bar.txt":                        nil,
+		"prebuilts/sdk/28/public/api/bar-removed.txt":              nil,
+		"prebuilts/sdk/28/system/api/bar-removed.txt":              nil,
+		"prebuilts/sdk/28/test/api/bar-removed.txt":                nil,
+		"prebuilts/sdk/30/public/api/foo.txt":                      nil,
+		"prebuilts/sdk/30/system/api/foo.txt":                      nil,
+		"prebuilts/sdk/30/test/api/foo.txt":                        nil,
+		"prebuilts/sdk/30/public/api/foo-removed.txt":              nil,
+		"prebuilts/sdk/30/system/api/foo-removed.txt":              nil,
+		"prebuilts/sdk/30/test/api/foo-removed.txt":                nil,
+		"prebuilts/sdk/30/public/api/bar.txt":                      nil,
+		"prebuilts/sdk/30/system/api/bar.txt":                      nil,
+		"prebuilts/sdk/30/test/api/bar.txt":                        nil,
+		"prebuilts/sdk/30/public/api/bar-removed.txt":              nil,
+		"prebuilts/sdk/30/system/api/bar-removed.txt":              nil,
+		"prebuilts/sdk/30/test/api/bar-removed.txt":                nil,
+		"prebuilts/sdk/tools/core-lambda-stubs.jar":                nil,
+		"prebuilts/sdk/Android.bp":                                 []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "30", "current"],}`),
 
 		"prebuilts/apk/app.apk":        nil,
 		"prebuilts/apk/app_arm.apk":    nil,