Allow java_sdk_library in an APEX to have higher min_sdk_version.
Inidividual boot or system server jars may have higher min_sdk_version than the contianing apex, since the runtime respects the values of min/max_sdk_version; e.g. runtime would not load a boot jar with higher min_sdk_version. This allows shipping new boot jars via apexes that target older platforms. Bug: 190818041 Test: presubmit Change-Id: I08ec0b4463a17bc8265b948fe09da55eb4e52ac3
This commit is contained in:
@@ -945,6 +945,14 @@ func CheckMinSdkVersion(ctx ModuleContext, minSdkVersion ApiLevel, walk WalkPayl
|
|||||||
if am, ok := from.(DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
|
if am, ok := from.(DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if m, ok := to.(ModuleWithMinSdkVersionCheck); ok {
|
||||||
|
// This dependency performs its own min_sdk_version check, just make sure it sets min_sdk_version
|
||||||
|
// to trigger the check.
|
||||||
|
if !m.MinSdkVersion(ctx).Specified() {
|
||||||
|
ctx.OtherModuleErrorf(m, "must set min_sdk_version")
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
if err := to.ShouldSupportSdkVersion(ctx, minSdkVersion); err != nil {
|
if err := to.ShouldSupportSdkVersion(ctx, minSdkVersion); err != nil {
|
||||||
toName := ctx.OtherModuleName(to)
|
toName := ctx.OtherModuleName(to)
|
||||||
if ver, ok := minSdkVersionAllowlist[toName]; !ok || ver.GreaterThan(minSdkVersion) {
|
if ver, ok := minSdkVersionAllowlist[toName]; !ok || ver.GreaterThan(minSdkVersion) {
|
||||||
|
@@ -8410,6 +8410,184 @@ func TestAndroidMk_RequiredModules(t *testing.T) {
|
|||||||
ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += otherapex")
|
ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += otherapex")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSdkLibraryCanHaveHigherMinSdkVersion(t *testing.T) {
|
||||||
|
preparer := android.GroupFixturePreparers(
|
||||||
|
PrepareForTestWithApexBuildComponents,
|
||||||
|
prepareForTestWithMyapex,
|
||||||
|
java.PrepareForTestWithJavaSdkLibraryFiles,
|
||||||
|
java.PrepareForTestWithJavaDefaultModules,
|
||||||
|
android.PrepareForTestWithAndroidBuildComponents,
|
||||||
|
dexpreopt.FixtureSetApexBootJars("myapex:mybootclasspathlib"),
|
||||||
|
dexpreopt.FixtureSetApexSystemServerJars("myapex:mysystemserverclasspathlib"),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Test java_sdk_library in bootclasspath_fragment may define higher min_sdk_version than the apex
|
||||||
|
t.Run("bootclasspath_fragment jar has higher min_sdk_version than apex", func(t *testing.T) {
|
||||||
|
preparer.RunTestWithBp(t, `
|
||||||
|
apex {
|
||||||
|
name: "myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
bootclasspath_fragments: ["mybootclasspathfragment"],
|
||||||
|
min_sdk_version: "30",
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
bootclasspath_fragment {
|
||||||
|
name: "mybootclasspathfragment",
|
||||||
|
contents: ["mybootclasspathlib"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library {
|
||||||
|
name: "mybootclasspathlib",
|
||||||
|
srcs: ["mybootclasspathlib.java"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
compile_dex: true,
|
||||||
|
unsafe_ignore_missing_latest_api: true,
|
||||||
|
min_sdk_version: "31",
|
||||||
|
static_libs: ["util"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library {
|
||||||
|
name: "util",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
min_sdk_version: "31",
|
||||||
|
static_libs: ["another_util"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library {
|
||||||
|
name: "another_util",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
min_sdk_version: "31",
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Test java_sdk_library in systemserverclasspath_fragment may define higher min_sdk_version than the apex
|
||||||
|
t.Run("systemserverclasspath_fragment jar has higher min_sdk_version than apex", func(t *testing.T) {
|
||||||
|
preparer.RunTestWithBp(t, `
|
||||||
|
apex {
|
||||||
|
name: "myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
|
||||||
|
min_sdk_version: "30",
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
systemserverclasspath_fragment {
|
||||||
|
name: "mysystemserverclasspathfragment",
|
||||||
|
contents: ["mysystemserverclasspathlib"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library {
|
||||||
|
name: "mysystemserverclasspathlib",
|
||||||
|
srcs: ["mysystemserverclasspathlib.java"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
compile_dex: true,
|
||||||
|
min_sdk_version: "32",
|
||||||
|
unsafe_ignore_missing_latest_api: true,
|
||||||
|
static_libs: ["util"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library {
|
||||||
|
name: "util",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
min_sdk_version: "31",
|
||||||
|
static_libs: ["another_util"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library {
|
||||||
|
name: "another_util",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
min_sdk_version: "31",
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("bootclasspath_fragment jar must set min_sdk_version", func(t *testing.T) {
|
||||||
|
preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "mybootclasspathlib".*must set min_sdk_version`)).
|
||||||
|
RunTestWithBp(t, `
|
||||||
|
apex {
|
||||||
|
name: "myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
bootclasspath_fragments: ["mybootclasspathfragment"],
|
||||||
|
min_sdk_version: "30",
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
bootclasspath_fragment {
|
||||||
|
name: "mybootclasspathfragment",
|
||||||
|
contents: ["mybootclasspathlib"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library {
|
||||||
|
name: "mybootclasspathlib",
|
||||||
|
srcs: ["mybootclasspathlib.java"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
compile_dex: true,
|
||||||
|
unsafe_ignore_missing_latest_api: true,
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("systemserverclasspath_fragment jar must set min_sdk_version", func(t *testing.T) {
|
||||||
|
preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "mysystemserverclasspathlib".*must set min_sdk_version`)).
|
||||||
|
RunTestWithBp(t, `
|
||||||
|
apex {
|
||||||
|
name: "myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
|
||||||
|
min_sdk_version: "30",
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
systemserverclasspath_fragment {
|
||||||
|
name: "mysystemserverclasspathfragment",
|
||||||
|
contents: ["mysystemserverclasspathlib"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library {
|
||||||
|
name: "mysystemserverclasspathlib",
|
||||||
|
srcs: ["mysystemserverclasspathlib.java"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
compile_dex: true,
|
||||||
|
unsafe_ignore_missing_latest_api: true,
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
@@ -1643,8 +1643,7 @@ func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implements android.ApexModule
|
// Implements android.ApexModule
|
||||||
func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
|
func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
|
||||||
sdkVersion android.ApiLevel) error {
|
|
||||||
sdkSpec := j.MinSdkVersion(ctx)
|
sdkSpec := j.MinSdkVersion(ctx)
|
||||||
if !sdkSpec.Specified() {
|
if !sdkSpec.Specified() {
|
||||||
return fmt.Errorf("min_sdk_version is not specified")
|
return fmt.Errorf("min_sdk_version is not specified")
|
||||||
|
@@ -1129,6 +1129,8 @@ func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext)
|
|||||||
return generatedScopes
|
return generatedScopes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ android.ModuleWithMinSdkVersionCheck = (*SdkLibrary)(nil)
|
||||||
|
|
||||||
func (module *SdkLibrary) CheckMinSdkVersion(ctx android.ModuleContext) {
|
func (module *SdkLibrary) CheckMinSdkVersion(ctx android.ModuleContext) {
|
||||||
android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx).ApiLevel, func(c android.ModuleContext, do android.PayloadDepsCallback) {
|
android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx).ApiLevel, func(c android.ModuleContext, do android.PayloadDepsCallback) {
|
||||||
ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
|
ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
|
||||||
|
Reference in New Issue
Block a user