blob: 046026533b0b309d35cbb8135481e31edea9a5cd [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
Cole Faust051fa912022-10-05 12:45:42 -070031var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib", "system-server"}
Pedro Loureirocc203502021-10-04 17:24:00 +000032
Jihoon Kang6592e872023-12-19 01:13:16 +000033type StubsType int
34
35const (
36 Everything StubsType = iota
37 Runtime
38 Exportable
Jihoon Kang78f89142023-12-27 01:40:29 +000039 Unavailable
Jihoon Kang6592e872023-12-19 01:13:16 +000040)
41
42func (s StubsType) String() string {
43 switch s {
44 case Everything:
45 return "everything"
46 case Runtime:
47 return "runtime"
48 case Exportable:
49 return "exportable"
50 default:
51 return ""
52 }
53}
54
Colin Cross2207f872021-03-24 12:39:08 -070055func init() {
56 RegisterStubsBuildComponents(android.InitRegistrationContext)
57}
58
59func RegisterStubsBuildComponents(ctx android.RegistrationContext) {
60 ctx.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
61
62 ctx.RegisterModuleType("droidstubs", DroidstubsFactory)
63 ctx.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
64
65 ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
66}
67
Colin Cross2207f872021-03-24 12:39:08 -070068// Droidstubs
Colin Cross2207f872021-03-24 12:39:08 -070069type Droidstubs struct {
70 Javadoc
Spandan Das2cc80ba2023-10-27 17:21:52 +000071 embeddableInModuleAndImport
Colin Cross2207f872021-03-24 12:39:08 -070072
73 properties DroidstubsProperties
Paul Duffinc71d2b72022-08-16 15:24:01 +000074 apiFile android.Path
75 removedApiFile android.Path
Colin Cross2207f872021-03-24 12:39:08 -070076 nullabilityWarningsFile android.WritablePath
77
78 checkCurrentApiTimestamp android.WritablePath
79 updateCurrentApiTimestamp android.WritablePath
80 checkLastReleasedApiTimestamp android.WritablePath
81 apiLintTimestamp android.WritablePath
82 apiLintReport android.WritablePath
83
84 checkNullabilityWarningsTimestamp android.WritablePath
85
86 annotationsZip android.WritablePath
87 apiVersionsXml android.WritablePath
88
Colin Cross2207f872021-03-24 12:39:08 -070089 metadataZip android.WritablePath
90 metadataDir android.WritablePath
Jihoon Kang3c89f042023-12-19 02:40:22 +000091
LaMont Jonesafe7baf2024-01-09 22:47:39 +000092 // Single aconfig "cache file" merged from this module and all dependencies.
93 mergedAconfigFiles map[string]android.Paths
94
Jihoon Kang3c89f042023-12-19 02:40:22 +000095 exportableApiFile android.WritablePath
96 exportableRemovedApiFile android.WritablePath
97 exportableNullabilityWarningsFile android.WritablePath
98 exportableAnnotationsZip android.WritablePath
99 exportableApiVersionsXml android.WritablePath
100 exportableMetadataZip android.WritablePath
101 exportableMetadataDir android.WritablePath
Colin Cross2207f872021-03-24 12:39:08 -0700102}
103
104type DroidstubsProperties struct {
105 // The generated public API filename by Metalava, defaults to <module>_api.txt
106 Api_filename *string
107
108 // the generated removed API filename by Metalava, defaults to <module>_removed.txt
109 Removed_api_filename *string
110
Colin Cross2207f872021-03-24 12:39:08 -0700111 Check_api struct {
112 Last_released ApiToCheck
113
114 Current ApiToCheck
115
116 Api_lint struct {
117 Enabled *bool
118
119 // If set, performs api_lint on any new APIs not found in the given signature file
120 New_since *string `android:"path"`
121
122 // If not blank, path to the baseline txt file for approved API lint violations.
123 Baseline_file *string `android:"path"`
124 }
125 }
126
127 // user can specify the version of previous released API file in order to do compatibility check.
128 Previous_api *string `android:"path"`
129
130 // is set to true, Metalava will allow framework SDK to contain annotations.
131 Annotations_enabled *bool
132
133 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
134 Merge_annotations_dirs []string
135
136 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
137 Merge_inclusion_annotations_dirs []string
138
139 // a file containing a list of classes to do nullability validation for.
140 Validate_nullability_from_list *string
141
142 // a file containing expected warnings produced by validation of nullability annotations.
143 Check_nullability_warnings *string
144
145 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
146 Create_doc_stubs *bool
147
148 // if set to true, cause Metalava to output Javadoc comments in the stubs source files. Defaults to false.
149 // Has no effect if create_doc_stubs: true.
150 Output_javadoc_comments *bool
151
152 // if set to false then do not write out stubs. Defaults to true.
153 //
154 // TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately.
155 Generate_stubs *bool
156
157 // if set to true, provides a hint to the build system that this rule uses a lot of memory,
Liz Kammer170dd722023-10-16 15:08:39 -0400158 // which can be used for scheduling purposes
Colin Cross2207f872021-03-24 12:39:08 -0700159 High_mem *bool
160
satayev783195c2021-06-23 21:49:57 +0100161 // if set to true, Metalava will allow framework SDK to contain API levels annotations.
Colin Cross2207f872021-03-24 12:39:08 -0700162 Api_levels_annotations_enabled *bool
163
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000164 // Apply the api levels database created by this module rather than generating one in this droidstubs.
165 Api_levels_module *string
166
Colin Cross2207f872021-03-24 12:39:08 -0700167 // the dirs which Metalava extracts API levels annotations from.
168 Api_levels_annotations_dirs []string
169
Cole Faust051fa912022-10-05 12:45:42 -0700170 // the sdk kind which Metalava extracts API levels annotations from. Supports 'public', 'system', 'module-lib' and 'system-server'; defaults to public.
satayev783195c2021-06-23 21:49:57 +0100171 Api_levels_sdk_type *string
172
Colin Cross2207f872021-03-24 12:39:08 -0700173 // the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
174 Api_levels_jar_filename *string
175
176 // if set to true, collect the values used by the Dev tools and
177 // write them in files packaged with the SDK. Defaults to false.
178 Write_sdk_values *bool
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200179
180 // path or filegroup to file defining extension an SDK name <-> numerical ID mapping and
181 // what APIs exist in which SDKs; passed to metalava via --sdk-extensions-info
182 Extensions_info_file *string `android:"path"`
Jihoon Kang3198f3c2023-01-26 08:08:52 +0000183
184 // API surface of this module. If set, the module contributes to an API surface.
185 // For the full list of available API surfaces, refer to soong/android/sdk_version.go
186 Api_surface *string
Jihoon Kang6592e872023-12-19 01:13:16 +0000187
188 // a list of aconfig_declarations module names that the stubs generated in this module
189 // depend on.
190 Aconfig_declarations []string
Colin Cross2207f872021-03-24 12:39:08 -0700191}
192
Anton Hansson52609322021-05-05 10:36:05 +0100193// Used by xsd_config
194type ApiFilePath interface {
195 ApiFilePath() android.Path
196}
197
198type ApiStubsSrcProvider interface {
199 StubsSrcJar() android.Path
200}
201
Jihoon Kangf55a5f72024-01-08 08:56:20 +0000202type ExportableApiStubsSrcProvider interface {
203 ExportableStubsSrcJar() android.Path
204}
205
Anton Hansson52609322021-05-05 10:36:05 +0100206// Provider of information about API stubs, used by java_sdk_library.
207type ApiStubsProvider interface {
Anton Hanssond78eb762021-09-21 15:25:12 +0100208 AnnotationsZip() android.Path
Anton Hansson52609322021-05-05 10:36:05 +0100209 ApiFilePath
210 RemovedApiFilePath() android.Path
211
212 ApiStubsSrcProvider
213}
214
Jihoon Kangf55a5f72024-01-08 08:56:20 +0000215type ExportableApiStubsProvider interface {
216 ExportableAnnotationsZip() android.Path
217 ExportableApiFilePath() android.Path
218 ExportableRemovedApiFilePath() android.Path
219
220 ExportableApiStubsSrcProvider
221}
222
Jihoon Kang063ec002023-06-28 01:16:23 +0000223type currentApiTimestampProvider interface {
224 CurrentApiTimestamp() android.Path
225}
226
Jihoon Kang3c89f042023-12-19 02:40:22 +0000227type annotationFlagsParams struct {
228 migratingNullability bool
229 validatingNullability bool
230 nullabilityWarningsFile android.WritablePath
231 annotationsZip android.WritablePath
232}
233type stubsCommandParams struct {
234 srcJarDir android.ModuleOutPath
235 stubsDir android.OptionalPath
236 stubsSrcJar android.WritablePath
237 metadataZip android.WritablePath
238 metadataDir android.WritablePath
239 apiVersionsXml android.WritablePath
240 nullabilityWarningsFile android.WritablePath
241 annotationsZip android.WritablePath
242 stubConfig stubsCommandConfigParams
243}
244type stubsCommandConfigParams struct {
245 stubsType StubsType
246 javaVersion javaVersion
247 deps deps
248 checkApi bool
249 generateStubs bool
250 doApiLint bool
251 doCheckReleased bool
252 writeSdkValues bool
253 migratingNullability bool
254 validatingNullability bool
255}
256
Colin Cross2207f872021-03-24 12:39:08 -0700257// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
258// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
259// a droiddoc module to generate documentation.
260func DroidstubsFactory() android.Module {
261 module := &Droidstubs{}
262
263 module.AddProperties(&module.properties,
264 &module.Javadoc.properties)
Spandan Das2cc80ba2023-10-27 17:21:52 +0000265 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -0700266
267 InitDroiddocModule(module, android.HostAndDeviceSupported)
Jihoon Kang3198f3c2023-01-26 08:08:52 +0000268
269 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
270 module.createApiContribution(ctx)
271 })
Colin Cross2207f872021-03-24 12:39:08 -0700272 return module
273}
274
275// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
276// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
277// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
278// module when symbols needed by the source files are provided by java_library_host modules.
279func DroidstubsHostFactory() android.Module {
280 module := &Droidstubs{}
281
282 module.AddProperties(&module.properties,
283 &module.Javadoc.properties)
284
285 InitDroiddocModule(module, android.HostSupported)
286 return module
287}
288
Jihoon Kang78f89142023-12-27 01:40:29 +0000289func getStubsTypeAndTag(tag string) (StubsType, string, error) {
290 if len(tag) == 0 {
291 return Everything, "", nil
292 }
293 if tag[0] != '.' {
294 return Unavailable, "", fmt.Errorf("tag must begin with \".\"")
295 }
296
297 stubsType := Everything
298 // Check if the tag has a stubs type prefix (e.g. ".exportable")
299 for st := Everything; st <= Exportable; st++ {
300 if strings.HasPrefix(tag, "."+st.String()) {
301 stubsType = st
302 }
303 }
304
305 return stubsType, strings.TrimPrefix(tag, "."+stubsType.String()), nil
306}
307
308// Droidstubs' tag supports specifying with the stubs type.
309// While supporting the pre-existing tags, it also supports tags with
310// the stubs type prefix. Some examples are shown below:
311// {.annotations.zip} - pre-existing behavior. Returns the path to the
312// annotation zip.
313// {.exportable} - Returns the path to the exportable stubs src jar.
314// {.exportable.annotations.zip} - Returns the path to the exportable
315// annotations zip file.
316// {.runtime.api_versions.xml} - Runtime stubs does not generate api versions
317// xml file. For unsupported combinations, the default everything output file
318// is returned.
Colin Cross2207f872021-03-24 12:39:08 -0700319func (d *Droidstubs) OutputFiles(tag string) (android.Paths, error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000320 stubsType, prefixRemovedTag, err := getStubsTypeAndTag(tag)
321 if err != nil {
322 return nil, err
323 }
324 switch prefixRemovedTag {
Colin Cross2207f872021-03-24 12:39:08 -0700325 case "":
Jihoon Kang78f89142023-12-27 01:40:29 +0000326 return d.StubsSrcJarWithStubsType(stubsType)
Colin Cross2207f872021-03-24 12:39:08 -0700327 case ".docs.zip":
Jihoon Kang78f89142023-12-27 01:40:29 +0000328 return d.DocZipWithStubsType(stubsType)
Colin Cross2207f872021-03-24 12:39:08 -0700329 case ".api.txt", android.DefaultDistTag:
330 // This is the default dist path for dist properties that have no tag property.
Jihoon Kang78f89142023-12-27 01:40:29 +0000331 return d.ApiFilePathWithStubsType(stubsType)
Colin Cross2207f872021-03-24 12:39:08 -0700332 case ".removed-api.txt":
Jihoon Kang78f89142023-12-27 01:40:29 +0000333 return d.RemovedApiFilePathWithStubsType(stubsType)
Colin Cross2207f872021-03-24 12:39:08 -0700334 case ".annotations.zip":
Jihoon Kang78f89142023-12-27 01:40:29 +0000335 return d.AnnotationsZipWithStubsType(stubsType)
Colin Cross2207f872021-03-24 12:39:08 -0700336 case ".api_versions.xml":
Jihoon Kang78f89142023-12-27 01:40:29 +0000337 return d.ApiVersionsXmlFilePathWithStubsType(stubsType)
Colin Cross2207f872021-03-24 12:39:08 -0700338 default:
339 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
340 }
341}
342
Anton Hanssond78eb762021-09-21 15:25:12 +0100343func (d *Droidstubs) AnnotationsZip() android.Path {
344 return d.annotationsZip
345}
346
Jihoon Kang78f89142023-12-27 01:40:29 +0000347func (d *Droidstubs) ExportableAnnotationsZip() android.Path {
348 return d.exportableAnnotationsZip
349}
350
351func (d *Droidstubs) AnnotationsZipWithStubsType(stubsType StubsType) (android.Paths, error) {
352 switch stubsType {
353 case Everything:
354 return android.Paths{d.AnnotationsZip()}, nil
355 case Exportable:
356 return android.Paths{d.ExportableAnnotationsZip()}, nil
357 default:
358 return nil, fmt.Errorf("annotations zip not supported for the stub type %s", stubsType.String())
359 }
360}
361
Colin Cross2207f872021-03-24 12:39:08 -0700362func (d *Droidstubs) ApiFilePath() android.Path {
Paul Duffinc71d2b72022-08-16 15:24:01 +0000363 return d.apiFile
Colin Cross2207f872021-03-24 12:39:08 -0700364}
365
Jihoon Kang78f89142023-12-27 01:40:29 +0000366func (d *Droidstubs) ExportableApiFilePath() android.Path {
367 return d.exportableApiFile
368}
369
370func (d *Droidstubs) ApiFilePathWithStubsType(stubsType StubsType) (android.Paths, error) {
371 switch stubsType {
372 case Everything:
373 return android.Paths{d.ApiFilePath()}, nil
374 case Exportable:
375 return android.Paths{d.ExportableApiFilePath()}, nil
376 default:
377 return nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
378 }
379}
380
381func (d *Droidstubs) ApiVersionsXmlFilePathWithStubsType(stubsType StubsType) (android.Paths, error) {
382 switch stubsType {
383 case Everything:
384 return android.Paths{d.apiVersionsXml}, nil
385 default:
386 return nil, fmt.Errorf("api versions xml file path not supported for the stub type %s", stubsType.String())
387 }
388}
389
390func (d *Droidstubs) DocZipWithStubsType(stubsType StubsType) (android.Paths, error) {
391 switch stubsType {
392 case Everything:
393 return android.Paths{d.docZip}, nil
394 default:
395 return nil, fmt.Errorf("docs zip not supported for the stub type %s", stubsType.String())
396 }
397}
398
Colin Cross2207f872021-03-24 12:39:08 -0700399func (d *Droidstubs) RemovedApiFilePath() android.Path {
Paul Duffinc71d2b72022-08-16 15:24:01 +0000400 return d.removedApiFile
Colin Cross2207f872021-03-24 12:39:08 -0700401}
402
Jihoon Kang78f89142023-12-27 01:40:29 +0000403func (d *Droidstubs) ExportableRemovedApiFilePath() android.Path {
404 return d.exportableRemovedApiFile
405}
406
407func (d *Droidstubs) RemovedApiFilePathWithStubsType(stubsType StubsType) (android.Paths, error) {
408 switch stubsType {
409 case Everything:
410 return android.Paths{d.RemovedApiFilePath()}, nil
411 case Exportable:
412 return android.Paths{d.ExportableRemovedApiFilePath()}, nil
413 default:
414 return nil, fmt.Errorf("removed api file path not supported for the stub type %s", stubsType.String())
415 }
416}
417
Colin Cross2207f872021-03-24 12:39:08 -0700418func (d *Droidstubs) StubsSrcJar() android.Path {
419 return d.stubsSrcJar
420}
421
Jihoon Kang78f89142023-12-27 01:40:29 +0000422func (d *Droidstubs) ExportableStubsSrcJar() android.Path {
423 return d.exportableStubsSrcJar
424}
425
426func (d *Droidstubs) StubsSrcJarWithStubsType(stubsType StubsType) (android.Paths, error) {
427 switch stubsType {
428 case Everything:
429 return android.Paths{d.StubsSrcJar()}, nil
430 case Exportable:
431 return android.Paths{d.ExportableStubsSrcJar()}, nil
432 default:
433 return nil, fmt.Errorf("stubs srcjar not supported for the stub type %s", stubsType.String())
434 }
435}
436
Jihoon Kang063ec002023-06-28 01:16:23 +0000437func (d *Droidstubs) CurrentApiTimestamp() android.Path {
438 return d.checkCurrentApiTimestamp
439}
440
Colin Cross2207f872021-03-24 12:39:08 -0700441var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
442var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
443var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000444var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"}
Jihoon Kang063ec002023-06-28 01:16:23 +0000445var metalavaCurrentApiTimestampTag = dependencyTag{name: "metalava-current-api-timestamp-tag"}
Colin Cross2207f872021-03-24 12:39:08 -0700446
447func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
448 d.Javadoc.addDeps(ctx)
449
450 if len(d.properties.Merge_annotations_dirs) != 0 {
451 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
452 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
453 }
454 }
455
456 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
457 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
458 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
459 }
460 }
461
462 if len(d.properties.Api_levels_annotations_dirs) != 0 {
463 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
464 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
465 }
466 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000467
Jihoon Kang6592e872023-12-19 01:13:16 +0000468 if len(d.properties.Aconfig_declarations) != 0 {
469 for _, aconfigDeclarationModuleName := range d.properties.Aconfig_declarations {
470 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationModuleName)
471 }
472 }
473
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000474 if d.properties.Api_levels_module != nil {
475 ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
476 }
Colin Cross2207f872021-03-24 12:39:08 -0700477}
478
Jihoon Kang3c89f042023-12-19 02:40:22 +0000479func (d *Droidstubs) sdkValuesFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, metadataDir android.WritablePath) {
480 cmd.FlagWithArg("--sdk-values ", metadataDir.String())
481}
482
483func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath, stubsType StubsType, checkApi bool) {
484 if checkApi || String(d.properties.Api_filename) != "" {
Colin Cross2207f872021-03-24 12:39:08 -0700485 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000486 uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
Paul Duffinc71d2b72022-08-16 15:24:01 +0000487 cmd.FlagWithOutput("--api ", uncheckedApiFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000488
489 if stubsType == Everything {
490 d.apiFile = uncheckedApiFile
491 } else if stubsType == Exportable {
492 d.exportableApiFile = uncheckedApiFile
493 }
Colin Cross2207f872021-03-24 12:39:08 -0700494 } else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
495 // If check api is disabled then make the source file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000496 d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700497 }
498
Jihoon Kang3c89f042023-12-19 02:40:22 +0000499 if checkApi || String(d.properties.Removed_api_filename) != "" {
Colin Cross2207f872021-03-24 12:39:08 -0700500 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000501 uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
Paul Duffinc71d2b72022-08-16 15:24:01 +0000502 cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000503
504 if stubsType == Everything {
505 d.removedApiFile = uncheckedRemovedFile
506 } else if stubsType == Exportable {
507 d.exportableRemovedApiFile = uncheckedRemovedFile
508 }
Colin Cross2207f872021-03-24 12:39:08 -0700509 } else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
510 // If check api is disabled then make the source removed api file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000511 d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700512 }
513
Colin Cross2207f872021-03-24 12:39:08 -0700514 if stubsDir.Valid() {
515 if Bool(d.properties.Create_doc_stubs) {
516 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
517 } else {
518 cmd.FlagWithArg("--stubs ", stubsDir.String())
519 if !Bool(d.properties.Output_javadoc_comments) {
520 cmd.Flag("--exclude-documentation-from-stubs")
521 }
522 }
523 }
524}
525
Jihoon Kang3c89f042023-12-19 02:40:22 +0000526func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, params annotationFlagsParams) {
Colin Cross2207f872021-03-24 12:39:08 -0700527 if Bool(d.properties.Annotations_enabled) {
Liz Kammere09e20e2023-10-16 15:07:54 -0400528 cmd.Flag(config.MetalavaAnnotationsFlags)
Andrei Onea4985e512021-04-29 16:29:34 +0100529
Jihoon Kang3c89f042023-12-19 02:40:22 +0000530 if params.migratingNullability {
Colin Cross2207f872021-03-24 12:39:08 -0700531 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
532 cmd.FlagWithInput("--migrate-nullness ", previousApi)
533 }
534
535 if s := String(d.properties.Validate_nullability_from_list); s != "" {
536 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
537 }
538
Jihoon Kang3c89f042023-12-19 02:40:22 +0000539 if params.validatingNullability {
540 cmd.FlagWithOutput("--nullability-warnings-txt ", params.nullabilityWarningsFile)
Colin Cross2207f872021-03-24 12:39:08 -0700541 }
542
Jihoon Kang3c89f042023-12-19 02:40:22 +0000543 cmd.FlagWithOutput("--extract-annotations ", params.annotationsZip)
Colin Cross2207f872021-03-24 12:39:08 -0700544
545 if len(d.properties.Merge_annotations_dirs) != 0 {
546 d.mergeAnnoDirFlags(ctx, cmd)
547 }
548
Liz Kammere09e20e2023-10-16 15:07:54 -0400549 cmd.Flag(config.MetalavaAnnotationsWarningsFlags)
Colin Cross2207f872021-03-24 12:39:08 -0700550 }
551}
552
553func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
554 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
555 if t, ok := m.(*ExportedDroiddocDir); ok {
556 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
557 } else {
558 ctx.PropertyErrorf("merge_annotations_dirs",
559 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
560 }
561 })
562}
563
564func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
565 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
566 if t, ok := m.(*ExportedDroiddocDir); ok {
567 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
568 } else {
569 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
570 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
571 }
572 })
573}
574
Jihoon Kang3c89f042023-12-19 02:40:22 +0000575func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000576 var apiVersions android.Path
577 if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000578 d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000579 apiVersions = d.apiVersionsXml
580 } else {
581 ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
582 if s, ok := m.(*Droidstubs); ok {
583 apiVersions = s.apiVersionsXml
584 } else {
585 ctx.PropertyErrorf("api_levels_module",
586 "module %q is not a droidstubs module", ctx.OtherModuleName(m))
587 }
588 })
Colin Cross2207f872021-03-24 12:39:08 -0700589 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000590 if apiVersions != nil {
591 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
592 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
593 cmd.FlagWithInput("--apply-api-levels ", apiVersions)
594 }
595}
Colin Cross2207f872021-03-24 12:39:08 -0700596
Jihoon Kang3c89f042023-12-19 02:40:22 +0000597func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Colin Cross2207f872021-03-24 12:39:08 -0700598 if len(d.properties.Api_levels_annotations_dirs) == 0 {
599 ctx.PropertyErrorf("api_levels_annotations_dirs",
600 "has to be non-empty if api levels annotations was enabled!")
601 }
602
Jihoon Kang3c89f042023-12-19 02:40:22 +0000603 cmd.FlagWithOutput("--generate-api-levels ", apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700604
605 filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
606
satayev783195c2021-06-23 21:49:57 +0100607 var dirs []string
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200608 var extensions_dir string
Colin Cross2207f872021-03-24 12:39:08 -0700609 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
610 if t, ok := m.(*ExportedDroiddocDir); ok {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200611 extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
612
613 // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
614 // ideally this should be read from prebuiltApis.properties.Extensions_*
Colin Cross2207f872021-03-24 12:39:08 -0700615 for _, dep := range t.deps {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200616 if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
617 if extensions_dir == "" {
618 extensions_dir = t.dir.String() + "/extensions"
619 }
620 cmd.Implicit(dep)
621 }
Colin Cross5f6ffc72021-03-29 21:54:45 -0700622 if dep.Base() == filename {
623 cmd.Implicit(dep)
624 }
625 if filename != "android.jar" && dep.Base() == "android.jar" {
626 // Metalava implicitly searches these patterns:
627 // prebuilts/tools/common/api-versions/android-%/android.jar
628 // prebuilts/sdk/%/public/android.jar
629 // Add android.jar files from the api_levels_annotations_dirs directories to try
630 // to satisfy these patterns. If Metalava can't find a match for an API level
631 // between 1 and 28 in at least one pattern it will fail.
Colin Cross2207f872021-03-24 12:39:08 -0700632 cmd.Implicit(dep)
633 }
634 }
satayev783195c2021-06-23 21:49:57 +0100635
636 dirs = append(dirs, t.dir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700637 } else {
638 ctx.PropertyErrorf("api_levels_annotations_dirs",
639 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
640 }
641 })
satayev783195c2021-06-23 21:49:57 +0100642
643 // Add all relevant --android-jar-pattern patterns for Metalava.
644 // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
645 // an actual file present on disk (in the order the patterns were passed). For system APIs for
646 // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
Pedro Loureirocc203502021-10-04 17:24:00 +0000647 // for older releases. Similarly, module-lib falls back to system API.
648 var sdkDirs []string
649 switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
Cole Faust051fa912022-10-05 12:45:42 -0700650 case "system-server":
651 sdkDirs = []string{"system-server", "module-lib", "system", "public"}
Pedro Loureirocc203502021-10-04 17:24:00 +0000652 case "module-lib":
653 sdkDirs = []string{"module-lib", "system", "public"}
654 case "system":
655 sdkDirs = []string{"system", "public"}
656 case "public":
657 sdkDirs = []string{"public"}
658 default:
659 ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
660 return
satayev783195c2021-06-23 21:49:57 +0100661 }
Pedro Loureirocc203502021-10-04 17:24:00 +0000662
663 for _, sdkDir := range sdkDirs {
664 for _, dir := range dirs {
665 cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
666 }
satayev783195c2021-06-23 21:49:57 +0100667 }
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200668
669 if d.properties.Extensions_info_file != nil {
670 if extensions_dir == "" {
671 ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
672 }
673 info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
674 cmd.Implicit(info_file)
675 cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
676 cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
677 }
Colin Cross2207f872021-03-24 12:39:08 -0700678}
679
Colin Crosse52c2ac2022-03-28 17:03:35 -0700680func metalavaUseRbe(ctx android.ModuleContext) bool {
681 return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
682}
683
Colin Cross2207f872021-03-24 12:39:08 -0700684func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Anton Hansson556e8142021-06-04 16:20:25 +0100685 srcJarList android.Path, bootclasspath, classpath classpath, homeDir android.WritablePath) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700686 rule.Command().Text("rm -rf").Flag(homeDir.String())
687 rule.Command().Text("mkdir -p").Flag(homeDir.String())
688
Anton Hansson556e8142021-06-04 16:20:25 +0100689 cmd := rule.Command()
Colin Cross2207f872021-03-24 12:39:08 -0700690 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())
691
Colin Crosse52c2ac2022-03-28 17:03:35 -0700692 if metalavaUseRbe(ctx) {
Colin Cross2207f872021-03-24 12:39:08 -0700693 rule.Remoteable(android.RemoteRuleSupports{RBE: true})
Colin Cross8095c292021-03-30 16:40:48 -0700694 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000695 compare := ctx.Config().IsEnvTrue("RBE_METALAVA_COMPARE")
696 remoteUpdateCache := !ctx.Config().IsEnvFalse("RBE_METALAVA_REMOTE_UPDATE_CACHE")
Colin Cross8095c292021-03-30 16:40:48 -0700697 labels := map[string]string{"type": "tool", "name": "metalava"}
698 // TODO: metalava pool rejects these jobs
699 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
700 rule.Rewrapper(&remoteexec.REParams{
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000701 Labels: labels,
702 ExecStrategy: execStrategy,
703 ToolchainInputs: []string{config.JavaCmd(ctx).String()},
704 Platform: map[string]string{remoteexec.PoolKey: pool},
705 Compare: compare,
706 NumLocalRuns: 1,
707 NumRemoteRuns: 1,
708 NoRemoteUpdateCache: !remoteUpdateCache,
Colin Cross8095c292021-03-30 16:40:48 -0700709 })
Colin Cross2207f872021-03-24 12:39:08 -0700710 }
711
Colin Cross6aa5c402021-03-24 12:28:50 -0700712 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
Colin Cross2207f872021-03-24 12:39:08 -0700713 Flag(config.JavacVmFlags).
Liz Kammere09e20e2023-10-16 15:07:54 -0400714 Flag(config.MetalavaAddOpens).
Paul Duffin808211e2023-08-09 12:36:08 +0100715 FlagWithArg("--java-source ", javaVersion.String()).
Colin Cross2207f872021-03-24 12:39:08 -0700716 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
717 FlagWithInput("@", srcJarList)
718
Paul Duffinf8aaaa12023-08-10 15:16:35 +0100719 // Metalava does not differentiate between bootclasspath and classpath and has not done so for
720 // years, so it is unlikely to change any time soon.
721 combinedPaths := append(([]android.Path)(nil), bootclasspath.Paths()...)
722 combinedPaths = append(combinedPaths, classpath.Paths()...)
723 if len(combinedPaths) > 0 {
724 cmd.FlagWithInputList("--classpath ", combinedPaths, ":")
Colin Cross2207f872021-03-24 12:39:08 -0700725 }
726
Liz Kammere09e20e2023-10-16 15:07:54 -0400727 cmd.Flag(config.MetalavaFlags)
Jihoon Kangc8313892023-09-20 00:54:47 +0000728
Colin Cross2207f872021-03-24 12:39:08 -0700729 return cmd
730}
731
Jihoon Kang3c89f042023-12-19 02:40:22 +0000732// Pass flagged apis related flags to metalava. When aconfig_declarations property is not
733// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
734// property is defined, apply transformations and only revert the flagged apis that are not
735// enabled via release configurations and are not specified in aconfig_declarations
736func (d *Droidstubs) generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
737
738 if len(aconfigFlagsPaths) == 0 {
739 cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
740 return
741 }
Jihoon Kang6592e872023-12-19 01:13:16 +0000742
743 releasedFlaggedApisFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flagged-apis-%s.txt", stubsType.String()))
744 revertAnnotationsFile := android.PathForModuleOut(ctx, fmt.Sprintf("revert-annotations-%s.txt", stubsType.String()))
745
746 var filterArgs string
747 switch stubsType {
748 // No flagged apis specific flags need to be passed to metalava when generating
749 // everything stubs
750 case Everything:
751 return
752
753 case Runtime:
754 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
755
756 case Exportable:
757 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY'"
758
759 }
760
761 ctx.Build(pctx, android.BuildParams{
762 Rule: gatherReleasedFlaggedApisRule,
763 Inputs: aconfigFlagsPaths,
764 Output: releasedFlaggedApisFile,
765 Description: fmt.Sprintf("%s gather aconfig flags", stubsType),
766 Args: map[string]string{
767 "flags_path": android.JoinPathsWithPrefix(aconfigFlagsPaths, "--cache "),
768 "filter_args": filterArgs,
769 },
770 })
771
772 ctx.Build(pctx, android.BuildParams{
773 Rule: generateMetalavaRevertAnnotationsRule,
774 Input: releasedFlaggedApisFile,
775 Output: revertAnnotationsFile,
776 Description: fmt.Sprintf("%s revert annotations", stubsType),
777 })
Jihoon Kang3c89f042023-12-19 02:40:22 +0000778
779 cmd.FlagWithInput("@", revertAnnotationsFile)
Jihoon Kang6592e872023-12-19 01:13:16 +0000780}
781
Jihoon Kang3c89f042023-12-19 02:40:22 +0000782func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
783 params stubsCommandParams) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700784 if BoolDefault(d.properties.High_mem, false) {
785 // This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
786 rule.HighMem()
787 }
788
Jihoon Kang3c89f042023-12-19 02:40:22 +0000789 if params.stubConfig.generateStubs {
790 rule.Command().Text("rm -rf").Text(params.stubsDir.String())
791 rule.Command().Text("mkdir -p").Text(params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700792 }
793
Jihoon Kang3c89f042023-12-19 02:40:22 +0000794 srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars)
Colin Cross2207f872021-03-24 12:39:08 -0700795
Jihoon Kang3c89f042023-12-19 02:40:22 +0000796 homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home")
797 cmd := metalavaCmd(ctx, rule, params.stubConfig.javaVersion, d.Javadoc.srcFiles, srcJarList,
798 params.stubConfig.deps.bootClasspath, params.stubConfig.deps.classpath, homeDir)
Colin Cross2207f872021-03-24 12:39:08 -0700799 cmd.Implicits(d.Javadoc.implicits)
800
Jihoon Kang3c89f042023-12-19 02:40:22 +0000801 d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
Colin Cross2207f872021-03-24 12:39:08 -0700802
Jihoon Kang3c89f042023-12-19 02:40:22 +0000803 if params.stubConfig.writeSdkValues {
804 d.sdkValuesFlags(ctx, cmd, params.metadataDir)
805 }
806
807 annotationParams := annotationFlagsParams{
808 migratingNullability: params.stubConfig.migratingNullability,
809 validatingNullability: params.stubConfig.validatingNullability,
810 nullabilityWarningsFile: params.nullabilityWarningsFile,
811 annotationsZip: params.annotationsZip,
812 }
813
814 d.annotationsFlags(ctx, cmd, annotationParams)
Colin Cross2207f872021-03-24 12:39:08 -0700815 d.inclusionAnnotationsFlags(ctx, cmd)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000816 d.apiLevelsAnnotationsFlags(ctx, cmd, params.stubConfig.stubsType, params.apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700817
Colin Crossbc139922021-03-25 18:33:16 -0700818 d.expandArgs(ctx, cmd)
Colin Cross2207f872021-03-24 12:39:08 -0700819
Colin Cross2207f872021-03-24 12:39:08 -0700820 for _, o := range d.Javadoc.properties.Out {
821 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
822 }
823
Jihoon Kang3c89f042023-12-19 02:40:22 +0000824 return cmd
825}
Colin Cross2207f872021-03-24 12:39:08 -0700826
Jihoon Kang3c89f042023-12-19 02:40:22 +0000827// Sandbox rule for generating the everything stubs and other artifacts
828func (d *Droidstubs) everythingStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
829 srcJarDir := android.PathForModuleOut(ctx, Everything.String(), "srcjars")
830 rule := android.NewRuleBuilder(pctx, ctx)
831 rule.Sbox(android.PathForModuleOut(ctx, Everything.String()),
832 android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
833 SandboxInputs()
834
835 var stubsDir android.OptionalPath
836 if params.generateStubs {
837 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, Everything.String(), "stubsDir"))
838 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
839 }
840
841 if params.writeSdkValues {
842 d.metadataDir = android.PathForModuleOut(ctx, Everything.String(), "metadata")
843 d.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
844 }
845
846 if Bool(d.properties.Annotations_enabled) {
847 if params.validatingNullability {
848 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
849 }
850 d.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
851 }
852 if Bool(d.properties.Api_levels_annotations_enabled) {
853 d.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
854 }
855
856 commonCmdParams := stubsCommandParams{
857 srcJarDir: srcJarDir,
858 stubsDir: stubsDir,
859 stubsSrcJar: d.Javadoc.stubsSrcJar,
860 metadataDir: d.metadataDir,
861 apiVersionsXml: d.apiVersionsXml,
862 nullabilityWarningsFile: d.nullabilityWarningsFile,
863 annotationsZip: d.annotationsZip,
864 stubConfig: params,
865 }
866
867 cmd := d.commonMetalavaStubCmd(ctx, rule, commonCmdParams)
868
869 d.everythingOptionalCmd(ctx, cmd, params.doApiLint, params.doCheckReleased)
870
871 if params.generateStubs {
872 rule.Command().
873 BuiltTool("soong_zip").
874 Flag("-write_if_changed").
875 Flag("-jar").
876 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
877 FlagWithArg("-C ", stubsDir.String()).
878 FlagWithArg("-D ", stubsDir.String())
879 }
880
881 if params.writeSdkValues {
882 rule.Command().
883 BuiltTool("soong_zip").
884 Flag("-write_if_changed").
885 Flag("-d").
886 FlagWithOutput("-o ", d.metadataZip).
887 FlagWithArg("-C ", d.metadataDir.String()).
888 FlagWithArg("-D ", d.metadataDir.String())
889 }
890
891 // TODO: We don't really need two separate API files, but this is a reminiscence of how
892 // we used to run metalava separately for API lint and the "last_released" check. Unify them.
893 if params.doApiLint {
894 rule.Command().Text("touch").Output(d.apiLintTimestamp)
895 }
896 if params.doCheckReleased {
897 rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
898 }
899
900 // TODO(b/183630617): rewrapper doesn't support restat rules
901 if !metalavaUseRbe(ctx) {
902 rule.Restat()
903 }
904
905 zipSyncCleanupCmd(rule, srcJarDir)
906
907 rule.Build("metalava", "metalava merged")
908}
909
910// Sandbox rule for generating the everything artifacts that are not run by
911// default but only run based on the module configurations
912func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, doApiLint bool, doCheckReleased bool) {
Colin Cross2207f872021-03-24 12:39:08 -0700913
914 // Add API lint options.
Jihoon Kang3c89f042023-12-19 02:40:22 +0000915 if doApiLint {
Colin Cross2207f872021-03-24 12:39:08 -0700916 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
917 if newSince.Valid() {
918 cmd.FlagWithInput("--api-lint ", newSince.Path())
919 } else {
920 cmd.Flag("--api-lint")
921 }
Jihoon Kang3c89f042023-12-19 02:40:22 +0000922 d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700923 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
924
Colin Cross0d532412021-03-25 09:38:45 -0700925 // TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
Colin Cross2207f872021-03-24 12:39:08 -0700926 if d.Name() != "android.car-system-stubs-docs" &&
927 d.Name() != "android.car-stubs-docs" {
928 cmd.Flag("--lints-as-errors")
929 cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
930 }
931
932 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000933 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "api_lint_baseline.txt")
934 d.apiLintTimestamp = android.PathForModuleOut(ctx, Everything.String(), "api_lint.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700935
936 // Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
Colin Cross2207f872021-03-24 12:39:08 -0700937 //
938 // TODO: metalava also has a slightly different message hardcoded. Should we unify this
939 // message and metalava's one?
940 msg := `$'` + // Enclose with $' ... '
941 `************************************************************\n` +
942 `Your API changes are triggering API Lint warnings or errors.\n` +
943 `To make these errors go away, fix the code according to the\n` +
944 `error and/or warning messages above.\n` +
945 `\n` +
946 `If it is not possible to do so, there are workarounds:\n` +
947 `\n` +
Aurimas Liutikasb23b7452021-05-24 18:00:37 +0000948 `1. You can suppress the errors with @SuppressLint("<id>")\n` +
949 ` where the <id> is given in brackets in the error message above.\n`
Colin Cross2207f872021-03-24 12:39:08 -0700950
951 if baselineFile.Valid() {
952 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
953 cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)
954
955 msg += fmt.Sprintf(``+
956 `2. You can update the baseline by executing the following\n`+
957 ` command:\n`+
Colin Cross63eeda02021-04-15 19:01:57 -0700958 ` (cd $ANDROID_BUILD_TOP && cp \\\n`+
959 ` "%s" \\\n`+
960 ` "%s")\n`+
Colin Cross2207f872021-03-24 12:39:08 -0700961 ` To submit the revised baseline.txt to the main Android\n`+
962 ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
963 } else {
964 msg += fmt.Sprintf(``+
965 `2. You can add a baseline file of existing lint failures\n`+
966 ` to the build rule of %s.\n`, d.Name())
967 }
968 // Note the message ends with a ' (single quote), to close the $' ... ' .
969 msg += `************************************************************\n'`
970
971 cmd.FlagWithArg("--error-message:api-lint ", msg)
972 }
973
974 // Add "check released" options. (Detect incompatible API changes from the last public release)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000975 if doCheckReleased {
Colin Cross2207f872021-03-24 12:39:08 -0700976 if len(d.Javadoc.properties.Out) > 0 {
977 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
978 }
979
980 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
981 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
982 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000983 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700984
Jihoon Kang3c89f042023-12-19 02:40:22 +0000985 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700986
987 cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
988 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
989
990 if baselineFile.Valid() {
991 cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
992 cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
993 }
994
995 // Note this string includes quote ($' ... '), which decodes the "\n"s.
996 msg := `$'\n******************************\n` +
997 `You have tried to change the API from what has been previously released in\n` +
998 `an SDK. Please fix the errors listed above.\n` +
999 `******************************\n'`
1000
1001 cmd.FlagWithArg("--error-message:compatibility:released ", msg)
1002 }
1003
Paul Duffin10a23c22023-08-11 22:47:31 +01001004 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1005 // Pass the current API file into metalava so it can use it as the basis for determining how to
1006 // generate the output signature files (both api and removed).
1007 currentApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1008 cmd.FlagWithInput("--use-same-format-as ", currentApiFile)
1009 }
Jihoon Kang3c89f042023-12-19 02:40:22 +00001010}
Paul Duffin10a23c22023-08-11 22:47:31 +01001011
Jihoon Kang3c89f042023-12-19 02:40:22 +00001012// Sandbox rule for generating exportable stubs and other artifacts
1013func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
1014 optionalCmdParams := stubsCommandParams{
1015 stubConfig: params,
1016 }
1017
1018 d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
1019 optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
1020 if params.writeSdkValues {
1021 d.exportableMetadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
1022 d.exportableMetadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
1023 optionalCmdParams.metadataZip = d.exportableMetadataZip
1024 optionalCmdParams.metadataDir = d.exportableMetadataDir
1025 }
1026
1027 if Bool(d.properties.Annotations_enabled) {
1028 if params.validatingNullability {
1029 d.exportableNullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
1030 optionalCmdParams.nullabilityWarningsFile = d.exportableNullabilityWarningsFile
1031 }
1032 d.exportableAnnotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
1033 optionalCmdParams.annotationsZip = d.exportableAnnotationsZip
1034 }
1035 if Bool(d.properties.Api_levels_annotations_enabled) {
1036 d.exportableApiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
1037 optionalCmdParams.apiVersionsXml = d.exportableApiVersionsXml
1038 }
1039
1040 if params.checkApi || String(d.properties.Api_filename) != "" {
1041 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
1042 d.exportableApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1043 }
1044
1045 if params.checkApi || String(d.properties.Removed_api_filename) != "" {
1046 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_api.txt")
1047 d.exportableRemovedApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1048 }
1049
1050 d.optionalStubCmd(ctx, optionalCmdParams)
1051}
1052
1053func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsCommandParams) {
1054
1055 params.srcJarDir = android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "srcjars")
1056 rule := android.NewRuleBuilder(pctx, ctx)
1057 rule.Sbox(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String()),
1058 android.PathForModuleOut(ctx, fmt.Sprintf("metalava_%s.sbox.textproto", params.stubConfig.stubsType.String()))).
1059 SandboxInputs()
1060
1061 if params.stubConfig.generateStubs {
1062 params.stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "stubsDir"))
1063 }
1064
1065 cmd := d.commonMetalavaStubCmd(ctx, rule, params)
1066
1067 d.generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
1068
1069 if params.stubConfig.doApiLint {
1070 // Pass the lint baseline file as an input to resolve the lint errors.
1071 // The exportable stubs generation does not update the lint baseline file.
1072 // Lint baseline file update is handled by the everything stubs
1073 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1074 if baselineFile.Valid() {
1075 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
1076 }
1077 }
1078
1079 if params.stubConfig.generateStubs {
Colin Cross2207f872021-03-24 12:39:08 -07001080 rule.Command().
1081 BuiltTool("soong_zip").
1082 Flag("-write_if_changed").
1083 Flag("-jar").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001084 FlagWithOutput("-o ", params.stubsSrcJar).
1085 FlagWithArg("-C ", params.stubsDir.String()).
1086 FlagWithArg("-D ", params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001087 }
1088
Jihoon Kang3c89f042023-12-19 02:40:22 +00001089 if params.stubConfig.writeSdkValues {
Colin Cross2207f872021-03-24 12:39:08 -07001090 rule.Command().
1091 BuiltTool("soong_zip").
1092 Flag("-write_if_changed").
1093 Flag("-d").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001094 FlagWithOutput("-o ", params.metadataZip).
1095 FlagWithArg("-C ", params.metadataDir.String()).
1096 FlagWithArg("-D ", params.metadataDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001097 }
1098
Colin Cross6aa5c402021-03-24 12:28:50 -07001099 // TODO(b/183630617): rewrapper doesn't support restat rules
Colin Crosse52c2ac2022-03-28 17:03:35 -07001100 if !metalavaUseRbe(ctx) {
1101 rule.Restat()
1102 }
Colin Cross2207f872021-03-24 12:39:08 -07001103
Jihoon Kang3c89f042023-12-19 02:40:22 +00001104 zipSyncCleanupCmd(rule, params.srcJarDir)
Colin Cross2207f872021-03-24 12:39:08 -07001105
Jihoon Kang3c89f042023-12-19 02:40:22 +00001106 rule.Build(fmt.Sprintf("metalava_%s", params.stubConfig.stubsType.String()), "metalava merged")
1107}
1108
1109func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1110 deps := d.Javadoc.collectDeps(ctx)
1111
1112 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
1113 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
1114
1115 // Add options for the other optional tasks: API-lint and check-released.
1116 // We generate separate timestamp files for them.
1117 doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
1118 doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1119
1120 writeSdkValues := Bool(d.properties.Write_sdk_values)
1121
1122 annotationsEnabled := Bool(d.properties.Annotations_enabled)
1123
1124 migratingNullability := annotationsEnabled && String(d.properties.Previous_api) != ""
1125 validatingNullability := annotationsEnabled && (strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
1126 String(d.properties.Validate_nullability_from_list) != "")
1127
1128 checkApi := apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1129 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1130
1131 stubCmdParams := stubsCommandConfigParams{
1132 javaVersion: javaVersion,
1133 deps: deps,
1134 checkApi: checkApi,
1135 generateStubs: generateStubs,
1136 doApiLint: doApiLint,
1137 doCheckReleased: doCheckReleased,
1138 writeSdkValues: writeSdkValues,
1139 migratingNullability: migratingNullability,
1140 validatingNullability: validatingNullability,
1141 }
1142 stubCmdParams.stubsType = Everything
1143 // Create default (i.e. "everything" stubs) rule for metalava
1144 d.everythingStubCmd(ctx, stubCmdParams)
1145
1146 // The module generates "exportable" (and "runtime" eventually) stubs regardless of whether
1147 // aconfig_declarations property is defined or not. If the property is not defined, the module simply
1148 // strips all flagged apis to generate the "exportable" stubs
1149 stubCmdParams.stubsType = Exportable
1150 d.exportableStubCmd(ctx, stubCmdParams)
Paul Duffinc166b682022-05-27 12:23:08 +00001151
Paul Duffine7a86642022-08-16 15:43:20 +00001152 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1153
1154 if len(d.Javadoc.properties.Out) > 0 {
1155 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1156 }
1157
1158 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1159 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
1160 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1161
1162 if baselineFile.Valid() {
1163 ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
1164 }
1165
Jihoon Kang3c89f042023-12-19 02:40:22 +00001166 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001167
1168 rule := android.NewRuleBuilder(pctx, ctx)
1169
1170 // Diff command line.
1171 // -F matches the closest "opening" line, such as "package android {"
1172 // and " public class Intent {".
1173 diff := `diff -u -F '{ *$'`
1174
1175 rule.Command().Text("( true")
1176 rule.Command().
1177 Text(diff).
1178 Input(apiFile).Input(d.apiFile)
1179
1180 rule.Command().
1181 Text(diff).
1182 Input(removedApiFile).Input(d.removedApiFile)
1183
1184 msg := fmt.Sprintf(`\n******************************\n`+
1185 `You have tried to change the API from what has been previously approved.\n\n`+
1186 `To make these errors go away, you have two choices:\n`+
1187 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
1188 ` to the new methods, etc. shown in the above diff.\n\n`+
1189 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
1190 ` m %s-update-current-api\n\n`+
1191 ` To submit the revised current.txt to the main Android repository,\n`+
1192 ` you will need approval.\n`+
Jihoon Kang3ea64672023-11-03 00:40:26 +00001193 `If your build failed due to stub validation, you can resolve the errors with\n`+
1194 `either of the two choices above and try re-building the target.\n`+
1195 `If the mismatch between the stubs and the current.txt is intended,\n`+
1196 `you can try re-building the target by executing the following command:\n`+
Jihoon Kang91bf3dd2024-01-24 00:40:23 +00001197 `m DISABLE_STUB_VALIDATION=true <your build target>.\n`+
1198 `Note that DISABLE_STUB_VALIDATION=true does not bypass checkapi.\n`+
Paul Duffine7a86642022-08-16 15:43:20 +00001199 `******************************\n`, ctx.ModuleName())
1200
1201 rule.Command().
1202 Text("touch").Output(d.checkCurrentApiTimestamp).
1203 Text(") || (").
1204 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1205 Text("; exit 38").
1206 Text(")")
1207
1208 rule.Build("metalavaCurrentApiCheck", "check current API")
1209
Jihoon Kang3c89f042023-12-19 02:40:22 +00001210 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001211
1212 // update API rule
1213 rule = android.NewRuleBuilder(pctx, ctx)
1214
1215 rule.Command().Text("( true")
1216
1217 rule.Command().
1218 Text("cp").Flag("-f").
1219 Input(d.apiFile).Flag(apiFile.String())
1220
1221 rule.Command().
1222 Text("cp").Flag("-f").
1223 Input(d.removedApiFile).Flag(removedApiFile.String())
1224
1225 msg = "failed to update public API"
1226
1227 rule.Command().
1228 Text("touch").Output(d.updateCurrentApiTimestamp).
1229 Text(") || (").
1230 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1231 Text("; exit 38").
1232 Text(")")
1233
1234 rule.Build("metalavaCurrentApiUpdate", "update current API")
1235 }
1236
Colin Cross2207f872021-03-24 12:39:08 -07001237 if String(d.properties.Check_nullability_warnings) != "" {
1238 if d.nullabilityWarningsFile == nil {
1239 ctx.PropertyErrorf("check_nullability_warnings",
1240 "Cannot specify check_nullability_warnings unless validating nullability")
1241 }
1242
1243 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1244
Jihoon Kang3c89f042023-12-19 02:40:22 +00001245 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -07001246
1247 msg := fmt.Sprintf(`\n******************************\n`+
1248 `The warnings encountered during nullability annotation validation did\n`+
1249 `not match the checked in file of expected warnings. The diffs are shown\n`+
1250 `above. You have two options:\n`+
1251 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1252 ` 2. Update the file of expected warnings by running:\n`+
1253 ` cp %s %s\n`+
1254 ` and submitting the updated file as part of your change.`,
1255 d.nullabilityWarningsFile, checkNullabilityWarnings)
1256
1257 rule := android.NewRuleBuilder(pctx, ctx)
1258
1259 rule.Command().
1260 Text("(").
1261 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1262 Text("&&").
1263 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1264 Text(") || (").
1265 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1266 Text("; exit 38").
1267 Text(")")
1268
1269 rule.Build("nullabilityWarningsCheck", "nullability warnings check")
1270 }
LaMont Jonesafe7baf2024-01-09 22:47:39 +00001271 android.CollectDependencyAconfigFiles(ctx, &d.mergedAconfigFiles)
Colin Cross2207f872021-03-24 12:39:08 -07001272}
1273
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001274func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
1275 api_file := d.properties.Check_api.Current.Api_file
1276 api_surface := d.properties.Api_surface
1277
1278 props := struct {
1279 Name *string
1280 Api_surface *string
1281 Api_file *string
Jihoon Kang42b589c2023-02-03 22:56:13 +00001282 Visibility []string
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001283 }{}
1284
1285 props.Name = proptools.StringPtr(d.Name() + ".api.contribution")
1286 props.Api_surface = api_surface
1287 props.Api_file = api_file
Jihoon Kang42b589c2023-02-03 22:56:13 +00001288 props.Visibility = []string{"//visibility:override", "//visibility:public"}
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001289
1290 ctx.CreateModule(ApiContributionFactory, &props)
1291}
1292
Spandan Das0b555e32022-11-28 18:48:51 +00001293// TODO (b/262014796): Export the API contributions of CorePlatformApi
1294// A map to populate the api surface of a droidstub from a substring appearing in its name
1295// This map assumes that droidstubs (either checked-in or created by java_sdk_library)
1296// use a strict naming convention
1297var (
1298 droidstubsModuleNamingToSdkKind = map[string]android.SdkKind{
1299 //public is commented out since the core libraries use public in their java_sdk_library names
1300 "intracore": android.SdkIntraCore,
1301 "intra.core": android.SdkIntraCore,
1302 "system_server": android.SdkSystemServer,
1303 "system-server": android.SdkSystemServer,
1304 "system": android.SdkSystem,
1305 "module_lib": android.SdkModule,
1306 "module-lib": android.SdkModule,
Spandan Dasda977552023-01-26 20:45:16 +00001307 "platform.api": android.SdkCorePlatform,
Spandan Das0b555e32022-11-28 18:48:51 +00001308 "test": android.SdkTest,
Spandan Das4ac2aed2022-12-28 01:54:29 +00001309 "toolchain": android.SdkToolchain,
Spandan Das0b555e32022-11-28 18:48:51 +00001310 }
1311)
1312
Colin Cross2207f872021-03-24 12:39:08 -07001313func StubsDefaultsFactory() android.Module {
1314 module := &DocDefaults{}
1315
1316 module.AddProperties(
1317 &JavadocProperties{},
1318 &DroidstubsProperties{},
1319 )
1320
1321 android.InitDefaultsModule(module)
1322
1323 return module
1324}
1325
1326var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
1327
1328type PrebuiltStubsSourcesProperties struct {
1329 Srcs []string `android:"path"`
1330}
1331
1332type PrebuiltStubsSources struct {
1333 android.ModuleBase
1334 android.DefaultableModuleBase
Spandan Das2cc80ba2023-10-27 17:21:52 +00001335 embeddableInModuleAndImport
1336
Colin Cross2207f872021-03-24 12:39:08 -07001337 prebuilt android.Prebuilt
Colin Cross2207f872021-03-24 12:39:08 -07001338
1339 properties PrebuiltStubsSourcesProperties
1340
kgui67007242022-01-25 13:50:25 +08001341 stubsSrcJar android.Path
Colin Cross2207f872021-03-24 12:39:08 -07001342}
1343
1344func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
1345 switch tag {
Jihoon Kangfa4a90d2023-12-20 02:53:38 +00001346 // prebuilt droidstubs does not output "exportable" stubs.
1347 // Output the "everything" stubs srcjar file if the tag is ".exportable".
1348 case "", ".exportable":
Colin Cross2207f872021-03-24 12:39:08 -07001349 return android.Paths{p.stubsSrcJar}, nil
1350 default:
1351 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1352 }
1353}
1354
1355func (d *PrebuiltStubsSources) StubsSrcJar() android.Path {
1356 return d.stubsSrcJar
1357}
1358
1359func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross2207f872021-03-24 12:39:08 -07001360 if len(p.properties.Srcs) != 1 {
Anton Hansson86758ac2021-11-03 14:44:12 +00001361 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 -07001362 return
1363 }
1364
Anton Hansson86758ac2021-11-03 14:44:12 +00001365 src := p.properties.Srcs[0]
1366 if filepath.Ext(src) == ".srcjar" {
1367 // This is a srcjar. We can use it directly.
1368 p.stubsSrcJar = android.PathForModuleSrc(ctx, src)
1369 } else {
1370 outPath := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Colin Cross2207f872021-03-24 12:39:08 -07001371
Anton Hansson86758ac2021-11-03 14:44:12 +00001372 // This is a directory. Glob the contents just in case the directory does not exist.
1373 srcGlob := src + "/**/*"
1374 srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})
Colin Cross2207f872021-03-24 12:39:08 -07001375
Anton Hansson86758ac2021-11-03 14:44:12 +00001376 // Although PathForModuleSrc can return nil if either the path doesn't exist or
1377 // the path components are invalid it won't in this case because no components
1378 // are specified and the module directory must exist in order to get this far.
1379 srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, src)
Colin Cross2207f872021-03-24 12:39:08 -07001380
Anton Hansson86758ac2021-11-03 14:44:12 +00001381 rule := android.NewRuleBuilder(pctx, ctx)
1382 rule.Command().
1383 BuiltTool("soong_zip").
1384 Flag("-write_if_changed").
1385 Flag("-jar").
1386 FlagWithOutput("-o ", outPath).
1387 FlagWithArg("-C ", srcDir.String()).
1388 FlagWithRspFileInputList("-r ", outPath.ReplaceExtension(ctx, "rsp"), srcPaths)
1389 rule.Restat()
1390 rule.Build("zip src", "Create srcjar from prebuilt source")
1391 p.stubsSrcJar = outPath
1392 }
Colin Cross2207f872021-03-24 12:39:08 -07001393}
1394
1395func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
1396 return &p.prebuilt
1397}
1398
1399func (p *PrebuiltStubsSources) Name() string {
1400 return p.prebuilt.Name(p.ModuleBase.Name())
1401}
1402
1403// prebuilt_stubs_sources imports a set of java source files as if they were
1404// generated by droidstubs.
1405//
1406// By default, a prebuilt_stubs_sources has a single variant that expects a
1407// set of `.java` files generated by droidstubs.
1408//
1409// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
1410// for host modules.
1411//
1412// Intended only for use by sdk snapshots.
1413func PrebuiltStubsSourcesFactory() android.Module {
1414 module := &PrebuiltStubsSources{}
1415
1416 module.AddProperties(&module.properties)
Spandan Das2cc80ba2023-10-27 17:21:52 +00001417 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -07001418
1419 android.InitPrebuiltModule(module, &module.properties.Srcs)
Colin Cross2207f872021-03-24 12:39:08 -07001420 InitDroiddocModule(module, android.HostAndDeviceSupported)
1421 return module
1422}