android_app APEX_GLOBAL_MIN_SDK_VERSION_OVERRIDE

Currently the product variable that is controlled by
APEX_GLOBAL_MIN_SDK_VERSION_OVERRIDE only overrides apexes, but it
doesn't apply to android_apps. This commit allows android_apps which set
updatable: true in their Android.bp to have their min_sdk_version be
overriden by this product variable.

Bug: 295311875
Test: go test
(cherry picked from https://android-review.googlesource.com/q/commit:0e0d96efa71e7146f2d43ec9c2fbe66226426811)
Merged-In: If3cb82a17cae4553b577dd1a4637ee13c3c95302
Change-Id: If3cb82a17cae4553b577dd1a4637ee13c3c95302
diff --git a/android/apex.go b/android/apex.go
index 35e1d02..5a25297 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -918,6 +918,19 @@
 	})
 }
 
+// Construct ApiLevel object from min_sdk_version string value
+func MinSdkVersionFromValue(ctx EarlyModuleContext, value string) ApiLevel {
+	if value == "" {
+		return NoneApiLevel
+	}
+	apiLevel, err := ApiLevelFromUser(ctx, value)
+	if err != nil {
+		ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
+		return NoneApiLevel
+	}
+	return apiLevel
+}
+
 // Implemented by apexBundle.
 type ApexTestInterface interface {
 	// Return true if the apex bundle is an apex_test
diff --git a/apex/apex.go b/apex/apex.go
index f7c7444..fca0944 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2943,13 +2943,13 @@
 	// 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.
-	minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
+	minApiLevel := android.MinSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
 	if minApiLevel.IsNone() {
 		return ""
 	}
 
 	overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
-	overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
+	overrideApiLevel := android.MinSdkVersionFromValue(ctx, overrideMinSdkValue)
 	if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
 		minApiLevel = overrideApiLevel
 	}
@@ -2964,20 +2964,7 @@
 
 // Returns apex's min_sdk_version ApiLevel, honoring overrides
 func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
-	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, value)
-	if err != nil {
-		ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
-		return android.NoneApiLevel
-	}
-	return apiLevel
+	return android.MinSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
 }
 
 // Ensures that a lib providing stub isn't statically linked
diff --git a/java/app.go b/java/app.go
index 8d96557..254906d 100755
--- a/java/app.go
+++ b/java/app.go
@@ -318,6 +318,17 @@
 	a.generateJavaUsedByApex(ctx)
 }
 
+func (a *AndroidApp) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
+	defaultMinSdkVersion := a.Module.MinSdkVersion(ctx)
+	if proptools.Bool(a.appProperties.Updatable) {
+		overrideApiLevel := android.MinSdkVersionFromValue(ctx, ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride())
+		if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(defaultMinSdkVersion) > 0 {
+			return overrideApiLevel
+		}
+	}
+	return defaultMinSdkVersion
+}
+
 func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
 	if a.Updatable() {
 		if !a.SdkVersion(ctx).Stable() {
diff --git a/java/app_test.go b/java/app_test.go
index 746ab75..f078021 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -3668,3 +3668,49 @@
 		"\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/bar.xml",
 	)
 }
+
+func TestApexGlobalMinSdkVersionOverride(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		PrepareForTestWithJavaDefaultModules,
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.ApexGlobalMinSdkVersionOverride = proptools.StringPtr("Tiramisu")
+		}),
+	).RunTestWithBp(t, `
+		android_app {
+			name: "com.android.bar",
+			srcs: ["a.java"],
+			sdk_version: "current",
+		}
+		android_app {
+			name: "com.android.foo",
+			srcs: ["a.java"],
+			sdk_version: "current",
+			min_sdk_version: "S",
+			updatable: true,
+		}
+		override_android_app {
+			name: "com.android.go.foo",
+			base: "com.android.foo",
+		}
+	`)
+	foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+	fooOverride := result.ModuleForTests("com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer")
+	bar := result.ModuleForTests("com.android.bar", "android_common").Rule("manifestFixer")
+
+	android.AssertStringDoesContain(t,
+		"expected manifest fixer to set com.android.bar minSdkVersion to S",
+		bar.BuildParams.Args["args"],
+		"--minSdkVersion  S",
+	)
+	android.AssertStringDoesContain(t,
+		"com.android.foo: expected manifest fixer to set minSdkVersion to T",
+		foo.BuildParams.Args["args"],
+		"--minSdkVersion  T",
+	)
+	android.AssertStringDoesContain(t,
+		"com.android.go.foo: expected manifest fixer to set minSdkVersion to T",
+		fooOverride.BuildParams.Args["args"],
+		"--minSdkVersion  T",
+	)
+
+}