From c8cb0c3eb5fe924e17b51d7860e0cde31c748fe8 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 8 Dec 2021 17:00:38 +0000 Subject: [PATCH] Set targetSdkVersion to 10000 iff a module is targeting an unreleased sdk Previously in aosp/1907152, targetSdkVersion for all modules would be 10000 in release builds. This would cause sdk compatibility errors like b/209301265#3 for modules that were targeting a released SDK This CL adds an additional check to set targetSdkVersion to 10000 only if a module's apilevel is in preview (i.e. unreleased SDK) Bug: 209301265 Test: Built various apk combinations locally, and used aapt2 to check targetSdkVersion Test: TARGET_BUILD_APPS=xyz m CaptivePortalLoginTests # targetSdkVersion: 30 Test: m CaptivePortalLoginTests #targetSdkVersion: 30 Test: (internal) TARGET_BUILD_APPS=xyz m MediaProviderGoogle # targetSdkVersion: 10000 Test: (internal) m MediaProviderGoogle #targetSdkVersion: Tiramisu Change-Id: Id2901f23d4e1b436f8906940e47edd606a93657d --- java/android_manifest.go | 22 +++++++++--- java/app_test.go | 73 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 4 deletions(-) diff --git a/java/android_manifest.go b/java/android_manifest.go index 38065f153..f29d8ad1a 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -16,6 +16,7 @@ package java import ( "fmt" + "strconv" "strings" "github.com/google/blueprint" @@ -42,6 +43,21 @@ var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger", }, "args", "libs") +// targetSdkVersion for manifest_fixer +// When TARGET_BUILD_APPS is not empty, this method returns 10000 for modules targeting an unreleased SDK +// This enables release builds (that run with TARGET_BUILD_APPS=[val...]) to target APIs that have not yet been finalized as part of an SDK +func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext android.SdkContext) string { + targetSdkVersionSpec := sdkContext.TargetSdkVersion(ctx) + if ctx.Config().UnbundledBuildApps() && targetSdkVersionSpec.ApiLevel.IsPreview() { + return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt()) + } + targetSdkVersion, err := targetSdkVersionSpec.EffectiveVersionString(ctx) + if err != nil { + ctx.ModuleErrorf("invalid targetSdkVersion: %s", err) + } + return targetSdkVersion +} + // Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext android.SdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap, isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, @@ -89,10 +105,8 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext args = append(args, "--logging-parent", loggingParent) } var deps android.Paths - targetSdkVersion, err := sdkContext.TargetSdkVersion(ctx).EffectiveVersionString(ctx) - if err != nil { - ctx.ModuleErrorf("invalid targetSdkVersion: %s", err) - } + targetSdkVersion := targetSdkVersionForManifestFixer(ctx, sdkContext) + if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" { targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String()) deps = append(deps, ApiFingerprintPath(ctx)) diff --git a/java/app_test.go b/java/app_test.go index 0aae9280d..4da7c3dba 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -2873,3 +2873,76 @@ func TestExportedProguardFlagFiles(t *testing.T) { t.Errorf("App does not use library proguard config") } } + +func TestTargetSdkVersionManifestFixer(t *testing.T) { + platform_sdk_codename := "Tiramisu" + testCases := []struct { + name string + targetSdkVersionInBp string + targetSdkVersionExpected string + unbundledBuild bool + }{ + { + name: "Non-Unbundled build: Android.bp has targetSdkVersion", + targetSdkVersionInBp: "30", + targetSdkVersionExpected: "30", + unbundledBuild: false, + }, + { + name: "Unbundled build: Android.bp has targetSdkVersion", + targetSdkVersionInBp: "30", + targetSdkVersionExpected: "30", + unbundledBuild: true, + }, + { + name: "Non-Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename", + targetSdkVersionInBp: platform_sdk_codename, + targetSdkVersionExpected: platform_sdk_codename, + unbundledBuild: false, + }, + { + name: "Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename", + targetSdkVersionInBp: platform_sdk_codename, + targetSdkVersionExpected: "10000", + unbundledBuild: true, + }, + + { + name: "Non-Unbundled build: Android.bp has no targetSdkVersion", + targetSdkVersionExpected: platform_sdk_codename, + unbundledBuild: false, + }, + { + name: "Unbundled build: Android.bp has no targetSdkVersion", + targetSdkVersionExpected: "10000", + unbundledBuild: true, + }, + } + for _, testCase := range testCases { + bp := fmt.Sprintf(` + android_app { + name: "foo", + sdk_version: "current", + target_sdk_version: "%v", + } + `, testCase.targetSdkVersionInBp) + fixture := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + // explicitly set platform_sdk_codename to make the test deterministic + variables.Platform_sdk_codename = &platform_sdk_codename + variables.Platform_version_active_codenames = []string{platform_sdk_codename} + // create a non-empty list if unbundledBuild==true + if testCase.unbundledBuild { + variables.Unbundled_build_apps = []string{"apex_a", "apex_b"} + } + }), + ) + + result := fixture.RunTestWithBp(t, bp) + foo := result.ModuleForTests("foo", "android_common") + + manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args + android.AssertStringEquals(t, testCase.name, testCase.targetSdkVersionExpected, manifestFixerArgs["targetSdkVersion"]) + } +}