Enable non-"everything" stubs generation in java_api_library
This change adds support to generate non-"everything" (i.e. "runtime" and "exportable") stubs in java_api_library, which generates the stubs from the api signature files. Unlike droidstubs module that generates "everything", "exportable" and "runtime" stubs in a single module, java_api_library generates a single set of stubs per module, which is set by the default-"everything" property `stubs_type`. This is because java_api_library is responsible for both generation and the compilation of the stubs srcjar, and compilation of the stubs srcjar are done in separate java_library modules for from-source stubs. Utilization of this feature will be done in a follow up change that generates the "exportable" java_api_library modules in java_sdk_library. Test: m nothing --no-skip-soong-tests Bug: 318009570 Change-Id: I1051544ac3bcdb3ba1f78bfec28eba4e9fad9c2d
This commit is contained in:
parent
60bdd05b21
commit
5d701272e4
7 changed files with 148 additions and 6 deletions
|
@ -64,6 +64,7 @@ java_api_library {
|
|||
"stub-annotations",
|
||||
],
|
||||
enable_validation: false,
|
||||
stubs_type: "everything",
|
||||
}
|
||||
|
||||
java_library {
|
||||
|
@ -248,6 +249,7 @@ java_api_library {
|
|||
"stub-annotations",
|
||||
],
|
||||
visibility: ["//visibility:private"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
|
||||
// Produces a dist file that is used by the
|
||||
|
@ -358,6 +360,7 @@ java_api_library {
|
|||
libs: [
|
||||
"stub-annotations",
|
||||
],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
|
||||
java_library {
|
||||
|
@ -446,6 +449,7 @@ java_api_library {
|
|||
libs: [
|
||||
"stub-annotations",
|
||||
],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
|
||||
java_library {
|
||||
|
|
|
@ -52,6 +52,19 @@ func (s StubsType) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
func StringToStubsType(s string) StubsType {
|
||||
switch strings.ToLower(s) {
|
||||
case Everything.String():
|
||||
return Everything
|
||||
case Runtime.String():
|
||||
return Runtime
|
||||
case Exportable.String():
|
||||
return Exportable
|
||||
default:
|
||||
return Unavailable
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterStubsBuildComponents(android.InitRegistrationContext)
|
||||
}
|
||||
|
@ -731,7 +744,7 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi
|
|||
// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
|
||||
// property is defined, apply transformations and only revert the flagged apis that are not
|
||||
// enabled via release configurations and are not specified in aconfig_declarations
|
||||
func (d *Droidstubs) generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
|
||||
func generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
|
||||
|
||||
if len(aconfigFlagsPaths) == 0 {
|
||||
cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
|
||||
|
@ -1106,7 +1119,7 @@ func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsComm
|
|||
|
||||
cmd := d.commonMetalavaStubCmd(ctx, rule, params)
|
||||
|
||||
d.generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
|
||||
generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
|
||||
|
||||
if params.stubConfig.doApiLint {
|
||||
// Pass the lint baseline file as an input to resolve the lint errors.
|
||||
|
|
|
@ -337,6 +337,7 @@ func TestGeneratedApiContributionVisibilityTest(t *testing.T) {
|
|||
name: "bar",
|
||||
api_surface: "public",
|
||||
api_contributions: ["foo.api.contribution"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`
|
||||
ctx, _ := testJavaWithFS(t, `
|
||||
|
|
52
java/java.go
52
java/java.go
|
@ -24,6 +24,7 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"android/soong/aconfig"
|
||||
"android/soong/remoteexec"
|
||||
"android/soong/testing"
|
||||
|
||||
|
@ -1863,6 +1864,10 @@ type ApiLibrary struct {
|
|||
dexJarFile OptionalDexJarPath
|
||||
|
||||
validationPaths android.Paths
|
||||
|
||||
stubsType StubsType
|
||||
|
||||
aconfigProtoFiles android.Paths
|
||||
}
|
||||
|
||||
type JavaApiLibraryProperties struct {
|
||||
|
@ -1904,6 +1909,20 @@ type JavaApiLibraryProperties struct {
|
|||
// in sync with the source Java files. However, the environment variable
|
||||
// DISABLE_STUB_VALIDATION has precedence over this property.
|
||||
Enable_validation *bool
|
||||
|
||||
// Type of stubs the module should generate. Must be one of "everything", "runtime" or
|
||||
// "exportable". Defaults to "everything".
|
||||
// - "everything" stubs include all non-flagged apis and flagged apis, regardless of the state
|
||||
// of the flag.
|
||||
// - "runtime" stubs include all non-flagged apis and flagged apis that are ENABLED or
|
||||
// READ_WRITE, and all other flagged apis are stripped.
|
||||
// - "exportable" stubs include all non-flagged apis and flagged apis that are ENABLED and
|
||||
// READ_ONLY, and all other flagged apis are stripped.
|
||||
Stubs_type *string
|
||||
|
||||
// List of aconfig_declarations module names that the stubs generated in this module
|
||||
// depend on.
|
||||
Aconfig_declarations []string
|
||||
}
|
||||
|
||||
func ApiLibraryFactory() android.Module {
|
||||
|
@ -2067,6 +2086,9 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|||
if al.properties.System_modules != nil {
|
||||
ctx.AddVariationDependencies(nil, systemModulesTag, String(al.properties.System_modules))
|
||||
}
|
||||
for _, aconfigDeclarationsName := range al.properties.Aconfig_declarations {
|
||||
ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationsName)
|
||||
}
|
||||
}
|
||||
|
||||
// Map where key is the api scope name and value is the int value
|
||||
|
@ -2087,7 +2109,23 @@ func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFiles
|
|||
return srcFilesInfo
|
||||
}
|
||||
|
||||
var validstubsType = []StubsType{Everything, Runtime, Exportable}
|
||||
|
||||
func (al *ApiLibrary) validateProperties(ctx android.ModuleContext) {
|
||||
if al.properties.Stubs_type == nil {
|
||||
ctx.ModuleErrorf("java_api_library module type must specify stubs_type property.")
|
||||
} else {
|
||||
al.stubsType = StringToStubsType(proptools.String(al.properties.Stubs_type))
|
||||
}
|
||||
|
||||
if !android.InList(al.stubsType, validstubsType) {
|
||||
ctx.PropertyErrorf("stubs_type", "%s is not a valid stubs_type property value. "+
|
||||
"Must be one of %s.", proptools.String(al.properties.Stubs_type), validstubsType)
|
||||
}
|
||||
}
|
||||
|
||||
func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
al.validateProperties(ctx)
|
||||
|
||||
rule := android.NewRuleBuilder(pctx, ctx)
|
||||
|
||||
|
@ -2131,6 +2169,18 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok {
|
||||
al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp())
|
||||
}
|
||||
case aconfigDeclarationTag:
|
||||
if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
|
||||
al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPath)
|
||||
} else if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok {
|
||||
al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPaths...)
|
||||
} else {
|
||||
ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
|
||||
"module type is allowed for flags_packages property, but %s is neither "+
|
||||
"of these supported module types",
|
||||
dep.Name(),
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -2156,6 +2206,8 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
|
||||
al.addValidation(ctx, cmd, al.validationPaths)
|
||||
|
||||
generateRevertAnnotationArgs(ctx, cmd, al.stubsType, al.aconfigProtoFiles)
|
||||
|
||||
al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")
|
||||
al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar")
|
||||
al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName()))
|
||||
|
|
|
@ -1756,6 +1756,7 @@ func TestJavaApiContributionEmptyApiFile(t *testing.T) {
|
|||
name: "bar",
|
||||
api_surface: "public",
|
||||
api_contributions: ["foo"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
@ -1792,12 +1793,14 @@ func TestJavaApiLibraryAndProviderLink(t *testing.T) {
|
|||
name: "bar1",
|
||||
api_surface: "public",
|
||||
api_contributions: ["foo1"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
|
||||
java_api_library {
|
||||
name: "bar2",
|
||||
api_surface: "system",
|
||||
api_contributions: ["foo1", "foo2"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`)
|
||||
|
||||
|
@ -1885,12 +1888,14 @@ func TestJavaApiLibraryAndDefaultsLink(t *testing.T) {
|
|||
name: "bar1",
|
||||
api_surface: "public",
|
||||
api_contributions: ["foo1"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
|
||||
java_api_library {
|
||||
name: "bar2",
|
||||
api_surface: "public",
|
||||
defaults:["baz1"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
|
||||
java_api_library {
|
||||
|
@ -1898,6 +1903,7 @@ func TestJavaApiLibraryAndDefaultsLink(t *testing.T) {
|
|||
api_surface: "system",
|
||||
defaults:["baz1", "baz2"],
|
||||
api_contributions: ["foo4"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`)
|
||||
|
||||
|
@ -1962,12 +1968,14 @@ func TestJavaApiLibraryJarGeneration(t *testing.T) {
|
|||
name: "bar1",
|
||||
api_surface: "public",
|
||||
api_contributions: ["foo1"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
|
||||
java_api_library {
|
||||
name: "bar2",
|
||||
api_surface: "system",
|
||||
api_contributions: ["foo1", "foo2"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`)
|
||||
|
||||
|
@ -2044,6 +2052,7 @@ func TestJavaApiLibraryLibsLink(t *testing.T) {
|
|||
api_surface: "public",
|
||||
api_contributions: ["foo1"],
|
||||
libs: ["lib1"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
|
||||
java_api_library {
|
||||
|
@ -2051,6 +2060,7 @@ func TestJavaApiLibraryLibsLink(t *testing.T) {
|
|||
api_surface: "system",
|
||||
api_contributions: ["foo1", "foo2"],
|
||||
libs: ["lib1", "lib2", "bar1"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`)
|
||||
|
||||
|
@ -2130,6 +2140,7 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) {
|
|||
api_surface: "public",
|
||||
api_contributions: ["foo1"],
|
||||
static_libs: ["lib1"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
|
||||
java_api_library {
|
||||
|
@ -2137,6 +2148,7 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) {
|
|||
api_surface: "system",
|
||||
api_contributions: ["foo1", "foo2"],
|
||||
static_libs: ["lib1", "lib2", "bar1"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`)
|
||||
|
||||
|
@ -2184,6 +2196,7 @@ func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) {
|
|||
name: "lib1",
|
||||
api_surface: "public",
|
||||
api_contributions: ["foo1", "foo2"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`
|
||||
|
||||
|
@ -2207,6 +2220,7 @@ func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) {
|
|||
api_surface: "public",
|
||||
api_contributions: ["foo1"],
|
||||
full_api_surface_stub: "lib1",
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`)
|
||||
|
||||
|
@ -2368,6 +2382,7 @@ func TestJavaApiContributionImport(t *testing.T) {
|
|||
java_api_library {
|
||||
name: "foo",
|
||||
api_contributions: ["bar"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
java_api_contribution_import {
|
||||
name: "bar",
|
||||
|
@ -2394,6 +2409,7 @@ func TestJavaApiLibraryApiFilesSorting(t *testing.T) {
|
|||
"module-lib-api-stubs-docs-non-updatable.api.contribution",
|
||||
"api-stubs-docs-non-updatable.api.contribution",
|
||||
],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`)
|
||||
m := ctx.ModuleForTests("foo", "android_common")
|
||||
|
@ -2466,6 +2482,7 @@ func TestApiLibraryDroidstubsDependency(t *testing.T) {
|
|||
"api-stubs-docs-non-updatable.api.contribution",
|
||||
],
|
||||
enable_validation: true,
|
||||
stubs_type: "everything",
|
||||
}
|
||||
java_api_library {
|
||||
name: "bar",
|
||||
|
@ -2473,6 +2490,7 @@ func TestApiLibraryDroidstubsDependency(t *testing.T) {
|
|||
"api-stubs-docs-non-updatable.api.contribution",
|
||||
],
|
||||
enable_validation: false,
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`)
|
||||
|
||||
|
@ -2624,3 +2642,54 @@ func TestMultiplePrebuilts(t *testing.T) {
|
|||
android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "bar", entries.EntryMap["LOCAL_MODULE"][0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestApiLibraryAconfigDeclarations(t *testing.T) {
|
||||
result := android.GroupFixturePreparers(
|
||||
prepareForJavaTest,
|
||||
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
||||
}),
|
||||
android.FixtureMergeMockFs(map[string][]byte{
|
||||
"a/A.java": nil,
|
||||
"a/current.txt": nil,
|
||||
"a/removed.txt": nil,
|
||||
}),
|
||||
).RunTestWithBp(t, `
|
||||
aconfig_declarations {
|
||||
name: "bar",
|
||||
package: "com.example.package",
|
||||
srcs: [
|
||||
"bar.aconfig",
|
||||
],
|
||||
}
|
||||
java_api_contribution {
|
||||
name: "baz",
|
||||
api_file: "a/current.txt",
|
||||
api_surface: "public",
|
||||
}
|
||||
java_api_library {
|
||||
name: "foo",
|
||||
api_surface: "public",
|
||||
api_contributions: [
|
||||
"baz",
|
||||
],
|
||||
aconfig_declarations: [
|
||||
"bar",
|
||||
],
|
||||
stubs_type: "exportable",
|
||||
enable_validation: false,
|
||||
}
|
||||
`)
|
||||
|
||||
// Check if java_api_library depends on aconfig_declarations
|
||||
android.AssertBoolEquals(t, "foo expected to depend on bar",
|
||||
CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"), true)
|
||||
|
||||
m := result.ModuleForTests("foo", "android_common")
|
||||
android.AssertStringDoesContain(t, "foo generates revert annotations file",
|
||||
strings.Join(m.AllOutputs(), ""), "revert-annotations-exportable.txt")
|
||||
|
||||
// revert-annotations.txt passed to exportable stubs generation metalava command
|
||||
manifest := m.Output("metalava.sbox.textproto")
|
||||
cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
|
||||
android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
|
||||
}
|
||||
|
|
|
@ -2024,6 +2024,7 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext,
|
|||
Full_api_surface_stub *string
|
||||
System_modules *string
|
||||
Enable_validation *bool
|
||||
Stubs_type *string
|
||||
}{}
|
||||
|
||||
props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope))
|
||||
|
@ -2073,6 +2074,7 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext,
|
|||
|
||||
props.System_modules = module.deviceProperties.System_modules
|
||||
props.Enable_validation = proptools.BoolPtr(true)
|
||||
props.Stubs_type = proptools.StringPtr("everything")
|
||||
|
||||
mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
|
||||
}
|
||||
|
|
|
@ -523,10 +523,11 @@ func gatherRequiredDepsForTest() string {
|
|||
|
||||
for libName, droidstubs := range extraApiLibraryModules {
|
||||
bp += fmt.Sprintf(`
|
||||
java_api_library {
|
||||
name: "%s",
|
||||
api_contributions: ["%s"],
|
||||
}
|
||||
java_api_library {
|
||||
name: "%s",
|
||||
api_contributions: ["%s"],
|
||||
stubs_type: "everything",
|
||||
}
|
||||
`, libName, droidstubs.name+".api.contribution")
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue