Merge "Generate "exportable" stubs library in java_sdk_library" into main
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 5fbf6c0..bdbaf92 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -1329,7 +1329,9 @@
func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
switch tag {
- case "":
+ // prebuilt droidstubs does not output "exportable" stubs.
+ // Output the "everything" stubs srcjar file if the tag is ".exportable".
+ case "", ".exportable":
return android.Paths{p.stubsSrcJar}, nil
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 6998bd2..0df869e 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -231,6 +231,10 @@
return ".stubs" + scope.moduleSuffix
}
+func (scope *apiScope) exportableStubsLibraryModuleNameSuffix() string {
+ return ".stubs.exportable" + scope.moduleSuffix
+}
+
func (scope *apiScope) apiLibraryModuleName(baseName string) string {
return scope.stubsLibraryModuleName(baseName) + ".from-text"
}
@@ -239,10 +243,18 @@
return scope.stubsLibraryModuleName(baseName) + ".from-source"
}
+func (scope *apiScope) exportableSourceStubsLibraryModuleName(baseName string) string {
+ return scope.exportableStubsLibraryModuleName(baseName) + ".from-source"
+}
+
func (scope *apiScope) stubsLibraryModuleName(baseName string) string {
return baseName + scope.stubsLibraryModuleNameSuffix()
}
+func (scope *apiScope) exportableStubsLibraryModuleName(baseName string) string {
+ return baseName + scope.exportableStubsLibraryModuleNameSuffix()
+}
+
func (scope *apiScope) stubsSourceModuleName(baseName string) string {
return baseName + ".stubs.source" + scope.moduleSuffix
}
@@ -895,6 +907,12 @@
return c.namingScheme.stubsLibraryModuleName(apiScope, baseName)
}
+// Name of the java_library module that compiles the exportable stubs source.
+func (c *commonToSdkLibraryAndImport) exportableStubsLibraryModuleName(apiScope *apiScope) string {
+ baseName := c.module.BaseModuleName()
+ return c.namingScheme.exportableStubsLibraryModuleName(apiScope, baseName)
+}
+
// Name of the droidstubs module that generates the stubs source and may also
// generate/check the API.
func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) string {
@@ -911,9 +929,16 @@
// Name of the java_library module that compiles the stubs
// generated from source Java files.
-func (c *commonToSdkLibraryAndImport) sourceStubLibraryModuleName(apiScope *apiScope) string {
+func (c *commonToSdkLibraryAndImport) sourceStubsLibraryModuleName(apiScope *apiScope) string {
baseName := c.module.BaseModuleName()
- return c.namingScheme.sourceStubLibraryModuleName(apiScope, baseName)
+ return c.namingScheme.sourceStubsLibraryModuleName(apiScope, baseName)
+}
+
+// Name of the java_library module that compiles the exportable stubs
+// generated from source Java files.
+func (c *commonToSdkLibraryAndImport) exportableSourceStubsLibraryModuleName(apiScope *apiScope) string {
+ baseName := c.module.BaseModuleName()
+ return c.namingScheme.exportableSourceStubsLibraryModuleName(apiScope, baseName)
}
// The component names for different outputs of the java_sdk_library.
@@ -1629,36 +1654,34 @@
mctx.CreateModule(LibraryFactory, properties...)
}
-// Creates a static java library that has API stubs
-func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
- props := struct {
- Name *string
- Visibility []string
- Srcs []string
- Installable *bool
- Sdk_version *string
- System_modules *string
- Patch_module *string
- Libs []string
- Static_libs []string
- Compile_dex *bool
- Java_version *string
- Openjdk9 struct {
- Srcs []string
- Javacflags []string
- }
- Dist struct {
- Targets []string
- Dest *string
- Dir *string
- Tag *string
- }
- }{}
+type libraryProperties struct {
+ Name *string
+ Visibility []string
+ Srcs []string
+ Installable *bool
+ Sdk_version *string
+ System_modules *string
+ Patch_module *string
+ Libs []string
+ Static_libs []string
+ Compile_dex *bool
+ Java_version *string
+ Openjdk9 struct {
+ Srcs []string
+ Javacflags []string
+ }
+ Dist struct {
+ Targets []string
+ Dest *string
+ Dir *string
+ Tag *string
+ }
+}
- props.Name = proptools.StringPtr(module.sourceStubLibraryModuleName(apiScope))
+func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
+ props := libraryProperties{}
props.Visibility = []string{"//visibility:override", "//visibility:private"}
// sources are generated from the droiddoc
- props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
props.Sdk_version = proptools.StringPtr(sdkVersion)
props.System_modules = module.deviceProperties.System_modules
@@ -1678,6 +1701,25 @@
// interop with older developer tools that don't support 1.9.
props.Java_version = proptools.StringPtr("1.8")
+ return props
+}
+
+// Creates a static java library that has API stubs
+func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
+
+ props := module.stubsLibraryProps(mctx, apiScope)
+ props.Name = proptools.StringPtr(module.sourceStubsLibraryModuleName(apiScope))
+ props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
+
+ mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
+// Create a static java library that compiles the "exportable" stubs
+func (module *SdkLibrary) createExportableStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
+ props := module.stubsLibraryProps(mctx, apiScope)
+ props.Name = proptools.StringPtr(module.exportableSourceStubsLibraryModuleName(apiScope))
+ props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope) + "{.exportable}"}
+
mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
@@ -1908,43 +1950,15 @@
mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
-func (module *SdkLibrary) createTopLevelStubsLibrary(
- mctx android.DefaultableHookContext, apiScope *apiScope, contributesToApiSurface bool) {
- props := struct {
- Name *string
- Visibility []string
- Sdk_version *string
- Static_libs []string
- System_modules *string
- Dist struct {
- Targets []string
- Dest *string
- Dir *string
- Tag *string
- }
- Compile_dex *bool
- }{}
- props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
+func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
+ props := libraryProperties{}
+
props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
props.Sdk_version = proptools.StringPtr(sdkVersion)
- // Add the stub compiling java_library/java_api_library as static lib based on build config
- staticLib := module.sourceStubLibraryModuleName(apiScope)
- if mctx.Config().BuildFromTextStub() && contributesToApiSurface {
- staticLib = module.apiLibraryModuleName(apiScope)
- }
- props.Static_libs = append(props.Static_libs, staticLib)
props.System_modules = module.deviceProperties.System_modules
- // Dist the class jar artifact for sdk builds.
- if !Bool(module.sdkLibraryProperties.No_dist) {
- props.Dist.Targets = []string{"sdk", "win_sdk"}
- props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
- props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
- props.Dist.Tag = proptools.StringPtr(".jar")
- }
-
// The imports need to be compiled to dex if the java_sdk_library requests it.
compileDex := module.dexProperties.Compile_dex
if module.stubLibrariesCompiledForDex() {
@@ -1952,6 +1966,43 @@
}
props.Compile_dex = compileDex
+ return props
+}
+
+func (module *SdkLibrary) createTopLevelStubsLibrary(
+ mctx android.DefaultableHookContext, apiScope *apiScope, contributesToApiSurface bool) {
+
+ props := module.topLevelStubsLibraryProps(mctx, apiScope)
+ props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
+
+ // Add the stub compiling java_library/java_api_library as static lib based on build config
+ staticLib := module.sourceStubsLibraryModuleName(apiScope)
+ if mctx.Config().BuildFromTextStub() && contributesToApiSurface {
+ staticLib = module.apiLibraryModuleName(apiScope)
+ }
+ props.Static_libs = append(props.Static_libs, staticLib)
+
+ mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
+}
+
+func (module *SdkLibrary) createTopLevelExportableStubsLibrary(
+ mctx android.DefaultableHookContext, apiScope *apiScope) {
+
+ props := module.topLevelStubsLibraryProps(mctx, apiScope)
+ props.Name = proptools.StringPtr(module.exportableStubsLibraryModuleName(apiScope))
+
+ // Dist the class jar artifact for sdk builds.
+ // "exportable" stubs are copied to dist for sdk builds instead of the "everything" stubs.
+ if !Bool(module.sdkLibraryProperties.No_dist) {
+ props.Dist.Targets = []string{"sdk", "win_sdk"}
+ props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
+ props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
+ props.Dist.Tag = proptools.StringPtr(".jar")
+ }
+
+ staticLib := module.exportableSourceStubsLibraryModuleName(apiScope)
+ props.Static_libs = append(props.Static_libs, staticLib)
+
mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
@@ -2157,6 +2208,7 @@
module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs)
module.createStubsLibrary(mctx, scope)
+ module.createExportableStubsLibrary(mctx, scope)
alternativeFullApiSurfaceStubLib := ""
if scope == apiScopePublic {
@@ -2168,6 +2220,7 @@
}
module.createTopLevelStubsLibrary(mctx, scope, contributesToApiSurface)
+ module.createTopLevelExportableStubsLibrary(mctx, scope)
}
if module.requiresRuntimeImplementationLibrary() {
@@ -2223,7 +2276,11 @@
apiLibraryModuleName(scope *apiScope, baseName string) string
- sourceStubLibraryModuleName(scope *apiScope, baseName string) string
+ sourceStubsLibraryModuleName(scope *apiScope, baseName string) string
+
+ exportableStubsLibraryModuleName(scope *apiScope, baseName string) string
+
+ exportableSourceStubsLibraryModuleName(scope *apiScope, baseName string) string
}
type defaultNamingScheme struct {
@@ -2241,34 +2298,47 @@
return scope.apiLibraryModuleName(baseName)
}
-func (s *defaultNamingScheme) sourceStubLibraryModuleName(scope *apiScope, baseName string) string {
+func (s *defaultNamingScheme) sourceStubsLibraryModuleName(scope *apiScope, baseName string) string {
return scope.sourceStubLibraryModuleName(baseName)
}
+func (s *defaultNamingScheme) exportableStubsLibraryModuleName(scope *apiScope, baseName string) string {
+ return scope.exportableStubsLibraryModuleName(baseName)
+}
+
+func (s *defaultNamingScheme) exportableSourceStubsLibraryModuleName(scope *apiScope, baseName string) string {
+ return scope.exportableSourceStubsLibraryModuleName(baseName)
+}
+
var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil)
+func hasStubsLibrarySuffix(name string, apiScope *apiScope) bool {
+ return strings.HasSuffix(name, apiScope.stubsLibraryModuleNameSuffix()) ||
+ strings.HasSuffix(name, apiScope.exportableStubsLibraryModuleNameSuffix())
+}
+
func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) {
name = strings.TrimSuffix(name, ".from-source")
// This suffix-based approach is fragile and could potentially mis-trigger.
// TODO(b/155164730): Clean this up when modules no longer reference sdk_lib stubs directly.
- if strings.HasSuffix(name, apiScopePublic.stubsLibraryModuleNameSuffix()) {
+ if hasStubsLibrarySuffix(name, apiScopePublic) {
if name == "hwbinder.stubs" || name == "libcore_private.stubs" {
// Due to a previous bug, these modules were not considered stubs, so we retain that.
return false, javaPlatform
}
return true, javaSdk
}
- if strings.HasSuffix(name, apiScopeSystem.stubsLibraryModuleNameSuffix()) {
+ if hasStubsLibrarySuffix(name, apiScopeSystem) {
return true, javaSystem
}
- if strings.HasSuffix(name, apiScopeModuleLib.stubsLibraryModuleNameSuffix()) {
+ if hasStubsLibrarySuffix(name, apiScopeModuleLib) {
return true, javaModule
}
- if strings.HasSuffix(name, apiScopeTest.stubsLibraryModuleNameSuffix()) {
+ if hasStubsLibrarySuffix(name, apiScopeTest) {
return true, javaSystem
}
- if strings.HasSuffix(name, apiScopeSystemServer.stubsLibraryModuleNameSuffix()) {
+ if hasStubsLibrarySuffix(name, apiScopeSystemServer) {
return true, javaSystemServer
}
return false, javaPlatform
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 63419d6..c14f3e6 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -1423,7 +1423,7 @@
for _, tt := range testCases {
t.Run(tt.module, func(t *testing.T) {
- m := result.ModuleForTests(tt.module+".stubs", "android_common").Module().(*Library)
+ m := result.ModuleForTests(apiScopePublic.exportableStubsLibraryModuleName(tt.module), "android_common").Module().(*Library)
dists := m.Dists()
if len(dists) != 1 {
t.Fatalf("expected exactly 1 dist entry, got %d", len(dists))
@@ -1693,3 +1693,56 @@
android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barPermissions.RuleParams.Command, `dependency=\"foo\"`)
}
+
+func TestSdkLibraryExportableStubsLibrary(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("foo"),
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.SetApiLibraries([]string{"foo"})
+ }),
+ ).RunTestWithBp(t, `
+ aconfig_declarations {
+ name: "bar",
+ package: "com.example.package",
+ srcs: [
+ "bar.aconfig",
+ ],
+ }
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java", "b.java"],
+ api_packages: ["foo"],
+ system: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ test: {
+ enabled: true,
+ },
+ aconfig_declarations: [
+ "bar",
+ ],
+ }
+ `)
+
+ exportableStubsLibraryModuleName := apiScopePublic.exportableStubsLibraryModuleName("foo")
+ exportableSourceStubsLibraryModuleName := apiScopePublic.exportableSourceStubsLibraryModuleName("foo")
+
+ // Check modules generation
+ topLevelModule := result.ModuleForTests(exportableStubsLibraryModuleName, "android_common")
+ result.ModuleForTests(exportableSourceStubsLibraryModuleName, "android_common")
+
+ // Check static lib dependency
+ android.AssertBoolEquals(t, "exportable top level stubs library module depends on the"+
+ "exportable source stubs library module", true,
+ CheckModuleHasDependency(t, result.TestContext, exportableStubsLibraryModuleName,
+ "android_common", exportableSourceStubsLibraryModuleName),
+ )
+ android.AssertArrayString(t, "exportable source stub library is a static lib of the"+
+ "top level exportable stubs library", []string{exportableSourceStubsLibraryModuleName},
+ topLevelModule.Module().(*Library).properties.Static_libs)
+}