java_sdk_library: Expose implementation within APEX

Access to the implementation JARs is restricted to avoid code from
depending on implementation details that could change from one release
to the next which could cause compatibility issues. That is not a
problem when referenced from within the APEX that contains the
java_sdk_library.

As references from within the same APEX often need to access
implementation specific details of the java_sdk_library and doing that
from within the same APEX is safe this change all references to a
java_sdk_library made within the same APEX to use the implementation
jars instead of stub jars.

Bug: 155164730
Test: m droid
Change-Id: If239059690de61683c2ad2d8a0ce2e47286a3637
(cherry picked from commit 9b879594ed)
This commit is contained in:
Paul Duffin 2020-05-26 13:21:35 +01:00
parent 2e7ed65fc4
commit bf19a97965
2 changed files with 123 additions and 9 deletions

View File

@ -19,6 +19,7 @@ import (
"os"
"path"
"reflect"
"regexp"
"sort"
"strings"
"testing"
@ -4020,6 +4021,15 @@ func TestLegacyAndroid10Support(t *testing.T) {
}
}
var filesForSdkLibrary = map[string][]byte{
"api/current.txt": nil,
"api/removed.txt": nil,
"api/system-current.txt": nil,
"api/system-removed.txt": nil,
"api/test-current.txt": nil,
"api/test-removed.txt": nil,
}
func TestJavaSDKLibrary(t *testing.T) {
ctx, _ := testApex(t, `
apex {
@ -4040,14 +4050,7 @@ func TestJavaSDKLibrary(t *testing.T) {
api_packages: ["foo"],
apex_available: [ "myapex" ],
}
`, withFiles(map[string][]byte{
"api/current.txt": nil,
"api/removed.txt": nil,
"api/system-current.txt": nil,
"api/system-removed.txt": nil,
"api/test-current.txt": nil,
"api/test-removed.txt": nil,
}))
`, withFiles(filesForSdkLibrary))
// java_sdk_library installs both impl jar and permission XML
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
@ -4059,6 +4062,98 @@ func TestJavaSDKLibrary(t *testing.T) {
ensureContains(t, sdkLibrary.RuleParams.Command, `<library name=\"foo\" file=\"/apex/myapex/javalib/foo.jar\"`)
}
func TestJavaSDKLibrary_WithinApex(t *testing.T) {
ctx, _ := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
java_libs: ["foo", "bar"],
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
java_sdk_library {
name: "foo",
srcs: ["a.java"],
api_packages: ["foo"],
apex_available: ["myapex"],
sdk_version: "none",
system_modules: "none",
}
java_library {
name: "bar",
srcs: ["a.java"],
libs: ["foo"],
apex_available: ["myapex"],
sdk_version: "none",
system_modules: "none",
}
`, withFiles(filesForSdkLibrary))
// java_sdk_library installs both impl jar and permission XML
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"javalib/bar.jar",
"javalib/foo.jar",
"etc/permissions/foo.xml",
})
// The bar library should depend on the implementation jar.
barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
t.Errorf("expected %q, found %#q", expected, actual)
}
}
func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
ctx, _ := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
java_libs: ["foo"],
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
java_sdk_library {
name: "foo",
srcs: ["a.java"],
api_packages: ["foo"],
apex_available: ["myapex"],
sdk_version: "none",
system_modules: "none",
}
java_library {
name: "bar",
srcs: ["a.java"],
libs: ["foo"],
sdk_version: "none",
system_modules: "none",
}
`, withFiles(filesForSdkLibrary))
// java_sdk_library installs both impl jar and permission XML
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"javalib/foo.jar",
"etc/permissions/foo.xml",
})
// The bar library should depend on the stubs jar.
barLibrary := ctx.ModuleForTests("bar", "android_common").Rule("javac")
if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
t.Errorf("expected %q, found %#q", expected, actual)
}
}
func TestCompatConfig(t *testing.T) {
ctx, _ := testApex(t, `
apex {

View File

@ -1295,6 +1295,24 @@ func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s sdkSpec) and
return android.Paths{jarPath.Path()}
}
// Get the apex name for module, "" if it is for platform.
func getApexNameForModule(module android.Module) string {
if apex, ok := module.(android.ApexModule); ok {
return apex.ApexName()
}
return ""
}
// Check to see if the other module is within the same named APEX as this module.
//
// If either this or the other module are on the platform then this will return
// false.
func (module *SdkLibrary) withinSameApexAs(other android.Module) bool {
name := module.ApexName()
return name != "" && getApexNameForModule(other) == name
}
func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
// Only provide access to the implementation library if it is actually built.
@ -1303,7 +1321,8 @@ func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkS
//
// Only allow access to the implementation library in the following condition:
// * No sdk_version specified on the referencing module.
if sdkVersion.kind == sdkPrivate {
// * The referencing module is in the same apex as this.
if sdkVersion.kind == sdkPrivate || module.withinSameApexAs(ctx.Module()) {
if headerJars {
return module.HeaderJars()
} else {