Merge "Ensure boot jar modules have been initialized properly for hidden API"
diff --git a/android/sdk_version.go b/android/sdk_version.go
index 5fdaa91..98db824 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -22,15 +22,15 @@
 
 type SdkContext interface {
 	// SdkVersion returns SdkSpec that corresponds to the sdk_version property of the current module
-	SdkVersion() SdkSpec
+	SdkVersion(ctx EarlyModuleContext) SdkSpec
 	// SystemModules returns the system_modules property of the current module, or an empty string if it is not set.
 	SystemModules() string
 	// MinSdkVersion returns SdkSpec that corresponds to the min_sdk_version property of the current module,
 	// or from sdk_version if it is not set.
-	MinSdkVersion() SdkSpec
+	MinSdkVersion(ctx EarlyModuleContext) SdkSpec
 	// TargetSdkVersion returns the SdkSpec that corresponds to the target_sdk_version property of the current module,
 	// or from sdk_version if it is not set.
-	TargetSdkVersion() SdkSpec
+	TargetSdkVersion(ctx EarlyModuleContext) SdkSpec
 }
 
 // SdkKind represents a particular category of an SDK spec like public, system, test, etc.
@@ -201,15 +201,23 @@
 	return ctx.Config().DefaultAppTargetSdk(ctx).String(), nil
 }
 
-func SdkSpecFrom(str string) SdkSpec {
+var (
+	SdkSpecNone = SdkSpec{SdkNone, NoneApiLevel, "(no version)"}
+	// TODO(b/175678607) ApiLevel of SdkSpecPrivate should be FutureApiLevel
+	SdkSpecPrivate = SdkSpec{SdkPrivate, NoneApiLevel, ""}
+	// TODO(b/175678607) ApiLevel of SdkSpecCorePlatform should be FutureApiLevel
+	SdkSpecCorePlatform = SdkSpec{SdkCorePlatform, NoneApiLevel, "core_platform"}
+)
+
+func SdkSpecFrom(ctx EarlyModuleContext, str string) SdkSpec {
 	switch str {
 	// special cases first
 	case "":
-		return SdkSpec{SdkPrivate, NoneApiLevel, str}
+		return SdkSpecPrivate
 	case "none":
-		return SdkSpec{SdkNone, NoneApiLevel, str}
+		return SdkSpecNone
 	case "core_platform":
-		return SdkSpec{SdkCorePlatform, NoneApiLevel, str}
+		return SdkSpecCorePlatform
 	default:
 		// the syntax is [kind_]version
 		sep := strings.LastIndex(str, "_")
@@ -242,15 +250,10 @@
 			return SdkSpec{SdkInvalid, NoneApiLevel, str}
 		}
 
-		var apiLevel ApiLevel
-		if versionString == "current" {
-			apiLevel = FutureApiLevel
-		} else if i, err := strconv.Atoi(versionString); err == nil {
-			apiLevel = uncheckedFinalApiLevel(i)
-		} else {
+		apiLevel, err := ApiLevelFromUser(ctx, versionString)
+		if err != nil {
 			return SdkSpec{SdkInvalid, apiLevel, str}
 		}
-
 		return SdkSpec{kind, apiLevel, str}
 	}
 }
diff --git a/apex/apex.go b/apex/apex.go
index 880028f..0eacf6d 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2272,8 +2272,10 @@
 		tag := ctx.OtherModuleDependencyTag(module)
 		switch tag {
 		case javaLibTag, androidAppTag:
-			if m, ok := module.(interface{ CheckStableSdkVersion() error }); ok {
-				if err := m.CheckStableSdkVersion(); err != nil {
+			if m, ok := module.(interface {
+				CheckStableSdkVersion(ctx android.BaseModuleContext) error
+			}); ok {
+				if err := m.CheckStableSdkVersion(ctx); err != nil {
 					ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
 				}
 			}
diff --git a/apex/builder.go b/apex/builder.go
index 2df380b..bbb4666 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -946,16 +946,19 @@
 			depInfos[to.Name()] = info
 		} else {
 			toMinSdkVersion := "(no version)"
-			if m, ok := to.(interface{ MinSdkVersion() string }); ok {
+			if m, ok := to.(interface {
+				MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
+			}); ok {
+				if v := m.MinSdkVersion(ctx); !v.ApiLevel.IsNone() {
+					toMinSdkVersion = v.ApiLevel.String()
+				}
+			} else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
+				// TODO(b/175678607) eliminate the use of MinSdkVersion returning
+				// string
 				if v := m.MinSdkVersion(); v != "" {
 					toMinSdkVersion = v
 				}
-			} else if m, ok := to.(interface{ MinSdkVersionString() string }); ok {
-				if v := m.MinSdkVersionString(); v != "" {
-					toMinSdkVersion = v
-				}
 			}
-
 			depInfos[to.Name()] = android.ApexModuleDepInfo{
 				To:            to.Name(),
 				From:          []string{from.Name()},
diff --git a/java/aar.go b/java/aar.go
index a122a94..04727e4 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -218,7 +218,7 @@
 	linkDeps = append(linkDeps, assetDeps...)
 
 	// SDK version flags
-	minSdkVersion, err := sdkContext.MinSdkVersion().EffectiveVersionString(ctx)
+	minSdkVersion, err := sdkContext.MinSdkVersion(ctx).EffectiveVersionString(ctx)
 	if err != nil {
 		ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
 	}
@@ -609,6 +609,9 @@
 	hideApexVariantFromMake bool
 
 	aarPath android.Path
+
+	sdkVersion    android.SdkSpec
+	minSdkVersion android.SdkSpec
 }
 
 var _ android.OutputFileProducer = (*AARImport)(nil)
@@ -625,23 +628,23 @@
 	}
 }
 
-func (a *AARImport) SdkVersion() android.SdkSpec {
-	return android.SdkSpecFrom(String(a.properties.Sdk_version))
+func (a *AARImport) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return android.SdkSpecFrom(ctx, String(a.properties.Sdk_version))
 }
 
 func (a *AARImport) SystemModules() string {
 	return ""
 }
 
-func (a *AARImport) MinSdkVersion() android.SdkSpec {
+func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
 	if a.properties.Min_sdk_version != nil {
-		return android.SdkSpecFrom(*a.properties.Min_sdk_version)
+		return android.SdkSpecFrom(ctx, *a.properties.Min_sdk_version)
 	}
-	return a.SdkVersion()
+	return a.SdkVersion(ctx)
 }
 
-func (a *AARImport) TargetSdkVersion() android.SdkSpec {
-	return a.SdkVersion()
+func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return a.SdkVersion(ctx)
 }
 
 func (a *AARImport) javaVersion() string {
@@ -727,6 +730,9 @@
 		return
 	}
 
+	a.sdkVersion = a.SdkVersion(ctx)
+	a.minSdkVersion = a.MinSdkVersion(ctx)
+
 	a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
 
 	aarName := ctx.ModuleName() + ".aar"
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 8510f30..331f941 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -51,7 +51,7 @@
 	if isLibrary {
 		args = append(args, "--library")
 	} else {
-		minSdkVersion, err := sdkContext.MinSdkVersion().EffectiveVersion(ctx)
+		minSdkVersion, err := sdkContext.MinSdkVersion(ctx).EffectiveVersion(ctx)
 		if err != nil {
 			ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
 		}
@@ -87,7 +87,7 @@
 		args = append(args, "--logging-parent", loggingParent)
 	}
 	var deps android.Paths
-	targetSdkVersion, err := sdkContext.TargetSdkVersion().EffectiveVersionString(ctx)
+	targetSdkVersion, err := sdkContext.TargetSdkVersion(ctx).EffectiveVersionString(ctx)
 	if err != nil {
 		ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
 	}
@@ -96,7 +96,7 @@
 		deps = append(deps, ApiFingerprintPath(ctx))
 	}
 
-	minSdkVersion, err := sdkContext.MinSdkVersion().EffectiveVersionString(ctx)
+	minSdkVersion, err := sdkContext.MinSdkVersion(ctx).EffectiveVersionString(ctx)
 	if err != nil {
 		ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
 	}
diff --git a/java/androidmk.go b/java/androidmk.go
index 75661a7..4e594a2 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -106,7 +106,7 @@
 					if len(library.dexpreopter.builtInstalled) > 0 {
 						entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", library.dexpreopter.builtInstalled)
 					}
-					entries.SetString("LOCAL_SDK_VERSION", library.SdkVersion().Raw)
+					entries.SetString("LOCAL_SDK_VERSION", library.sdkVersion.String())
 					entries.SetPath("LOCAL_SOONG_CLASSES_JAR", library.implementationAndResourcesJar)
 					entries.SetPath("LOCAL_SOONG_HEADER_JAR", library.headerJarFile)
 
@@ -205,7 +205,7 @@
 				}
 				entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedClasspathFile)
 				entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile)
-				entries.SetString("LOCAL_SDK_VERSION", prebuilt.makeSdkVersion())
+				entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion.String())
 				entries.SetString("LOCAL_MODULE_STEM", prebuilt.Stem())
 			},
 		},
@@ -255,7 +255,7 @@
 				entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", prebuilt.proguardFlags)
 				entries.SetPath("LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES", prebuilt.extraAaptPackagesFile)
 				entries.SetPath("LOCAL_FULL_MANIFEST_FILE", prebuilt.manifest)
-				entries.SetString("LOCAL_SDK_VERSION", prebuilt.SdkVersion().Raw)
+				entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion.String())
 			},
 		},
 	}}
diff --git a/java/app.go b/java/app.go
index 04406e7..5695022 100755
--- a/java/app.go
+++ b/java/app.go
@@ -213,7 +213,7 @@
 func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
 	a.Module.deps(ctx)
 
-	if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion().Specified() {
+	if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
 		ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
 	}
 
@@ -222,7 +222,7 @@
 		a.aapt.deps(ctx, sdkDep)
 	}
 
-	usesSDK := a.SdkVersion().Specified() && a.SdkVersion().Kind != android.SdkCorePlatform
+	usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
 
 	if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
 		ctx.PropertyErrorf("jni_uses_sdk_apis",
@@ -279,14 +279,14 @@
 
 func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
 	if a.Updatable() {
-		if !a.SdkVersion().Stable() {
-			ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion())
+		if !a.SdkVersion(ctx).Stable() {
+			ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
 		}
 		if String(a.deviceProperties.Min_sdk_version) == "" {
 			ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
 		}
 
-		if minSdkVersion, err := a.MinSdkVersion().EffectiveVersion(ctx); err == nil {
+		if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
 			a.checkJniLibsSdkVersion(ctx, minSdkVersion)
 			android.CheckMinSdkVersion(a, ctx, minSdkVersion)
 		} else {
@@ -314,7 +314,7 @@
 		// The domain of cc.sdk_version is "current" and <number>
 		// We can rely on android.SdkSpec to convert it to <number> so that "current" is
 		// handled properly regardless of sdk finalization.
-		jniSdkVersion, err := android.SdkSpecFrom(dep.SdkVersion()).EffectiveVersion(ctx)
+		jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.SdkVersion()).EffectiveVersion(ctx)
 		if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
 			ctx.OtherModuleErrorf(dep, "sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
 				dep.SdkVersion(), minSdkVersion, ctx.ModuleName())
@@ -327,9 +327,9 @@
 // Returns true if the native libraries should be stored in the APK uncompressed and the
 // extractNativeLibs application flag should be set to false in the manifest.
 func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
-	minSdkVersion, err := a.MinSdkVersion().EffectiveVersion(ctx)
+	minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
 	if err != nil {
-		ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(), err)
+		ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
 	}
 
 	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
@@ -381,7 +381,7 @@
 
 func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
 	usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
-	if ctx.Module().(android.SdkContext).SdkVersion().Kind == android.SdkModule {
+	if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
 		usePlatformAPI = true
 	}
 	a.aapt.usesNonSdkApis = usePlatformAPI
@@ -724,8 +724,8 @@
 }
 
 type appDepsInterface interface {
-	SdkVersion() android.SdkSpec
-	MinSdkVersion() android.SdkSpec
+	SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
+	MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
 	RequiresStableAPIs(ctx android.BaseModuleContext) bool
 }
 
@@ -738,8 +738,8 @@
 	seenModulePaths := make(map[string]bool)
 
 	if checkNativeSdkVersion {
-		checkNativeSdkVersion = app.SdkVersion().Specified() &&
-			app.SdkVersion().Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
+		checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
+			app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
 	}
 
 	ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
@@ -829,12 +829,16 @@
 			depsInfo[depName] = info
 		} else {
 			toMinSdkVersion := "(no version)"
-			if m, ok := to.(interface{ MinSdkVersion() string }); ok {
-				if v := m.MinSdkVersion(); v != "" {
-					toMinSdkVersion = v
+			if m, ok := to.(interface {
+				MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
+			}); ok {
+				if v := m.MinSdkVersion(ctx); !v.ApiLevel.IsNone() {
+					toMinSdkVersion = v.ApiLevel.String()
 				}
-			} else if m, ok := to.(interface{ MinSdkVersionString() string }); ok {
-				if v := m.MinSdkVersionString(); v != "" {
+			} else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
+				// TODO(b/175678607) eliminate the use of MinSdkVersion returning
+				// string
+				if v := m.MinSdkVersion(); v != "" {
 					toMinSdkVersion = v
 				}
 			}
@@ -848,7 +852,7 @@
 		return true
 	})
 
-	a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersionString(), depsInfo)
+	a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
 }
 
 func (a *AndroidApp) Updatable() bool {
diff --git a/java/app_import.go b/java/app_import.go
index 32cec23..839051e 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -394,12 +394,12 @@
 	return false
 }
 
-func (a *AndroidAppImport) SdkVersion() android.SdkSpec {
-	return android.SdkSpecFrom("")
+func (a *AndroidAppImport) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return android.SdkSpecPrivate
 }
 
-func (a *AndroidAppImport) MinSdkVersion() android.SdkSpec {
-	return android.SdkSpecFrom("")
+func (a *AndroidAppImport) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return android.SdkSpecPrivate
 }
 
 var _ android.ApexModule = (*AndroidAppImport)(nil)
diff --git a/java/base.go b/java/base.go
index 9bc0738..19c85cd 100644
--- a/java/base.go
+++ b/java/base.go
@@ -370,10 +370,13 @@
 	modulePaths []string
 
 	hideApexVariantFromMake bool
+
+	sdkVersion    android.SdkSpec
+	minSdkVersion android.SdkSpec
 }
 
-func (j *Module) CheckStableSdkVersion() error {
-	sdkVersion := j.SdkVersion()
+func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
+	sdkVersion := j.SdkVersion(ctx)
 	if sdkVersion.Stable() {
 		return nil
 	}
@@ -393,7 +396,7 @@
 func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
 	if j.RequiresStableAPIs(ctx) {
 		if sc, ok := ctx.Module().(android.SdkContext); ok {
-			if !sc.SdkVersion().Specified() {
+			if !sc.SdkVersion(ctx).Specified() {
 				ctx.PropertyErrorf("sdk_version",
 					"sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).")
 			}
@@ -418,7 +421,7 @@
 func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
 	if sc, ok := ctx.Module().(android.SdkContext); ok {
 		usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis)
-		sdkVersionSpecified := sc.SdkVersion().Specified()
+		sdkVersionSpecified := sc.SdkVersion(ctx).Specified()
 		if usePlatformAPI && sdkVersionSpecified {
 			ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.")
 		} else if !usePlatformAPI && !sdkVersionSpecified {
@@ -512,30 +515,30 @@
 	return false
 }
 
-func (j *Module) SdkVersion() android.SdkSpec {
-	return android.SdkSpecFrom(String(j.deviceProperties.Sdk_version))
+func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version))
 }
 
 func (j *Module) SystemModules() string {
 	return proptools.String(j.deviceProperties.System_modules)
 }
 
-func (j *Module) MinSdkVersion() android.SdkSpec {
+func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
 	if j.deviceProperties.Min_sdk_version != nil {
-		return android.SdkSpecFrom(*j.deviceProperties.Min_sdk_version)
+		return android.SdkSpecFrom(ctx, *j.deviceProperties.Min_sdk_version)
 	}
-	return j.SdkVersion()
-}
-
-func (j *Module) TargetSdkVersion() android.SdkSpec {
-	if j.deviceProperties.Target_sdk_version != nil {
-		return android.SdkSpecFrom(*j.deviceProperties.Target_sdk_version)
-	}
-	return j.SdkVersion()
+	return j.SdkVersion(ctx)
 }
 
 func (j *Module) MinSdkVersionString() string {
-	return j.MinSdkVersion().ApiLevel.String()
+	return j.minSdkVersion.Raw
+}
+
+func (j *Module) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	if j.deviceProperties.Target_sdk_version != nil {
+		return android.SdkSpecFrom(ctx, *j.deviceProperties.Target_sdk_version)
+	}
+	return j.SdkVersion(ctx)
 }
 
 func (j *Module) AvailableFor(what string) bool {
@@ -1209,7 +1212,7 @@
 			}
 			// Dex compilation
 			var dexOutputFile android.OutputPath
-			dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(), outputFile, jarName)
+			dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), outputFile, jarName)
 			if ctx.Failed() {
 				return
 			}
@@ -1267,9 +1270,9 @@
 		j.linter.srcJars = srcJars
 		j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...)
 		j.linter.classes = j.implementationJarFile
-		j.linter.minSdkVersion = lintSDKVersionString(j.MinSdkVersion())
-		j.linter.targetSdkVersion = lintSDKVersionString(j.TargetSdkVersion())
-		j.linter.compileSdkVersion = lintSDKVersionString(j.SdkVersion())
+		j.linter.minSdkVersion = lintSDKVersionString(j.MinSdkVersion(ctx))
+		j.linter.targetSdkVersion = lintSDKVersionString(j.TargetSdkVersion(ctx))
+		j.linter.compileSdkVersion = lintSDKVersionString(j.SdkVersion(ctx))
 		j.linter.javaLanguageLevel = flags.javaVersion.String()
 		j.linter.kotlinLanguageLevel = "1.3"
 		if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() {
@@ -1471,7 +1474,7 @@
 // Implements android.ApexModule
 func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
 	sdkVersion android.ApiLevel) error {
-	sdkSpec := j.MinSdkVersion()
+	sdkSpec := j.MinSdkVersion(ctx)
 	if !sdkSpec.Specified() {
 		return fmt.Errorf("min_sdk_version is not specified")
 	}
@@ -1551,10 +1554,10 @@
 
 type moduleWithSdkDep interface {
 	android.Module
-	getSdkLinkType(name string) (ret sdkLinkType, stubs bool)
+	getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool)
 }
 
-func (m *Module) getSdkLinkType(name string) (ret sdkLinkType, stubs bool) {
+func (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) {
 	switch name {
 	case "core.current.stubs", "legacy.core.platform.api.stubs", "stable.core.platform.api.stubs",
 		"stub-annotations", "private-stub-annotations-jar",
@@ -1576,7 +1579,7 @@
 		return linkType, true
 	}
 
-	ver := m.SdkVersion()
+	ver := m.SdkVersion(ctx)
 	switch ver.Kind {
 	case android.SdkCore:
 		return javaCore, false
@@ -1606,11 +1609,11 @@
 		return
 	}
 
-	myLinkType, stubs := j.getSdkLinkType(ctx.ModuleName())
+	myLinkType, stubs := j.getSdkLinkType(ctx, ctx.ModuleName())
 	if stubs {
 		return
 	}
-	depLinkType, _ := dep.getSdkLinkType(ctx.OtherModuleName(dep))
+	depLinkType, _ := dep.getSdkLinkType(ctx, ctx.OtherModuleName(dep))
 
 	if myLinkType.rank() < depLinkType.rank() {
 		ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+
@@ -1638,7 +1641,7 @@
 		}
 	}
 
-	sdkLinkType, _ := j.getSdkLinkType(ctx.ModuleName())
+	sdkLinkType, _ := j.getSdkLinkType(ctx, ctx.ModuleName())
 
 	ctx.VisitDirectDeps(func(module android.Module) {
 		otherName := ctx.OtherModuleName(module)
@@ -1656,7 +1659,7 @@
 		if dep, ok := module.(SdkLibraryDependency); ok {
 			switch tag {
 			case libTag:
-				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion())...)
+				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...)
 			case staticLibTag:
 				ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
 			}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index e527d59..01c0f16 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -261,20 +261,20 @@
 
 var _ android.OutputFileProducer = (*Javadoc)(nil)
 
-func (j *Javadoc) SdkVersion() android.SdkSpec {
-	return android.SdkSpecFrom(String(j.properties.Sdk_version))
+func (j *Javadoc) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version))
 }
 
 func (j *Javadoc) SystemModules() string {
 	return proptools.String(j.properties.System_modules)
 }
 
-func (j *Javadoc) MinSdkVersion() android.SdkSpec {
-	return j.SdkVersion()
+func (j *Javadoc) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return j.SdkVersion(ctx)
 }
 
-func (j *Javadoc) TargetSdkVersion() android.SdkSpec {
-	return j.SdkVersion()
+func (j *Javadoc) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return j.SdkVersion(ctx)
 }
 
 func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
@@ -386,7 +386,7 @@
 			}
 		case libTag:
 			if dep, ok := module.(SdkLibraryDependency); ok {
-				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion())...)
+				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...)
 			} else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
 				dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
 				deps.classpath = append(deps.classpath, dep.HeaderJars...)
diff --git a/java/java.go b/java/java.go
index fa7c96e..ee4f2eb 100644
--- a/java/java.go
+++ b/java/java.go
@@ -356,7 +356,7 @@
 	if javaVersion != "" {
 		return normalizeJavaVersion(ctx, javaVersion)
 	} else if ctx.Device() {
-		return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion())
+		return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx))
 	} else {
 		return JAVA_VERSION_9
 	}
@@ -463,6 +463,9 @@
 	// would the <x> library if <x> was configured as a boot jar.
 	j.initHiddenAPI(ctx, j.ConfigurationName())
 
+	j.sdkVersion = j.SdkVersion(ctx)
+	j.minSdkVersion = j.MinSdkVersion(ctx)
+
 	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
 	if !apexInfo.IsForPlatform() {
 		j.hideApexVariantFromMake = true
@@ -1130,33 +1133,28 @@
 	exportAidlIncludeDirs android.Paths
 
 	hideApexVariantFromMake bool
+
+	sdkVersion    android.SdkSpec
+	minSdkVersion android.SdkSpec
 }
 
-func (j *Import) SdkVersion() android.SdkSpec {
-	return android.SdkSpecFrom(String(j.properties.Sdk_version))
-}
-
-func (j *Import) makeSdkVersion() string {
-	return j.SdkVersion().Raw
+func (j *Import) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version))
 }
 
 func (j *Import) SystemModules() string {
 	return "none"
 }
 
-func (j *Import) MinSdkVersion() android.SdkSpec {
+func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
 	if j.properties.Min_sdk_version != nil {
-		return android.SdkSpecFrom(*j.properties.Min_sdk_version)
+		return android.SdkSpecFrom(ctx, *j.properties.Min_sdk_version)
 	}
-	return j.SdkVersion()
+	return j.SdkVersion(ctx)
 }
 
-func (j *Import) TargetSdkVersion() android.SdkSpec {
-	return j.SdkVersion()
-}
-
-func (j *Import) MinSdkVersionString() string {
-	return j.MinSdkVersion().ApiLevel.String()
+func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return j.SdkVersion(ctx)
 }
 
 func (j *Import) Prebuilt() *android.Prebuilt {
@@ -1192,6 +1190,9 @@
 }
 
 func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	j.sdkVersion = j.SdkVersion(ctx)
+	j.minSdkVersion = j.MinSdkVersion(ctx)
+
 	// Initialize the hiddenapi structure.
 	j.initHiddenAPI(ctx, j.BaseModuleName())
 
@@ -1230,7 +1231,7 @@
 		} else if dep, ok := module.(SdkLibraryDependency); ok {
 			switch tag {
 			case libTag:
-				flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion())...)
+				flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...)
 			}
 		}
 
@@ -1291,7 +1292,7 @@
 			j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
 
 			var dexOutputFile android.OutputPath
-			dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(), outputFile, jarName)
+			dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), outputFile, jarName)
 			if ctx.Failed() {
 				return
 			}
@@ -1359,7 +1360,7 @@
 // Implements android.ApexModule
 func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
 	sdkVersion android.ApiLevel) error {
-	sdkSpec := j.MinSdkVersion()
+	sdkSpec := j.MinSdkVersion(ctx)
 	if !sdkSpec.Specified() {
 		return fmt.Errorf("min_sdk_version is not specified")
 	}
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 8a442b5..c33e6c2 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -253,14 +253,8 @@
 		files := getPrebuiltFilesInSubdir(mctx, nextApiDir, "api/*incompatibilities.txt")
 		for _, f := range files {
 			localPath := strings.TrimPrefix(f, mydir)
-			module, _, scope := parseApiFilePath(mctx, localPath)
-
-			// Figure out which module is referenced by this file. Special case for "android".
-			referencedModule := strings.TrimSuffix(module, "incompatibilities")
-			referencedModule = strings.TrimSuffix(referencedModule, "-")
-			if referencedModule == "" {
-				referencedModule = "android"
-			}
+			filename, _, scope := parseApiFilePath(mctx, localPath)
+			referencedModule := strings.TrimSuffix(filename, "-incompatibilities")
 
 			createApiModule(mctx, apiModuleName(referencedModule+"-incompatibilities", scope, "latest"), localPath)
 
diff --git a/java/rro.go b/java/rro.go
index 4ae0014..2e58c04 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -141,23 +141,23 @@
 	ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile)
 }
 
-func (r *RuntimeResourceOverlay) SdkVersion() android.SdkSpec {
-	return android.SdkSpecFrom(String(r.properties.Sdk_version))
+func (r *RuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return android.SdkSpecFrom(ctx, String(r.properties.Sdk_version))
 }
 
 func (r *RuntimeResourceOverlay) SystemModules() string {
 	return ""
 }
 
-func (r *RuntimeResourceOverlay) MinSdkVersion() android.SdkSpec {
+func (r *RuntimeResourceOverlay) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
 	if r.properties.Min_sdk_version != nil {
-		return android.SdkSpecFrom(*r.properties.Min_sdk_version)
+		return android.SdkSpecFrom(ctx, *r.properties.Min_sdk_version)
 	}
-	return r.SdkVersion()
+	return r.SdkVersion(ctx)
 }
 
-func (r *RuntimeResourceOverlay) TargetSdkVersion() android.SdkSpec {
-	return r.SdkVersion()
+func (r *RuntimeResourceOverlay) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return r.SdkVersion(ctx)
 }
 
 func (r *RuntimeResourceOverlay) Certificate() Certificate {
diff --git a/java/sdk.go b/java/sdk.go
index f324b76..d6e20a7 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -61,7 +61,7 @@
 }
 
 func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) sdkDep {
-	sdkVersion := sdkContext.SdkVersion()
+	sdkVersion := sdkContext.SdkVersion(ctx)
 	if !sdkVersion.Valid() {
 		ctx.PropertyErrorf("sdk_version", "invalid version %q", sdkVersion.Raw)
 		return sdkDep{}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 96135c3..e5ee397 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1512,7 +1512,7 @@
 	// 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("module_current")
+		sdkVersion = android.SdkSpecFrom(ctx, "module_current")
 	}
 
 	// Only provide access to the implementation library if it is actually built.
diff --git a/tests/lib.sh b/tests/lib.sh
index 3c97e14..b61ca91 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -54,7 +54,7 @@
     mkdir -p "$MOCK_TOP"
   else
     MOCK_TOP=$(mktemp -t -d st.XXXXX)
-    trap 'echo cd / && echo rm -fr "$MOCK_TOP"' EXIT
+    trap 'cd / && rm -fr "$MOCK_TOP"' EXIT
   fi
 
   echo "Test case: ${FUNCNAME[1]}, mock top path: $MOCK_TOP"