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

Commit 964a46cb authored by Harshit Mahajan's avatar Harshit Mahajan Committed by Gerrit Code Review
Browse files

Merge "Enforce mainline modules to have latest target sdk version by default."

parents 085d5446 5b8b730c
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -270,7 +270,7 @@ var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",

func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext,
	classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
	extraLinkFlags ...string) {
	enforceDefaultTargetSdkVersion bool, extraLinkFlags ...string) {

	transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags :=
		aaptLibs(ctx, sdkContext, classLoaderContexts)
@@ -292,6 +292,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
		UseEmbeddedDex:                 a.useEmbeddedDex,
		HasNoCode:                      a.hasNoCode,
		LoggingParent:                  a.LoggingParent,
		EnforceDefaultTargetSdkVersion: enforceDefaultTargetSdkVersion,
	})

	// Add additional manifest files to transitive manifests.
@@ -535,7 +536,7 @@ func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	a.aapt.isLibrary = true
	a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
	a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil)
	a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil, false)

	a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()

+28 −17
Original line number Diff line number Diff line
@@ -43,13 +43,12 @@ var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger",
// 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)
	// Return 10000 for modules targeting "current" if either
	// 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty)
	// 2. The module is run as part of MTS, and should be testable on stable branches
func targetSdkVersionForManifestFixer(ctx android.ModuleContext, params ManifestFixerParams) string {
	targetSdkVersionSpec := params.SdkContext.TargetSdkVersion(ctx)

	// Check if we want to return 10000
	// TODO(b/240294501): Determine the rules for handling test apexes
	if targetSdkVersionSpec.ApiLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module())) {
	if shouldReturnFinalOrFutureInt(ctx, targetSdkVersionSpec, params.EnforceDefaultTargetSdkVersion) {
		return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
	}
	targetSdkVersion, err := targetSdkVersionSpec.EffectiveVersionString(ctx)
@@ -59,6 +58,17 @@ func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext andr
	return targetSdkVersion
}

// Return true for modules targeting "current" if either
// 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty)
// 2. The module is run as part of MTS, and should be testable on stable branches
// Do not return 10000 if we are enforcing default targetSdkVersion and sdk has been finalised
func shouldReturnFinalOrFutureInt(ctx android.ModuleContext, targetSdkVersionSpec android.SdkSpec, enforceDefaultTargetSdkVersion bool) bool {
	if enforceDefaultTargetSdkVersion && ctx.Config().PlatformSdkFinal() {
		return false
	}
	return targetSdkVersionSpec.ApiLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module()))
}

// Helper function that casts android.Module to java.androidTestApp
// If this type conversion is possible, it queries whether the test app is included in an MTS suite
func includedInMts(module android.Module) bool {
@@ -79,6 +89,7 @@ type ManifestFixerParams struct {
	HasNoCode                      bool
	TestOnly                       bool
	LoggingParent                  string
	EnforceDefaultTargetSdkVersion bool
}

// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
@@ -137,7 +148,7 @@ func ManifestFixer(ctx android.ModuleContext, manifest android.Path,
	var argsMapper = make(map[string]string)

	if params.SdkContext != nil {
		targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params.SdkContext)
		targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params)
		args = append(args, "--targetSdkVersion ", targetSdkVersion)

		if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
+30 −1
Original line number Diff line number Diff line
@@ -101,6 +101,15 @@ type appProperties struct {
	PreventInstall    bool `blueprint:"mutated"`
	IsCoverageVariant bool `blueprint:"mutated"`

	// It can be set to test the behaviour of default target sdk version.
	// Only required when updatable: false. It is an error if updatable: true and this is false.
	Enforce_default_target_sdk_version *bool

	// If set, the targetSdkVersion for the target is set to the latest default API level.
	// This would be by default false, unless updatable: true or
	// enforce_default_target_sdk_version: true in which case this defaults to true.
	EnforceDefaultTargetSdkVersion bool `blueprint:"mutated"`

	// Whether this app is considered mainline updatable or not. When set to true, this will enforce
	// additional rules to make sure an app can safely be updated. Default is false.
	// Prefer using other specific properties if build behaviour must be changed; avoid using this
@@ -296,6 +305,18 @@ func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
		} else {
			ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
		}

		if !BoolDefault(a.appProperties.Enforce_default_target_sdk_version, true) {
			ctx.PropertyErrorf("enforce_default_target_sdk_version", "Updatable apps must enforce default target sdk version")
		}
		// TODO(b/227460469) after all the modules removes the target sdk version, throw an error if the target sdk version is explicitly set.
		if a.deviceProperties.Target_sdk_version == nil {
			a.SetEnforceDefaultTargetSdkVersion(true)
		}
	}

	if Bool(a.appProperties.Enforce_default_target_sdk_version) {
		a.SetEnforceDefaultTargetSdkVersion(true)
	}

	a.checkPlatformAPI(ctx)
@@ -427,7 +448,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
		a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
	}
	a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts,
		a.usesLibraryProperties.Exclude_uses_libs, aaptLinkFlags...)
		a.usesLibraryProperties.Exclude_uses_libs, a.enforceDefaultTargetSdkVersion(), aaptLinkFlags...)

	// apps manifests are handled by aapt, don't let Module see them
	a.properties.Manifest = nil
@@ -865,6 +886,14 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
	a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
}

func (a *AndroidApp) enforceDefaultTargetSdkVersion() bool {
	return a.appProperties.EnforceDefaultTargetSdkVersion
}

func (a *AndroidApp) SetEnforceDefaultTargetSdkVersion(val bool) {
	a.appProperties.EnforceDefaultTargetSdkVersion = val
}

func (a *AndroidApp) Updatable() bool {
	return Bool(a.appProperties.Updatable)
}
+173 −0
Original line number Diff line number Diff line
@@ -3057,6 +3057,179 @@ func TestTargetSdkVersionManifestFixer(t *testing.T) {
	}
}

func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) {
	platform_sdk_codename := "Tiramisu"
	platform_sdk_version := 33
	testCases := []struct {
		name                     string
		platform_sdk_final       bool
		targetSdkVersionInBp     *string
		targetSdkVersionExpected *string
		updatable                bool
	}{
		{
			name:                     "Non-Updatable Module: Android.bp has older targetSdkVersion",
			targetSdkVersionInBp:     proptools.StringPtr("29"),
			targetSdkVersionExpected: proptools.StringPtr("29"),
			updatable:                false,
		},
		{
			name:                     "Updatable Module: Android.bp has older targetSdkVersion",
			targetSdkVersionInBp:     proptools.StringPtr("30"),
			targetSdkVersionExpected: proptools.StringPtr("30"),
			updatable:                true,
		},
		{
			name:                     "Updatable Module: Android.bp has no targetSdkVersion",
			targetSdkVersionExpected: proptools.StringPtr("10000"),
			updatable:                true,
		},
		{
			name:                     "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion",
			platform_sdk_final:       true,
			targetSdkVersionInBp:     proptools.StringPtr("30"),
			targetSdkVersionExpected: proptools.StringPtr("30"),
			updatable:                false,
		},
		{
			name:                     "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion",
			platform_sdk_final:       true,
			targetSdkVersionInBp:     proptools.StringPtr("30"),
			targetSdkVersionExpected: proptools.StringPtr("30"),
			updatable:                true,
		},
		{
			name:                     "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename",
			platform_sdk_final:       true,
			targetSdkVersionInBp:     proptools.StringPtr(platform_sdk_codename),
			targetSdkVersionExpected: proptools.StringPtr("33"),
			updatable:                true,
		},
		{
			name:                     "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion",
			platform_sdk_final:       true,
			targetSdkVersionExpected: proptools.StringPtr("33"),
			updatable:                true,
		},
	}
	for _, testCase := range testCases {
		bp := fmt.Sprintf(`
			android_app {
				name: "foo",
				sdk_version: "current",
				min_sdk_version: "29",
				target_sdk_version: "%v",
				updatable: %t,
				enforce_default_target_sdk_version: %t
			}
			`, proptools.String(testCase.targetSdkVersionInBp), testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable

		fixture := android.GroupFixturePreparers(
			PrepareForTestWithJavaDefaultModules,
			android.PrepareForTestWithAllowMissingDependencies,
			android.PrepareForTestWithAndroidMk,
			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
				// explicitly set following platform variables to make the test deterministic
				variables.Platform_sdk_final = &testCase.platform_sdk_final
				variables.Platform_sdk_version = &platform_sdk_version
				variables.Platform_sdk_codename = &platform_sdk_codename
				variables.Platform_version_active_codenames = []string{platform_sdk_codename}
				variables.Unbundled_build_apps = []string{"sampleModule"}
			}),
		)

		result := fixture.RunTestWithBp(t, bp)
		foo := result.ModuleForTests("foo", "android_common")

		manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
		android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion  "+*testCase.targetSdkVersionExpected)
	}
}

func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) {
	platform_sdk_codename := "Tiramisu"
	platform_sdk_version := 33
	testCases := []struct {
		name                           string
		enforceDefaultTargetSdkVersion bool
		expectedError                  string
		platform_sdk_final             bool
		targetSdkVersionInBp           string
		targetSdkVersionExpected       string
		updatable                      bool
	}{
		{
			name:                           "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
			enforceDefaultTargetSdkVersion: false,
			targetSdkVersionInBp:           "29",
			targetSdkVersionExpected:       "29",
			updatable:                      false,
		},
		{
			name:                           "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
			enforceDefaultTargetSdkVersion: true,
			platform_sdk_final:             true,
			targetSdkVersionInBp:           "current",
			targetSdkVersionExpected:       "33",
			updatable:                      true,
		},
		{
			name:                           "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
			enforceDefaultTargetSdkVersion: true,
			platform_sdk_final:             false,
			targetSdkVersionInBp:           "current",
			targetSdkVersionExpected:       "10000",
			updatable:                      false,
		},
		{
			name:                           "Not enforcing Target SDK Version for Updatable app",
			enforceDefaultTargetSdkVersion: false,
			expectedError:                  "Updatable apps must enforce default target sdk version",
			targetSdkVersionInBp:           "29",
			targetSdkVersionExpected:       "29",
			updatable:                      true,
		},
	}
	for _, testCase := range testCases {
		errExpected := testCase.expectedError != ""
		bp := fmt.Sprintf(`
			android_app {
				name: "foo",
				enforce_default_target_sdk_version: %t,
				sdk_version: "current",
				min_sdk_version: "29",
				target_sdk_version: "%v",
				updatable: %t
			}
			`, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable)

		fixture := android.GroupFixturePreparers(
			PrepareForTestWithJavaDefaultModules,
			android.PrepareForTestWithAllowMissingDependencies,
			android.PrepareForTestWithAndroidMk,
			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
				// explicitly set following platform variables to make the test deterministic
				variables.Platform_sdk_final = &testCase.platform_sdk_final
				variables.Platform_sdk_version = &platform_sdk_version
				variables.Platform_sdk_codename = &platform_sdk_codename
				variables.Unbundled_build_apps = []string{"sampleModule"}
			}),
		)

		errorHandler := android.FixtureExpectsNoErrors
		if errExpected {
			errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
		}
		result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)

		if !errExpected {
			foo := result.ModuleForTests("foo", "android_common")
			manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
			android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion  "+testCase.targetSdkVersionExpected)
		}
	}
}

func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
	result := android.GroupFixturePreparers(
		PrepareForTestWithJavaDefaultModules,
+1 −1
Original line number Diff line number Diff line
@@ -142,7 +142,7 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC
		aaptLinkFlags = append(aaptLinkFlags,
			"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name)
	}
	r.aapt.buildActions(ctx, r, nil, nil, aaptLinkFlags...)
	r.aapt.buildActions(ctx, r, nil, nil, false, aaptLinkFlags...)

	// Sign the built package
	_, _, certificates := collectAppDeps(ctx, r, false, false)