Browse Source

Merge changes I10e8bea5,I8e013ec1

* changes:
  Create EffectiveVersion* functions for ApiLevel
  Create two sentinel api levels
Spandan Das 1 year ago
parent
commit
7947b31a55
4 changed files with 101 additions and 39 deletions
  1. 85 0
      android/api_levels.go
  2. 9 0
      android/config.go
  3. 5 37
      android/sdk_version.go
  4. 2 2
      android/sdk_version_test.go

+ 85 - 0
android/api_levels.go

@@ -55,6 +55,9 @@ type ApiLevel struct {
 }
 
 func (this ApiLevel) FinalInt() int {
+	if this.IsInvalid() {
+		panic(fmt.Errorf("%v is not a recognized api_level\n", this))
+	}
 	if this.IsPreview() {
 		panic("Requested a final int from a non-final ApiLevel")
 	} else {
@@ -63,6 +66,9 @@ func (this ApiLevel) FinalInt() int {
 }
 
 func (this ApiLevel) FinalOrFutureInt() int {
+	if this.IsInvalid() {
+		panic(fmt.Errorf("%v is not a recognized api_level\n", this))
+	}
 	if this.IsPreview() {
 		return FutureApiLevelInt
 	} else {
@@ -76,6 +82,9 @@ func (this ApiLevel) FinalOrFutureInt() int {
 // - preview codenames -> preview base (9000) + index
 // - otherwise -> cast to int
 func (this ApiLevel) FinalOrPreviewInt() int {
+	if this.IsInvalid() {
+		panic(fmt.Errorf("%v is not a recognized api_level\n", this))
+	}
 	if this.IsCurrent() {
 		return this.number
 	}
@@ -97,6 +106,11 @@ func (this ApiLevel) IsPreview() bool {
 	return this.isPreview
 }
 
+// Returns true if the raw api level string is invalid
+func (this ApiLevel) IsInvalid() bool {
+	return this.EqualTo(InvalidApiLevel)
+}
+
 // Returns true if this is the unfinalized "current" API level. This means
 // different things across Java and native. Java APIs do not use explicit
 // codenames, so all non-final codenames are grouped into "current". For native
@@ -113,6 +127,64 @@ func (this ApiLevel) IsNone() bool {
 	return this.number == -1
 }
 
+// Returns true if an app is compiling against private apis.
+// e.g. if sdk_version = "" in Android.bp, then the ApiLevel of that "sdk" is at PrivateApiLevel.
+func (this ApiLevel) IsPrivate() bool {
+	return this.number == PrivateApiLevel.number
+}
+
+// EffectiveVersion converts an ApiLevel 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 (l ApiLevel) EffectiveVersion(ctx EarlyModuleContext) (ApiLevel, error) {
+	if l.EqualTo(InvalidApiLevel) {
+		return l, fmt.Errorf("invalid version in sdk_version %q", l.value)
+	}
+	if !l.IsPreview() {
+		return l, 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 (l ApiLevel) EffectiveVersionString(ctx EarlyModuleContext) (string, error) {
+	if l.EqualTo(InvalidApiLevel) {
+		return l.value, fmt.Errorf("invalid version in sdk_version %q", l.value)
+	}
+	if !l.IsPreview() {
+		return l.String(), nil
+	}
+	// Determine the default sdk
+	ret := ctx.Config().DefaultAppTargetSdk(ctx)
+	if !ret.IsPreview() {
+		// If the default sdk has been finalized, return that
+		return ret.String(), nil
+	}
+	// There can be more than one active in-development sdks
+	// If an app is targeting an active sdk, but not the default one, return the requested active sdk.
+	// e.g.
+	// SETUP
+	// In-development: UpsideDownCake, VanillaIceCream
+	// Default: VanillaIceCream
+	// Android.bp
+	// min_sdk_version: `UpsideDownCake`
+	// RETURN
+	// UpsideDownCake and not VanillaIceCream
+	for _, preview := range ctx.Config().PreviewApiLevels() {
+		if l.String() == preview.String() {
+			return preview.String(), nil
+		}
+	}
+	// Otherwise return the default one
+	return ret.String(), nil
+}
+
 // 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 {
@@ -166,6 +238,19 @@ var NoneApiLevel = ApiLevel{
 	isPreview: true,
 }
 
+// Sentinel ApiLevel to validate that an apiLevel is either an int or a recognized codename.
+var InvalidApiLevel = NewInvalidApiLevel("invalid")
+
+// Returns an apiLevel object at the same level as InvalidApiLevel.
+// The object contains the raw string provied in bp file, and can be used for error handling.
+func NewInvalidApiLevel(raw string) ApiLevel {
+	return ApiLevel{
+		value:     raw,
+		number:    -2, // One less than NoneApiLevel
+		isPreview: true,
+	}
+}
+
 // The first version that introduced 64-bit ABIs.
 var FirstLp64Version = uncheckedFinalApiLevel(21)
 

+ 9 - 0
android/config.go

@@ -52,6 +52,15 @@ var StringDefault = proptools.StringDefault
 // FutureApiLevelInt is a placeholder constant for unreleased API levels.
 const FutureApiLevelInt = 10000
 
+// PrivateApiLevel represents the api level of SdkSpecPrivate (sdk_version: "")
+// This api_level exists to differentiate user-provided "" from "current" sdk_version
+// The differentiation is necessary to enable different validation rules for these two possible values.
+var PrivateApiLevel = ApiLevel{
+	value:     "current",             // The value is current since aidl expects `current` as the default (TestAidlFlagsWithMinSdkVersion)
+	number:    FutureApiLevelInt + 1, // This is used to differentiate it from FutureApiLevel
+	isPreview: true,
+}
+
 // FutureApiLevel represents unreleased API levels.
 var FutureApiLevel = ApiLevel{
 	value:     "current",

+ 5 - 37
android/sdk_version.go

@@ -221,14 +221,7 @@ func (s SdkSpec) EffectiveVersion(ctx EarlyModuleContext) (ApiLevel, error) {
 	if ctx.DeviceSpecific() || ctx.SocSpecific() {
 		s = s.ForVendorPartition(ctx)
 	}
-	if !s.ApiLevel.IsPreview() {
-		return s.ApiLevel, nil
-	}
-	ret := ctx.Config().DefaultAppTargetSdk(ctx)
-	if ret.IsPreview() {
-		return FutureApiLevel, nil
-	}
-	return ret, nil
+	return s.ApiLevel.EffectiveVersion(ctx)
 }
 
 // EffectiveVersionString converts an SdkSpec into the concrete version string that the module
@@ -242,37 +235,12 @@ func (s SdkSpec) EffectiveVersionString(ctx EarlyModuleContext) (string, error)
 	if ctx.DeviceSpecific() || ctx.SocSpecific() {
 		s = s.ForVendorPartition(ctx)
 	}
-	if !s.ApiLevel.IsPreview() {
-		return s.ApiLevel.String(), nil
-	}
-	// Determine the default sdk
-	ret := ctx.Config().DefaultAppTargetSdk(ctx)
-	if !ret.IsPreview() {
-		// If the default sdk has been finalized, return that
-		return ret.String(), nil
-	}
-	// There can be more than one active in-development sdks
-	// If an app is targeting an active sdk, but not the default one, return the requested active sdk.
-	// e.g.
-	// SETUP
-	// In-development: UpsideDownCake, VanillaIceCream
-	// Default: VanillaIceCream
-	// Android.bp
-	// min_sdk_version: `UpsideDownCake`
-	// RETURN
-	// UpsideDownCake and not VanillaIceCream
-	for _, preview := range ctx.Config().PreviewApiLevels() {
-		if s.ApiLevel.String() == preview.String() {
-			return preview.String(), nil
-		}
-	}
-	// Otherwise return the default one
-	return ret.String(), nil
+	return s.ApiLevel.EffectiveVersionString(ctx)
 }
 
 var (
 	SdkSpecNone         = SdkSpec{SdkNone, NoneApiLevel, "(no version)"}
-	SdkSpecPrivate      = SdkSpec{SdkPrivate, FutureApiLevel, ""}
+	SdkSpecPrivate      = SdkSpec{SdkPrivate, PrivateApiLevel, ""}
 	SdkSpecCorePlatform = SdkSpec{SdkCorePlatform, FutureApiLevel, "core_platform"}
 )
 
@@ -295,7 +263,7 @@ func SdkSpecFromWithConfig(config Config, str string) SdkSpec {
 
 		var kindString string
 		if sep == 0 {
-			return SdkSpec{SdkInvalid, NoneApiLevel, str}
+			return SdkSpec{SdkInvalid, NewInvalidApiLevel(str), str}
 		} else if sep == -1 {
 			kindString = ""
 		} else {
@@ -323,7 +291,7 @@ func SdkSpecFromWithConfig(config Config, str string) SdkSpec {
 
 		apiLevel, err := ApiLevelFromUserWithConfig(config, versionString)
 		if err != nil {
-			return SdkSpec{SdkInvalid, apiLevel, str}
+			return SdkSpec{SdkInvalid, NewInvalidApiLevel(versionString), str}
 		}
 		return SdkSpec{kind, apiLevel, str}
 	}

+ 2 - 2
android/sdk_version_test.go

@@ -37,11 +37,11 @@ func TestSdkSpecFrom(t *testing.T) {
 		},
 		{
 			input:    "_",
-			expected: "invalid_(no version)",
+			expected: "invalid__",
 		},
 		{
 			input:    "_31",
-			expected: "invalid_(no version)",
+			expected: "invalid__31",
 		},
 		{
 			input:    "system_R",