From eefabcf32197ed897ec9566d7f886fa97b0cee7a Mon Sep 17 00:00:00 2001 From: Albert Martin Date: Mon, 21 Mar 2022 20:11:16 +0000 Subject: [PATCH] Flag to globally override apexes' min_sdk_version Override all mainline updateable apexes' min_sdk_version to same version to get single shared native libs on DCLA. Test: Run "vendor/google/build/go/mainline_go_modules_arm.sh" and inspect built apexes Bug: 212609891 Change-Id: Ide7d3f2bc772ac6240f1c917b87285d051d6f605 Merged-In: Ide7d3f2bc772ac6240f1c917b87285d051d6f605 --- android/config.go | 4 ++ android/variable.go | 2 + apex/apex.go | 35 +++++++++++-- apex/apex_test.go | 124 ++++++++++++++++++++++++++++++++++++++++++++ apex/builder.go | 2 +- 5 files changed, 161 insertions(+), 6 deletions(-) diff --git a/android/config.go b/android/config.go index 5c41ee8bf..5dcb95935 100644 --- a/android/config.go +++ b/android/config.go @@ -1360,6 +1360,10 @@ func findOverrideValue(overrides []string, name string, errorMsg string) (newVal return "", false } +func (c *deviceConfig) ApexGlobalMinSdkVersionOverride() string { + return String(c.config.productVariables.ApexGlobalMinSdkVersionOverride) +} + func (c *config) IntegerOverflowDisabledForPath(path string) bool { if len(c.productVariables.IntegerOverflowExcludePaths) == 0 { return false diff --git a/android/variable.go b/android/variable.go index 4ed05070e..077b81097 100644 --- a/android/variable.go +++ b/android/variable.go @@ -389,6 +389,8 @@ type productVariables struct { CertificateOverrides []string `json:",omitempty"` PackageNameOverrides []string `json:",omitempty"` + ApexGlobalMinSdkVersionOverride *string `json:",omitempty"` + EnforceSystemCertificate *bool `json:",omitempty"` EnforceSystemCertificateAllowList []string `json:",omitempty"` diff --git a/apex/apex.go b/apex/apex.go index 2fe17da59..a7b0a4fe2 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2450,20 +2450,43 @@ func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) { android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps) } +// Returns apex's min_sdk_version string value, honoring overrides +func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string { + // Only override the minSdkVersion value on Apexes which already specify + // a min_sdk_version (it's optional for non-updatable apexes), and that its + // min_sdk_version value is lower than the one to override with. + overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride() + overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue) + originalMinApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version)) + isMinSdkSet := a.properties.Min_sdk_version != nil + isOverrideValueHigher := overrideApiLevel.CompareTo(originalMinApiLevel) > 0 + if overrideMinSdkValue != "" && isMinSdkSet && isOverrideValueHigher { + return overrideMinSdkValue + } + + return proptools.String(a.properties.Min_sdk_version) +} + +// Returns apex's min_sdk_version SdkSpec, honoring overrides func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return android.SdkSpec{ Kind: android.SdkNone, ApiLevel: a.minSdkVersion(ctx), - Raw: String(a.properties.Min_sdk_version), + Raw: a.minSdkVersionValue(ctx), } } +// Returns apex's min_sdk_version ApiLevel, honoring overrides func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { - ver := proptools.String(a.properties.Min_sdk_version) - if ver == "" { + return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx)) +} + +// Construct ApiLevel object from min_sdk_version string value +func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel { + if value == "" { return android.NoneApiLevel } - apiLevel, err := android.ApiLevelFromUser(ctx, ver) + apiLevel, err := android.ApiLevelFromUser(ctx, value) if err != nil { ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) return android.NoneApiLevel @@ -2518,7 +2541,7 @@ func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext // checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes. func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) { if a.Updatable() { - if String(a.properties.Min_sdk_version) == "" { + if a.minSdkVersionValue(ctx) == "" { ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well") } if a.UsePlatformApis() { @@ -3398,6 +3421,8 @@ func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) { fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts)) } + // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but + // given it's coming via config, we probably don't want to put it in here. var minSdkVersion *string if a.properties.Min_sdk_version != nil { minSdkVersion = a.properties.Min_sdk_version diff --git a/apex/apex_test.go b/apex/apex_test.go index 3e01f2608..5021f275d 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -113,6 +113,12 @@ func withManifestPackageNameOverrides(specs []string) android.FixturePreparer { }) } +func withApexGlobalMinSdkVersionOverride(minSdkOverride *string) android.FixturePreparer { + return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.ApexGlobalMinSdkVersionOverride = minSdkOverride + }) +} + var withBinder32bit = android.FixtureModifyProductVariables( func(variables android.FixtureProductVariables) { variables.Binder32bit = proptools.BoolPtr(true) @@ -6314,6 +6320,124 @@ func TestOverrideApex(t *testing.T) { ensureNotContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.apex") } +func TestMinSdkVersionOverride(t *testing.T) { + // Override from 29 to 31 + minSdkOverride31 := "31" + ctx := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + native_shared_libs: ["mylib"], + updatable: true, + min_sdk_version: "29" + } + + override_apex { + name: "override_myapex", + base: "myapex", + logging_parent: "com.foo.bar", + package_name: "test.overridden.package" + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "mylib", + srcs: ["mylib.cpp"], + runtime_libs: ["libbar"], + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + min_sdk_version: "apex_inherit" + } + + cc_library { + name: "libbar", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + min_sdk_version: "apex_inherit" + } + + `, withApexGlobalMinSdkVersionOverride(&minSdkOverride31)) + + apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") + copyCmds := apexRule.Args["copy_commands"] + + // Ensure that direct non-stubs dep is always included + ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") + + // Ensure that runtime_libs dep in included + ensureContains(t, copyCmds, "image.apex/lib64/libbar.so") + + // Ensure libraries target overridden min_sdk_version value + ensureListContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared_apex31") +} + +func TestMinSdkVersionOverrideToLowerVersionNoOp(t *testing.T) { + // Attempt to override from 31 to 29, should be a NOOP + minSdkOverride29 := "29" + ctx := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + native_shared_libs: ["mylib"], + updatable: true, + min_sdk_version: "31" + } + + override_apex { + name: "override_myapex", + base: "myapex", + logging_parent: "com.foo.bar", + package_name: "test.overridden.package" + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "mylib", + srcs: ["mylib.cpp"], + runtime_libs: ["libbar"], + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + min_sdk_version: "apex_inherit" + } + + cc_library { + name: "libbar", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + min_sdk_version: "apex_inherit" + } + + `, withApexGlobalMinSdkVersionOverride(&minSdkOverride29)) + + apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") + copyCmds := apexRule.Args["copy_commands"] + + // Ensure that direct non-stubs dep is always included + ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") + + // Ensure that runtime_libs dep in included + ensureContains(t, copyCmds, "image.apex/lib64/libbar.so") + + // Ensure libraries target the original min_sdk_version value rather than the overridden + ensureListContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared_apex31") +} + func TestLegacyAndroid10Support(t *testing.T) { ctx := testApex(t, ` apex { diff --git a/apex/builder.go b/apex/builder.go index ea61e1ae8..293f388ea 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -994,7 +994,7 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) { return !externalDep }) - a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, proptools.String(a.properties.Min_sdk_version), depInfos) + a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).Raw, depInfos) ctx.Build(pctx, android.BuildParams{ Rule: android.Phony,