Merge "Add aconfig_declarations property to droidstubs and java_sdk_library" into main

This commit is contained in:
Jihoon Kang
2024-01-08 23:52:27 +00:00
committed by Gerrit Code Review
6 changed files with 157 additions and 0 deletions

View File

@@ -274,11 +274,29 @@ var (
` cat $$f; ` +
`done > $out`,
})
gatherReleasedFlaggedApisRule = pctx.AndroidStaticRule("gatherReleasedFlaggedApisRule",
blueprint.RuleParams{
Command: `${aconfig} dump --format bool ` +
`--out ${out} ` +
`${flags_path} ` +
`${filter_args} `,
CommandDeps: []string{"${aconfig}"},
Description: "aconfig_bool",
}, "flags_path", "filter_args")
generateMetalavaRevertAnnotationsRule = pctx.AndroidStaticRule("generateMetalavaRevertAnnotationsRule",
blueprint.RuleParams{
Command: `${keep-flagged-apis} ${in} > ${out}`,
})
)
func init() {
pctx.Import("android/soong/android")
pctx.Import("android/soong/java/config")
pctx.HostBinToolVariable("aconfig", "aconfig")
pctx.HostBinToolVariable("keep-flagged-apis", "keep-flagged-apis")
}
type javaBuilderFlags struct {

View File

@@ -397,6 +397,15 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
sm := module.(SystemModulesProvider)
outputDir, outputDeps := sm.OutputDirAndDeps()
deps.systemModules = &systemModules{outputDir, outputDeps}
case aconfigDeclarationTag:
if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey); ok {
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPath)
} else {
ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
"flags_packages property, but %s is not aconfig_declarations module type",
module.Name(),
)
}
}
})
// do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs

View File

@@ -30,6 +30,27 @@ import (
// The values allowed for Droidstubs' Api_levels_sdk_type
var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib", "system-server"}
type StubsType int
const (
Everything StubsType = iota
Runtime
Exportable
)
func (s StubsType) String() string {
switch s {
case Everything:
return "everything"
case Runtime:
return "runtime"
case Exportable:
return "exportable"
default:
return ""
}
}
func init() {
RegisterStubsBuildComponents(android.InitRegistrationContext)
}
@@ -151,6 +172,10 @@ type DroidstubsProperties struct {
// API surface of this module. If set, the module contributes to an API surface.
// For the full list of available API surfaces, refer to soong/android/sdk_version.go
Api_surface *string
// a list of aconfig_declarations module names that the stubs generated in this module
// depend on.
Aconfig_declarations []string
}
// Used by xsd_config
@@ -274,6 +299,12 @@ func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
}
}
if len(d.properties.Aconfig_declarations) != 0 {
for _, aconfigDeclarationModuleName := range d.properties.Aconfig_declarations {
ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationModuleName)
}
}
if d.properties.Api_levels_module != nil {
ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
}
@@ -538,11 +569,59 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi
return cmd
}
// Generate flagged apis related flags. 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, stubsType StubsType, aconfigFlagsPaths android.Paths) {
releasedFlaggedApisFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flagged-apis-%s.txt", stubsType.String()))
revertAnnotationsFile := android.PathForModuleOut(ctx, fmt.Sprintf("revert-annotations-%s.txt", stubsType.String()))
var filterArgs string
switch stubsType {
// No flagged apis specific flags need to be passed to metalava when generating
// everything stubs
case Everything:
return
case Runtime:
filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
case Exportable:
filterArgs = "--filter='state:ENABLED+permission:READ_ONLY'"
}
ctx.Build(pctx, android.BuildParams{
Rule: gatherReleasedFlaggedApisRule,
Inputs: aconfigFlagsPaths,
Output: releasedFlaggedApisFile,
Description: fmt.Sprintf("%s gather aconfig flags", stubsType),
Args: map[string]string{
"flags_path": android.JoinPathsWithPrefix(aconfigFlagsPaths, "--cache "),
"filter_args": filterArgs,
},
})
ctx.Build(pctx, android.BuildParams{
Rule: generateMetalavaRevertAnnotationsRule,
Input: releasedFlaggedApisFile,
Output: revertAnnotationsFile,
Description: fmt.Sprintf("%s revert annotations", stubsType),
})
}
func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
deps := d.Javadoc.collectDeps(ctx)
javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
// If the module specifies aconfig_declarations property, "exportable" (and "runtime" eventually) stubs are generated
if len(deps.aconfigProtoFiles) > 0 {
// Files required to generate "exportable" stubs
stubsType := Exportable
d.generateRevertAnnotationArgs(ctx, stubsType, deps.aconfigProtoFiles)
}
// Create rule for metalava
srcJarDir := android.PathForModuleOut(ctx, "metalava", "srcjars")

View File

@@ -395,3 +395,46 @@ func TestDroidstubsHideFlaggedApi(t *testing.T) {
cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "--revert-annotation android.annotation.FlaggedApi")
}
func TestAconfigDeclarations(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",
],
}
droidstubs {
name: "foo",
srcs: ["a/A.java"],
api_surface: "public",
check_api: {
current: {
api_file: "a/current.txt",
removed_api_file: "a/removed.txt",
}
},
aconfig_declarations: [
"bar",
],
}
`)
// Check that droidstubs depend 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")
}

View File

@@ -26,6 +26,7 @@ import (
"android/soong/remoteexec"
"android/soong/testing"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -519,6 +520,7 @@ type deps struct {
kotlinStdlib android.Paths
kotlinAnnotations android.Paths
kotlinPlugins android.Paths
aconfigProtoFiles android.Paths
disableTurbine bool
}

View File

@@ -628,6 +628,10 @@ type sdkLibraryProperties struct {
// Defaults to false.
Contribute_to_android_api *bool
// a list of aconfig_declarations module names that the stubs generated in this module
// depend on.
Aconfig_declarations []string
// TODO: determines whether to create HTML doc or not
// Html_doc *bool
}
@@ -1698,6 +1702,7 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC
Merge_inclusion_annotations_dirs []string
Generate_stubs *bool
Previous_api *string
Aconfig_declarations []string
Check_api struct {
Current ApiToCheck
Last_released ApiToCheck
@@ -1742,6 +1747,7 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC
props.Annotations_enabled = module.sdkLibraryProperties.Annotations_enabled
props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
props.Aconfig_declarations = module.sdkLibraryProperties.Aconfig_declarations
droidstubsArgs := []string{}
if len(module.sdkLibraryProperties.Api_packages) != 0 {