Add default_to_stubs option to java_sdk_library
Previously, when a lib that doesn't have sdk_version property set depends on a java_sdk_library, the impl library was used for linking. This might be too permissive because the client lib might be using empty sdk_version because it needed some private APIs from the platform, but not from the java_sdk_library. This actually happend for some of the CTS tests. They don't set sdk_version, but were directly depending on android.test.[base|runner|mock].stubs libraries. If we switch the references to the stub libraries into the corresponding java_sdk_library modules (e.g. aandroid.test.[base|runner|mock]), then we would be allowing private APIs to the CTS tests, which is not good. To solve this problem, default_to_stub property is introduced. It when set to true prevents the impl lib from being used for linking. When a module that doesn't have sdk_version depends on it, the widest API surface that the java_sdk_library provides is linked instead. Bug: 157007292 Test: m Change-Id: Id2acc3cafb71d1e90d4fdc9c0c70a73983355e0f
This commit is contained in:
parent
bd371b6533
commit
932cdfeb06
|
@ -1465,6 +1465,33 @@ func TestJavaSdkLibrary_FallbackScope(t *testing.T) {
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestJavaSdkLibrary_DefaultToStubs(t *testing.T) {
|
||||||
|
ctx, _ := testJava(t, `
|
||||||
|
java_sdk_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
system: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
default_to_stubs: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library {
|
||||||
|
name: "baz",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
libs: ["foo"],
|
||||||
|
// does not have sdk_version set, should fallback to module,
|
||||||
|
// which will then fallback to system because the module scope
|
||||||
|
// is not enabled.
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
// The baz library should depend on the system stubs jar.
|
||||||
|
bazLibrary := ctx.ModuleForTests("baz", "android_common").Rule("javac")
|
||||||
|
if expected, actual := `^-classpath .*:/[^:]*/turbine-combined/foo\.stubs.system\.jar$`, bazLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
|
||||||
|
t.Errorf("expected %q, found %#q", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var compilerFlagsTestCases = []struct {
|
var compilerFlagsTestCases = []struct {
|
||||||
in string
|
in string
|
||||||
out bool
|
out bool
|
||||||
|
|
|
@ -435,6 +435,14 @@ type sdkLibraryProperties struct {
|
||||||
// disabled by default.
|
// disabled by default.
|
||||||
Module_lib ApiScopeProperties
|
Module_lib ApiScopeProperties
|
||||||
|
|
||||||
|
// Determines if the stubs are preferred over the implementation library
|
||||||
|
// for linking, even when the client doesn't specify sdk_version. When this
|
||||||
|
// is set to true, such clients are provided with the widest API surface that
|
||||||
|
// this lib provides. Note however that this option doesn't affect the clients
|
||||||
|
// that are in the same APEX as this library. In that case, the clients are
|
||||||
|
// always linked with the implementation library. Default is false.
|
||||||
|
Default_to_stubs *bool
|
||||||
|
|
||||||
// Properties related to api linting.
|
// Properties related to api linting.
|
||||||
Api_lint struct {
|
Api_lint struct {
|
||||||
// Enable api linting.
|
// Enable api linting.
|
||||||
|
@ -1342,6 +1350,13 @@ func (module *SdkLibrary) withinSameApexAs(other android.Module) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
|
func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
|
||||||
|
// If the client doesn't set sdk_version, but if this library prefers stubs over
|
||||||
|
// the impl library, let's provide the widest API surface possible. To do so,
|
||||||
|
// force override sdk_version to module_current so that the closest possible API
|
||||||
|
// surface could be found in selectHeaderJarsForSdkVersion
|
||||||
|
if module.defaultsToStubs() && !sdkVersion.specified() {
|
||||||
|
sdkVersion = sdkSpecFrom("module_current")
|
||||||
|
}
|
||||||
|
|
||||||
// Only provide access to the implementation library if it is actually built.
|
// Only provide access to the implementation library if it is actually built.
|
||||||
if module.requiresRuntimeImplementationLibrary() {
|
if module.requiresRuntimeImplementationLibrary() {
|
||||||
|
@ -1505,6 +1520,10 @@ func (module *SdkLibrary) requiresRuntimeImplementationLibrary() bool {
|
||||||
return !proptools.Bool(module.sdkLibraryProperties.Api_only)
|
return !proptools.Bool(module.sdkLibraryProperties.Api_only)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (module *SdkLibrary) defaultsToStubs() bool {
|
||||||
|
return proptools.Bool(module.sdkLibraryProperties.Default_to_stubs)
|
||||||
|
}
|
||||||
|
|
||||||
// Defines how to name the individual component modules the sdk library creates.
|
// Defines how to name the individual component modules the sdk library creates.
|
||||||
type sdkLibraryComponentNamingScheme interface {
|
type sdkLibraryComponentNamingScheme interface {
|
||||||
stubsLibraryModuleName(scope *apiScope, baseName string) string
|
stubsLibraryModuleName(scope *apiScope, baseName string) string
|
||||||
|
|
Loading…
Reference in New Issue