java_sdk_library_import - expose system and test stubs

Previously, the java_sdk_library_import only exposed the public stubs.
This change adds support for exposing system and test stubs too by adding
separate structures for public, system and test scopes. The existing
properties are kept for legacy reasons (and because libs can be common
across the differents scopes).

It extracts some code that is common to both sdk library and sdk
library import.

The legacy support will be removed in a future change once all existing
usages have been switched over.

Bug: 148080325
Test: m droid
      TARGET_BUILD_APPS=Camera2 m
Change-Id: I0b26cc8af9ee044437ff3b80c1eca611816b9386
This commit is contained in:
Paul Duffin 2020-01-31 13:36:25 +00:00
parent db84575f84
commit 56d4490d59
3 changed files with 188 additions and 46 deletions

View file

@ -458,7 +458,7 @@ func TestPrebuilts(t *testing.T) {
java_library {
name: "foo",
srcs: ["a.java", ":stubs-source"],
libs: ["bar", "sdklib"],
libs: ["bar", "sdklib", "sdklib-legacy"],
static_libs: ["baz"],
}
@ -478,10 +478,17 @@ func TestPrebuilts(t *testing.T) {
}
java_sdk_library_import {
name: "sdklib",
name: "sdklib-legacy",
jars: ["b.jar"],
}
java_sdk_library_import {
name: "sdklib",
public: {
jars: ["c.jar"],
},
}
prebuilt_stubs_sources {
name: "stubs-source",
srcs: ["stubs/sources"],
@ -531,6 +538,54 @@ func assertDeepEquals(t *testing.T, message string, expected interface{}, actual
}
}
func TestJavaSdkLibraryImport(t *testing.T) {
ctx, _ := testJava(t, `
java_library {
name: "foo",
srcs: ["a.java"],
libs: ["sdklib"],
sdk_version: "current",
}
java_library {
name: "foo.system",
srcs: ["a.java"],
libs: ["sdklib"],
sdk_version: "system_current",
}
java_library {
name: "foo.test",
srcs: ["a.java"],
libs: ["sdklib"],
sdk_version: "test_current",
}
java_sdk_library_import {
name: "sdklib",
public: {
jars: ["a.jar"],
},
system: {
jars: ["b.jar"],
},
test: {
jars: ["c.jar"],
},
}
`)
for _, scope := range []string{"", ".system", ".test"} {
fooModule := ctx.ModuleForTests("foo"+scope, "android_common")
javac := fooModule.Rule("javac")
sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs"+scope, "android_common").Rule("combineJar").Output
if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) {
t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String())
}
}
}
func TestDefaults(t *testing.T) {
ctx, _ := testJava(t, `
java_defaults {

View file

@ -225,12 +225,30 @@ type scopePaths struct {
apiFilePath android.Path
}
// Common code between sdk library and sdk library import
type commonToSdkLibraryAndImport struct {
scopePaths map[*apiScope]*scopePaths
}
func (c *commonToSdkLibraryAndImport) getScopePaths(scope *apiScope) *scopePaths {
if c.scopePaths == nil {
c.scopePaths = make(map[*apiScope]*scopePaths)
}
paths := c.scopePaths[scope]
if paths == nil {
paths = &scopePaths{}
c.scopePaths[scope] = paths
}
return paths
}
type SdkLibrary struct {
Library
sdkLibraryProperties sdkLibraryProperties
scopePaths map[*apiScope]*scopePaths
commonToSdkLibraryAndImport
permissionsFile android.Path
}
@ -246,19 +264,6 @@ func (module *SdkLibrary) getActiveApiScopes() apiScopes {
}
}
func (module *SdkLibrary) getScopePaths(scope *apiScope) *scopePaths {
if module.scopePaths == nil {
module.scopePaths = make(map[*apiScope]*scopePaths)
}
paths := module.scopePaths[scope]
if paths == nil {
paths = &scopePaths{}
module.scopePaths[scope] = paths
}
return paths
}
func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
useBuiltStubs := !ctx.Config().UnbundledBuildUsePrebuiltSdks()
for _, apiScope := range module.getActiveApiScopes() {
@ -833,7 +838,8 @@ func SdkLibraryFactory() android.Module {
// SDK library prebuilts
//
type sdkLibraryImportProperties struct {
// Properties associated with each api scope.
type sdkLibraryScopeProperties struct {
Jars []string `android:"path"`
Sdk_version *string
@ -842,6 +848,17 @@ type sdkLibraryImportProperties struct {
Libs []string
}
type sdkLibraryImportProperties struct {
// Properties associated with the public api scope.
Public sdkLibraryScopeProperties
// Properties associated with the system api scope.
System sdkLibraryScopeProperties
// Properties associated with the test api scope.
Test sdkLibraryScopeProperties
}
type sdkLibraryImport struct {
android.ModuleBase
android.DefaultableModuleBase
@ -849,7 +866,12 @@ type sdkLibraryImport struct {
properties sdkLibraryImportProperties
stubsPath android.Paths
// Legacy properties for the public api scope.
//
// Should use properties.Public instead.
legacyPublicProperties sdkLibraryScopeProperties
commonToSdkLibraryAndImport
}
var _ SdkLibraryDependency = (*sdkLibraryImport)(nil)
@ -858,9 +880,9 @@ var _ SdkLibraryDependency = (*sdkLibraryImport)(nil)
func sdkLibraryImportFactory() android.Module {
module := &sdkLibraryImport{}
module.AddProperties(&module.properties)
module.AddProperties(&module.properties, &module.legacyPublicProperties)
android.InitPrebuiltModule(module, &module.properties.Jars)
android.InitPrebuiltModule(module, &module.legacyPublicProperties.Jars)
InitJavaModule(module, android.HostAndDeviceSupported)
android.AddLoadHook(module, func(mctx android.LoadHookContext) { module.createInternalModules(mctx) })
@ -876,28 +898,57 @@ func (module *sdkLibraryImport) Name() string {
}
func (module *sdkLibraryImport) createInternalModules(mctx android.LoadHookContext) {
// Creates a java import for the jar with ".stubs" suffix
props := struct {
Name *string
Soc_specific *bool
Device_specific *bool
Product_specific *bool
System_ext_specific *bool
}{}
props.Name = proptools.StringPtr(module.BaseModuleName() + sdkStubsLibrarySuffix)
if module.SocSpecific() {
props.Soc_specific = proptools.BoolPtr(true)
} else if module.DeviceSpecific() {
props.Device_specific = proptools.BoolPtr(true)
} else if module.ProductSpecific() {
props.Product_specific = proptools.BoolPtr(true)
} else if module.SystemExtSpecific() {
props.System_ext_specific = proptools.BoolPtr(true)
// Prepend any of the libs from the legacy public properties to the libs for each of the
// scopes to avoid having to duplicate them in each scope.
for _, scopeProperties := range module.scopeProperties() {
scopeProperties.Libs = append(module.legacyPublicProperties.Libs, scopeProperties.Libs...)
}
mctx.CreateModule(ImportFactory, &props, &module.properties)
if module.legacyPublicProperties.Jars != nil {
if module.properties.Public.Jars != nil {
mctx.ModuleErrorf("cannot set both `jars` and `public.jars`")
return
}
// The legacy set of properties has been used so copy them over the public properties.
module.properties.Public = module.legacyPublicProperties
}
for apiScope, scopeProperties := range module.scopeProperties() {
if len(scopeProperties.Jars) == 0 {
continue
}
// Creates a java import for the jar with ".stubs" suffix
props := struct {
Name *string
Soc_specific *bool
Device_specific *bool
Product_specific *bool
System_ext_specific *bool
Sdk_version *string
Libs []string
Jars []string
}{}
props.Name = proptools.StringPtr(apiScope.stubsModuleName(module.BaseModuleName()))
props.Sdk_version = scopeProperties.Sdk_version
props.Libs = scopeProperties.Libs
props.Jars = scopeProperties.Jars
if module.SocSpecific() {
props.Soc_specific = proptools.BoolPtr(true)
} else if module.DeviceSpecific() {
props.Device_specific = proptools.BoolPtr(true)
} else if module.ProductSpecific() {
props.Product_specific = proptools.BoolPtr(true)
} else if module.SystemExtSpecific() {
props.System_ext_specific = proptools.BoolPtr(true)
}
mctx.CreateModule(ImportFactory, &props)
}
javaSdkLibraries := javaSdkLibraries(mctx.Config())
javaSdkLibrariesLock.Lock()
@ -905,9 +956,23 @@ func (module *sdkLibraryImport) createInternalModules(mctx android.LoadHookConte
*javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
}
func (module *sdkLibraryImport) scopeProperties() map[*apiScope]*sdkLibraryScopeProperties {
p := make(map[*apiScope]*sdkLibraryScopeProperties)
p[apiScopePublic] = &module.properties.Public
p[apiScopeSystem] = &module.properties.System
p[apiScopeTest] = &module.properties.Test
return p
}
func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies to the prebuilt stubs library
ctx.AddVariationDependencies(nil, apiScopePublic.stubsTag, module.BaseModuleName()+sdkStubsLibrarySuffix)
for apiScope, scopeProperties := range module.scopeProperties() {
if len(scopeProperties.Jars) == 0 {
continue
}
// Add dependencies to the prebuilt stubs library
ctx.AddVariationDependencies(nil, apiScope.stubsTag, apiScope.stubsModuleName(module.BaseModuleName()))
}
}
func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@ -915,21 +980,42 @@ func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
ctx.VisitDirectDeps(func(to android.Module) {
tag := ctx.OtherModuleDependencyTag(to)
switch tag {
case apiScopePublic.stubsTag:
module.stubsPath = to.(Dependency).HeaderJars()
if lib, ok := to.(Dependency); ok {
if scopeTag, ok := tag.(scopeDependencyTag); ok {
apiScope := scopeTag.apiScope
scopePaths := module.getScopePaths(apiScope)
scopePaths.stubsHeaderPath = lib.HeaderJars()
}
}
})
}
func (module *sdkLibraryImport) sdkJars(
ctx android.BaseModuleContext,
sdkVersion sdkSpec) android.Paths {
var apiScope *apiScope
switch sdkVersion.kind {
case sdkSystem:
apiScope = apiScopeSystem
case sdkTest:
apiScope = apiScopeTest
default:
apiScope = apiScopePublic
}
paths := module.getScopePaths(apiScope)
return paths.stubsHeaderPath
}
// to satisfy SdkLibraryDependency interface
func (module *sdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
// This module is just a wrapper for the prebuilt stubs.
return module.stubsPath
return module.sdkJars(ctx, sdkVersion)
}
// to satisfy SdkLibraryDependency interface
func (module *sdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
// This module is just a wrapper for the stubs.
return module.stubsPath
return module.sdkJars(ctx, sdkVersion)
}

View file

@ -30,6 +30,7 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string
"b.kt": nil,
"a.jar": nil,
"b.jar": nil,
"c.jar": nil,
"APP_NOTICE": nil,
"GENRULE_NOTICE": nil,
"LIB_NOTICE": nil,