diff --git a/java/java_test.go b/java/java_test.go index c4ab13d05..924f76bdc 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -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 { diff --git a/java/sdk_library.go b/java/sdk_library.go index d51d31723..503f1d60a 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -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) } diff --git a/java/testing.go b/java/testing.go index 08bae4407..e746e2d33 100644 --- a/java/testing.go +++ b/java/testing.go @@ -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,