diff options
Diffstat (limited to 'java/droidstubs.go')
-rw-r--r-- | java/droidstubs.go | 139 |
1 files changed, 93 insertions, 46 deletions
diff --git a/java/droidstubs.go b/java/droidstubs.go index 02b81a4fe..730be14b0 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -532,8 +532,8 @@ func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.Ru cmd.Flag(config.MetalavaAnnotationsFlags) if params.migratingNullability { - previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api)) - cmd.FlagWithInput("--migrate-nullness ", previousApi) + previousApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Previous_api)}) + cmd.FlagForEachInput("--migrate-nullness ", previousApiFiles) } if s := String(d.properties.Validate_nullability_from_list); s != "" { @@ -604,6 +604,11 @@ func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *a } } +// AndroidPlusUpdatableJar is the name of some extra jars added into `module-lib` and +// `system-server` directories that contain all the APIs provided by the platform and updatable +// modules because the `android.jar` files do not. See b/337836752. +const AndroidPlusUpdatableJar = "android-plus-updatable.jar" + func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) { if len(d.properties.Api_levels_annotations_dirs) == 0 { ctx.PropertyErrorf("api_levels_annotations_dirs", @@ -614,25 +619,72 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar") + // TODO: Avoid the duplication of API surfaces, reuse apiScope. + // Add all relevant --android-jar-pattern patterns for Metalava. + // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines + // an actual file present on disk (in the order the patterns were passed). For system APIs for + // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs + // for older releases. Similarly, module-lib falls back to system API. + var sdkDirs []string + apiLevelsSdkType := proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") + switch apiLevelsSdkType { + case "system-server": + sdkDirs = []string{"system-server", "module-lib", "system", "public"} + case "module-lib": + sdkDirs = []string{"module-lib", "system", "public"} + case "system": + sdkDirs = []string{"system", "public"} + case "public": + sdkDirs = []string{"public"} + default: + ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes) + return + } + + // Construct a pattern to match the appropriate extensions that should be included in the + // generated api-versions.xml file. + // + // Use the first item in the sdkDirs array as that is the sdk type for the target API levels + // being generated but has the advantage over `Api_levels_sdk_type` as it has been validated. + // The exception is for system-server which needs to include module-lib and system-server. That + // is because while system-server extends module-lib the system-server extension directory only + // contains service-* modules which provide system-server APIs it does not list the modules which + // only provide a module-lib, so they have to be included separately. + extensionSurfacesPattern := sdkDirs[0] + if apiLevelsSdkType == "system-server" { + // Take the first two items in sdkDirs, which are system-server and module-lib, and construct + // a pattern that will match either. + extensionSurfacesPattern = strings.Join(sdkDirs[0:2], "|") + } + extensionsPattern := fmt.Sprintf(`/extensions/[0-9]+/(%s)/.*\.jar`, extensionSurfacesPattern) + var dirs []string var extensions_dir string ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) { if t, ok := m.(*ExportedDroiddocDir); ok { - extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`) + extRegex := regexp.MustCompile(t.dir.String() + extensionsPattern) // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps; // ideally this should be read from prebuiltApis.properties.Extensions_* for _, dep := range t.deps { + // Check to see if it matches an extension first. + depBase := dep.Base() if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil { if extensions_dir == "" { extensions_dir = t.dir.String() + "/extensions" } cmd.Implicit(dep) - } - if dep.Base() == filename { + } else if depBase == filename { + // Check to see if it matches a dessert release for an SDK, e.g. Android, Car, Wear, etc.. cmd.Implicit(dep) - } - if filename != "android.jar" && dep.Base() == "android.jar" { + } else if depBase == AndroidPlusUpdatableJar && d.properties.Extensions_info_file != nil { + // The output api-versions.xml has been requested to include information on SDK + // extensions. That means it also needs to include + // so + // The module-lib and system-server directories should use `android-plus-updatable.jar` + // instead of `android.jar`. See AndroidPlusUpdatableJar for more information. + cmd.Implicit(dep) + } else if filename != "android.jar" && depBase == "android.jar" { // Metalava implicitly searches these patterns: // prebuilts/tools/common/api-versions/android-%/android.jar // prebuilts/sdk/%/public/android.jar @@ -650,29 +702,25 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an } }) - // Add all relevant --android-jar-pattern patterns for Metalava. - // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines - // an actual file present on disk (in the order the patterns were passed). For system APIs for - // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs - // for older releases. Similarly, module-lib falls back to system API. - var sdkDirs []string - switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") { - case "system-server": - sdkDirs = []string{"system-server", "module-lib", "system", "public"} - case "module-lib": - sdkDirs = []string{"module-lib", "system", "public"} - case "system": - sdkDirs = []string{"system", "public"} - case "public": - sdkDirs = []string{"public"} - default: - ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes) - return - } - + // Generate the list of --android-jar-pattern options. The order matters so the first one which + // matches will be the one that is used for a specific api level.. for _, sdkDir := range sdkDirs { for _, dir := range dirs { - cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename)) + addPattern := func(jarFilename string) { + cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, jarFilename)) + } + + if sdkDir == "module-lib" || sdkDir == "system-server" { + // The module-lib and system-server android.jars do not include the updatable modules (as + // doing so in the source would introduce dependency cycles and the prebuilts have to + // match the sources). So, instead an additional `android-plus-updatable.jar` will be used + // that does include the updatable modules and this pattern will match that. This pattern + // is added in addition to the following pattern to decouple this change from the change + // to add the `android-plus-updatable.jar`. + addPattern(AndroidPlusUpdatableJar) + } + + addPattern(filename) } } @@ -692,11 +740,11 @@ func (d *Droidstubs) apiCompatibilityFlags(ctx android.ModuleContext, cmd *andro ctx.PropertyErrorf("out", "out property may not be combined with check_api") } - apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file)) - removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file)) + apiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Api_file)}) + removedApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Removed_api_file)}) - cmd.FlagWithInput("--check-compatibility:api:released ", apiFile) - cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile) + cmd.FlagForEachInput("--check-compatibility:api:released ", apiFiles) + cmd.FlagForEachInput("--check-compatibility:removed:released ", removedApiFiles) baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file) if baselineFile.Valid() { @@ -708,8 +756,8 @@ func metalavaUseRbe(ctx android.ModuleContext) bool { return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA") } -func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths, - srcJarList android.Path, bootclasspath, classpath classpath, homeDir android.WritablePath) *android.RuleBuilderCommand { +func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths, + srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams) *android.RuleBuilderCommand { rule.Command().Text("rm -rf").Flag(homeDir.String()) rule.Command().Text("mkdir -p").Flag(homeDir.String()) @@ -739,14 +787,14 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")). Flag(config.JavacVmFlags). Flag(config.MetalavaAddOpens). - FlagWithArg("--java-source ", javaVersion.String()). - FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs). + FlagWithArg("--java-source ", params.javaVersion.String()). + FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, fmt.Sprintf("%s.metalava.rsp", params.stubsType.String())), srcs). FlagWithInput("@", srcJarList) // Metalava does not differentiate between bootclasspath and classpath and has not done so for // years, so it is unlikely to change any time soon. - combinedPaths := append(([]android.Path)(nil), bootclasspath.Paths()...) - combinedPaths = append(combinedPaths, classpath.Paths()...) + combinedPaths := append(([]android.Path)(nil), params.deps.bootClasspath.Paths()...) + combinedPaths = append(combinedPaths, params.deps.classpath.Paths()...) if len(combinedPaths) > 0 { cmd.FlagWithInputList("--classpath ", combinedPaths, ":") } @@ -827,8 +875,7 @@ func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *andr srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars) homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home") - cmd := metalavaCmd(ctx, rule, params.stubConfig.javaVersion, d.Javadoc.srcFiles, srcJarList, - params.stubConfig.deps.bootClasspath, params.stubConfig.deps.classpath, homeDir) + cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig) cmd.Implicits(d.Javadoc.implicits) d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi) @@ -950,12 +997,12 @@ func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *andro // Add API lint options. if doApiLint { - newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since) - if newSince.Valid() { - cmd.FlagWithInput("--api-lint ", newSince.Path()) - } else { - cmd.Flag("--api-lint") + var newSince android.Paths + if d.properties.Check_api.Api_lint.New_since != nil { + newSince = android.PathsForModuleSrc(ctx, []string{proptools.String(d.properties.Check_api.Api_lint.New_since)}) } + cmd.Flag("--api-lint") + cmd.FlagForEachInput("--api-lint-previous-api ", newSince) d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt") cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint" @@ -1323,7 +1370,7 @@ func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) { // use a strict naming convention var ( droidstubsModuleNamingToSdkKind = map[string]android.SdkKind{ - //public is commented out since the core libraries use public in their java_sdk_library names + // public is commented out since the core libraries use public in their java_sdk_library names "intracore": android.SdkIntraCore, "intra.core": android.SdkIntraCore, "system_server": android.SdkSystemServer, |