Loading android/config.go +42 −0 Original line number Diff line number Diff line Loading @@ -302,6 +302,9 @@ type config struct { // modules that aren't mixed-built for at least one variant will cause a build // failure ensureAllowlistIntegrity bool // List of Api libraries that contribute to Api surfaces. apiLibraries map[string]struct{} } type deviceConfig struct { Loading Loading @@ -622,6 +625,33 @@ func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error) config.BazelContext, err = NewBazelContext(config) config.Bp2buildPackageConfig = GetBp2BuildAllowList() // TODO(b/276958307): Replace the hardcoded list to a sdk_library local prop. config.apiLibraries = map[string]struct{}{ "android.net.ipsec.ike": {}, "art.module.public.api": {}, "conscrypt.module.public.api": {}, "framework-adservices": {}, "framework-appsearch": {}, "framework-bluetooth": {}, "framework-connectivity": {}, "framework-connectivity-t": {}, "framework-graphics": {}, "framework-media": {}, "framework-mediaprovider": {}, "framework-ondevicepersonalization": {}, "framework-permission": {}, "framework-permission-s": {}, "framework-scheduling": {}, "framework-sdkextensions": {}, "framework-statsd": {}, "framework-sdksandbox": {}, "framework-tethering": {}, "framework-uwb": {}, "framework-virtualization": {}, "framework-wifi": {}, "i18n.module.public.api": {}, } return Config{config}, err } Loading Loading @@ -1979,8 +2009,20 @@ func (c *config) BuildFromTextStub() bool { func (c *config) SetBuildFromTextStub(b bool) { c.buildFromTextStub = b } func (c *config) AddForceEnabledModules(forceEnabled []string) { for _, forceEnabledModule := range forceEnabled { c.bazelForceEnabledModules[forceEnabledModule] = struct{}{} } } func (c *config) SetApiLibraries(libs []string) { c.apiLibraries = make(map[string]struct{}) for _, lib := range libs { c.apiLibraries[lib] = struct{}{} } } func (c *config) GetApiLibraries() map[string]struct{} { return c.apiLibraries } java/sdk_library.go +77 −1 Original line number Diff line number Diff line Loading @@ -156,6 +156,9 @@ type apiScope struct { // Whether the api scope can be treated as unstable, and should skip compat checks. unstable bool // Represents the SDK kind of this scope. kind android.SdkKind } // Initialize a scope, creating and adding appropriate dependency tags Loading Loading @@ -229,6 +232,10 @@ func (scope *apiScope) stubsLibraryModuleNameSuffix() string { return ".stubs" + scope.moduleSuffix } func (scope *apiScope) apiLibraryModuleName(baseName string) string { return scope.stubsLibraryModuleName(baseName) + ".from-text" } func (scope *apiScope) stubsLibraryModuleName(baseName string) string { return baseName + scope.stubsLibraryModuleNameSuffix() } Loading Loading @@ -289,6 +296,7 @@ var ( return &module.sdkLibraryProperties.Public }, sdkVersion: "current", kind: android.SdkPublic, }) apiScopeSystem = initApiScope(&apiScope{ name: "system", Loading @@ -301,6 +309,7 @@ var ( moduleSuffix: ".system", sdkVersion: "system_current", annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS)", kind: android.SdkSystem, }) apiScopeTest = initApiScope(&apiScope{ name: "test", Loading @@ -314,6 +323,7 @@ var ( sdkVersion: "test_current", annotation: "android.annotation.TestApi", unstable: true, kind: android.SdkTest, }) apiScopeModuleLib = initApiScope(&apiScope{ name: "module-lib", Loading @@ -331,6 +341,7 @@ var ( moduleSuffix: ".module_lib", sdkVersion: "module_current", annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES)", kind: android.SdkModule, }) apiScopeSystemServer = initApiScope(&apiScope{ name: "system-server", Loading Loading @@ -361,6 +372,7 @@ var ( // com.android.* classes are okay in this interface" "--hide", "InternalClasses", }, kind: android.SdkSystemServer, }) allApiScopes = apiScopes{ apiScopePublic, Loading Loading @@ -842,6 +854,13 @@ func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) return c.namingScheme.stubsSourceModuleName(apiScope, baseName) } // Name of the java_api_library module that generates the from-text stubs source // and compiles to a jar file. func (c *commonToSdkLibraryAndImport) apiLibraryModuleName(apiScope *apiScope) string { baseName := c.module.BaseModuleName() return c.namingScheme.apiLibraryModuleName(apiScope, baseName) } // The component names for different outputs of the java_sdk_library. // // They are similar to the names used for the child modules it creates Loading Loading @@ -1269,7 +1288,9 @@ func (module *SdkLibrary) ComponentDepsMutator(ctx android.BottomUpMutatorContex // Add dependencies to the stubs library stubModuleName := module.stubsLibraryModuleName(apiScope) // Use JavaApiLibraryName function to be redirected to stubs generated from .txt if applicable if module.contributesToApiSurface(ctx.Config()) { stubModuleName = android.JavaApiLibraryName(ctx.Config(), stubModuleName) } ctx.AddVariationDependencies(nil, apiScope.stubsTag, stubModuleName) // Add a dependency on the stubs source in order to access both stubs source and api information. Loading Loading @@ -1477,6 +1498,11 @@ func (module *SdkLibrary) latestIncompatibilitiesModuleName(apiScope *apiScope) return latestPrebuiltApiModuleName(module.distStem()+"-incompatibilities", apiScope) } func (module *SdkLibrary) contributesToApiSurface(c android.Config) bool { _, exists := c.GetApiLibraries()[module.Name()] return exists } func childModuleVisibility(childVisibility []string) []string { if childVisibility == nil { // No child visibility set. The child will use the visibility of the sdk_library. Loading Loading @@ -1758,6 +1784,46 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC mctx.CreateModule(DroidstubsFactory, &props).(*Droidstubs).CallHookIfAvailable(mctx) } func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) { props := struct { Name *string Visibility []string Api_contributions []string Libs []string Static_libs []string Dep_api_srcs *string }{} props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope)) props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility) apiContributions := []string{} // Api surfaces are not independent of each other, but have subset relationships, // and so does the api files. To generate from-text stubs for api surfaces other than public, // all subset api domains' api_contriubtions must be added as well. scope := apiScope for scope != nil { apiContributions = append(apiContributions, module.stubsSourceModuleName(scope)+".api.contribution") scope = scope.extends } props.Api_contributions = apiContributions props.Libs = module.properties.Libs props.Libs = append(props.Libs, module.sdkLibraryProperties.Stub_only_libs...) props.Libs = append(props.Libs, "stub-annotations") props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs props.Dep_api_srcs = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + ".from-text") // android_module_lib_stubs_current.from-text only comprises api contributions from art, conscrypt and i18n. // Thus, replace with android_module_lib_stubs_current_full.from-text, which comprises every api domains. if apiScope.kind == android.SdkModule { props.Dep_api_srcs = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + "_full.from-text") } mctx.CreateModule(ApiLibraryFactory, &props) } func (module *SdkLibrary) compareAgainstLatestApi(apiScope *apiScope) bool { return !(apiScope.unstable || module.sdkLibraryProperties.Unsafe_ignore_missing_latest_api) } Loading Loading @@ -1954,6 +2020,10 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs) module.createStubsLibrary(mctx, scope) if module.contributesToApiSurface(mctx.Config()) { module.createApiLibrary(mctx, scope) } } if module.requiresRuntimeImplementationLibrary() { Loading Loading @@ -2006,6 +2076,8 @@ type sdkLibraryComponentNamingScheme interface { stubsLibraryModuleName(scope *apiScope, baseName string) string stubsSourceModuleName(scope *apiScope, baseName string) string apiLibraryModuleName(scope *apiScope, baseName string) string } type defaultNamingScheme struct { Loading @@ -2019,6 +2091,10 @@ func (s *defaultNamingScheme) stubsSourceModuleName(scope *apiScope, baseName st return scope.stubsSourceModuleName(baseName) } func (s *defaultNamingScheme) apiLibraryModuleName(scope *apiScope, baseName string) string { return scope.apiLibraryModuleName(baseName) } var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil) func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) { Loading java/sdk_library_test.go +63 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,9 @@ func TestJavaSdkLibrary(t *testing.T) { "29": {"foo"}, "30": {"bar", "barney", "baz", "betty", "foo", "fred", "quuz", "wilma"}, }), android.FixtureModifyConfig(func(config android.Config) { config.SetApiLibraries([]string{"foo"}) }), ).RunTestWithBp(t, ` droiddoc_exported_dir { name: "droiddoc-templates-sdk", Loading Loading @@ -121,6 +124,7 @@ func TestJavaSdkLibrary(t *testing.T) { result.ModuleForTests(apiScopeSystem.stubsSourceModuleName("foo"), "android_common") result.ModuleForTests(apiScopeTest.stubsSourceModuleName("foo"), "android_common") result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo")+".api.contribution", "") result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common") result.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common") result.ModuleForTests("foo.api.public.28", "") result.ModuleForTests("foo.api.system.28", "") Loading Loading @@ -1412,3 +1416,62 @@ func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) { fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs) android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs, "bar-lib") } func TestJavaSdkLibrary_ApiLibrary(t *testing.T) { result := android.GroupFixturePreparers( prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("foo"), android.FixtureModifyConfig(func(config android.Config) { config.SetApiLibraries([]string{"foo"}) }), ).RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java", "b.java"], api_packages: ["foo"], system: { enabled: true, }, module_lib: { enabled: true, }, test: { enabled: true, }, } `) testCases := []struct { scope *apiScope apiContributions []string depApiSrcs string }{ { scope: apiScopePublic, apiContributions: []string{"foo.stubs.source.api.contribution"}, depApiSrcs: "android_stubs_current.from-text", }, { scope: apiScopeSystem, apiContributions: []string{"foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, depApiSrcs: "android_system_stubs_current.from-text", }, { scope: apiScopeTest, apiContributions: []string{"foo.stubs.source.test.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, depApiSrcs: "android_test_stubs_current.from-text", }, { scope: apiScopeModuleLib, apiContributions: []string{"foo.stubs.source.module_lib.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, depApiSrcs: "android_module_lib_stubs_current_full.from-text", }, } for _, c := range testCases { m := result.ModuleForTests(c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary) android.AssertArrayString(t, "Module expected to contain api contributions", c.apiContributions, m.properties.Api_contributions) android.AssertStringEquals(t, "Module expected to contain full api surface api library", c.depApiSrcs, *m.properties.Dep_api_srcs) } } Loading
android/config.go +42 −0 Original line number Diff line number Diff line Loading @@ -302,6 +302,9 @@ type config struct { // modules that aren't mixed-built for at least one variant will cause a build // failure ensureAllowlistIntegrity bool // List of Api libraries that contribute to Api surfaces. apiLibraries map[string]struct{} } type deviceConfig struct { Loading Loading @@ -622,6 +625,33 @@ func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error) config.BazelContext, err = NewBazelContext(config) config.Bp2buildPackageConfig = GetBp2BuildAllowList() // TODO(b/276958307): Replace the hardcoded list to a sdk_library local prop. config.apiLibraries = map[string]struct{}{ "android.net.ipsec.ike": {}, "art.module.public.api": {}, "conscrypt.module.public.api": {}, "framework-adservices": {}, "framework-appsearch": {}, "framework-bluetooth": {}, "framework-connectivity": {}, "framework-connectivity-t": {}, "framework-graphics": {}, "framework-media": {}, "framework-mediaprovider": {}, "framework-ondevicepersonalization": {}, "framework-permission": {}, "framework-permission-s": {}, "framework-scheduling": {}, "framework-sdkextensions": {}, "framework-statsd": {}, "framework-sdksandbox": {}, "framework-tethering": {}, "framework-uwb": {}, "framework-virtualization": {}, "framework-wifi": {}, "i18n.module.public.api": {}, } return Config{config}, err } Loading Loading @@ -1979,8 +2009,20 @@ func (c *config) BuildFromTextStub() bool { func (c *config) SetBuildFromTextStub(b bool) { c.buildFromTextStub = b } func (c *config) AddForceEnabledModules(forceEnabled []string) { for _, forceEnabledModule := range forceEnabled { c.bazelForceEnabledModules[forceEnabledModule] = struct{}{} } } func (c *config) SetApiLibraries(libs []string) { c.apiLibraries = make(map[string]struct{}) for _, lib := range libs { c.apiLibraries[lib] = struct{}{} } } func (c *config) GetApiLibraries() map[string]struct{} { return c.apiLibraries }
java/sdk_library.go +77 −1 Original line number Diff line number Diff line Loading @@ -156,6 +156,9 @@ type apiScope struct { // Whether the api scope can be treated as unstable, and should skip compat checks. unstable bool // Represents the SDK kind of this scope. kind android.SdkKind } // Initialize a scope, creating and adding appropriate dependency tags Loading Loading @@ -229,6 +232,10 @@ func (scope *apiScope) stubsLibraryModuleNameSuffix() string { return ".stubs" + scope.moduleSuffix } func (scope *apiScope) apiLibraryModuleName(baseName string) string { return scope.stubsLibraryModuleName(baseName) + ".from-text" } func (scope *apiScope) stubsLibraryModuleName(baseName string) string { return baseName + scope.stubsLibraryModuleNameSuffix() } Loading Loading @@ -289,6 +296,7 @@ var ( return &module.sdkLibraryProperties.Public }, sdkVersion: "current", kind: android.SdkPublic, }) apiScopeSystem = initApiScope(&apiScope{ name: "system", Loading @@ -301,6 +309,7 @@ var ( moduleSuffix: ".system", sdkVersion: "system_current", annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS)", kind: android.SdkSystem, }) apiScopeTest = initApiScope(&apiScope{ name: "test", Loading @@ -314,6 +323,7 @@ var ( sdkVersion: "test_current", annotation: "android.annotation.TestApi", unstable: true, kind: android.SdkTest, }) apiScopeModuleLib = initApiScope(&apiScope{ name: "module-lib", Loading @@ -331,6 +341,7 @@ var ( moduleSuffix: ".module_lib", sdkVersion: "module_current", annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES)", kind: android.SdkModule, }) apiScopeSystemServer = initApiScope(&apiScope{ name: "system-server", Loading Loading @@ -361,6 +372,7 @@ var ( // com.android.* classes are okay in this interface" "--hide", "InternalClasses", }, kind: android.SdkSystemServer, }) allApiScopes = apiScopes{ apiScopePublic, Loading Loading @@ -842,6 +854,13 @@ func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) return c.namingScheme.stubsSourceModuleName(apiScope, baseName) } // Name of the java_api_library module that generates the from-text stubs source // and compiles to a jar file. func (c *commonToSdkLibraryAndImport) apiLibraryModuleName(apiScope *apiScope) string { baseName := c.module.BaseModuleName() return c.namingScheme.apiLibraryModuleName(apiScope, baseName) } // The component names for different outputs of the java_sdk_library. // // They are similar to the names used for the child modules it creates Loading Loading @@ -1269,7 +1288,9 @@ func (module *SdkLibrary) ComponentDepsMutator(ctx android.BottomUpMutatorContex // Add dependencies to the stubs library stubModuleName := module.stubsLibraryModuleName(apiScope) // Use JavaApiLibraryName function to be redirected to stubs generated from .txt if applicable if module.contributesToApiSurface(ctx.Config()) { stubModuleName = android.JavaApiLibraryName(ctx.Config(), stubModuleName) } ctx.AddVariationDependencies(nil, apiScope.stubsTag, stubModuleName) // Add a dependency on the stubs source in order to access both stubs source and api information. Loading Loading @@ -1477,6 +1498,11 @@ func (module *SdkLibrary) latestIncompatibilitiesModuleName(apiScope *apiScope) return latestPrebuiltApiModuleName(module.distStem()+"-incompatibilities", apiScope) } func (module *SdkLibrary) contributesToApiSurface(c android.Config) bool { _, exists := c.GetApiLibraries()[module.Name()] return exists } func childModuleVisibility(childVisibility []string) []string { if childVisibility == nil { // No child visibility set. The child will use the visibility of the sdk_library. Loading Loading @@ -1758,6 +1784,46 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC mctx.CreateModule(DroidstubsFactory, &props).(*Droidstubs).CallHookIfAvailable(mctx) } func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) { props := struct { Name *string Visibility []string Api_contributions []string Libs []string Static_libs []string Dep_api_srcs *string }{} props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope)) props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility) apiContributions := []string{} // Api surfaces are not independent of each other, but have subset relationships, // and so does the api files. To generate from-text stubs for api surfaces other than public, // all subset api domains' api_contriubtions must be added as well. scope := apiScope for scope != nil { apiContributions = append(apiContributions, module.stubsSourceModuleName(scope)+".api.contribution") scope = scope.extends } props.Api_contributions = apiContributions props.Libs = module.properties.Libs props.Libs = append(props.Libs, module.sdkLibraryProperties.Stub_only_libs...) props.Libs = append(props.Libs, "stub-annotations") props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs props.Dep_api_srcs = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + ".from-text") // android_module_lib_stubs_current.from-text only comprises api contributions from art, conscrypt and i18n. // Thus, replace with android_module_lib_stubs_current_full.from-text, which comprises every api domains. if apiScope.kind == android.SdkModule { props.Dep_api_srcs = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + "_full.from-text") } mctx.CreateModule(ApiLibraryFactory, &props) } func (module *SdkLibrary) compareAgainstLatestApi(apiScope *apiScope) bool { return !(apiScope.unstable || module.sdkLibraryProperties.Unsafe_ignore_missing_latest_api) } Loading Loading @@ -1954,6 +2020,10 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs) module.createStubsLibrary(mctx, scope) if module.contributesToApiSurface(mctx.Config()) { module.createApiLibrary(mctx, scope) } } if module.requiresRuntimeImplementationLibrary() { Loading Loading @@ -2006,6 +2076,8 @@ type sdkLibraryComponentNamingScheme interface { stubsLibraryModuleName(scope *apiScope, baseName string) string stubsSourceModuleName(scope *apiScope, baseName string) string apiLibraryModuleName(scope *apiScope, baseName string) string } type defaultNamingScheme struct { Loading @@ -2019,6 +2091,10 @@ func (s *defaultNamingScheme) stubsSourceModuleName(scope *apiScope, baseName st return scope.stubsSourceModuleName(baseName) } func (s *defaultNamingScheme) apiLibraryModuleName(scope *apiScope, baseName string) string { return scope.apiLibraryModuleName(baseName) } var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil) func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) { Loading
java/sdk_library_test.go +63 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,9 @@ func TestJavaSdkLibrary(t *testing.T) { "29": {"foo"}, "30": {"bar", "barney", "baz", "betty", "foo", "fred", "quuz", "wilma"}, }), android.FixtureModifyConfig(func(config android.Config) { config.SetApiLibraries([]string{"foo"}) }), ).RunTestWithBp(t, ` droiddoc_exported_dir { name: "droiddoc-templates-sdk", Loading Loading @@ -121,6 +124,7 @@ func TestJavaSdkLibrary(t *testing.T) { result.ModuleForTests(apiScopeSystem.stubsSourceModuleName("foo"), "android_common") result.ModuleForTests(apiScopeTest.stubsSourceModuleName("foo"), "android_common") result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo")+".api.contribution", "") result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common") result.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common") result.ModuleForTests("foo.api.public.28", "") result.ModuleForTests("foo.api.system.28", "") Loading Loading @@ -1412,3 +1416,62 @@ func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) { fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs) android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs, "bar-lib") } func TestJavaSdkLibrary_ApiLibrary(t *testing.T) { result := android.GroupFixturePreparers( prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("foo"), android.FixtureModifyConfig(func(config android.Config) { config.SetApiLibraries([]string{"foo"}) }), ).RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java", "b.java"], api_packages: ["foo"], system: { enabled: true, }, module_lib: { enabled: true, }, test: { enabled: true, }, } `) testCases := []struct { scope *apiScope apiContributions []string depApiSrcs string }{ { scope: apiScopePublic, apiContributions: []string{"foo.stubs.source.api.contribution"}, depApiSrcs: "android_stubs_current.from-text", }, { scope: apiScopeSystem, apiContributions: []string{"foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, depApiSrcs: "android_system_stubs_current.from-text", }, { scope: apiScopeTest, apiContributions: []string{"foo.stubs.source.test.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, depApiSrcs: "android_test_stubs_current.from-text", }, { scope: apiScopeModuleLib, apiContributions: []string{"foo.stubs.source.module_lib.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, depApiSrcs: "android_module_lib_stubs_current_full.from-text", }, } for _, c := range testCases { m := result.ModuleForTests(c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary) android.AssertArrayString(t, "Module expected to contain api contributions", c.apiContributions, m.properties.Api_contributions) android.AssertStringEquals(t, "Module expected to contain full api surface api library", c.depApiSrcs, *m.properties.Dep_api_srcs) } }