diff --git a/android/apex.go b/android/apex.go index 31c62e994..d3f8d2ada 100644 --- a/android/apex.go +++ b/android/apex.go @@ -830,9 +830,8 @@ func CheckMinSdkVersion(m UpdatableModule, ctx ModuleContext, minSdkVersion ApiL return } - // 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.IsCurrent() { + // do not enforce deps.min_sdk_version if APEX/APK doesn't set min_sdk_version + if minSdkVersion.IsNone() { return } diff --git a/android/api_levels.go b/android/api_levels.go index 08328e16d..1b53f3f2a 100644 --- a/android/api_levels.go +++ b/android/api_levels.go @@ -81,6 +81,10 @@ func (this ApiLevel) IsCurrent() bool { return this.value == "current" } +func (this ApiLevel) IsNone() bool { + return this.number == -1 +} + // Returns -1 if the current API level is less than the argument, 0 if they // are equal, and 1 if it is greater than the argument. func (this ApiLevel) CompareTo(other ApiLevel) int { diff --git a/apex/apex.go b/apex/apex.go index 384d6c7a6..ade8fa909 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -854,11 +854,17 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) { Contents: apexContents, }) + minSdkVersion := a.minSdkVersion(mctx) + // When min_sdk_version is not set, the apex is built against FutureApiLevel. + if minSdkVersion.IsNone() { + minSdkVersion = android.FutureApiLevel + } + // This is the main part of this mutator. Mark the collected dependencies that they need to // be built for this apexBundle. apexInfo := android.ApexInfo{ ApexVariationName: mctx.ModuleName(), - MinSdkVersionStr: a.minSdkVersion(mctx).String(), + MinSdkVersionStr: minSdkVersion.String(), RequiredSdks: a.RequiredSdks(), Updatable: a.Updatable(), InApexes: []string{mctx.ModuleName()}, @@ -2116,17 +2122,13 @@ func (a *apexBundle) checkMinSdkVersion(ctx android.ModuleContext) { func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) android.ApiLevel { ver := proptools.String(a.properties.Min_sdk_version) if ver == "" { - return android.FutureApiLevel + return android.NoneApiLevel } apiLevel, err := android.ApiLevelFromUser(ctx, ver) if err != nil { ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) return android.NoneApiLevel } - if apiLevel.IsPreview() { - // All codenames should build against "current". - return android.FutureApiLevel - } return apiLevel } diff --git a/apex/apex_test.go b/apex/apex_test.go index ae0cbe969..cded7707c 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -2135,6 +2135,74 @@ func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion expectLink("mylib", "shared_apex30", "mylib2", "shared_apex30") } +func TestApexMinSdkVersion_WorksWithSdkCodename(t *testing.T) { + withSAsActiveCodeNames := func(fs map[string][]byte, config android.Config) { + config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("S") + config.TestProductVariables.Platform_version_active_codenames = []string{"S"} + } + testApexError(t, `libbar.*: should support min_sdk_version\(S\)`, ` + apex { + name: "myapex", + key: "myapex.key", + native_shared_libs: ["libfoo"], + min_sdk_version: "S", + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + cc_library { + name: "libfoo", + shared_libs: ["libbar"], + apex_available: ["myapex"], + min_sdk_version: "29", + } + cc_library { + name: "libbar", + apex_available: ["myapex"], + } + `, withSAsActiveCodeNames) +} + +func TestApexMinSdkVersion_WorksWithActiveCodenames(t *testing.T) { + withSAsActiveCodeNames := func(fs map[string][]byte, config android.Config) { + config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("S") + config.TestProductVariables.Platform_version_active_codenames = []string{"S", "T"} + } + ctx, _ := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + native_shared_libs: ["libfoo"], + min_sdk_version: "S", + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + cc_library { + name: "libfoo", + shared_libs: ["libbar"], + apex_available: ["myapex"], + min_sdk_version: "S", + } + cc_library { + name: "libbar", + stubs: { + symbol_file: "libbar.map.txt", + versions: ["30", "S", "T"], + }, + } + `, withSAsActiveCodeNames) + + // ensure libfoo is linked with "S" version of libbar stub + libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex10000") + libFlags := libfoo.Rule("ld").Args["libFlags"] + ensureContains(t, libFlags, "android_arm64_armv8-a_shared_S/libbar.so") +} + func TestFilesInSubDir(t *testing.T) { ctx, _ := testApex(t, ` apex { diff --git a/apex/builder.go b/apex/builder.go index 67314d85b..ee0a41063 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -598,7 +598,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { // bundletool doesn't understand what "current" is. We need to transform it to // codename - if moduleMinSdkVersion.IsCurrent() { + if moduleMinSdkVersion.IsCurrent() || moduleMinSdkVersion.IsNone() { minSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String() } // apex module doesn't have a concept of target_sdk_version, hence for the time