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

This commit is contained in:
Harshit Mahajan
2022-09-27 17:04:27 +00:00
committed by Gerrit Code Review
5 changed files with 244 additions and 30 deletions

View File

@@ -270,7 +270,7 @@ var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext, func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext,
classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string, classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
extraLinkFlags ...string) { enforceDefaultTargetSdkVersion bool, extraLinkFlags ...string) {
transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags := transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags :=
aaptLibs(ctx, sdkContext, classLoaderContexts) aaptLibs(ctx, sdkContext, classLoaderContexts)
@@ -283,15 +283,16 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon
manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile) manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{ manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{
SdkContext: sdkContext, SdkContext: sdkContext,
ClassLoaderContexts: classLoaderContexts, ClassLoaderContexts: classLoaderContexts,
IsLibrary: a.isLibrary, IsLibrary: a.isLibrary,
DefaultManifestVersion: a.defaultManifestVersion, DefaultManifestVersion: a.defaultManifestVersion,
UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs, UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
UsesNonSdkApis: a.usesNonSdkApis, UsesNonSdkApis: a.usesNonSdkApis,
UseEmbeddedDex: a.useEmbeddedDex, UseEmbeddedDex: a.useEmbeddedDex,
HasNoCode: a.hasNoCode, HasNoCode: a.hasNoCode,
LoggingParent: a.LoggingParent, LoggingParent: a.LoggingParent,
EnforceDefaultTargetSdkVersion: enforceDefaultTargetSdkVersion,
}) })
// Add additional manifest files to transitive manifests. // 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) { func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.aapt.isLibrary = true a.aapt.isLibrary = true
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx) 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() a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()

View File

@@ -43,13 +43,12 @@ var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger",
// targetSdkVersion for manifest_fixer // targetSdkVersion for manifest_fixer
// When TARGET_BUILD_APPS is not empty, this method returns 10000 for modules targeting an unreleased SDK // 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 // 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 { func targetSdkVersionForManifestFixer(ctx android.ModuleContext, params ManifestFixerParams) string {
targetSdkVersionSpec := sdkContext.TargetSdkVersion(ctx) targetSdkVersionSpec := params.SdkContext.TargetSdkVersion(ctx)
// Return 10000 for modules targeting "current" if either
// 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty) // Check if we want to return 10000
// 2. The module is run as part of MTS, and should be testable on stable branches
// TODO(b/240294501): Determine the rules for handling test apexes // 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()) return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
} }
targetSdkVersion, err := targetSdkVersionSpec.EffectiveVersionString(ctx) targetSdkVersion, err := targetSdkVersionSpec.EffectiveVersionString(ctx)
@@ -59,6 +58,17 @@ func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext andr
return targetSdkVersion 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 // 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 // If this type conversion is possible, it queries whether the test app is included in an MTS suite
func includedInMts(module android.Module) bool { func includedInMts(module android.Module) bool {
@@ -69,16 +79,17 @@ func includedInMts(module android.Module) bool {
} }
type ManifestFixerParams struct { type ManifestFixerParams struct {
SdkContext android.SdkContext SdkContext android.SdkContext
ClassLoaderContexts dexpreopt.ClassLoaderContextMap ClassLoaderContexts dexpreopt.ClassLoaderContextMap
IsLibrary bool IsLibrary bool
DefaultManifestVersion string DefaultManifestVersion string
UseEmbeddedNativeLibs bool UseEmbeddedNativeLibs bool
UsesNonSdkApis bool UsesNonSdkApis bool
UseEmbeddedDex bool UseEmbeddedDex bool
HasNoCode bool HasNoCode bool
TestOnly bool TestOnly bool
LoggingParent string LoggingParent string
EnforceDefaultTargetSdkVersion bool
} }
// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml // 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) var argsMapper = make(map[string]string)
if params.SdkContext != nil { if params.SdkContext != nil {
targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params.SdkContext) targetSdkVersion := targetSdkVersionForManifestFixer(ctx, params)
args = append(args, "--targetSdkVersion ", targetSdkVersion) args = append(args, "--targetSdkVersion ", targetSdkVersion)
if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" { if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {

View File

@@ -101,6 +101,15 @@ type appProperties struct {
PreventInstall bool `blueprint:"mutated"` PreventInstall bool `blueprint:"mutated"`
IsCoverageVariant 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 // 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. // 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 // 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 { } else {
ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) 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) a.checkPlatformAPI(ctx)
@@ -427,7 +448,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
} }
a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, 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 // apps manifests are handled by aapt, don't let Module see them
a.properties.Manifest = nil a.properties.Manifest = nil
@@ -865,6 +886,14 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo) 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 { func (a *AndroidApp) Updatable() bool {
return Bool(a.appProperties.Updatable) return Bool(a.appProperties.Updatable)
} }

View File

@@ -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) { func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
result := android.GroupFixturePreparers( result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules, PrepareForTestWithJavaDefaultModules,

View File

@@ -142,7 +142,7 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC
aaptLinkFlags = append(aaptLinkFlags, aaptLinkFlags = append(aaptLinkFlags,
"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name) "--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 // Sign the built package
_, _, certificates := collectAppDeps(ctx, r, false, false) _, _, certificates := collectAppDeps(ctx, r, false, false)