Replace ApiStrToNum uses with ApiLevel.
Test: treehugger
Bug: http://b/154667674
Change-Id: I2954bb21c1cfdeb305f25cfb6c8711c930f6ed50
diff --git a/android/apex.go b/android/apex.go
index f857ec6..3cc663b 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -24,29 +24,36 @@
"github.com/google/blueprint"
)
-const (
- SdkVersion_Android10 = 29
+var (
+ SdkVersion_Android10 = uncheckedFinalApiLevel(29)
)
type ApexInfo struct {
// Name of the apex variation that this module is mutated into
ApexVariationName string
- MinSdkVersion int
- Updatable bool
- RequiredSdks SdkRefs
+ // Serialized ApiLevel. Use via MinSdkVersion() method. Cannot be stored in
+ // its struct form because this is cloned into properties structs, and
+ // ApiLevel has private members.
+ MinSdkVersionStr string
+ Updatable bool
+ RequiredSdks SdkRefs
InApexes []string
}
-func (i ApexInfo) mergedName() string {
- name := "apex" + strconv.Itoa(i.MinSdkVersion)
+func (i ApexInfo) mergedName(ctx EarlyModuleContext) string {
+ name := "apex" + strconv.Itoa(i.MinSdkVersion(ctx).FinalOrFutureInt())
for _, sdk := range i.RequiredSdks {
name += "_" + sdk.Name + "_" + sdk.Version
}
return name
}
+func (this *ApexInfo) MinSdkVersion(ctx EarlyModuleContext) ApiLevel {
+ return ApiLevelOrPanic(ctx, this.MinSdkVersionStr)
+}
+
// Extracted from ApexModule to make it easier to define custom subsets of the
// ApexModule interface and improve code navigation within the IDE.
type DepIsInSameApex interface {
@@ -141,7 +148,7 @@
// Returns nil if this module supports sdkVersion
// Otherwise, returns error with reason
- ShouldSupportSdkVersion(ctx BaseModuleContext, sdkVersion int) error
+ ShouldSupportSdkVersion(ctx BaseModuleContext, sdkVersion ApiLevel) error
// Returns true if this module needs a unique variation per apex, for example if
// use_apex_name_macro is set.
@@ -347,18 +354,18 @@
// mergeApexVariations deduplicates APEX variations that would build identically into a common
// variation. It returns the reduced list of variations and a list of aliases from the original
// variation names to the new variation names.
-func mergeApexVariations(apexVariations []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
+func mergeApexVariations(ctx EarlyModuleContext, apexVariations []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
sort.Sort(byApexName(apexVariations))
seen := make(map[string]int)
for _, apexInfo := range apexVariations {
apexName := apexInfo.ApexVariationName
- mergedName := apexInfo.mergedName()
+ mergedName := apexInfo.mergedName(ctx)
if index, exists := seen[mergedName]; exists {
merged[index].InApexes = append(merged[index].InApexes, apexName)
merged[index].Updatable = merged[index].Updatable || apexInfo.Updatable
} else {
seen[mergedName] = len(merged)
- apexInfo.ApexVariationName = apexInfo.mergedName()
+ apexInfo.ApexVariationName = apexInfo.mergedName(ctx)
apexInfo.InApexes = CopyOf(apexInfo.InApexes)
merged = append(merged, apexInfo)
}
@@ -374,7 +381,7 @@
var apexVariations []ApexInfo
var aliases [][2]string
if !mctx.Module().(ApexModule).UniqueApexVariations() && !m.ApexProperties.UniqueApexVariationsForDeps {
- apexVariations, aliases = mergeApexVariations(m.apexVariations)
+ apexVariations, aliases = mergeApexVariations(mctx, m.apexVariations)
} else {
apexVariations = m.apexVariations
}
@@ -603,7 +610,13 @@
}
// TODO(b/158059172): remove minSdkVersion allowlist
-var minSdkVersionAllowlist = map[string]int{
+var minSdkVersionAllowlist = func(apiMap map[string]int) map[string]ApiLevel {
+ list := make(map[string]ApiLevel, len(apiMap))
+ for name, finalApiInt := range apiMap {
+ list[name] = uncheckedFinalApiLevel(finalApiInt)
+ }
+ return list
+}(map[string]int{
"adbd": 30,
"android.net.ipsec.ike": 30,
"androidx-constraintlayout_constraintlayout-solver": 30,
@@ -672,7 +685,7 @@
"statsd": 30,
"tensorflow_headers": 30,
"xz-java": 29,
-}
+})
// Function called while walking an APEX's payload dependencies.
//
@@ -686,7 +699,7 @@
}
// CheckMinSdkVersion checks if every dependency of an updatable module sets min_sdk_version accordingly
-func CheckMinSdkVersion(m UpdatableModule, ctx ModuleContext, minSdkVersion int) {
+func CheckMinSdkVersion(m UpdatableModule, ctx ModuleContext, minSdkVersion ApiLevel) {
// do not enforce min_sdk_version for host
if ctx.Host() {
return
@@ -699,7 +712,7 @@
// do not enforce deps.min_sdk_version if APEX/APK doesn't set min_sdk_version or
// min_sdk_version is not finalized (e.g. current or codenames)
- if minSdkVersion == FutureApiLevel {
+ if minSdkVersion.IsCurrent() {
return
}
@@ -714,7 +727,7 @@
}
if err := to.ShouldSupportSdkVersion(ctx, minSdkVersion); err != nil {
toName := ctx.OtherModuleName(to)
- if ver, ok := minSdkVersionAllowlist[toName]; !ok || ver > minSdkVersion {
+ if ver, ok := minSdkVersionAllowlist[toName]; !ok || ver.GreaterThan(minSdkVersion) {
ctx.OtherModuleErrorf(to, "should support min_sdk_version(%v) for %q: %v. Dependency path: %s",
minSdkVersion, ctx.ModuleName(), err.Error(), ctx.GetPathString(false))
return false
diff --git a/android/api_levels.go b/android/api_levels.go
index ddcdbb7..81f5db0 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -49,6 +49,14 @@
isPreview bool
}
+func (this ApiLevel) FinalOrFutureInt() int {
+ if this.IsPreview() {
+ return FutureApiLevel
+ } else {
+ return this.number
+ }
+}
+
// Returns the canonical name for this API level. For a finalized API level
// this will be the API number as a string. For a preview API level this
// will be the codename, or "current".
@@ -261,6 +269,17 @@
"R": 30,
}
+ // TODO: Differentiate "current" and "future".
+ // The code base calls it FutureApiLevel, but the spelling is "current",
+ // and these are really two different things. When defining APIs it
+ // means the API has not yet been added to a specific release. When
+ // choosing an API level to build for it means that the future API level
+ // should be used, except in the case where the build is finalized in
+ // which case the platform version should be used. This is *weird*,
+ // because in the circumstance where API foo was added in R and bar was
+ // added in S, both of these are usable when building for "current" when
+ // neither R nor S are final, but the S APIs stop being available in a
+ // final R build.
if Bool(config.productVariables.Platform_sdk_final) {
apiLevelsMap["current"] = config.PlatformSdkVersionInt()
}
@@ -300,24 +319,6 @@
}).(map[string]int)
}
-// Converts an API level string into its numeric form.
-// * Codenames are decoded.
-// * Numeric API levels are simply converted.
-// * "current" is mapped to FutureApiLevel(10000)
-// * "minimum" is NDK specific and not handled with this. (refer normalizeNdkApiLevel in cc.go)
-func ApiStrToNum(ctx BaseModuleContext, apiLevel string) (int, error) {
- if apiLevel == "current" {
- return FutureApiLevel, nil
- }
- if num, ok := getApiLevelsMap(ctx.Config())[apiLevel]; ok {
- return num, nil
- }
- if num, err := strconv.Atoi(apiLevel); err == nil {
- return num, nil
- }
- return 0, fmt.Errorf("SDK version should be one of \"current\", <number> or <codename>: %q", apiLevel)
-}
-
func (a *apiLevelsSingleton) GenerateBuildActions(ctx SingletonContext) {
apiLevelsMap := getApiLevelsMap(ctx.Config())
apiLevelsJson := GetApiLevelsJson(ctx)