Merge "Ensure APEX's Java deps use stable SDKs." into rvc-dev

This commit is contained in:
Artur Satayev 2020-05-05 09:59:34 +00:00 committed by Android (Google) Code Review
commit b25992b4eb
4 changed files with 150 additions and 2 deletions

View file

@ -1871,6 +1871,8 @@ func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
if String(a.properties.Min_sdk_version) == "" {
ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
}
a.checkJavaStableSdkVersion(ctx)
}
}
@ -1940,7 +1942,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.checkApexAvailability(ctx)
a.checkUpdatable(ctx)
a.collectDepsInfo(ctx)
handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
@ -2247,6 +2248,23 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.buildApexDependencyInfo(ctx)
}
// Enforce that Java deps of the apex are using stable SDKs to compile
func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
// Visit direct deps only. As long as we guarantee top-level deps are using
// stable SDKs, java's checkLinkType guarantees correct usage for transitive deps
ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
tag := ctx.OtherModuleDependencyTag(module)
switch tag {
case javaLibTag, androidAppTag:
if m, ok := module.(interface{ CheckStableSdkVersion() error }); ok {
if err := m.CheckStableSdkVersion(); err != nil {
ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
}
}
}
})
}
func whitelistedApexAvailable(apex, moduleName string) bool {
key := apex
moduleName = normalizeModuleName(moduleName)

View file

@ -1377,6 +1377,122 @@ func TestInvalidMinSdkVersion(t *testing.T) {
`)
}
func TestJavaStableSdkVersion(t *testing.T) {
testCases := []struct {
name string
expectedError string
bp string
}{
{
name: "Non-updatable apex with non-stable dep",
bp: `
apex {
name: "myapex",
java_libs: ["myjar"],
key: "myapex.key",
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
java_library {
name: "myjar",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "core_platform",
apex_available: ["myapex"],
}
`,
},
{
name: "Updatable apex with stable dep",
bp: `
apex {
name: "myapex",
java_libs: ["myjar"],
key: "myapex.key",
updatable: true,
min_sdk_version: "29",
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
java_library {
name: "myjar",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "current",
apex_available: ["myapex"],
}
`,
},
{
name: "Updatable apex with non-stable dep",
expectedError: "cannot depend on \"myjar\"",
bp: `
apex {
name: "myapex",
java_libs: ["myjar"],
key: "myapex.key",
updatable: true,
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
java_library {
name: "myjar",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "core_platform",
apex_available: ["myapex"],
}
`,
},
{
name: "Updatable apex with non-stable transitive dep",
expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against non-public Android API.",
bp: `
apex {
name: "myapex",
java_libs: ["myjar"],
key: "myapex.key",
updatable: true,
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
java_library {
name: "myjar",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "current",
apex_available: ["myapex"],
static_libs: ["transitive-jar"],
}
java_library {
name: "transitive-jar",
srcs: ["foo/bar/MyClass.java"],
sdk_version: "core_platform",
apex_available: ["myapex"],
}
`,
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
if test.expectedError == "" {
testApex(t, test.bp)
} else {
testApexError(t, test.expectedError, test.bp)
}
})
}
}
func TestFilesInSubDir(t *testing.T) {
ctx, _ := testApex(t, `
apex {
@ -4289,6 +4405,7 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
java_library {
name: "some-updatable-apex-lib",
srcs: ["a.java"],
sdk_version: "current",
apex_available: [
"some-updatable-apex",
],
@ -4297,12 +4414,14 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
java_library {
name: "some-platform-lib",
srcs: ["a.java"],
sdk_version: "current",
installable: true,
}
java_library {
name: "some-art-lib",
srcs: ["a.java"],
sdk_version: "current",
apex_available: [
"com.android.art.something",
],

View file

@ -86,6 +86,14 @@ func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
}
func (j *Module) CheckStableSdkVersion() error {
sdkVersion := j.sdkVersion()
if sdkVersion.stable() {
return nil
}
return fmt.Errorf("non stable SDK %v", sdkVersion)
}
func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
if j.SocSpecific() || j.DeviceSpecific() ||
(j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {

View file

@ -170,9 +170,12 @@ func (s sdkSpec) stable() bool {
return false
}
switch s.kind {
case sdkNone:
// there is nothing to manage and version in this case; de facto stable API.
return true
case sdkCore, sdkPublic, sdkSystem, sdkModule, sdkSystemServer:
return true
case sdkNone, sdkCorePlatform, sdkTest, sdkPrivate:
case sdkCorePlatform, sdkTest, sdkPrivate:
return false
default:
panic(fmt.Errorf("unknown sdkKind=%v", s.kind))