Merge changes from topics "soong-apilevel", "soong-config-apilevel"

* changes:
  Convert more versions in config to ApiLevel.
  Replace FutureApiLevel with an ApiLevel.
  Replace ApiStrToNum uses with ApiLevel.
This commit is contained in:
Dan Albert 2020-09-24 21:02:07 +00:00 committed by Gerrit Code Review
commit 8bd5095362
22 changed files with 184 additions and 183 deletions

View file

@ -24,29 +24,36 @@ import (
"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 @@ type ApexModule interface {
// 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 @@ func (a byApexName) Less(i, j int) bool { return a[i].ApexVariationName < a[j].A
// 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 @@ func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Mod
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 @@ func (d *ApexBundleDepsInfo) BuildDepsInfoLists(ctx ModuleContext, minSdkVersion
}
// 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 @@ var minSdkVersionAllowlist = map[string]int{
"statsd": 30,
"tensorflow_headers": 30,
"xz-java": 29,
}
})
// Function called while walking an APEX's payload dependencies.
//
@ -686,7 +699,7 @@ type UpdatableModule interface {
}
// 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 @@ func CheckMinSdkVersion(m UpdatableModule, ctx ModuleContext, minSdkVersion int)
// 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 @@ func CheckMinSdkVersion(m UpdatableModule, ctx ModuleContext, minSdkVersion int)
}
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

View file

@ -49,6 +49,14 @@ type ApiLevel struct {
isPreview bool
}
func (this ApiLevel) FinalOrFutureInt() int {
if this.IsPreview() {
return FutureApiLevelInt
} 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".
@ -119,13 +127,6 @@ func uncheckedFinalApiLevel(num int) ApiLevel {
}
}
// TODO: Merge with FutureApiLevel
var CurrentApiLevel = ApiLevel{
value: "current",
number: 10000,
isPreview: true,
}
var NoneApiLevel = ApiLevel{
value: "(no version)",
// Not 0 because we don't want this to compare equal with the first preview.
@ -180,7 +181,7 @@ func ApiLevelFromUser(ctx EarlyModuleContext, raw string) (ApiLevel, error) {
}
if raw == "current" {
return CurrentApiLevel, nil
return FutureApiLevel, nil
}
for _, preview := range ctx.Config().PreviewApiLevels() {
@ -261,8 +262,19 @@ func getFinalCodenamesMap(config Config) map[string]int {
"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()
apiLevelsMap["current"] = config.PlatformSdkVersion().FinalOrFutureInt()
}
return apiLevelsMap
@ -300,24 +312,6 @@ func getApiLevelsMap(config Config) map[string]int {
}).(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)

View file

@ -21,7 +21,6 @@ import (
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"sync"
@ -37,7 +36,13 @@ var Bool = proptools.Bool
var String = proptools.String
var StringDefault = proptools.StringDefault
const FutureApiLevel = 10000
const FutureApiLevelInt = 10000
var FutureApiLevel = ApiLevel{
value: "current",
number: FutureApiLevelInt,
isPreview: true,
}
// The configuration file name
const configFileName = "soong.config"
@ -222,15 +227,17 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string
config := &config{
productVariables: productVariables{
DeviceName: stringPtr("test_device"),
Platform_sdk_version: intPtr(30),
DeviceSystemSdkVersions: []string{"14", "15"},
Platform_systemsdk_versions: []string{"29", "30"},
AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
AAPTPreferredConfig: stringPtr("xhdpi"),
AAPTCharacteristics: stringPtr("nosdcard"),
AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
UncompressPrivAppDex: boolPtr(true),
DeviceName: stringPtr("test_device"),
Platform_sdk_version: intPtr(30),
Platform_sdk_codename: stringPtr("S"),
Platform_version_active_codenames: []string{"S"},
DeviceSystemSdkVersions: []string{"14", "15"},
Platform_systemsdk_versions: []string{"29", "30"},
AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
AAPTPreferredConfig: stringPtr("xhdpi"),
AAPTCharacteristics: stringPtr("nosdcard"),
AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
UncompressPrivAppDex: boolPtr(true),
},
buildDir: buildDir,
@ -614,12 +621,8 @@ func (c *config) PlatformVersionName() string {
return String(c.productVariables.Platform_version_name)
}
func (c *config) PlatformSdkVersionInt() int {
return *c.productVariables.Platform_sdk_version
}
func (c *config) PlatformSdkVersion() string {
return strconv.Itoa(c.PlatformSdkVersionInt())
func (c *config) PlatformSdkVersion() ApiLevel {
return uncheckedFinalApiLevel(*c.productVariables.Platform_sdk_version)
}
func (c *config) PlatformSdkCodename() string {
@ -648,7 +651,7 @@ func (c *config) MinSupportedSdkVersion() ApiLevel {
func (c *config) FinalApiLevels() []ApiLevel {
var levels []ApiLevel
for i := 1; i <= c.PlatformSdkVersionInt(); i++ {
for i := 1; i <= c.PlatformSdkVersion().FinalOrFutureInt(); i++ {
levels = append(levels, uncheckedFinalApiLevel(i))
}
return levels
@ -672,19 +675,18 @@ func (c *config) AllSupportedApiLevels() []ApiLevel {
return append(levels, c.PreviewApiLevels()...)
}
func (c *config) DefaultAppTargetSdkInt() int {
if Bool(c.productVariables.Platform_sdk_final) {
return c.PlatformSdkVersionInt()
} else {
return FutureApiLevel
}
}
func (c *config) DefaultAppTargetSdk() string {
func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel {
if Bool(c.productVariables.Platform_sdk_final) {
return c.PlatformSdkVersion()
} else {
return c.PlatformSdkCodename()
codename := c.PlatformSdkCodename()
if codename == "" {
return NoneApiLevel
}
if codename == "REL" {
panic("Platform_sdk_codename should not be REL when Platform_sdk_final is true")
}
return ApiLevelOrPanic(ctx, codename)
}
}

View file

@ -795,7 +795,7 @@ func apexDepsMutator(mctx android.TopDownMutatorContext) {
}
apexInfo := android.ApexInfo{
ApexVariationName: mctx.ModuleName(),
MinSdkVersion: a.minSdkVersion(mctx),
MinSdkVersionStr: a.minSdkVersion(mctx).String(),
RequiredSdks: a.RequiredSdks(),
Updatable: a.Updatable(),
InApexes: []string{mctx.ModuleName()},
@ -1952,27 +1952,21 @@ func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.Paylo
})
}
func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) int {
func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) android.ApiLevel {
ver := proptools.String(a.properties.Min_sdk_version)
if ver == "" {
return android.FutureApiLevel
}
// Treat the current codenames as "current", which means future API version (10000)
// Otherwise, ApiStrToNum converts codename(non-finalized) to a value from [9000...]
// and would fail to build against "current".
if android.InList(ver, ctx.Config().PlatformVersionActiveCodenames()) {
return android.FutureApiLevel
}
// In "REL" branch, "current" is mapped to finalized sdk version
if ctx.Config().PlatformSdkCodename() == "REL" && ver == "current" {
return ctx.Config().PlatformSdkVersionInt()
}
// Finalized codenames are OKAY and will be converted to int
intVer, err := android.ApiStrToNum(ctx, ver)
apiLevel, err := android.ApiLevelFromUser(ctx, ver)
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
return android.NoneApiLevel
}
return intVer
if apiLevel.IsPreview() {
// All codenames should build against "current".
return android.FutureApiLevel
}
return apiLevel
}
func (a *apexBundle) Updatable() bool {
@ -2046,7 +2040,9 @@ func (a *apexBundle) checkMinSdkVersion(ctx android.ModuleContext) {
if proptools.Bool(a.properties.Use_vendor) && ctx.DeviceConfig().VndkVersion() == "" {
return
}
android.CheckMinSdkVersion(a, ctx, a.minSdkVersion(ctx))
// apexBundle::minSdkVersion reports its own errors.
minSdkVersion := a.minSdkVersion(ctx)
android.CheckMinSdkVersion(a, ctx, minSdkVersion)
}
// Ensures that a lib providing stub isn't statically linked

View file

@ -207,7 +207,7 @@ func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*andr
config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"}
config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Q")
config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false)
config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
config.TestProductVariables.Platform_version_active_codenames = []string{"Q"}
config.TestProductVariables.Platform_vndk_version = proptools.StringPtr("VER")
for _, handler := range handlers {
@ -1425,13 +1425,7 @@ func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
// 9000 is quite a magic number.
// Finalized SDK codenames are mapped as P(28), Q(29), ...
// And, codenames which are not finalized yet(active_codenames + future_codenames) are numbered from 9000, 9001, ...
// to distinguish them from finalized and future_api(10000)
// In this test, "R" is assumed not finalized yet( listed in Platform_version_active_codenames) and translated into 9000
// (refer android/api_levels.go)
expectLink("libx", "shared_apex10000", "libz", "shared_9000")
expectLink("libx", "shared_apex10000", "libz", "shared_R")
expectNoLink("libx", "shared_apex10000", "libz", "shared_29")
expectNoLink("libx", "shared_apex10000", "libz", "shared")
}
@ -6130,7 +6124,7 @@ func TestNonPreferredPrebuiltDependency(t *testing.T) {
name: "mylib",
srcs: ["mylib.cpp"],
stubs: {
versions: ["10000"],
versions: ["current"],
},
apex_available: ["myapex"],
}
@ -6140,7 +6134,7 @@ func TestNonPreferredPrebuiltDependency(t *testing.T) {
prefer: false,
srcs: ["prebuilt.so"],
stubs: {
versions: ["10000"],
versions: ["current"],
},
apex_available: ["myapex"],
}

View file

@ -21,7 +21,6 @@ import (
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
"android/soong/android"
@ -214,7 +213,8 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs,
},
})
if a.minSdkVersion(ctx) == android.SdkVersion_Android10 {
minSdkVersion := a.minSdkVersion(ctx)
if minSdkVersion.EqualTo(android.SdkVersion_Android10) {
// b/143654022 Q apexd can't understand newly added keys in apex_manifest.json
// prepare stripped-down version so that APEX modules built from R+ can be installed to Q
a.manifestJsonOut = android.PathForModuleOut(ctx, "apex_manifest.json")
@ -426,7 +426,8 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
var emitCommands []string
imageContentFile := android.PathForModuleOut(ctx, "content.txt")
emitCommands = append(emitCommands, "echo ./apex_manifest.pb >> "+imageContentFile.String())
if a.minSdkVersion(ctx) == android.SdkVersion_Android10 {
minSdkVersion := a.minSdkVersion(ctx)
if minSdkVersion.EqualTo(android.SdkVersion_Android10) {
emitCommands = append(emitCommands, "echo ./apex_manifest.json >> "+imageContentFile.String())
}
for _, fi := range a.filesInfo {
@ -532,12 +533,13 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
optFlags = append(optFlags, "--android_manifest "+androidManifestFile.String())
}
targetSdkVersion := ctx.Config().DefaultAppTargetSdk()
targetSdkVersion := ctx.Config().DefaultAppTargetSdk(ctx).String()
// TODO(b/157078772): propagate min_sdk_version to apexer.
minSdkVersion := ctx.Config().DefaultAppTargetSdk()
minSdkVersion := ctx.Config().DefaultAppTargetSdk(ctx).String()
if a.minSdkVersion(ctx) == android.SdkVersion_Android10 {
minSdkVersion = strconv.Itoa(a.minSdkVersion(ctx))
moduleMinSdkVersion := a.minSdkVersion(ctx)
if moduleMinSdkVersion.EqualTo(android.SdkVersion_Android10) {
minSdkVersion = moduleMinSdkVersion.String()
}
if java.UseApiFingerprint(ctx) {
@ -566,7 +568,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
ctx.PropertyErrorf("test_only_no_hashtree", "not available")
return
}
if a.minSdkVersion(ctx) > android.SdkVersion_Android10 || a.testOnlyShouldSkipHashtreeGeneration() {
if moduleMinSdkVersion.GreaterThan(android.SdkVersion_Android10) || a.testOnlyShouldSkipHashtreeGeneration() {
// Apexes which are supposed to be installed in builtin dirs(/system, etc)
// don't need hashtree for activation. Therefore, by removing hashtree from
// apex bundle (filesystem image in it, to be specific), we can save storage.
@ -583,7 +585,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
optFlags = append(optFlags, "--do_not_check_keyname")
}
if a.minSdkVersion(ctx) == android.SdkVersion_Android10 {
if moduleMinSdkVersion == android.SdkVersion_Android10 {
implicitInputs = append(implicitInputs, a.manifestJsonOut)
optFlags = append(optFlags, "--manifest_json "+a.manifestJsonOut.String())
}

View file

@ -326,7 +326,7 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Args: map[string]string{
"abis": strings.Join(java.SupportedAbis(ctx), ","),
"allow-prereleased": strconv.FormatBool(proptools.Bool(a.properties.Prerelease)),
"sdk-version": ctx.Config().PlatformSdkVersion(),
"sdk-version": ctx.Config().PlatformSdkVersion().String(),
},
})

View file

@ -16,7 +16,6 @@ package apex
import (
"path/filepath"
"strconv"
"strings"
"sync"
@ -124,10 +123,10 @@ func makeCompatSymlinks(name string, ctx android.ModuleContext) (symlinks []stri
// Since prebuilt vndk libs still depend on system/lib/vndk path
if strings.HasPrefix(name, vndkApexNamePrefix) {
vndkVersion := strings.TrimPrefix(name, vndkApexNamePrefix)
if numVer, err := strconv.Atoi(vndkVersion); err != nil {
if ver, err := android.ApiLevelFromUser(ctx, vndkVersion); err != nil {
ctx.ModuleErrorf("apex_vndk should be named as %v<ver:number>: %s", vndkApexNamePrefix, name)
return
} else if numVer > android.SdkVersion_Android10 {
} else if ver.GreaterThan(android.SdkVersion_Android10) {
return
}
// the name of vndk apex is formatted "com.android.vndk.v" + version

View file

@ -354,7 +354,7 @@ type ModuleContextIntf interface {
useClangLld(actx ModuleContext) bool
isForPlatform() bool
apexVariationName() string
apexSdkVersion() int
apexSdkVersion() android.ApiLevel
hasStubsVariants() bool
isStubs() bool
bootstrap() bool
@ -615,7 +615,7 @@ type Module struct {
kytheFiles android.Paths
// For apex variants, this is set as apex.min_sdk_version
apexSdkVersion int
apexSdkVersion android.ApiLevel
}
func (c *Module) Toc() android.OptionalPath {
@ -1328,7 +1328,7 @@ func (ctx *moduleContextImpl) apexVariationName() string {
return ctx.mod.ApexVariationName()
}
func (ctx *moduleContextImpl) apexSdkVersion() int {
func (ctx *moduleContextImpl) apexSdkVersion() android.ApiLevel {
return ctx.mod.apexSdkVersion
}
@ -2317,7 +2317,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
// For the dependency from platform to apex, use the latest stubs
c.apexSdkVersion = android.FutureApiLevel
if !c.IsForPlatform() {
c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion
c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion(ctx)
}
if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
@ -2421,7 +2421,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
if libDepTag, ok := depTag.(libraryDependencyTag); ok {
// Only use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859)
if libDepTag.staticUnwinder && c.apexSdkVersion > android.SdkVersion_Android10 {
if libDepTag.staticUnwinder && c.apexSdkVersion.GreaterThan(android.SdkVersion_Android10) {
return
}
@ -2465,7 +2465,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
// when to use (unspecified) stubs, check min_sdk_version and choose the right one
if useThisDep && depIsStubs && !libDepTag.explicitlyVersioned {
versionToUse, err := c.ChooseSdkVersion(ccDep.StubsVersions(), c.apexSdkVersion)
versionToUse, err := c.ChooseSdkVersion(ccDep.StubsVersions(), c.apexSdkVersion.FinalOrFutureInt())
if err != nil {
ctx.OtherModuleErrorf(dep, err.Error())
return
@ -2488,7 +2488,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
// if this is for use_vendor apex && dep has stubsVersions
// apply the same rule of apex sdk enforcement to choose right version
var err error
versionToUse, err = c.ChooseSdkVersion(versions, c.apexSdkVersion)
versionToUse, err = c.ChooseSdkVersion(versions, c.apexSdkVersion.FinalOrFutureInt())
if err != nil {
ctx.OtherModuleErrorf(dep, err.Error())
return
@ -3012,21 +3012,8 @@ func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
return true
}
// b/154667674: refactor this to handle "current" in a consistent way
func decodeSdkVersionString(ctx android.BaseModuleContext, versionString string) (int, error) {
if versionString == "" {
return 0, fmt.Errorf("not specified")
}
if versionString == "current" {
if ctx.Config().PlatformSdkCodename() == "REL" {
return ctx.Config().PlatformSdkVersionInt(), nil
}
return android.FutureApiLevel, nil
}
return android.ApiStrToNum(ctx, versionString)
}
func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
// We ignore libclang_rt.* prebuilt libs since they declare sdk_version: 14(b/121358700)
if strings.HasPrefix(ctx.OtherModuleName(c), "libclang_rt") {
return nil
@ -3050,11 +3037,17 @@ func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersi
// non-SDK variant resets sdk_version, which works too.
minSdkVersion = c.SdkVersion()
}
ver, err := decodeSdkVersionString(ctx, minSdkVersion)
if minSdkVersion == "" {
return fmt.Errorf("neither min_sdk_version nor sdk_version specificed")
}
// Not using nativeApiLevelFromUser because the context here is not
// necessarily a native context.
ver, err := android.ApiLevelFromUser(ctx, minSdkVersion)
if err != nil {
return err
}
if ver > sdkVersion {
if ver.GreaterThan(sdkVersion) {
return fmt.Errorf("newer SDK(%v)", ver)
}
return nil

View file

@ -354,7 +354,9 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_NAME__='\""+ctx.apexVariationName()+"\"'")
}
if ctx.Device() {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_SDK_VERSION__="+strconv.Itoa(ctx.apexSdkVersion()))
flags.Global.CommonFlags = append(flags.Global.CommonFlags,
fmt.Sprintf("-D__ANDROID_SDK_VERSION__=%d",
ctx.apexSdkVersion().FinalOrFutureInt()))
}
}
@ -390,7 +392,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps
if ctx.Os().Class == android.Device {
version := ctx.sdkVersion()
if version == "" || version == "current" {
target += strconv.Itoa(android.FutureApiLevel)
target += strconv.Itoa(android.FutureApiLevelInt)
} else {
target += version
}

View file

@ -19,8 +19,6 @@ import (
"io"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
"sync"
@ -1520,20 +1518,18 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) {
}
func normalizeVersions(ctx android.BaseModuleContext, versions []string) {
numVersions := make([]int, len(versions))
var previous android.ApiLevel
for i, v := range versions {
numVer, err := android.ApiStrToNum(ctx, v)
ver, err := android.ApiLevelFromUser(ctx, v)
if err != nil {
ctx.PropertyErrorf("versions", "%s", err.Error())
return
}
numVersions[i] = numVer
}
if !sort.IsSorted(sort.IntSlice(numVersions)) {
ctx.PropertyErrorf("versions", "not sorted: %v", versions)
}
for i, v := range numVersions {
versions[i] = strconv.Itoa(v)
if i > 0 && ver.LessThanOrEqualTo(previous) {
ctx.PropertyErrorf("versions", "not sorted: %v", versions)
}
versions[i] = ver.String()
previous = ver
}
}

View file

@ -195,7 +195,7 @@ func TestStubsVersions(t *testing.T) {
name: "libfoo",
srcs: ["foo.c"],
stubs: {
versions: ["29", "R", "10000"],
versions: ["29", "R", "current"],
},
}
`
@ -204,7 +204,7 @@ func TestStubsVersions(t *testing.T) {
ctx := testCcWithConfig(t, config)
variants := ctx.ModuleVariantsForTests("libfoo")
for _, expectedVer := range []string{"29", "9000", "10000"} {
for _, expectedVer := range []string{"29", "R", "current"} {
expectedVariant := "android_arm_armv7-a-neon_shared_" + expectedVer
if !inList(expectedVariant, variants) {
t.Errorf("missing expected variant: %q", expectedVariant)
@ -218,7 +218,7 @@ func TestStubsVersions_NotSorted(t *testing.T) {
name: "libfoo",
srcs: ["foo.c"],
stubs: {
versions: ["29", "10000", "R"],
versions: ["29", "current", "R"],
},
}
`
@ -233,10 +233,10 @@ func TestStubsVersions_ParseError(t *testing.T) {
name: "libfoo",
srcs: ["foo.c"],
stubs: {
versions: ["29", "10000", "X"],
versions: ["29", "current", "X"],
},
}
`
testCcError(t, `"libfoo" .*: versions: SDK version should be`, bp)
testCcError(t, `"libfoo" .*: versions: "X" could not be parsed as an integer and is not a recognized codename`, bp)
}

View file

@ -118,8 +118,8 @@ func generatePerApiVariants(ctx android.BottomUpMutatorContext, m *Module,
versionStrs = append(versionStrs, version.String())
}
}
versions = append(versions, android.CurrentApiLevel)
versionStrs = append(versionStrs, android.CurrentApiLevel.String())
versions = append(versions, android.FutureApiLevel)
versionStrs = append(versionStrs, android.FutureApiLevel.String())
modules := ctx.CreateVariations(versionStrs...)
for i, module := range modules {

View file

@ -555,7 +555,8 @@ func (g *Module) AndroidMk() android.AndroidMkData {
}
}
func (g *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
func (g *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
// Because generated outputs are checked by client modules(e.g. cc_library, ...)
// we can safely ignore the check here.
return nil

View file

@ -189,7 +189,7 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext,
// Version code
if !hasVersionCode {
linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion())
linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion().String())
}
if !hasVersionName {
@ -774,7 +774,8 @@ func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.M
return a.depIsInSameApex(ctx, dep)
}
func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
return nil
}

View file

@ -157,7 +157,7 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext)
"abis": strings.Join(SupportedAbis(ctx), ","),
"allow-prereleased": strconv.FormatBool(proptools.Bool(as.properties.Prerelease)),
"screen-densities": screenDensities,
"sdk-version": ctx.Config().PlatformSdkVersion(),
"sdk-version": ctx.Config().PlatformSdkVersion().String(),
"stem": as.BaseModuleName(),
"apkcerts": as.apkcertsFile.String(),
"partition": as.PartitionTag(ctx.DeviceConfig()),
@ -436,7 +436,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, int(minSdkVersion))
android.CheckMinSdkVersion(a, ctx, minSdkVersion.ApiLevel(ctx))
} else {
ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
}
@ -1637,7 +1637,8 @@ func (a *AndroidAppImport) minSdkVersion() sdkSpec {
return sdkSpecFrom("")
}
func (j *AndroidAppImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
func (j *AndroidAppImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
// Do not check for prebuilts against the min_sdk_version of enclosing APEX
return nil
}

View file

@ -1078,6 +1078,7 @@ func TestAppSdkVersion(t *testing.T) {
platformSdkFinal bool
expectedMinSdkVersion string
platformApis bool
activeCodenames []string
}{
{
name: "current final SDK",
@ -1094,6 +1095,7 @@ func TestAppSdkVersion(t *testing.T) {
platformSdkCodename: "OMR1",
platformSdkFinal: false,
expectedMinSdkVersion: "OMR1",
activeCodenames: []string{"OMR1"},
},
{
name: "default final SDK",
@ -1112,11 +1114,14 @@ func TestAppSdkVersion(t *testing.T) {
platformSdkCodename: "OMR1",
platformSdkFinal: false,
expectedMinSdkVersion: "OMR1",
activeCodenames: []string{"OMR1"},
},
{
name: "14",
sdkVersion: "14",
expectedMinSdkVersion: "14",
platformSdkCodename: "S",
activeCodenames: []string{"S"},
},
}
@ -1137,6 +1142,7 @@ func TestAppSdkVersion(t *testing.T) {
config := testAppConfig(nil, bp, nil)
config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
config.TestProductVariables.Platform_version_active_codenames = test.activeCodenames
config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
checkSdkVersion(t, config, test.expectedMinSdkVersion)
@ -1173,15 +1179,6 @@ func TestVendorAppSdkVersion(t *testing.T) {
deviceCurrentApiLevelForVendorModules: "28",
expectedMinSdkVersion: "28",
},
{
name: "current final SDK",
sdkVersion: "current",
platformSdkInt: 29,
platformSdkCodename: "Q",
platformSdkFinal: false,
deviceCurrentApiLevelForVendorModules: "current",
expectedMinSdkVersion: "Q",
},
{
name: "current final SDK",
sdkVersion: "current",

View file

@ -1228,7 +1228,7 @@ func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *a
cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")

View file

@ -1658,7 +1658,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
if v := sdkSpec.version; v.isNumbered() {
return v.String()
} else {
return ctx.Config().DefaultAppTargetSdk()
return ctx.Config().DefaultAppTargetSdk(ctx).String()
}
}
@ -1876,7 +1876,8 @@ func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
return j.depIsInSameApex(ctx, dep)
}
func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
sdkSpec := j.minSdkVersion()
if !sdkSpec.specified() {
return fmt.Errorf("min_sdk_version is not specified")
@ -1888,7 +1889,7 @@ func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersi
if err != nil {
return err
}
if int(ver) > sdkVersion {
if ver.ApiLevel(ctx).GreaterThan(sdkVersion) {
return fmt.Errorf("newer SDK(%v)", ver)
}
return nil
@ -2753,7 +2754,8 @@ func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
return j.depIsInSameApex(ctx, dep)
}
func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
// Do not check for prebuilts against the min_sdk_version of enclosing APEX
return nil
}
@ -2936,7 +2938,8 @@ func (j *DexImport) DexJarBuildPath() android.Path {
return j.dexJarFile
}
func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
// we don't check prebuilt modules for sdk_version
return nil
}

View file

@ -107,7 +107,7 @@ type sdkVersion int
const (
// special version number for a not-yet-frozen SDK
sdkVersionCurrent sdkVersion = sdkVersion(android.FutureApiLevel)
sdkVersionCurrent sdkVersion = sdkVersion(android.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)
@ -133,6 +133,10 @@ func (v sdkVersion) String() string {
return "(no version)"
}
func (v sdkVersion) ApiLevel(ctx android.EarlyModuleContext) android.ApiLevel {
return android.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"),
@ -243,7 +247,7 @@ func (s sdkSpec) effectiveVersion(ctx android.EarlyModuleContext) (sdkVersion, e
if s.version.isNumbered() {
return s.version, nil
}
return sdkVersion(ctx.Config().DefaultAppTargetSdkInt()), nil
return sdkVersion(ctx.Config().DefaultAppTargetSdk(ctx).FinalOrFutureInt()), nil
}
// effectiveVersionString converts an sdkSpec into the concrete version string that the module
@ -251,8 +255,8 @@ func (s sdkSpec) effectiveVersion(ctx android.EarlyModuleContext) (sdkVersion, e
// it returns the codename (P, Q, R, etc.)
func (s sdkSpec) effectiveVersionString(ctx android.EarlyModuleContext) (string, error) {
ver, err := s.effectiveVersion(ctx)
if err == nil && int(ver) == ctx.Config().DefaultAppTargetSdkInt() {
return ctx.Config().DefaultAppTargetSdk(), nil
if err == nil && int(ver) == ctx.Config().DefaultAppTargetSdk(ctx).FinalOrFutureInt() {
return ctx.Config().DefaultAppTargetSdk(ctx).String(), nil
}
return ver.String(), err
}

View file

@ -1878,7 +1878,8 @@ func (module *SdkLibraryImport) DepIsInSameApex(mctx android.BaseModuleContext,
return false
}
func (module *SdkLibraryImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
func (module *SdkLibraryImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
// we don't check prebuilt modules for sdk_version
return nil
}
@ -2078,7 +2079,8 @@ func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) {
// do nothing
}
func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
// sdkLibraryXml doesn't need to be checked separately because java_sdk_library is checked
return nil
}

View file

@ -310,7 +310,8 @@ func (m *syspropLibrary) AndroidMk() android.AndroidMkData {
}}
}
func (m *syspropLibrary) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
func (m *syspropLibrary) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
return fmt.Errorf("sysprop_library is not supposed to be part of apex modules")
}