blob: d9efb408f72700ad3b4ced3d1adf3b9fed1fd5ef [file] [log] [blame]
Colin Cross2207f872021-03-24 12:39:08 -07001// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
18 "fmt"
Anton Hansson86758ac2021-11-03 14:44:12 +000019 "path/filepath"
Mårten Kongstad802ae0f2022-07-27 13:47:32 +020020 "regexp"
Colin Cross2207f872021-03-24 12:39:08 -070021 "strings"
22
23 "github.com/google/blueprint/proptools"
24
25 "android/soong/android"
26 "android/soong/java/config"
27 "android/soong/remoteexec"
28)
29
Pedro Loureirocc203502021-10-04 17:24:00 +000030// The values allowed for Droidstubs' Api_levels_sdk_type
31var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib"}
32
Colin Cross2207f872021-03-24 12:39:08 -070033func init() {
34 RegisterStubsBuildComponents(android.InitRegistrationContext)
35}
36
37func RegisterStubsBuildComponents(ctx android.RegistrationContext) {
38 ctx.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
39
40 ctx.RegisterModuleType("droidstubs", DroidstubsFactory)
41 ctx.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
42
43 ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
44}
45
Colin Cross2207f872021-03-24 12:39:08 -070046// Droidstubs
Colin Cross2207f872021-03-24 12:39:08 -070047type Droidstubs struct {
48 Javadoc
49 android.SdkBase
50
51 properties DroidstubsProperties
Paul Duffinc71d2b72022-08-16 15:24:01 +000052 apiFile android.Path
53 removedApiFile android.Path
Colin Cross2207f872021-03-24 12:39:08 -070054 nullabilityWarningsFile android.WritablePath
55
56 checkCurrentApiTimestamp android.WritablePath
57 updateCurrentApiTimestamp android.WritablePath
58 checkLastReleasedApiTimestamp android.WritablePath
59 apiLintTimestamp android.WritablePath
60 apiLintReport android.WritablePath
61
62 checkNullabilityWarningsTimestamp android.WritablePath
63
64 annotationsZip android.WritablePath
65 apiVersionsXml android.WritablePath
66
Colin Cross2207f872021-03-24 12:39:08 -070067 metadataZip android.WritablePath
68 metadataDir android.WritablePath
69}
70
71type DroidstubsProperties struct {
72 // The generated public API filename by Metalava, defaults to <module>_api.txt
73 Api_filename *string
74
75 // the generated removed API filename by Metalava, defaults to <module>_removed.txt
76 Removed_api_filename *string
77
Colin Cross2207f872021-03-24 12:39:08 -070078 Check_api struct {
79 Last_released ApiToCheck
80
81 Current ApiToCheck
82
83 Api_lint struct {
84 Enabled *bool
85
86 // If set, performs api_lint on any new APIs not found in the given signature file
87 New_since *string `android:"path"`
88
89 // If not blank, path to the baseline txt file for approved API lint violations.
90 Baseline_file *string `android:"path"`
91 }
92 }
93
94 // user can specify the version of previous released API file in order to do compatibility check.
95 Previous_api *string `android:"path"`
96
97 // is set to true, Metalava will allow framework SDK to contain annotations.
98 Annotations_enabled *bool
99
100 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
101 Merge_annotations_dirs []string
102
103 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
104 Merge_inclusion_annotations_dirs []string
105
106 // a file containing a list of classes to do nullability validation for.
107 Validate_nullability_from_list *string
108
109 // a file containing expected warnings produced by validation of nullability annotations.
110 Check_nullability_warnings *string
111
112 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
113 Create_doc_stubs *bool
114
115 // if set to true, cause Metalava to output Javadoc comments in the stubs source files. Defaults to false.
116 // Has no effect if create_doc_stubs: true.
117 Output_javadoc_comments *bool
118
119 // if set to false then do not write out stubs. Defaults to true.
120 //
121 // TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately.
122 Generate_stubs *bool
123
124 // if set to true, provides a hint to the build system that this rule uses a lot of memory,
125 // whicih can be used for scheduling purposes
126 High_mem *bool
127
satayev783195c2021-06-23 21:49:57 +0100128 // if set to true, Metalava will allow framework SDK to contain API levels annotations.
Colin Cross2207f872021-03-24 12:39:08 -0700129 Api_levels_annotations_enabled *bool
130
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000131 // Apply the api levels database created by this module rather than generating one in this droidstubs.
132 Api_levels_module *string
133
Colin Cross2207f872021-03-24 12:39:08 -0700134 // the dirs which Metalava extracts API levels annotations from.
135 Api_levels_annotations_dirs []string
136
Pedro Loureirocc203502021-10-04 17:24:00 +0000137 // the sdk kind which Metalava extracts API levels annotations from. Supports 'public', 'system' and 'module-lib' for now; defaults to public.
satayev783195c2021-06-23 21:49:57 +0100138 Api_levels_sdk_type *string
139
Colin Cross2207f872021-03-24 12:39:08 -0700140 // the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
141 Api_levels_jar_filename *string
142
143 // if set to true, collect the values used by the Dev tools and
144 // write them in files packaged with the SDK. Defaults to false.
145 Write_sdk_values *bool
Mårten Kongstad802ae0f2022-07-27 13:47:32 +0200146
147 // path or filegroup to file defining extension an SDK name <-> numerical ID mapping and
148 // what APIs exist in which SDKs; passed to metalava via --sdk-extensions-info
149 Extensions_info_file *string `android:"path"`
Colin Cross2207f872021-03-24 12:39:08 -0700150}
151
Anton Hansson52609322021-05-05 10:36:05 +0100152// Used by xsd_config
153type ApiFilePath interface {
154 ApiFilePath() android.Path
155}
156
157type ApiStubsSrcProvider interface {
158 StubsSrcJar() android.Path
159}
160
161// Provider of information about API stubs, used by java_sdk_library.
162type ApiStubsProvider interface {
Anton Hanssond78eb762021-09-21 15:25:12 +0100163 AnnotationsZip() android.Path
Anton Hansson52609322021-05-05 10:36:05 +0100164 ApiFilePath
165 RemovedApiFilePath() android.Path
166
167 ApiStubsSrcProvider
168}
169
Colin Cross2207f872021-03-24 12:39:08 -0700170// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
171// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
172// a droiddoc module to generate documentation.
173func DroidstubsFactory() android.Module {
174 module := &Droidstubs{}
175
176 module.AddProperties(&module.properties,
177 &module.Javadoc.properties)
178
179 InitDroiddocModule(module, android.HostAndDeviceSupported)
180 android.InitSdkAwareModule(module)
181 return module
182}
183
184// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
185// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
186// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
187// module when symbols needed by the source files are provided by java_library_host modules.
188func DroidstubsHostFactory() android.Module {
189 module := &Droidstubs{}
190
191 module.AddProperties(&module.properties,
192 &module.Javadoc.properties)
193
194 InitDroiddocModule(module, android.HostSupported)
195 return module
196}
197
198func (d *Droidstubs) OutputFiles(tag string) (android.Paths, error) {
199 switch tag {
200 case "":
201 return android.Paths{d.stubsSrcJar}, nil
202 case ".docs.zip":
203 return android.Paths{d.docZip}, nil
204 case ".api.txt", android.DefaultDistTag:
205 // This is the default dist path for dist properties that have no tag property.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000206 return android.Paths{d.apiFile}, nil
Colin Cross2207f872021-03-24 12:39:08 -0700207 case ".removed-api.txt":
Paul Duffinc71d2b72022-08-16 15:24:01 +0000208 return android.Paths{d.removedApiFile}, nil
Colin Cross2207f872021-03-24 12:39:08 -0700209 case ".annotations.zip":
210 return android.Paths{d.annotationsZip}, nil
211 case ".api_versions.xml":
212 return android.Paths{d.apiVersionsXml}, nil
213 default:
214 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
215 }
216}
217
Anton Hanssond78eb762021-09-21 15:25:12 +0100218func (d *Droidstubs) AnnotationsZip() android.Path {
219 return d.annotationsZip
220}
221
Colin Cross2207f872021-03-24 12:39:08 -0700222func (d *Droidstubs) ApiFilePath() android.Path {
Paul Duffinc71d2b72022-08-16 15:24:01 +0000223 return d.apiFile
Colin Cross2207f872021-03-24 12:39:08 -0700224}
225
226func (d *Droidstubs) RemovedApiFilePath() android.Path {
Paul Duffinc71d2b72022-08-16 15:24:01 +0000227 return d.removedApiFile
Colin Cross2207f872021-03-24 12:39:08 -0700228}
229
230func (d *Droidstubs) StubsSrcJar() android.Path {
231 return d.stubsSrcJar
232}
233
234var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
235var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
236var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000237var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"}
Colin Cross2207f872021-03-24 12:39:08 -0700238
239func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
240 d.Javadoc.addDeps(ctx)
241
242 if len(d.properties.Merge_annotations_dirs) != 0 {
243 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
244 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
245 }
246 }
247
248 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
249 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
250 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
251 }
252 }
253
254 if len(d.properties.Api_levels_annotations_dirs) != 0 {
255 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
256 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
257 }
258 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000259
260 if d.properties.Api_levels_module != nil {
261 ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
262 }
Colin Cross2207f872021-03-24 12:39:08 -0700263}
264
265func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) {
266 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
267 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
268 String(d.properties.Api_filename) != "" {
269 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
Paul Duffinc71d2b72022-08-16 15:24:01 +0000270 uncheckedApiFile := android.PathForModuleOut(ctx, "metalava", filename)
271 cmd.FlagWithOutput("--api ", uncheckedApiFile)
272 d.apiFile = uncheckedApiFile
Colin Cross2207f872021-03-24 12:39:08 -0700273 } else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
274 // If check api is disabled then make the source file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000275 d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700276 }
277
278 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
279 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
280 String(d.properties.Removed_api_filename) != "" {
281 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
Paul Duffinc71d2b72022-08-16 15:24:01 +0000282 uncheckedRemovedFile := android.PathForModuleOut(ctx, "metalava", filename)
283 cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
284 d.removedApiFile = uncheckedRemovedFile
Colin Cross2207f872021-03-24 12:39:08 -0700285 } else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
286 // If check api is disabled then make the source removed api file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000287 d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700288 }
289
Colin Cross2207f872021-03-24 12:39:08 -0700290 if Bool(d.properties.Write_sdk_values) {
Colin Crosscb77f752021-03-24 12:04:44 -0700291 d.metadataDir = android.PathForModuleOut(ctx, "metalava", "metadata")
Colin Cross2207f872021-03-24 12:39:08 -0700292 cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
293 }
294
295 if stubsDir.Valid() {
296 if Bool(d.properties.Create_doc_stubs) {
297 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
298 } else {
299 cmd.FlagWithArg("--stubs ", stubsDir.String())
300 if !Bool(d.properties.Output_javadoc_comments) {
301 cmd.Flag("--exclude-documentation-from-stubs")
302 }
303 }
304 }
305}
306
307func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
308 if Bool(d.properties.Annotations_enabled) {
309 cmd.Flag("--include-annotations")
310
Andrei Onea4985e512021-04-29 16:29:34 +0100311 cmd.FlagWithArg("--exclude-annotation ", "androidx.annotation.RequiresApi")
312
Colin Cross2207f872021-03-24 12:39:08 -0700313 validatingNullability :=
Colin Crossbc139922021-03-25 18:33:16 -0700314 strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
Colin Cross2207f872021-03-24 12:39:08 -0700315 String(d.properties.Validate_nullability_from_list) != ""
316
317 migratingNullability := String(d.properties.Previous_api) != ""
318 if migratingNullability {
319 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
320 cmd.FlagWithInput("--migrate-nullness ", previousApi)
321 }
322
323 if s := String(d.properties.Validate_nullability_from_list); s != "" {
324 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
325 }
326
327 if validatingNullability {
Colin Crosscb77f752021-03-24 12:04:44 -0700328 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700329 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
330 }
331
Colin Crosscb77f752021-03-24 12:04:44 -0700332 d.annotationsZip = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"_annotations.zip")
Colin Cross2207f872021-03-24 12:39:08 -0700333 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
334
335 if len(d.properties.Merge_annotations_dirs) != 0 {
336 d.mergeAnnoDirFlags(ctx, cmd)
337 }
338
339 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
340 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
341 FlagWithArg("--hide ", "SuperfluousPrefix").
Sam Gilbert049af112022-03-04 16:03:53 -0500342 FlagWithArg("--hide ", "AnnotationExtraction").
343 // b/222738070
Sam Gilbert675f0b42022-03-08 11:24:44 -0500344 FlagWithArg("--hide ", "BannedThrow").
345 // b/223382732
346 FlagWithArg("--hide ", "ChangedDefault")
Colin Cross2207f872021-03-24 12:39:08 -0700347 }
348}
349
350func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
351 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
352 if t, ok := m.(*ExportedDroiddocDir); ok {
353 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
354 } else {
355 ctx.PropertyErrorf("merge_annotations_dirs",
356 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
357 }
358 })
359}
360
361func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
362 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
363 if t, ok := m.(*ExportedDroiddocDir); ok {
364 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
365 } else {
366 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
367 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
368 }
369 })
370}
371
372func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000373 var apiVersions android.Path
374 if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
375 d.apiLevelsGenerationFlags(ctx, cmd)
376 apiVersions = d.apiVersionsXml
377 } else {
378 ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
379 if s, ok := m.(*Droidstubs); ok {
380 apiVersions = s.apiVersionsXml
381 } else {
382 ctx.PropertyErrorf("api_levels_module",
383 "module %q is not a droidstubs module", ctx.OtherModuleName(m))
384 }
385 })
Colin Cross2207f872021-03-24 12:39:08 -0700386 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000387 if apiVersions != nil {
388 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
389 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
390 cmd.FlagWithInput("--apply-api-levels ", apiVersions)
391 }
392}
Colin Cross2207f872021-03-24 12:39:08 -0700393
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000394func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Colin Cross2207f872021-03-24 12:39:08 -0700395 if len(d.properties.Api_levels_annotations_dirs) == 0 {
396 ctx.PropertyErrorf("api_levels_annotations_dirs",
397 "has to be non-empty if api levels annotations was enabled!")
398 }
399
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000400 d.apiVersionsXml = android.PathForModuleOut(ctx, "metalava", "api-versions.xml")
Colin Cross2207f872021-03-24 12:39:08 -0700401 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700402
403 filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
404
satayev783195c2021-06-23 21:49:57 +0100405 var dirs []string
Mårten Kongstad802ae0f2022-07-27 13:47:32 +0200406 var extensions_dir string
Colin Cross2207f872021-03-24 12:39:08 -0700407 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
408 if t, ok := m.(*ExportedDroiddocDir); ok {
Mårten Kongstad802ae0f2022-07-27 13:47:32 +0200409 extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
410
411 // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
412 // ideally this should be read from prebuiltApis.properties.Extensions_*
Colin Cross2207f872021-03-24 12:39:08 -0700413 for _, dep := range t.deps {
Mårten Kongstad802ae0f2022-07-27 13:47:32 +0200414 if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
415 if extensions_dir == "" {
416 extensions_dir = t.dir.String() + "/extensions"
417 }
418 cmd.Implicit(dep)
419 }
Colin Cross5f6ffc72021-03-29 21:54:45 -0700420 if dep.Base() == filename {
421 cmd.Implicit(dep)
422 }
423 if filename != "android.jar" && dep.Base() == "android.jar" {
424 // Metalava implicitly searches these patterns:
425 // prebuilts/tools/common/api-versions/android-%/android.jar
426 // prebuilts/sdk/%/public/android.jar
427 // Add android.jar files from the api_levels_annotations_dirs directories to try
428 // to satisfy these patterns. If Metalava can't find a match for an API level
429 // between 1 and 28 in at least one pattern it will fail.
Colin Cross2207f872021-03-24 12:39:08 -0700430 cmd.Implicit(dep)
431 }
432 }
satayev783195c2021-06-23 21:49:57 +0100433
434 dirs = append(dirs, t.dir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700435 } else {
436 ctx.PropertyErrorf("api_levels_annotations_dirs",
437 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
438 }
439 })
satayev783195c2021-06-23 21:49:57 +0100440
441 // Add all relevant --android-jar-pattern patterns for Metalava.
442 // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
443 // an actual file present on disk (in the order the patterns were passed). For system APIs for
444 // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
Pedro Loureirocc203502021-10-04 17:24:00 +0000445 // for older releases. Similarly, module-lib falls back to system API.
446 var sdkDirs []string
447 switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
448 case "module-lib":
449 sdkDirs = []string{"module-lib", "system", "public"}
450 case "system":
451 sdkDirs = []string{"system", "public"}
452 case "public":
453 sdkDirs = []string{"public"}
454 default:
455 ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
456 return
satayev783195c2021-06-23 21:49:57 +0100457 }
Pedro Loureirocc203502021-10-04 17:24:00 +0000458
459 for _, sdkDir := range sdkDirs {
460 for _, dir := range dirs {
461 cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
462 }
satayev783195c2021-06-23 21:49:57 +0100463 }
Mårten Kongstad802ae0f2022-07-27 13:47:32 +0200464
465 if d.properties.Extensions_info_file != nil {
466 if extensions_dir == "" {
467 ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
468 }
469 info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
470 cmd.Implicit(info_file)
471 cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
472 cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
473 }
Colin Cross2207f872021-03-24 12:39:08 -0700474}
475
Colin Crosse52c2ac2022-03-28 17:03:35 -0700476func metalavaUseRbe(ctx android.ModuleContext) bool {
477 return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
478}
479
Colin Cross2207f872021-03-24 12:39:08 -0700480func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Anton Hansson556e8142021-06-04 16:20:25 +0100481 srcJarList android.Path, bootclasspath, classpath classpath, homeDir android.WritablePath) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700482 rule.Command().Text("rm -rf").Flag(homeDir.String())
483 rule.Command().Text("mkdir -p").Flag(homeDir.String())
484
Anton Hansson556e8142021-06-04 16:20:25 +0100485 cmd := rule.Command()
Colin Cross2207f872021-03-24 12:39:08 -0700486 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())
487
Colin Crosse52c2ac2022-03-28 17:03:35 -0700488 if metalavaUseRbe(ctx) {
Colin Cross2207f872021-03-24 12:39:08 -0700489 rule.Remoteable(android.RemoteRuleSupports{RBE: true})
Colin Cross8095c292021-03-30 16:40:48 -0700490 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
491 labels := map[string]string{"type": "tool", "name": "metalava"}
492 // TODO: metalava pool rejects these jobs
493 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
494 rule.Rewrapper(&remoteexec.REParams{
495 Labels: labels,
496 ExecStrategy: execStrategy,
497 ToolchainInputs: []string{config.JavaCmd(ctx).String()},
498 Platform: map[string]string{remoteexec.PoolKey: pool},
499 })
Colin Cross2207f872021-03-24 12:39:08 -0700500 }
501
Colin Cross6aa5c402021-03-24 12:28:50 -0700502 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
Colin Cross2207f872021-03-24 12:39:08 -0700503 Flag(config.JavacVmFlags).
504 Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED").
505 FlagWithArg("-encoding ", "UTF-8").
506 FlagWithArg("-source ", javaVersion.String()).
507 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
508 FlagWithInput("@", srcJarList)
509
Colin Cross2207f872021-03-24 12:39:08 -0700510 if len(bootclasspath) > 0 {
511 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
512 }
513
514 if len(classpath) > 0 {
515 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
516 }
517
Colin Cross2207f872021-03-24 12:39:08 -0700518 cmd.Flag("--no-banner").
519 Flag("--color").
520 Flag("--quiet").
521 Flag("--format=v2").
522 FlagWithArg("--repeat-errors-max ", "10").
Sam Gilbert09cb5db2021-10-06 11:28:28 -0400523 FlagWithArg("--hide ", "UnresolvedImport").
Ember Rose7c57af32022-04-01 10:34:44 -0400524 FlagWithArg("--hide ", "InvalidNullabilityOverride").
Sam Gilbert28e41282022-03-09 15:24:48 +0000525 // b/223382732
526 FlagWithArg("--hide ", "ChangedDefault")
Colin Cross2207f872021-03-24 12:39:08 -0700527
528 return cmd
529}
530
531func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
532 deps := d.Javadoc.collectDeps(ctx)
533
Jiyong Parkf1691d22021-03-29 20:11:58 +0900534 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
Colin Cross2207f872021-03-24 12:39:08 -0700535
536 // Create rule for metalava
537
Colin Crosscb77f752021-03-24 12:04:44 -0700538 srcJarDir := android.PathForModuleOut(ctx, "metalava", "srcjars")
Colin Cross2207f872021-03-24 12:39:08 -0700539
540 rule := android.NewRuleBuilder(pctx, ctx)
541
Colin Cross8095c292021-03-30 16:40:48 -0700542 rule.Sbox(android.PathForModuleOut(ctx, "metalava"),
543 android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
544 SandboxInputs()
Colin Cross6aa5c402021-03-24 12:28:50 -0700545
Colin Cross2207f872021-03-24 12:39:08 -0700546 if BoolDefault(d.properties.High_mem, false) {
547 // This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
548 rule.HighMem()
549 }
550
551 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
552 var stubsDir android.OptionalPath
553 if generateStubs {
Colin Crosscb77f752021-03-24 12:04:44 -0700554 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")
555 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, "metalava", "stubsDir"))
Colin Cross2207f872021-03-24 12:39:08 -0700556 rule.Command().Text("rm -rf").Text(stubsDir.String())
557 rule.Command().Text("mkdir -p").Text(stubsDir.String())
558 }
559
560 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
561
Colin Crosscb77f752021-03-24 12:04:44 -0700562 homeDir := android.PathForModuleOut(ctx, "metalava", "home")
Colin Cross2207f872021-03-24 12:39:08 -0700563 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
Anton Hansson556e8142021-06-04 16:20:25 +0100564 deps.bootClasspath, deps.classpath, homeDir)
Colin Cross2207f872021-03-24 12:39:08 -0700565 cmd.Implicits(d.Javadoc.implicits)
566
567 d.stubsFlags(ctx, cmd, stubsDir)
568
569 d.annotationsFlags(ctx, cmd)
570 d.inclusionAnnotationsFlags(ctx, cmd)
571 d.apiLevelsAnnotationsFlags(ctx, cmd)
572
Colin Crossbc139922021-03-25 18:33:16 -0700573 d.expandArgs(ctx, cmd)
Colin Cross2207f872021-03-24 12:39:08 -0700574
Colin Cross2207f872021-03-24 12:39:08 -0700575 for _, o := range d.Javadoc.properties.Out {
576 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
577 }
578
579 // Add options for the other optional tasks: API-lint and check-released.
580 // We generate separate timestamp files for them.
581
582 doApiLint := false
583 doCheckReleased := false
584
585 // Add API lint options.
586
587 if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) {
588 doApiLint = true
589
590 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
591 if newSince.Valid() {
592 cmd.FlagWithInput("--api-lint ", newSince.Path())
593 } else {
594 cmd.Flag("--api-lint")
595 }
Colin Crosscb77f752021-03-24 12:04:44 -0700596 d.apiLintReport = android.PathForModuleOut(ctx, "metalava", "api_lint_report.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700597 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
598
Colin Cross0d532412021-03-25 09:38:45 -0700599 // TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
Colin Cross2207f872021-03-24 12:39:08 -0700600 if d.Name() != "android.car-system-stubs-docs" &&
601 d.Name() != "android.car-stubs-docs" {
602 cmd.Flag("--lints-as-errors")
603 cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
604 }
605
606 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
Colin Crosscb77f752021-03-24 12:04:44 -0700607 updatedBaselineOutput := android.PathForModuleOut(ctx, "metalava", "api_lint_baseline.txt")
608 d.apiLintTimestamp = android.PathForModuleOut(ctx, "metalava", "api_lint.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700609
610 // Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
Colin Cross2207f872021-03-24 12:39:08 -0700611 //
612 // TODO: metalava also has a slightly different message hardcoded. Should we unify this
613 // message and metalava's one?
614 msg := `$'` + // Enclose with $' ... '
615 `************************************************************\n` +
616 `Your API changes are triggering API Lint warnings or errors.\n` +
617 `To make these errors go away, fix the code according to the\n` +
618 `error and/or warning messages above.\n` +
619 `\n` +
620 `If it is not possible to do so, there are workarounds:\n` +
621 `\n` +
Aurimas Liutikasb23b7452021-05-24 18:00:37 +0000622 `1. You can suppress the errors with @SuppressLint("<id>")\n` +
623 ` where the <id> is given in brackets in the error message above.\n`
Colin Cross2207f872021-03-24 12:39:08 -0700624
625 if baselineFile.Valid() {
626 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
627 cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)
628
629 msg += fmt.Sprintf(``+
630 `2. You can update the baseline by executing the following\n`+
631 ` command:\n`+
Colin Cross63eeda02021-04-15 19:01:57 -0700632 ` (cd $ANDROID_BUILD_TOP && cp \\\n`+
633 ` "%s" \\\n`+
634 ` "%s")\n`+
Colin Cross2207f872021-03-24 12:39:08 -0700635 ` To submit the revised baseline.txt to the main Android\n`+
636 ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
637 } else {
638 msg += fmt.Sprintf(``+
639 `2. You can add a baseline file of existing lint failures\n`+
640 ` to the build rule of %s.\n`, d.Name())
641 }
642 // Note the message ends with a ' (single quote), to close the $' ... ' .
643 msg += `************************************************************\n'`
644
645 cmd.FlagWithArg("--error-message:api-lint ", msg)
646 }
647
648 // Add "check released" options. (Detect incompatible API changes from the last public release)
649
650 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") {
651 doCheckReleased = true
652
653 if len(d.Javadoc.properties.Out) > 0 {
654 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
655 }
656
657 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
658 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
659 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
Colin Crosscb77f752021-03-24 12:04:44 -0700660 updatedBaselineOutput := android.PathForModuleOut(ctx, "metalava", "last_released_baseline.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700661
Colin Crosscb77f752021-03-24 12:04:44 -0700662 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "metalava", "check_last_released_api.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700663
664 cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
665 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
666
667 if baselineFile.Valid() {
668 cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
669 cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
670 }
671
672 // Note this string includes quote ($' ... '), which decodes the "\n"s.
673 msg := `$'\n******************************\n` +
674 `You have tried to change the API from what has been previously released in\n` +
675 `an SDK. Please fix the errors listed above.\n` +
676 `******************************\n'`
677
678 cmd.FlagWithArg("--error-message:compatibility:released ", msg)
679 }
680
Colin Cross2207f872021-03-24 12:39:08 -0700681 if generateStubs {
682 rule.Command().
683 BuiltTool("soong_zip").
684 Flag("-write_if_changed").
685 Flag("-jar").
686 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
687 FlagWithArg("-C ", stubsDir.String()).
688 FlagWithArg("-D ", stubsDir.String())
689 }
690
691 if Bool(d.properties.Write_sdk_values) {
Colin Crosscb77f752021-03-24 12:04:44 -0700692 d.metadataZip = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-metadata.zip")
Colin Cross2207f872021-03-24 12:39:08 -0700693 rule.Command().
694 BuiltTool("soong_zip").
695 Flag("-write_if_changed").
696 Flag("-d").
697 FlagWithOutput("-o ", d.metadataZip).
698 FlagWithArg("-C ", d.metadataDir.String()).
699 FlagWithArg("-D ", d.metadataDir.String())
700 }
701
702 // TODO: We don't really need two separate API files, but this is a reminiscence of how
703 // we used to run metalava separately for API lint and the "last_released" check. Unify them.
704 if doApiLint {
705 rule.Command().Text("touch").Output(d.apiLintTimestamp)
706 }
707 if doCheckReleased {
708 rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
709 }
710
Colin Cross6aa5c402021-03-24 12:28:50 -0700711 // TODO(b/183630617): rewrapper doesn't support restat rules
Colin Crosse52c2ac2022-03-28 17:03:35 -0700712 if !metalavaUseRbe(ctx) {
713 rule.Restat()
714 }
Colin Cross2207f872021-03-24 12:39:08 -0700715
716 zipSyncCleanupCmd(rule, srcJarDir)
717
Paul Duffinc166b682022-05-27 12:23:08 +0000718 rule.Build("metalava", "metalava merged")
719
Paul Duffine7a86642022-08-16 15:43:20 +0000720 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
721
722 if len(d.Javadoc.properties.Out) > 0 {
723 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
724 }
725
726 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
727 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
728 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
729
730 if baselineFile.Valid() {
731 ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
732 }
733
734 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "metalava", "check_current_api.timestamp")
735
736 rule := android.NewRuleBuilder(pctx, ctx)
737
738 // Diff command line.
739 // -F matches the closest "opening" line, such as "package android {"
740 // and " public class Intent {".
741 diff := `diff -u -F '{ *$'`
742
743 rule.Command().Text("( true")
744 rule.Command().
745 Text(diff).
746 Input(apiFile).Input(d.apiFile)
747
748 rule.Command().
749 Text(diff).
750 Input(removedApiFile).Input(d.removedApiFile)
751
752 msg := fmt.Sprintf(`\n******************************\n`+
753 `You have tried to change the API from what has been previously approved.\n\n`+
754 `To make these errors go away, you have two choices:\n`+
755 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
756 ` to the new methods, etc. shown in the above diff.\n\n`+
757 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
758 ` m %s-update-current-api\n\n`+
759 ` To submit the revised current.txt to the main Android repository,\n`+
760 ` you will need approval.\n`+
761 `******************************\n`, ctx.ModuleName())
762
763 rule.Command().
764 Text("touch").Output(d.checkCurrentApiTimestamp).
765 Text(") || (").
766 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
767 Text("; exit 38").
768 Text(")")
769
770 rule.Build("metalavaCurrentApiCheck", "check current API")
771
772 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "metalava", "update_current_api.timestamp")
773
774 // update API rule
775 rule = android.NewRuleBuilder(pctx, ctx)
776
777 rule.Command().Text("( true")
778
779 rule.Command().
780 Text("cp").Flag("-f").
781 Input(d.apiFile).Flag(apiFile.String())
782
783 rule.Command().
784 Text("cp").Flag("-f").
785 Input(d.removedApiFile).Flag(removedApiFile.String())
786
787 msg = "failed to update public API"
788
789 rule.Command().
790 Text("touch").Output(d.updateCurrentApiTimestamp).
791 Text(") || (").
792 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
793 Text("; exit 38").
794 Text(")")
795
796 rule.Build("metalavaCurrentApiUpdate", "update current API")
797 }
798
Colin Cross2207f872021-03-24 12:39:08 -0700799 if String(d.properties.Check_nullability_warnings) != "" {
800 if d.nullabilityWarningsFile == nil {
801 ctx.PropertyErrorf("check_nullability_warnings",
802 "Cannot specify check_nullability_warnings unless validating nullability")
803 }
804
805 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
806
Colin Crosscb77f752021-03-24 12:04:44 -0700807 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "metalava", "check_nullability_warnings.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700808
809 msg := fmt.Sprintf(`\n******************************\n`+
810 `The warnings encountered during nullability annotation validation did\n`+
811 `not match the checked in file of expected warnings. The diffs are shown\n`+
812 `above. You have two options:\n`+
813 ` 1. Resolve the differences by editing the nullability annotations.\n`+
814 ` 2. Update the file of expected warnings by running:\n`+
815 ` cp %s %s\n`+
816 ` and submitting the updated file as part of your change.`,
817 d.nullabilityWarningsFile, checkNullabilityWarnings)
818
819 rule := android.NewRuleBuilder(pctx, ctx)
820
821 rule.Command().
822 Text("(").
823 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
824 Text("&&").
825 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
826 Text(") || (").
827 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
828 Text("; exit 38").
829 Text(")")
830
831 rule.Build("nullabilityWarningsCheck", "nullability warnings check")
832 }
833}
834
835func StubsDefaultsFactory() android.Module {
836 module := &DocDefaults{}
837
838 module.AddProperties(
839 &JavadocProperties{},
840 &DroidstubsProperties{},
841 )
842
843 android.InitDefaultsModule(module)
844
845 return module
846}
847
848var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
849
850type PrebuiltStubsSourcesProperties struct {
851 Srcs []string `android:"path"`
852}
853
854type PrebuiltStubsSources struct {
855 android.ModuleBase
856 android.DefaultableModuleBase
857 prebuilt android.Prebuilt
858 android.SdkBase
859
860 properties PrebuiltStubsSourcesProperties
861
kgui67007242022-01-25 13:50:25 +0800862 stubsSrcJar android.Path
Colin Cross2207f872021-03-24 12:39:08 -0700863}
864
865func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
866 switch tag {
867 case "":
868 return android.Paths{p.stubsSrcJar}, nil
869 default:
870 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
871 }
872}
873
874func (d *PrebuiltStubsSources) StubsSrcJar() android.Path {
875 return d.stubsSrcJar
876}
877
878func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross2207f872021-03-24 12:39:08 -0700879 if len(p.properties.Srcs) != 1 {
Anton Hansson86758ac2021-11-03 14:44:12 +0000880 ctx.PropertyErrorf("srcs", "must only specify one directory path or srcjar, contains %d paths", len(p.properties.Srcs))
Colin Cross2207f872021-03-24 12:39:08 -0700881 return
882 }
883
Anton Hansson86758ac2021-11-03 14:44:12 +0000884 src := p.properties.Srcs[0]
885 if filepath.Ext(src) == ".srcjar" {
886 // This is a srcjar. We can use it directly.
887 p.stubsSrcJar = android.PathForModuleSrc(ctx, src)
888 } else {
889 outPath := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Colin Cross2207f872021-03-24 12:39:08 -0700890
Anton Hansson86758ac2021-11-03 14:44:12 +0000891 // This is a directory. Glob the contents just in case the directory does not exist.
892 srcGlob := src + "/**/*"
893 srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})
Colin Cross2207f872021-03-24 12:39:08 -0700894
Anton Hansson86758ac2021-11-03 14:44:12 +0000895 // Although PathForModuleSrc can return nil if either the path doesn't exist or
896 // the path components are invalid it won't in this case because no components
897 // are specified and the module directory must exist in order to get this far.
898 srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, src)
Colin Cross2207f872021-03-24 12:39:08 -0700899
Anton Hansson86758ac2021-11-03 14:44:12 +0000900 rule := android.NewRuleBuilder(pctx, ctx)
901 rule.Command().
902 BuiltTool("soong_zip").
903 Flag("-write_if_changed").
904 Flag("-jar").
905 FlagWithOutput("-o ", outPath).
906 FlagWithArg("-C ", srcDir.String()).
907 FlagWithRspFileInputList("-r ", outPath.ReplaceExtension(ctx, "rsp"), srcPaths)
908 rule.Restat()
909 rule.Build("zip src", "Create srcjar from prebuilt source")
910 p.stubsSrcJar = outPath
911 }
Colin Cross2207f872021-03-24 12:39:08 -0700912}
913
914func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
915 return &p.prebuilt
916}
917
918func (p *PrebuiltStubsSources) Name() string {
919 return p.prebuilt.Name(p.ModuleBase.Name())
920}
921
922// prebuilt_stubs_sources imports a set of java source files as if they were
923// generated by droidstubs.
924//
925// By default, a prebuilt_stubs_sources has a single variant that expects a
926// set of `.java` files generated by droidstubs.
927//
928// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
929// for host modules.
930//
931// Intended only for use by sdk snapshots.
932func PrebuiltStubsSourcesFactory() android.Module {
933 module := &PrebuiltStubsSources{}
934
935 module.AddProperties(&module.properties)
936
937 android.InitPrebuiltModule(module, &module.properties.Srcs)
938 android.InitSdkAwareModule(module)
939 InitDroiddocModule(module, android.HostAndDeviceSupported)
940 return module
941}