diff --git a/apex/apex.go b/apex/apex.go index a314cc5ea..f7c74440c 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -224,6 +224,9 @@ type apexBundleProperties struct { // Name that dependencies can specify in their apex_available properties to refer to this module. // If not specified, this defaults to Soong module name. Apex_available_name *string + + // Variant version of the mainline module. Must be an integer between 0-9 + Variant_version *string } type ApexNativeDependencies struct { diff --git a/apex/apex_test.go b/apex/apex_test.go index d5af826e4..d5493dd32 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -6556,6 +6556,89 @@ func TestApexAvailable_InvalidApexName(t *testing.T) { }`) } +func TestApexAvailable_ApexAvailableNameWithVersionCodeError(t *testing.T) { + t.Run("negative variant_version produces error", func(t *testing.T) { + testApexError(t, "expected an integer between 0-9; got -1", ` + apex { + name: "myapex", + key: "myapex.key", + apex_available_name: "com.android.foo", + variant_version: "-1", + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) + }) + + t.Run("variant_version greater than 9 produces error", func(t *testing.T) { + testApexError(t, "expected an integer between 0-9; got 10", ` + apex { + name: "myapex", + key: "myapex.key", + apex_available_name: "com.android.foo", + variant_version: "10", + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) + }) +} + +func TestApexAvailable_ApexAvailableNameWithVersionCode(t *testing.T) { + context := android.GroupFixturePreparers( + android.PrepareForIntegrationTestWithAndroid, + PrepareForTestWithApexBuildComponents, + android.FixtureMergeMockFs(android.MockFS{ + "system/sepolicy/apex/foo-file_contexts": nil, + "system/sepolicy/apex/bar-file_contexts": nil, + }), + ) + result := context.RunTestWithBp(t, ` + apex { + name: "foo", + key: "myapex.key", + apex_available_name: "com.android.foo", + variant_version: "0", + updatable: false, + } + apex { + name: "bar", + key: "myapex.key", + apex_available_name: "com.android.foo", + variant_version: "3", + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) + + fooManifestRule := result.ModuleForTests("foo", "android_common_foo_image").Rule("apexManifestRule") + fooExpectedDefaultVersion := android.DefaultUpdatableModuleVersion + fooActualDefaultVersion := fooManifestRule.Args["default_version"] + if fooActualDefaultVersion != fooExpectedDefaultVersion { + t.Errorf("expected to find defaultVersion %q; got %q", fooExpectedDefaultVersion, fooActualDefaultVersion) + } + + barManifestRule := result.ModuleForTests("bar", "android_common_bar_image").Rule("apexManifestRule") + defaultVersionInt, _ := strconv.Atoi(android.DefaultUpdatableModuleVersion) + barExpectedDefaultVersion := fmt.Sprint(defaultVersionInt + 3) + barActualDefaultVersion := barManifestRule.Args["default_version"] + if barActualDefaultVersion != barExpectedDefaultVersion { + t.Errorf("expected to find defaultVersion %q; got %q", barExpectedDefaultVersion, barActualDefaultVersion) + } +} + func TestApexAvailable_ApexAvailableName(t *testing.T) { t.Run("using name of apex that sets apex_available_name is not allowed", func(t *testing.T) { testApexError(t, "Consider adding \"myapex\" to 'apex_available' property of \"AppFoo\"", ` diff --git a/apex/builder.go b/apex/builder.go index 3c7671b00..f49bed93c 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -275,6 +275,22 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs, manifestJsonFullOut := android.PathForModuleOut(ctx, "apex_manifest_full.json") defaultVersion := android.DefaultUpdatableModuleVersion + if a.properties.Variant_version != nil { + defaultVersionInt, err := strconv.Atoi(defaultVersion) + if err != nil { + ctx.ModuleErrorf("expected DefaultUpdatableModuleVersion to be an int, but got %s", defaultVersion) + } + if defaultVersionInt%10 != 0 { + ctx.ModuleErrorf("expected DefaultUpdatableModuleVersion to end in a zero, but got %s", defaultVersion) + } + variantVersion := []rune(*a.properties.Variant_version) + if len(variantVersion) != 1 || variantVersion[0] < '0' || variantVersion[0] > '9' { + ctx.PropertyErrorf("variant_version", "expected an integer between 0-9; got %s", *a.properties.Variant_version) + } + defaultVersionRunes := []rune(defaultVersion) + defaultVersionRunes[len(defaultVersion)-1] = []rune(variantVersion)[0] + defaultVersion = string(defaultVersionRunes) + } if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" { defaultVersion = override }