diff --git a/android/sdk_version.go b/android/sdk_version.go index ce22b5f46..5fdaa91f4 100644 --- a/android/sdk_version.go +++ b/android/sdk_version.go @@ -75,58 +75,15 @@ func (k SdkKind) String() string { } } -// SdkVersion represents a specific version number of an SDK spec of a particular kind -type SdkVersion int - -const ( - // special version number for a not-yet-frozen SDK - SdkVersionCurrent SdkVersion = SdkVersion(FutureApiLevelInt) - // special version number to be used for SDK specs where version number doesn't - // make sense, e.g. "none", "", etc. - SdkVersionNone SdkVersion = SdkVersion(0) -) - -// IsCurrent checks if the SdkVersion refers to the not-yet-published version of an SdkKind -func (v SdkVersion) IsCurrent() bool { - return v == SdkVersionCurrent -} - -// IsNumbered checks if the SdkVersion refers to the published (a.k.a numbered) version of an SdkKind -func (v SdkVersion) IsNumbered() bool { - return !v.IsCurrent() && v != SdkVersionNone -} - -// String returns the string representation of this SdkVersion. -func (v SdkVersion) String() string { - if v.IsCurrent() { - return "current" - } else if v.IsNumbered() { - return strconv.Itoa(int(v)) - } - return "(no version)" -} - -func (v SdkVersion) ApiLevel(ctx EarlyModuleContext) ApiLevel { - return ApiLevelOrPanic(ctx, v.String()) -} - -// AsNumberString directly converts the numeric value of this sdk version as a string. -// When isNumbered() is true, this method is the same as String(). However, for SdkVersionCurrent -// and SdkVersionNone, this returns 10000 and 0 while String() returns "current" and "(no version"), -// respectively. -func (v SdkVersion) AsNumberString() string { - return strconv.Itoa(int(v)) -} - // SdkSpec represents the kind and the version of an SDK for a module to build against type SdkSpec struct { - Kind SdkKind - Version SdkVersion - Raw string + Kind SdkKind + ApiLevel ApiLevel + Raw string } func (s SdkSpec) String() string { - return fmt.Sprintf("%s_%s", s.Kind, s.Version) + return fmt.Sprintf("%s_%s", s.Kind, s.ApiLevel) } // Valid checks if this SdkSpec is well-formed. Note however that true doesn't mean that the @@ -177,10 +134,10 @@ func (s SdkSpec) ForVendorPartition(ctx EarlyModuleContext) SdkSpec { } if s.Kind == SdkPublic || s.Kind == SdkSystem { - if s.Version.IsCurrent() { + if s.ApiLevel.IsCurrent() { if i, err := strconv.Atoi(currentSdkVersion); err == nil { - version := SdkVersion(i) - return SdkSpec{s.Kind, version, s.Raw} + apiLevel := uncheckedFinalApiLevel(i) + return SdkSpec{s.Kind, apiLevel, s.Raw} } panic(fmt.Errorf("BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES must be either \"current\" or a number, but was %q", currentSdkVersion)) } @@ -190,10 +147,10 @@ func (s SdkSpec) ForVendorPartition(ctx EarlyModuleContext) SdkSpec { // UsePrebuilt determines whether prebuilt SDK should be used for this SdkSpec with the given context. func (s SdkSpec) UsePrebuilt(ctx EarlyModuleContext) bool { - if s.Version.IsCurrent() { + if s.ApiLevel.IsCurrent() { // "current" can be built from source and be from prebuilt SDK return ctx.Config().AlwaysUsePrebuiltSdks() - } else if s.Version.IsNumbered() { + } else if !s.ApiLevel.IsPreview() { // validation check if s.Kind != SdkPublic && s.Kind != SdkSystem && s.Kind != SdkTest && s.Kind != SdkModule { panic(fmt.Errorf("prebuilt SDK is not not available for SdkKind=%q", s.Kind)) @@ -206,50 +163,60 @@ func (s SdkSpec) UsePrebuilt(ctx EarlyModuleContext) bool { return false } -// EffectiveVersion converts an SdkSpec into the concrete SdkVersion that the module -// should use. For modules targeting an unreleased SDK (meaning it does not yet have a number) -// it returns FutureApiLevel(10000). -func (s SdkSpec) EffectiveVersion(ctx EarlyModuleContext) (SdkVersion, error) { +// EffectiveVersion converts an SdkSpec into the concrete ApiLevel that the module should use. For +// modules targeting an unreleased SDK (meaning it does not yet have a number) it returns +// FutureApiLevel(10000). +func (s SdkSpec) EffectiveVersion(ctx EarlyModuleContext) (ApiLevel, error) { if !s.Valid() { - return s.Version, fmt.Errorf("invalid sdk version %q", s.Raw) + return s.ApiLevel, fmt.Errorf("invalid sdk version %q", s.Raw) } if ctx.DeviceSpecific() || ctx.SocSpecific() { s = s.ForVendorPartition(ctx) } - if s.Version.IsNumbered() { - return s.Version, nil + if !s.ApiLevel.IsPreview() { + return s.ApiLevel, nil } - return SdkVersion(ctx.Config().DefaultAppTargetSdk(ctx).FinalOrFutureInt()), nil + ret := ctx.Config().DefaultAppTargetSdk(ctx) + if ret.IsPreview() { + return FutureApiLevel, nil + } + return ret, nil } // EffectiveVersionString converts an SdkSpec into the concrete version string that the module // should use. For modules targeting an unreleased SDK (meaning it does not yet have a number) // it returns the codename (P, Q, R, etc.) func (s SdkSpec) EffectiveVersionString(ctx EarlyModuleContext) (string, error) { - ver, err := s.EffectiveVersion(ctx) - if err == nil && int(ver) == ctx.Config().DefaultAppTargetSdk(ctx).FinalOrFutureInt() { - return ctx.Config().DefaultAppTargetSdk(ctx).String(), nil + if !s.Valid() { + return s.ApiLevel.String(), fmt.Errorf("invalid sdk version %q", s.Raw) } - return ver.String(), err + + if ctx.DeviceSpecific() || ctx.SocSpecific() { + s = s.ForVendorPartition(ctx) + } + if !s.ApiLevel.IsPreview() { + return s.ApiLevel.String(), nil + } + return ctx.Config().DefaultAppTargetSdk(ctx).String(), nil } func SdkSpecFrom(str string) SdkSpec { switch str { // special cases first case "": - return SdkSpec{SdkPrivate, SdkVersionNone, str} + return SdkSpec{SdkPrivate, NoneApiLevel, str} case "none": - return SdkSpec{SdkNone, SdkVersionNone, str} + return SdkSpec{SdkNone, NoneApiLevel, str} case "core_platform": - return SdkSpec{SdkCorePlatform, SdkVersionNone, str} + return SdkSpec{SdkCorePlatform, NoneApiLevel, str} default: // the syntax is [kind_]version sep := strings.LastIndex(str, "_") var kindString string if sep == 0 { - return SdkSpec{SdkInvalid, SdkVersionNone, str} + return SdkSpec{SdkInvalid, NoneApiLevel, str} } else if sep == -1 { kindString = "" } else { @@ -272,19 +239,19 @@ func SdkSpecFrom(str string) SdkSpec { case "system_server": kind = SdkSystemServer default: - return SdkSpec{SdkInvalid, SdkVersionNone, str} + return SdkSpec{SdkInvalid, NoneApiLevel, str} } - var version SdkVersion + var apiLevel ApiLevel if versionString == "current" { - version = SdkVersionCurrent + apiLevel = FutureApiLevel } else if i, err := strconv.Atoi(versionString); err == nil { - version = SdkVersion(i) + apiLevel = uncheckedFinalApiLevel(i) } else { - return SdkSpec{SdkInvalid, SdkVersionNone, str} + return SdkSpec{SdkInvalid, apiLevel, str} } - return SdkSpec{kind, version, str} + return SdkSpec{kind, apiLevel, str} } } @@ -292,7 +259,7 @@ func (s SdkSpec) ValidateSystemSdk(ctx EarlyModuleContext) bool { // Ensures that the specified system SDK version is one of BOARD_SYSTEMSDK_VERSIONS (for vendor/product Java module) // Assuming that BOARD_SYSTEMSDK_VERSIONS := 28 29, // sdk_version of the modules in vendor/product that use system sdk must be either system_28, system_29 or system_current - if s.Kind != SdkSystem || !s.Version.IsNumbered() { + if s.Kind != SdkSystem || s.ApiLevel.IsPreview() { return true } allowedVersions := ctx.DeviceConfig().PlatformSystemSdkVersions() @@ -302,7 +269,7 @@ func (s SdkSpec) ValidateSystemSdk(ctx EarlyModuleContext) bool { allowedVersions = systemSdkVersions } } - if len(allowedVersions) > 0 && !InList(s.Version.String(), allowedVersions) { + if len(allowedVersions) > 0 && !InList(s.ApiLevel.String(), allowedVersions) { ctx.PropertyErrorf("sdk_version", "incompatible sdk version %q. System SDK version should be one of %q", s.Raw, allowedVersions) return false diff --git a/java/android_manifest.go b/java/android_manifest.go index 6b7395baa..8510f30dd 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -55,7 +55,7 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext if err != nil { ctx.ModuleErrorf("invalid minSdkVersion: %s", err) } - if minSdkVersion >= 23 { + if minSdkVersion.FinalOrFutureInt() >= 23 { args = append(args, fmt.Sprintf("--extract-native-libs=%v", !useEmbeddedNativeLibs)) } else if useEmbeddedNativeLibs { ctx.ModuleErrorf("module attempted to store uncompressed native libraries, but minSdkVersion=%d doesn't support it", diff --git a/java/app.go b/java/app.go index ec30b4940..dcb3bc66e 100755 --- a/java/app.go +++ b/java/app.go @@ -288,7 +288,7 @@ func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) { if minSdkVersion, err := a.MinSdkVersion().EffectiveVersion(ctx); err == nil { a.checkJniLibsSdkVersion(ctx, minSdkVersion) - android.CheckMinSdkVersion(a, ctx, minSdkVersion.ApiLevel(ctx)) + android.CheckMinSdkVersion(a, ctx, minSdkVersion) } else { ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) } @@ -304,7 +304,7 @@ func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) { // because, sdk_version is overridden by min_sdk_version (if set as smaller) // and sdkLinkType is checked with dependencies so we can be sure that the whole dependency tree // will meet the requirements. -func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.SdkVersion) { +func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) { // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType() ctx.VisitDirectDeps(func(m android.Module) { if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) { @@ -315,7 +315,7 @@ func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVer // We can rely on android.SdkSpec to convert it to so that "current" is // handled properly regardless of sdk finalization. jniSdkVersion, err := android.SdkSpecFrom(dep.SdkVersion()).EffectiveVersion(ctx) - if err != nil || minSdkVersion < jniSdkVersion { + 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()) return @@ -333,7 +333,7 @@ func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool { } apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) - return (minSdkVersion >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) || + return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) || !apexInfo.IsForPlatform() } diff --git a/java/base.go b/java/base.go index 73e5352f0..9bc0738e6 100644 --- a/java/base.go +++ b/java/base.go @@ -535,7 +535,7 @@ func (j *Module) TargetSdkVersion() android.SdkSpec { } func (j *Module) MinSdkVersionString() string { - return j.MinSdkVersion().Version.String() + return j.MinSdkVersion().ApiLevel.String() } func (j *Module) AvailableFor(what string) bool { @@ -1255,7 +1255,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { if ctx.Device() { lintSDKVersionString := func(sdkSpec android.SdkSpec) string { - if v := sdkSpec.Version; v.IsNumbered() { + if v := sdkSpec.ApiLevel; !v.IsPreview() { return v.String() } else { return ctx.Config().DefaultAppTargetSdk(ctx).String() @@ -1482,7 +1482,7 @@ func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, if err != nil { return err } - if ver.ApiLevel(ctx).GreaterThan(sdkVersion) { + if ver.GreaterThan(sdkVersion) { return fmt.Errorf("newer SDK(%v)", ver) } return nil diff --git a/java/dex.go b/java/dex.go index 5c6d41d87..7898e9dff 100644 --- a/java/dex.go +++ b/java/dex.go @@ -15,6 +15,7 @@ package java import ( + "strconv" "strings" "github.com/google/blueprint" @@ -179,7 +180,7 @@ func (d *dexer) dexCommonFlags(ctx android.ModuleContext, minSdkVersion android. ctx.PropertyErrorf("min_sdk_version", "%s", err) } - flags = append(flags, "--min-api "+effectiveVersion.AsNumberString()) + flags = append(flags, "--min-api "+strconv.Itoa(effectiveVersion.FinalOrFutureInt())) return flags } diff --git a/java/java.go b/java/java.go index 5fe8814f5..fa7c96eff 100644 --- a/java/java.go +++ b/java/java.go @@ -1156,7 +1156,7 @@ func (j *Import) TargetSdkVersion() android.SdkSpec { } func (j *Import) MinSdkVersionString() string { - return j.MinSdkVersion().Version.String() + return j.MinSdkVersion().ApiLevel.String() } func (j *Import) Prebuilt() *android.Prebuilt { @@ -1370,7 +1370,7 @@ func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, if err != nil { return err } - if ver.ApiLevel(ctx).GreaterThan(sdkVersion) { + if ver.GreaterThan(sdkVersion) { return fmt.Errorf("newer SDK(%v)", ver) } return nil diff --git a/java/sdk.go b/java/sdk.go index b546ca029..f324b7661 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -51,9 +51,9 @@ func defaultJavaLanguageVersion(ctx android.EarlyModuleContext, s android.SdkSpe if err != nil { ctx.PropertyErrorf("sdk_version", "%s", err) } - if sdk <= 23 { + if sdk.FinalOrFutureInt() <= 23 { return JAVA_VERSION_7 - } else if sdk <= 29 { + } else if sdk.FinalOrFutureInt() <= 29 { return JAVA_VERSION_8 } else { return JAVA_VERSION_9 @@ -76,11 +76,11 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) } if sdkVersion.UsePrebuilt(ctx) { - dir := filepath.Join("prebuilts", "sdk", sdkVersion.Version.String(), sdkVersion.Kind.String()) + dir := filepath.Join("prebuilts", "sdk", sdkVersion.ApiLevel.String(), sdkVersion.Kind.String()) jar := filepath.Join(dir, "android.jar") // There's no aidl for other SDKs yet. // TODO(77525052): Add aidl files for other SDKs too. - publicDir := filepath.Join("prebuilts", "sdk", sdkVersion.Version.String(), "public") + publicDir := filepath.Join("prebuilts", "sdk", sdkVersion.ApiLevel.String(), "public") aidl := filepath.Join(publicDir, "framework.aidl") jarPath := android.ExistentPathForSource(ctx, jar) aidlPath := android.ExistentPathForSource(ctx, aidl) @@ -89,7 +89,7 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() { return sdkDep{ invalidVersion: true, - bootclasspath: []string{fmt.Sprintf("sdk_%s_%s_android", sdkVersion.Kind, sdkVersion.Version.String())}, + bootclasspath: []string{fmt.Sprintf("sdk_%s_%s_android", sdkVersion.Kind, sdkVersion.ApiLevel.String())}, } } @@ -105,7 +105,7 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) var systemModules string if defaultJavaLanguageVersion(ctx, sdkVersion).usesJavaModules() { - systemModules = "sdk_public_" + sdkVersion.Version.String() + "_system_modules" + systemModules = "sdk_public_" + sdkVersion.ApiLevel.String() + "_system_modules" } return sdkDep{ diff --git a/java/sdk_library.go b/java/sdk_library.go index ebb21549f..37b8d9f62 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -817,7 +817,7 @@ func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *sco 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.Version.IsNumbered() { + if !sdkVersion.ApiLevel.IsPreview() { return PrebuiltJars(ctx, c.moduleBase.BaseModuleName(), sdkVersion) } @@ -1466,15 +1466,15 @@ func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) { } func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s android.SdkSpec) android.Paths { - var ver android.SdkVersion + var ver android.ApiLevel var kind android.SdkKind if s.UsePrebuilt(ctx) { - ver = s.Version + 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.SdkVersionCurrent + ver = android.FutureApiLevel kind = android.SdkSystem }