Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8cb0c3e authored by Spandan Das's avatar Spandan Das
Browse files

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
parent ab9f3a2b
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -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))
+73 −0
Original line number Diff line number Diff line
@@ -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"])
	}
}