blob: e506ee6d16404ee846f998d7053496919ce1781d [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
Jihoon Kang5d701272024-02-15 21:53:49 +000055func StringToStubsType(s string) StubsType {
56 switch strings.ToLower(s) {
57 case Everything.String():
58 return Everything
59 case Runtime.String():
60 return Runtime
61 case Exportable.String():
62 return Exportable
63 default:
64 return Unavailable
65 }
66}
67
Colin Cross2207f872021-03-24 12:39:08 -070068func init() {
69 RegisterStubsBuildComponents(android.InitRegistrationContext)
70}
71
72func RegisterStubsBuildComponents(ctx android.RegistrationContext) {
73 ctx.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
74
75 ctx.RegisterModuleType("droidstubs", DroidstubsFactory)
76 ctx.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
77
78 ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
79}
80
Jihoon Kangee113282024-01-23 00:16:41 +000081type stubsArtifacts struct {
82 nullabilityWarningsFile android.WritablePath
83 annotationsZip android.WritablePath
84 apiVersionsXml android.WritablePath
85 metadataZip android.WritablePath
86 metadataDir android.WritablePath
87}
88
Colin Cross2207f872021-03-24 12:39:08 -070089// Droidstubs
Colin Cross2207f872021-03-24 12:39:08 -070090type Droidstubs struct {
91 Javadoc
Spandan Das2cc80ba2023-10-27 17:21:52 +000092 embeddableInModuleAndImport
Colin Cross2207f872021-03-24 12:39:08 -070093
Jihoon Kangee113282024-01-23 00:16:41 +000094 properties DroidstubsProperties
95 apiFile android.Path
96 removedApiFile android.Path
Colin Cross2207f872021-03-24 12:39:08 -070097
98 checkCurrentApiTimestamp android.WritablePath
99 updateCurrentApiTimestamp android.WritablePath
100 checkLastReleasedApiTimestamp android.WritablePath
101 apiLintTimestamp android.WritablePath
102 apiLintReport android.WritablePath
103
104 checkNullabilityWarningsTimestamp android.WritablePath
105
Jihoon Kangee113282024-01-23 00:16:41 +0000106 everythingArtifacts stubsArtifacts
107 exportableArtifacts stubsArtifacts
Jihoon Kang3c89f042023-12-19 02:40:22 +0000108
LaMont Jonesafe7baf2024-01-09 22:47:39 +0000109 // Single aconfig "cache file" merged from this module and all dependencies.
110 mergedAconfigFiles map[string]android.Paths
111
Jihoon Kangee113282024-01-23 00:16:41 +0000112 exportableApiFile android.WritablePath
113 exportableRemovedApiFile android.WritablePath
Colin Cross2207f872021-03-24 12:39:08 -0700114}
115
116type DroidstubsProperties struct {
117 // The generated public API filename by Metalava, defaults to <module>_api.txt
118 Api_filename *string
119
120 // the generated removed API filename by Metalava, defaults to <module>_removed.txt
121 Removed_api_filename *string
122
Colin Cross2207f872021-03-24 12:39:08 -0700123 Check_api struct {
124 Last_released ApiToCheck
125
126 Current ApiToCheck
127
128 Api_lint struct {
129 Enabled *bool
130
131 // If set, performs api_lint on any new APIs not found in the given signature file
132 New_since *string `android:"path"`
133
134 // If not blank, path to the baseline txt file for approved API lint violations.
135 Baseline_file *string `android:"path"`
136 }
137 }
138
139 // user can specify the version of previous released API file in order to do compatibility check.
140 Previous_api *string `android:"path"`
141
142 // is set to true, Metalava will allow framework SDK to contain annotations.
143 Annotations_enabled *bool
144
145 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
146 Merge_annotations_dirs []string
147
148 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
149 Merge_inclusion_annotations_dirs []string
150
151 // a file containing a list of classes to do nullability validation for.
152 Validate_nullability_from_list *string
153
154 // a file containing expected warnings produced by validation of nullability annotations.
155 Check_nullability_warnings *string
156
157 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
158 Create_doc_stubs *bool
159
160 // if set to true, cause Metalava to output Javadoc comments in the stubs source files. Defaults to false.
161 // Has no effect if create_doc_stubs: true.
162 Output_javadoc_comments *bool
163
164 // if set to false then do not write out stubs. Defaults to true.
165 //
166 // TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately.
167 Generate_stubs *bool
168
169 // 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 -0400170 // which can be used for scheduling purposes
Colin Cross2207f872021-03-24 12:39:08 -0700171 High_mem *bool
172
satayev783195c2021-06-23 21:49:57 +0100173 // if set to true, Metalava will allow framework SDK to contain API levels annotations.
Colin Cross2207f872021-03-24 12:39:08 -0700174 Api_levels_annotations_enabled *bool
175
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000176 // Apply the api levels database created by this module rather than generating one in this droidstubs.
177 Api_levels_module *string
178
Colin Cross2207f872021-03-24 12:39:08 -0700179 // the dirs which Metalava extracts API levels annotations from.
180 Api_levels_annotations_dirs []string
181
Cole Faust051fa912022-10-05 12:45:42 -0700182 // 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 +0100183 Api_levels_sdk_type *string
184
Colin Cross2207f872021-03-24 12:39:08 -0700185 // the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
186 Api_levels_jar_filename *string
187
188 // if set to true, collect the values used by the Dev tools and
189 // write them in files packaged with the SDK. Defaults to false.
190 Write_sdk_values *bool
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200191
192 // path or filegroup to file defining extension an SDK name <-> numerical ID mapping and
193 // what APIs exist in which SDKs; passed to metalava via --sdk-extensions-info
194 Extensions_info_file *string `android:"path"`
Jihoon Kang3198f3c2023-01-26 08:08:52 +0000195
196 // API surface of this module. If set, the module contributes to an API surface.
197 // For the full list of available API surfaces, refer to soong/android/sdk_version.go
198 Api_surface *string
Jihoon Kang6592e872023-12-19 01:13:16 +0000199
200 // a list of aconfig_declarations module names that the stubs generated in this module
201 // depend on.
202 Aconfig_declarations []string
Colin Cross2207f872021-03-24 12:39:08 -0700203}
204
Anton Hansson52609322021-05-05 10:36:05 +0100205// Used by xsd_config
206type ApiFilePath interface {
Jihoon Kangee113282024-01-23 00:16:41 +0000207 ApiFilePath(StubsType) (android.Path, error)
Anton Hansson52609322021-05-05 10:36:05 +0100208}
209
210type ApiStubsSrcProvider interface {
Jihoon Kangee113282024-01-23 00:16:41 +0000211 StubsSrcJar(StubsType) (android.Path, error)
Jihoon Kangf55a5f72024-01-08 08:56:20 +0000212}
213
Anton Hansson52609322021-05-05 10:36:05 +0100214// Provider of information about API stubs, used by java_sdk_library.
215type ApiStubsProvider interface {
Jihoon Kangee113282024-01-23 00:16:41 +0000216 AnnotationsZip(StubsType) (android.Path, error)
Anton Hansson52609322021-05-05 10:36:05 +0100217 ApiFilePath
Jihoon Kangee113282024-01-23 00:16:41 +0000218 RemovedApiFilePath(StubsType) (android.Path, error)
Anton Hansson52609322021-05-05 10:36:05 +0100219
220 ApiStubsSrcProvider
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 {
Jihoon Kang6b93b382024-01-26 22:37:41 +0000245 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 annotationsEnabled bool
256 apiLevelsAnnotationsEnabled bool
Jihoon Kang3c89f042023-12-19 02:40:22 +0000257}
258
Colin Cross2207f872021-03-24 12:39:08 -0700259// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
260// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
261// a droiddoc module to generate documentation.
262func DroidstubsFactory() android.Module {
263 module := &Droidstubs{}
264
265 module.AddProperties(&module.properties,
266 &module.Javadoc.properties)
Spandan Das2cc80ba2023-10-27 17:21:52 +0000267 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -0700268
269 InitDroiddocModule(module, android.HostAndDeviceSupported)
Jihoon Kang3198f3c2023-01-26 08:08:52 +0000270
271 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
272 module.createApiContribution(ctx)
273 })
Colin Cross2207f872021-03-24 12:39:08 -0700274 return module
275}
276
277// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
278// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
279// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
280// module when symbols needed by the source files are provided by java_library_host modules.
281func DroidstubsHostFactory() android.Module {
282 module := &Droidstubs{}
283
284 module.AddProperties(&module.properties,
285 &module.Javadoc.properties)
286
287 InitDroiddocModule(module, android.HostSupported)
288 return module
289}
290
Jihoon Kang78f89142023-12-27 01:40:29 +0000291func getStubsTypeAndTag(tag string) (StubsType, string, error) {
292 if len(tag) == 0 {
293 return Everything, "", nil
294 }
295 if tag[0] != '.' {
296 return Unavailable, "", fmt.Errorf("tag must begin with \".\"")
297 }
298
299 stubsType := Everything
300 // Check if the tag has a stubs type prefix (e.g. ".exportable")
301 for st := Everything; st <= Exportable; st++ {
302 if strings.HasPrefix(tag, "."+st.String()) {
303 stubsType = st
304 }
305 }
306
307 return stubsType, strings.TrimPrefix(tag, "."+stubsType.String()), nil
308}
309
310// Droidstubs' tag supports specifying with the stubs type.
311// While supporting the pre-existing tags, it also supports tags with
312// the stubs type prefix. Some examples are shown below:
313// {.annotations.zip} - pre-existing behavior. Returns the path to the
314// annotation zip.
315// {.exportable} - Returns the path to the exportable stubs src jar.
316// {.exportable.annotations.zip} - Returns the path to the exportable
317// annotations zip file.
318// {.runtime.api_versions.xml} - Runtime stubs does not generate api versions
319// xml file. For unsupported combinations, the default everything output file
320// is returned.
Colin Cross2207f872021-03-24 12:39:08 -0700321func (d *Droidstubs) OutputFiles(tag string) (android.Paths, error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000322 stubsType, prefixRemovedTag, err := getStubsTypeAndTag(tag)
323 if err != nil {
324 return nil, err
325 }
326 switch prefixRemovedTag {
Colin Cross2207f872021-03-24 12:39:08 -0700327 case "":
Jihoon Kangee113282024-01-23 00:16:41 +0000328 stubsSrcJar, err := d.StubsSrcJar(stubsType)
329 return android.Paths{stubsSrcJar}, err
Colin Cross2207f872021-03-24 12:39:08 -0700330 case ".docs.zip":
Jihoon Kangee113282024-01-23 00:16:41 +0000331 docZip, err := d.DocZip(stubsType)
332 return android.Paths{docZip}, err
Colin Cross2207f872021-03-24 12:39:08 -0700333 case ".api.txt", android.DefaultDistTag:
334 // This is the default dist path for dist properties that have no tag property.
Jihoon Kangee113282024-01-23 00:16:41 +0000335 apiFilePath, err := d.ApiFilePath(stubsType)
336 return android.Paths{apiFilePath}, err
Colin Cross2207f872021-03-24 12:39:08 -0700337 case ".removed-api.txt":
Jihoon Kangee113282024-01-23 00:16:41 +0000338 removedApiFilePath, err := d.RemovedApiFilePath(stubsType)
339 return android.Paths{removedApiFilePath}, err
Colin Cross2207f872021-03-24 12:39:08 -0700340 case ".annotations.zip":
Jihoon Kangee113282024-01-23 00:16:41 +0000341 annotationsZip, err := d.AnnotationsZip(stubsType)
342 return android.Paths{annotationsZip}, err
Colin Cross2207f872021-03-24 12:39:08 -0700343 case ".api_versions.xml":
Jihoon Kangee113282024-01-23 00:16:41 +0000344 apiVersionsXmlFilePath, err := d.ApiVersionsXmlFilePath(stubsType)
345 return android.Paths{apiVersionsXmlFilePath}, err
Colin Cross2207f872021-03-24 12:39:08 -0700346 default:
347 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
348 }
349}
350
Jihoon Kang246690a2024-02-01 21:55:01 +0000351func (d *Droidstubs) AnnotationsZip(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000352 switch stubsType {
353 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000354 ret, err = d.everythingArtifacts.annotationsZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000355 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000356 ret, err = d.exportableArtifacts.annotationsZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000357 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000358 ret, err = nil, fmt.Errorf("annotations zip not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000359 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000360 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000361}
362
Jihoon Kang246690a2024-02-01 21:55:01 +0000363func (d *Droidstubs) ApiFilePath(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000364 switch stubsType {
365 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000366 ret, err = d.apiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000367 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000368 ret, err = d.exportableApiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000369 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000370 ret, err = nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000371 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000372 if ret == nil && err == nil {
373 err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
374 }
375 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000376}
377
Jihoon Kang246690a2024-02-01 21:55:01 +0000378func (d *Droidstubs) ApiVersionsXmlFilePath(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000379 switch stubsType {
380 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000381 ret, err = d.everythingArtifacts.apiVersionsXml, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000382 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000383 ret, err = d.exportableArtifacts.apiVersionsXml, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000384 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000385 ret, err = nil, fmt.Errorf("api versions xml file path not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000386 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000387 if ret == nil && err == nil {
388 err = fmt.Errorf("api versions xml file is null for the stub type %s", stubsType.String())
389 }
390 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000391}
392
Jihoon Kang246690a2024-02-01 21:55:01 +0000393func (d *Droidstubs) DocZip(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000394 switch stubsType {
395 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000396 ret, err = d.docZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000397 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000398 ret, err = nil, fmt.Errorf("docs zip not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000399 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000400 if ret == nil && err == nil {
401 err = fmt.Errorf("docs zip is null for the stub type %s", stubsType.String())
402 }
403 return ret, err
404}
405
406func (d *Droidstubs) RemovedApiFilePath(stubsType StubsType) (ret android.Path, err error) {
407 switch stubsType {
408 case Everything:
409 ret, err = d.removedApiFile, nil
410 case Exportable:
411 ret, err = d.exportableRemovedApiFile, nil
412 default:
413 ret, err = nil, fmt.Errorf("removed api file path not supported for the stub type %s", stubsType.String())
414 }
415 if ret == nil && err == nil {
416 err = fmt.Errorf("removed api file is null for the stub type %s", stubsType.String())
417 }
418 return ret, err
419}
420
421func (d *Droidstubs) StubsSrcJar(stubsType StubsType) (ret android.Path, err error) {
422 switch stubsType {
423 case Everything:
424 ret, err = d.stubsSrcJar, nil
425 case Exportable:
426 ret, err = d.exportableStubsSrcJar, nil
427 default:
428 ret, err = nil, fmt.Errorf("stubs srcjar not supported for the stub type %s", stubsType.String())
429 }
430 if ret == nil && err == nil {
431 err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
432 }
433 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000434}
435
Jihoon Kang063ec002023-06-28 01:16:23 +0000436func (d *Droidstubs) CurrentApiTimestamp() android.Path {
437 return d.checkCurrentApiTimestamp
438}
439
Colin Cross2207f872021-03-24 12:39:08 -0700440var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
441var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
442var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000443var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"}
Jihoon Kang063ec002023-06-28 01:16:23 +0000444var metalavaCurrentApiTimestampTag = dependencyTag{name: "metalava-current-api-timestamp-tag"}
Colin Cross2207f872021-03-24 12:39:08 -0700445
446func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
447 d.Javadoc.addDeps(ctx)
448
449 if len(d.properties.Merge_annotations_dirs) != 0 {
450 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
451 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
452 }
453 }
454
455 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
456 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
457 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
458 }
459 }
460
461 if len(d.properties.Api_levels_annotations_dirs) != 0 {
462 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
463 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
464 }
465 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000466
Jihoon Kang6592e872023-12-19 01:13:16 +0000467 if len(d.properties.Aconfig_declarations) != 0 {
468 for _, aconfigDeclarationModuleName := range d.properties.Aconfig_declarations {
469 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationModuleName)
470 }
471 }
472
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000473 if d.properties.Api_levels_module != nil {
474 ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
475 }
Colin Cross2207f872021-03-24 12:39:08 -0700476}
477
Jihoon Kang3c89f042023-12-19 02:40:22 +0000478func (d *Droidstubs) sdkValuesFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, metadataDir android.WritablePath) {
479 cmd.FlagWithArg("--sdk-values ", metadataDir.String())
480}
481
482func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath, stubsType StubsType, checkApi bool) {
483 if checkApi || String(d.properties.Api_filename) != "" {
Colin Cross2207f872021-03-24 12:39:08 -0700484 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000485 uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
Paul Duffinc71d2b72022-08-16 15:24:01 +0000486 cmd.FlagWithOutput("--api ", uncheckedApiFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000487
488 if stubsType == Everything {
489 d.apiFile = uncheckedApiFile
490 } else if stubsType == Exportable {
491 d.exportableApiFile = uncheckedApiFile
492 }
Colin Cross2207f872021-03-24 12:39:08 -0700493 } else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
494 // If check api is disabled then make the source file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000495 d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700496 }
497
Jihoon Kang3c89f042023-12-19 02:40:22 +0000498 if checkApi || String(d.properties.Removed_api_filename) != "" {
Colin Cross2207f872021-03-24 12:39:08 -0700499 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000500 uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
Paul Duffinc71d2b72022-08-16 15:24:01 +0000501 cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000502
503 if stubsType == Everything {
504 d.removedApiFile = uncheckedRemovedFile
505 } else if stubsType == Exportable {
506 d.exportableRemovedApiFile = uncheckedRemovedFile
507 }
Colin Cross2207f872021-03-24 12:39:08 -0700508 } else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
509 // If check api is disabled then make the source removed api file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000510 d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700511 }
512
Colin Cross2207f872021-03-24 12:39:08 -0700513 if stubsDir.Valid() {
514 if Bool(d.properties.Create_doc_stubs) {
515 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
516 } else {
517 cmd.FlagWithArg("--stubs ", stubsDir.String())
518 if !Bool(d.properties.Output_javadoc_comments) {
519 cmd.Flag("--exclude-documentation-from-stubs")
520 }
521 }
522 }
523}
524
Jihoon Kang3c89f042023-12-19 02:40:22 +0000525func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, params annotationFlagsParams) {
Jihoon Kang6b93b382024-01-26 22:37:41 +0000526 cmd.Flag(config.MetalavaAnnotationsFlags)
Andrei Onea4985e512021-04-29 16:29:34 +0100527
Jihoon Kang6b93b382024-01-26 22:37:41 +0000528 if params.migratingNullability {
529 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
530 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Colin Cross2207f872021-03-24 12:39:08 -0700531 }
Jihoon Kang6b93b382024-01-26 22:37:41 +0000532
533 if s := String(d.properties.Validate_nullability_from_list); s != "" {
534 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
535 }
536
537 if params.validatingNullability {
538 cmd.FlagWithOutput("--nullability-warnings-txt ", params.nullabilityWarningsFile)
539 }
540
Jihoon Kang17f01d92024-03-05 16:12:20 +0000541 cmd.FlagWithOutput("--extract-annotations ", params.annotationsZip)
Jihoon Kang6b93b382024-01-26 22:37:41 +0000542
543 if len(d.properties.Merge_annotations_dirs) != 0 {
544 d.mergeAnnoDirFlags(ctx, cmd)
545 }
546
547 cmd.Flag(config.MetalavaAnnotationsWarningsFlags)
Colin Cross2207f872021-03-24 12:39:08 -0700548}
549
550func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
551 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
552 if t, ok := m.(*ExportedDroiddocDir); ok {
553 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
554 } else {
555 ctx.PropertyErrorf("merge_annotations_dirs",
556 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
557 }
558 })
559}
560
561func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
562 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
563 if t, ok := m.(*ExportedDroiddocDir); ok {
564 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
565 } else {
566 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
567 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
568 }
569 })
570}
571
Jihoon Kang6b93b382024-01-26 22:37:41 +0000572func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, params stubsCommandParams) {
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000573 var apiVersions android.Path
Jihoon Kang6b93b382024-01-26 22:37:41 +0000574 stubsType := params.stubConfig.stubsType
575 apiVersionsXml := params.apiVersionsXml
576 if params.stubConfig.apiLevelsAnnotationsEnabled {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000577 d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
Jihoon Kangd9a06942024-01-26 01:49:20 +0000578 apiVersions = apiVersionsXml
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000579 } else {
580 ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
581 if s, ok := m.(*Droidstubs); ok {
Jihoon Kangd9a06942024-01-26 01:49:20 +0000582 if stubsType == Everything {
583 apiVersions = s.everythingArtifacts.apiVersionsXml
584 } else if stubsType == Exportable {
585 apiVersions = s.exportableArtifacts.apiVersionsXml
586 } else {
Jihoon Kang17f01d92024-03-05 16:12:20 +0000587 ctx.ModuleErrorf("%s stubs type does not generate api-versions.xml file", stubsType.String())
Jihoon Kangd9a06942024-01-26 01:49:20 +0000588 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000589 } else {
590 ctx.PropertyErrorf("api_levels_module",
591 "module %q is not a droidstubs module", ctx.OtherModuleName(m))
592 }
593 })
Colin Cross2207f872021-03-24 12:39:08 -0700594 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000595 if apiVersions != nil {
596 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
597 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
598 cmd.FlagWithInput("--apply-api-levels ", apiVersions)
599 }
600}
Colin Cross2207f872021-03-24 12:39:08 -0700601
Jihoon Kang3c89f042023-12-19 02:40:22 +0000602func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Colin Cross2207f872021-03-24 12:39:08 -0700603 if len(d.properties.Api_levels_annotations_dirs) == 0 {
604 ctx.PropertyErrorf("api_levels_annotations_dirs",
605 "has to be non-empty if api levels annotations was enabled!")
606 }
607
Jihoon Kang3c89f042023-12-19 02:40:22 +0000608 cmd.FlagWithOutput("--generate-api-levels ", apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700609
610 filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
611
satayev783195c2021-06-23 21:49:57 +0100612 var dirs []string
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200613 var extensions_dir string
Colin Cross2207f872021-03-24 12:39:08 -0700614 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
615 if t, ok := m.(*ExportedDroiddocDir); ok {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200616 extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
617
618 // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
619 // ideally this should be read from prebuiltApis.properties.Extensions_*
Colin Cross2207f872021-03-24 12:39:08 -0700620 for _, dep := range t.deps {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200621 if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
622 if extensions_dir == "" {
623 extensions_dir = t.dir.String() + "/extensions"
624 }
625 cmd.Implicit(dep)
626 }
Colin Cross5f6ffc72021-03-29 21:54:45 -0700627 if dep.Base() == filename {
628 cmd.Implicit(dep)
629 }
630 if filename != "android.jar" && dep.Base() == "android.jar" {
631 // Metalava implicitly searches these patterns:
632 // prebuilts/tools/common/api-versions/android-%/android.jar
633 // prebuilts/sdk/%/public/android.jar
634 // Add android.jar files from the api_levels_annotations_dirs directories to try
635 // to satisfy these patterns. If Metalava can't find a match for an API level
636 // between 1 and 28 in at least one pattern it will fail.
Colin Cross2207f872021-03-24 12:39:08 -0700637 cmd.Implicit(dep)
638 }
639 }
satayev783195c2021-06-23 21:49:57 +0100640
641 dirs = append(dirs, t.dir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700642 } else {
643 ctx.PropertyErrorf("api_levels_annotations_dirs",
644 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
645 }
646 })
satayev783195c2021-06-23 21:49:57 +0100647
648 // Add all relevant --android-jar-pattern patterns for Metalava.
649 // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
650 // an actual file present on disk (in the order the patterns were passed). For system APIs for
651 // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
Pedro Loureirocc203502021-10-04 17:24:00 +0000652 // for older releases. Similarly, module-lib falls back to system API.
653 var sdkDirs []string
654 switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
Cole Faust051fa912022-10-05 12:45:42 -0700655 case "system-server":
656 sdkDirs = []string{"system-server", "module-lib", "system", "public"}
Pedro Loureirocc203502021-10-04 17:24:00 +0000657 case "module-lib":
658 sdkDirs = []string{"module-lib", "system", "public"}
659 case "system":
660 sdkDirs = []string{"system", "public"}
661 case "public":
662 sdkDirs = []string{"public"}
663 default:
664 ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
665 return
satayev783195c2021-06-23 21:49:57 +0100666 }
Pedro Loureirocc203502021-10-04 17:24:00 +0000667
668 for _, sdkDir := range sdkDirs {
669 for _, dir := range dirs {
670 cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
671 }
satayev783195c2021-06-23 21:49:57 +0100672 }
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200673
674 if d.properties.Extensions_info_file != nil {
675 if extensions_dir == "" {
676 ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
677 }
678 info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
679 cmd.Implicit(info_file)
680 cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
681 cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
682 }
Colin Cross2207f872021-03-24 12:39:08 -0700683}
684
Colin Crosse52c2ac2022-03-28 17:03:35 -0700685func metalavaUseRbe(ctx android.ModuleContext) bool {
686 return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
687}
688
Colin Cross2207f872021-03-24 12:39:08 -0700689func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Anton Hansson556e8142021-06-04 16:20:25 +0100690 srcJarList android.Path, bootclasspath, classpath classpath, homeDir android.WritablePath) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700691 rule.Command().Text("rm -rf").Flag(homeDir.String())
692 rule.Command().Text("mkdir -p").Flag(homeDir.String())
693
Anton Hansson556e8142021-06-04 16:20:25 +0100694 cmd := rule.Command()
Colin Cross2207f872021-03-24 12:39:08 -0700695 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())
696
Colin Crosse52c2ac2022-03-28 17:03:35 -0700697 if metalavaUseRbe(ctx) {
Colin Cross2207f872021-03-24 12:39:08 -0700698 rule.Remoteable(android.RemoteRuleSupports{RBE: true})
Colin Cross8095c292021-03-30 16:40:48 -0700699 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000700 compare := ctx.Config().IsEnvTrue("RBE_METALAVA_COMPARE")
701 remoteUpdateCache := !ctx.Config().IsEnvFalse("RBE_METALAVA_REMOTE_UPDATE_CACHE")
Colin Cross8095c292021-03-30 16:40:48 -0700702 labels := map[string]string{"type": "tool", "name": "metalava"}
703 // TODO: metalava pool rejects these jobs
704 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
705 rule.Rewrapper(&remoteexec.REParams{
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000706 Labels: labels,
707 ExecStrategy: execStrategy,
708 ToolchainInputs: []string{config.JavaCmd(ctx).String()},
709 Platform: map[string]string{remoteexec.PoolKey: pool},
710 Compare: compare,
711 NumLocalRuns: 1,
712 NumRemoteRuns: 1,
713 NoRemoteUpdateCache: !remoteUpdateCache,
Colin Cross8095c292021-03-30 16:40:48 -0700714 })
Colin Cross2207f872021-03-24 12:39:08 -0700715 }
716
Colin Cross6aa5c402021-03-24 12:28:50 -0700717 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
Colin Cross2207f872021-03-24 12:39:08 -0700718 Flag(config.JavacVmFlags).
Liz Kammere09e20e2023-10-16 15:07:54 -0400719 Flag(config.MetalavaAddOpens).
Paul Duffin808211e2023-08-09 12:36:08 +0100720 FlagWithArg("--java-source ", javaVersion.String()).
Colin Cross2207f872021-03-24 12:39:08 -0700721 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
722 FlagWithInput("@", srcJarList)
723
Paul Duffinf8aaaa12023-08-10 15:16:35 +0100724 // Metalava does not differentiate between bootclasspath and classpath and has not done so for
725 // years, so it is unlikely to change any time soon.
726 combinedPaths := append(([]android.Path)(nil), bootclasspath.Paths()...)
727 combinedPaths = append(combinedPaths, classpath.Paths()...)
728 if len(combinedPaths) > 0 {
729 cmd.FlagWithInputList("--classpath ", combinedPaths, ":")
Colin Cross2207f872021-03-24 12:39:08 -0700730 }
731
Liz Kammere09e20e2023-10-16 15:07:54 -0400732 cmd.Flag(config.MetalavaFlags)
Jihoon Kangc8313892023-09-20 00:54:47 +0000733
Colin Cross2207f872021-03-24 12:39:08 -0700734 return cmd
735}
736
Jihoon Kang3c89f042023-12-19 02:40:22 +0000737// Pass flagged apis related flags to metalava. When aconfig_declarations property is not
738// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
739// property is defined, apply transformations and only revert the flagged apis that are not
740// enabled via release configurations and are not specified in aconfig_declarations
Jihoon Kang5d701272024-02-15 21:53:49 +0000741func generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000742
743 if len(aconfigFlagsPaths) == 0 {
744 cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
745 return
746 }
Jihoon Kang6592e872023-12-19 01:13:16 +0000747
748 releasedFlaggedApisFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flagged-apis-%s.txt", stubsType.String()))
749 revertAnnotationsFile := android.PathForModuleOut(ctx, fmt.Sprintf("revert-annotations-%s.txt", stubsType.String()))
750
751 var filterArgs string
752 switch stubsType {
753 // No flagged apis specific flags need to be passed to metalava when generating
754 // everything stubs
755 case Everything:
756 return
757
758 case Runtime:
759 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
760
761 case Exportable:
Jihoon Kang59198152024-02-06 22:43:18 +0000762 // When the build flag RELEASE_EXPORT_RUNTIME_APIS is set to true, apis marked with
763 // the flagged apis that have read_write permissions are exposed on top of the enabled
764 // and read_only apis. This is to support local override of flag values at runtime.
765 if ctx.Config().ReleaseExportRuntimeApis() {
766 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
767 } else {
768 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY'"
769 }
Jihoon Kang6592e872023-12-19 01:13:16 +0000770 }
771
772 ctx.Build(pctx, android.BuildParams{
773 Rule: gatherReleasedFlaggedApisRule,
774 Inputs: aconfigFlagsPaths,
775 Output: releasedFlaggedApisFile,
776 Description: fmt.Sprintf("%s gather aconfig flags", stubsType),
777 Args: map[string]string{
778 "flags_path": android.JoinPathsWithPrefix(aconfigFlagsPaths, "--cache "),
779 "filter_args": filterArgs,
780 },
781 })
782
783 ctx.Build(pctx, android.BuildParams{
784 Rule: generateMetalavaRevertAnnotationsRule,
785 Input: releasedFlaggedApisFile,
786 Output: revertAnnotationsFile,
787 Description: fmt.Sprintf("%s revert annotations", stubsType),
788 })
Jihoon Kang3c89f042023-12-19 02:40:22 +0000789
790 cmd.FlagWithInput("@", revertAnnotationsFile)
Jihoon Kang6592e872023-12-19 01:13:16 +0000791}
792
Jihoon Kang3c89f042023-12-19 02:40:22 +0000793func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
794 params stubsCommandParams) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700795 if BoolDefault(d.properties.High_mem, false) {
796 // This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
797 rule.HighMem()
798 }
799
Jihoon Kang3c89f042023-12-19 02:40:22 +0000800 if params.stubConfig.generateStubs {
801 rule.Command().Text("rm -rf").Text(params.stubsDir.String())
802 rule.Command().Text("mkdir -p").Text(params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700803 }
804
Jihoon Kang3c89f042023-12-19 02:40:22 +0000805 srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars)
Colin Cross2207f872021-03-24 12:39:08 -0700806
Jihoon Kang3c89f042023-12-19 02:40:22 +0000807 homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home")
808 cmd := metalavaCmd(ctx, rule, params.stubConfig.javaVersion, d.Javadoc.srcFiles, srcJarList,
809 params.stubConfig.deps.bootClasspath, params.stubConfig.deps.classpath, homeDir)
Colin Cross2207f872021-03-24 12:39:08 -0700810 cmd.Implicits(d.Javadoc.implicits)
811
Jihoon Kang3c89f042023-12-19 02:40:22 +0000812 d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
Colin Cross2207f872021-03-24 12:39:08 -0700813
Jihoon Kang3c89f042023-12-19 02:40:22 +0000814 if params.stubConfig.writeSdkValues {
815 d.sdkValuesFlags(ctx, cmd, params.metadataDir)
816 }
817
818 annotationParams := annotationFlagsParams{
819 migratingNullability: params.stubConfig.migratingNullability,
820 validatingNullability: params.stubConfig.validatingNullability,
821 nullabilityWarningsFile: params.nullabilityWarningsFile,
822 annotationsZip: params.annotationsZip,
823 }
824
Jihoon Kang6b93b382024-01-26 22:37:41 +0000825 if params.stubConfig.annotationsEnabled {
826 d.annotationsFlags(ctx, cmd, annotationParams)
827 }
Colin Cross2207f872021-03-24 12:39:08 -0700828 d.inclusionAnnotationsFlags(ctx, cmd)
Jihoon Kang6b93b382024-01-26 22:37:41 +0000829 d.apiLevelsAnnotationsFlags(ctx, cmd, params)
Colin Cross2207f872021-03-24 12:39:08 -0700830
Colin Crossbc139922021-03-25 18:33:16 -0700831 d.expandArgs(ctx, cmd)
Colin Cross2207f872021-03-24 12:39:08 -0700832
Colin Cross2207f872021-03-24 12:39:08 -0700833 for _, o := range d.Javadoc.properties.Out {
834 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
835 }
836
Jihoon Kang3c89f042023-12-19 02:40:22 +0000837 return cmd
838}
Colin Cross2207f872021-03-24 12:39:08 -0700839
Jihoon Kang3c89f042023-12-19 02:40:22 +0000840// Sandbox rule for generating the everything stubs and other artifacts
841func (d *Droidstubs) everythingStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
842 srcJarDir := android.PathForModuleOut(ctx, Everything.String(), "srcjars")
843 rule := android.NewRuleBuilder(pctx, ctx)
844 rule.Sbox(android.PathForModuleOut(ctx, Everything.String()),
845 android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
846 SandboxInputs()
847
848 var stubsDir android.OptionalPath
849 if params.generateStubs {
850 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, Everything.String(), "stubsDir"))
851 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
852 }
853
854 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +0000855 d.everythingArtifacts.metadataDir = android.PathForModuleOut(ctx, Everything.String(), "metadata")
856 d.everythingArtifacts.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000857 }
858
Jihoon Kang6b93b382024-01-26 22:37:41 +0000859 if params.annotationsEnabled {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000860 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +0000861 d.everythingArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000862 }
Jihoon Kangee113282024-01-23 00:16:41 +0000863 d.everythingArtifacts.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000864 }
Jihoon Kang6b93b382024-01-26 22:37:41 +0000865 if params.apiLevelsAnnotationsEnabled {
Jihoon Kangee113282024-01-23 00:16:41 +0000866 d.everythingArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000867 }
868
869 commonCmdParams := stubsCommandParams{
870 srcJarDir: srcJarDir,
871 stubsDir: stubsDir,
872 stubsSrcJar: d.Javadoc.stubsSrcJar,
Jihoon Kangee113282024-01-23 00:16:41 +0000873 metadataDir: d.everythingArtifacts.metadataDir,
874 apiVersionsXml: d.everythingArtifacts.apiVersionsXml,
875 nullabilityWarningsFile: d.everythingArtifacts.nullabilityWarningsFile,
876 annotationsZip: d.everythingArtifacts.annotationsZip,
Jihoon Kang3c89f042023-12-19 02:40:22 +0000877 stubConfig: params,
878 }
879
880 cmd := d.commonMetalavaStubCmd(ctx, rule, commonCmdParams)
881
882 d.everythingOptionalCmd(ctx, cmd, params.doApiLint, params.doCheckReleased)
883
884 if params.generateStubs {
885 rule.Command().
886 BuiltTool("soong_zip").
887 Flag("-write_if_changed").
888 Flag("-jar").
889 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
890 FlagWithArg("-C ", stubsDir.String()).
891 FlagWithArg("-D ", stubsDir.String())
892 }
893
894 if params.writeSdkValues {
895 rule.Command().
896 BuiltTool("soong_zip").
897 Flag("-write_if_changed").
898 Flag("-d").
Jihoon Kangee113282024-01-23 00:16:41 +0000899 FlagWithOutput("-o ", d.everythingArtifacts.metadataZip).
900 FlagWithArg("-C ", d.everythingArtifacts.metadataDir.String()).
901 FlagWithArg("-D ", d.everythingArtifacts.metadataDir.String())
Jihoon Kang3c89f042023-12-19 02:40:22 +0000902 }
903
904 // TODO: We don't really need two separate API files, but this is a reminiscence of how
905 // we used to run metalava separately for API lint and the "last_released" check. Unify them.
906 if params.doApiLint {
907 rule.Command().Text("touch").Output(d.apiLintTimestamp)
908 }
909 if params.doCheckReleased {
910 rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
911 }
912
913 // TODO(b/183630617): rewrapper doesn't support restat rules
914 if !metalavaUseRbe(ctx) {
915 rule.Restat()
916 }
917
918 zipSyncCleanupCmd(rule, srcJarDir)
919
920 rule.Build("metalava", "metalava merged")
921}
922
923// Sandbox rule for generating the everything artifacts that are not run by
924// default but only run based on the module configurations
925func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, doApiLint bool, doCheckReleased bool) {
Colin Cross2207f872021-03-24 12:39:08 -0700926
927 // Add API lint options.
Jihoon Kang3c89f042023-12-19 02:40:22 +0000928 if doApiLint {
Colin Cross2207f872021-03-24 12:39:08 -0700929 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
930 if newSince.Valid() {
931 cmd.FlagWithInput("--api-lint ", newSince.Path())
932 } else {
933 cmd.Flag("--api-lint")
934 }
Jihoon Kang3c89f042023-12-19 02:40:22 +0000935 d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700936 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
937
Colin Cross0d532412021-03-25 09:38:45 -0700938 // TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
Colin Cross2207f872021-03-24 12:39:08 -0700939 if d.Name() != "android.car-system-stubs-docs" &&
940 d.Name() != "android.car-stubs-docs" {
941 cmd.Flag("--lints-as-errors")
942 cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
943 }
944
945 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000946 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "api_lint_baseline.txt")
947 d.apiLintTimestamp = android.PathForModuleOut(ctx, Everything.String(), "api_lint.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700948
949 // Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
Colin Cross2207f872021-03-24 12:39:08 -0700950 //
951 // TODO: metalava also has a slightly different message hardcoded. Should we unify this
952 // message and metalava's one?
953 msg := `$'` + // Enclose with $' ... '
954 `************************************************************\n` +
955 `Your API changes are triggering API Lint warnings or errors.\n` +
956 `To make these errors go away, fix the code according to the\n` +
957 `error and/or warning messages above.\n` +
958 `\n` +
959 `If it is not possible to do so, there are workarounds:\n` +
960 `\n` +
Aurimas Liutikasb23b7452021-05-24 18:00:37 +0000961 `1. You can suppress the errors with @SuppressLint("<id>")\n` +
962 ` where the <id> is given in brackets in the error message above.\n`
Colin Cross2207f872021-03-24 12:39:08 -0700963
964 if baselineFile.Valid() {
965 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
966 cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)
967
968 msg += fmt.Sprintf(``+
969 `2. You can update the baseline by executing the following\n`+
970 ` command:\n`+
Colin Cross63eeda02021-04-15 19:01:57 -0700971 ` (cd $ANDROID_BUILD_TOP && cp \\\n`+
972 ` "%s" \\\n`+
973 ` "%s")\n`+
Colin Cross2207f872021-03-24 12:39:08 -0700974 ` To submit the revised baseline.txt to the main Android\n`+
975 ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
976 } else {
977 msg += fmt.Sprintf(``+
978 `2. You can add a baseline file of existing lint failures\n`+
979 ` to the build rule of %s.\n`, d.Name())
980 }
981 // Note the message ends with a ' (single quote), to close the $' ... ' .
982 msg += `************************************************************\n'`
983
984 cmd.FlagWithArg("--error-message:api-lint ", msg)
985 }
986
987 // Add "check released" options. (Detect incompatible API changes from the last public release)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000988 if doCheckReleased {
Colin Cross2207f872021-03-24 12:39:08 -0700989 if len(d.Javadoc.properties.Out) > 0 {
990 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
991 }
992
993 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
994 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
995 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000996 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700997
Jihoon Kang3c89f042023-12-19 02:40:22 +0000998 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700999
1000 cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
1001 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1002
1003 if baselineFile.Valid() {
1004 cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
1005 cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
1006 }
1007
1008 // Note this string includes quote ($' ... '), which decodes the "\n"s.
1009 msg := `$'\n******************************\n` +
1010 `You have tried to change the API from what has been previously released in\n` +
1011 `an SDK. Please fix the errors listed above.\n` +
1012 `******************************\n'`
1013
1014 cmd.FlagWithArg("--error-message:compatibility:released ", msg)
1015 }
1016
Paul Duffin10a23c22023-08-11 22:47:31 +01001017 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1018 // Pass the current API file into metalava so it can use it as the basis for determining how to
1019 // generate the output signature files (both api and removed).
1020 currentApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1021 cmd.FlagWithInput("--use-same-format-as ", currentApiFile)
1022 }
Jihoon Kang3c89f042023-12-19 02:40:22 +00001023}
Paul Duffin10a23c22023-08-11 22:47:31 +01001024
Jihoon Kang3c89f042023-12-19 02:40:22 +00001025// Sandbox rule for generating exportable stubs and other artifacts
1026func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
1027 optionalCmdParams := stubsCommandParams{
1028 stubConfig: params,
1029 }
1030
Jihoon Kang246690a2024-02-01 21:55:01 +00001031 if params.generateStubs {
1032 d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
1033 optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
1034 }
1035
Jihoon Kang3c89f042023-12-19 02:40:22 +00001036 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +00001037 d.exportableArtifacts.metadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
1038 d.exportableArtifacts.metadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
1039 optionalCmdParams.metadataZip = d.exportableArtifacts.metadataZip
1040 optionalCmdParams.metadataDir = d.exportableArtifacts.metadataDir
Jihoon Kang3c89f042023-12-19 02:40:22 +00001041 }
1042
Jihoon Kang6b93b382024-01-26 22:37:41 +00001043 if params.annotationsEnabled {
Jihoon Kang3c89f042023-12-19 02:40:22 +00001044 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +00001045 d.exportableArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
1046 optionalCmdParams.nullabilityWarningsFile = d.exportableArtifacts.nullabilityWarningsFile
Jihoon Kang3c89f042023-12-19 02:40:22 +00001047 }
Jihoon Kangee113282024-01-23 00:16:41 +00001048 d.exportableArtifacts.annotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
1049 optionalCmdParams.annotationsZip = d.exportableArtifacts.annotationsZip
Jihoon Kang3c89f042023-12-19 02:40:22 +00001050 }
Jihoon Kang6b93b382024-01-26 22:37:41 +00001051 if params.apiLevelsAnnotationsEnabled {
Jihoon Kangee113282024-01-23 00:16:41 +00001052 d.exportableArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
1053 optionalCmdParams.apiVersionsXml = d.exportableArtifacts.apiVersionsXml
Jihoon Kang3c89f042023-12-19 02:40:22 +00001054 }
1055
1056 if params.checkApi || String(d.properties.Api_filename) != "" {
1057 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
1058 d.exportableApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1059 }
1060
1061 if params.checkApi || String(d.properties.Removed_api_filename) != "" {
1062 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_api.txt")
1063 d.exportableRemovedApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1064 }
1065
1066 d.optionalStubCmd(ctx, optionalCmdParams)
1067}
1068
1069func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsCommandParams) {
1070
1071 params.srcJarDir = android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "srcjars")
1072 rule := android.NewRuleBuilder(pctx, ctx)
1073 rule.Sbox(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String()),
1074 android.PathForModuleOut(ctx, fmt.Sprintf("metalava_%s.sbox.textproto", params.stubConfig.stubsType.String()))).
1075 SandboxInputs()
1076
1077 if params.stubConfig.generateStubs {
1078 params.stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "stubsDir"))
1079 }
1080
1081 cmd := d.commonMetalavaStubCmd(ctx, rule, params)
1082
Jihoon Kang5d701272024-02-15 21:53:49 +00001083 generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
Jihoon Kang3c89f042023-12-19 02:40:22 +00001084
1085 if params.stubConfig.doApiLint {
1086 // Pass the lint baseline file as an input to resolve the lint errors.
1087 // The exportable stubs generation does not update the lint baseline file.
1088 // Lint baseline file update is handled by the everything stubs
1089 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1090 if baselineFile.Valid() {
1091 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
1092 }
1093 }
1094
1095 if params.stubConfig.generateStubs {
Colin Cross2207f872021-03-24 12:39:08 -07001096 rule.Command().
1097 BuiltTool("soong_zip").
1098 Flag("-write_if_changed").
1099 Flag("-jar").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001100 FlagWithOutput("-o ", params.stubsSrcJar).
1101 FlagWithArg("-C ", params.stubsDir.String()).
1102 FlagWithArg("-D ", params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001103 }
1104
Jihoon Kang3c89f042023-12-19 02:40:22 +00001105 if params.stubConfig.writeSdkValues {
Colin Cross2207f872021-03-24 12:39:08 -07001106 rule.Command().
1107 BuiltTool("soong_zip").
1108 Flag("-write_if_changed").
1109 Flag("-d").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001110 FlagWithOutput("-o ", params.metadataZip).
1111 FlagWithArg("-C ", params.metadataDir.String()).
1112 FlagWithArg("-D ", params.metadataDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001113 }
1114
Colin Cross6aa5c402021-03-24 12:28:50 -07001115 // TODO(b/183630617): rewrapper doesn't support restat rules
Colin Crosse52c2ac2022-03-28 17:03:35 -07001116 if !metalavaUseRbe(ctx) {
1117 rule.Restat()
1118 }
Colin Cross2207f872021-03-24 12:39:08 -07001119
Jihoon Kang3c89f042023-12-19 02:40:22 +00001120 zipSyncCleanupCmd(rule, params.srcJarDir)
Colin Cross2207f872021-03-24 12:39:08 -07001121
Jihoon Kang3c89f042023-12-19 02:40:22 +00001122 rule.Build(fmt.Sprintf("metalava_%s", params.stubConfig.stubsType.String()), "metalava merged")
1123}
1124
1125func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1126 deps := d.Javadoc.collectDeps(ctx)
1127
1128 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
1129 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
1130
1131 // Add options for the other optional tasks: API-lint and check-released.
1132 // We generate separate timestamp files for them.
1133 doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
1134 doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1135
1136 writeSdkValues := Bool(d.properties.Write_sdk_values)
1137
1138 annotationsEnabled := Bool(d.properties.Annotations_enabled)
1139
1140 migratingNullability := annotationsEnabled && String(d.properties.Previous_api) != ""
1141 validatingNullability := annotationsEnabled && (strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
1142 String(d.properties.Validate_nullability_from_list) != "")
1143
1144 checkApi := apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1145 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1146
Jihoon Kang6b93b382024-01-26 22:37:41 +00001147 apiLevelsAnnotationsEnabled := proptools.Bool(d.properties.Api_levels_annotations_enabled)
1148
Jihoon Kang3c89f042023-12-19 02:40:22 +00001149 stubCmdParams := stubsCommandConfigParams{
Jihoon Kang6b93b382024-01-26 22:37:41 +00001150 javaVersion: javaVersion,
1151 deps: deps,
1152 checkApi: checkApi,
1153 generateStubs: generateStubs,
1154 doApiLint: doApiLint,
1155 doCheckReleased: doCheckReleased,
1156 writeSdkValues: writeSdkValues,
1157 migratingNullability: migratingNullability,
1158 validatingNullability: validatingNullability,
1159 annotationsEnabled: annotationsEnabled,
1160 apiLevelsAnnotationsEnabled: apiLevelsAnnotationsEnabled,
Jihoon Kang3c89f042023-12-19 02:40:22 +00001161 }
1162 stubCmdParams.stubsType = Everything
1163 // Create default (i.e. "everything" stubs) rule for metalava
1164 d.everythingStubCmd(ctx, stubCmdParams)
1165
Jihoon Kang17f01d92024-03-05 16:12:20 +00001166 // The module generates "exportable" (and "runtime" eventually) stubs regardless of whether
Jihoon Kang3c89f042023-12-19 02:40:22 +00001167 // aconfig_declarations property is defined or not. If the property is not defined, the module simply
1168 // strips all flagged apis to generate the "exportable" stubs
1169 stubCmdParams.stubsType = Exportable
1170 d.exportableStubCmd(ctx, stubCmdParams)
Paul Duffinc166b682022-05-27 12:23:08 +00001171
Paul Duffine7a86642022-08-16 15:43:20 +00001172 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1173
1174 if len(d.Javadoc.properties.Out) > 0 {
1175 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1176 }
1177
1178 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1179 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
1180 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1181
1182 if baselineFile.Valid() {
1183 ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
1184 }
1185
Jihoon Kang3c89f042023-12-19 02:40:22 +00001186 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001187
1188 rule := android.NewRuleBuilder(pctx, ctx)
1189
1190 // Diff command line.
1191 // -F matches the closest "opening" line, such as "package android {"
1192 // and " public class Intent {".
1193 diff := `diff -u -F '{ *$'`
1194
1195 rule.Command().Text("( true")
1196 rule.Command().
1197 Text(diff).
1198 Input(apiFile).Input(d.apiFile)
1199
1200 rule.Command().
1201 Text(diff).
1202 Input(removedApiFile).Input(d.removedApiFile)
1203
1204 msg := fmt.Sprintf(`\n******************************\n`+
1205 `You have tried to change the API from what has been previously approved.\n\n`+
1206 `To make these errors go away, you have two choices:\n`+
1207 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
1208 ` to the new methods, etc. shown in the above diff.\n\n`+
1209 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
1210 ` m %s-update-current-api\n\n`+
1211 ` To submit the revised current.txt to the main Android repository,\n`+
1212 ` you will need approval.\n`+
Jihoon Kang3ea64672023-11-03 00:40:26 +00001213 `If your build failed due to stub validation, you can resolve the errors with\n`+
1214 `either of the two choices above and try re-building the target.\n`+
1215 `If the mismatch between the stubs and the current.txt is intended,\n`+
1216 `you can try re-building the target by executing the following command:\n`+
Jihoon Kang91bf3dd2024-01-24 00:40:23 +00001217 `m DISABLE_STUB_VALIDATION=true <your build target>.\n`+
1218 `Note that DISABLE_STUB_VALIDATION=true does not bypass checkapi.\n`+
Paul Duffine7a86642022-08-16 15:43:20 +00001219 `******************************\n`, ctx.ModuleName())
1220
1221 rule.Command().
1222 Text("touch").Output(d.checkCurrentApiTimestamp).
1223 Text(") || (").
1224 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1225 Text("; exit 38").
1226 Text(")")
1227
1228 rule.Build("metalavaCurrentApiCheck", "check current API")
1229
Jihoon Kang3c89f042023-12-19 02:40:22 +00001230 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001231
1232 // update API rule
1233 rule = android.NewRuleBuilder(pctx, ctx)
1234
1235 rule.Command().Text("( true")
1236
1237 rule.Command().
1238 Text("cp").Flag("-f").
1239 Input(d.apiFile).Flag(apiFile.String())
1240
1241 rule.Command().
1242 Text("cp").Flag("-f").
1243 Input(d.removedApiFile).Flag(removedApiFile.String())
1244
1245 msg = "failed to update public API"
1246
1247 rule.Command().
1248 Text("touch").Output(d.updateCurrentApiTimestamp).
1249 Text(") || (").
1250 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1251 Text("; exit 38").
1252 Text(")")
1253
1254 rule.Build("metalavaCurrentApiUpdate", "update current API")
1255 }
1256
Colin Cross2207f872021-03-24 12:39:08 -07001257 if String(d.properties.Check_nullability_warnings) != "" {
Jihoon Kangee113282024-01-23 00:16:41 +00001258 if d.everythingArtifacts.nullabilityWarningsFile == nil {
Colin Cross2207f872021-03-24 12:39:08 -07001259 ctx.PropertyErrorf("check_nullability_warnings",
1260 "Cannot specify check_nullability_warnings unless validating nullability")
1261 }
1262
1263 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1264
Jihoon Kang3c89f042023-12-19 02:40:22 +00001265 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -07001266
1267 msg := fmt.Sprintf(`\n******************************\n`+
1268 `The warnings encountered during nullability annotation validation did\n`+
1269 `not match the checked in file of expected warnings. The diffs are shown\n`+
1270 `above. You have two options:\n`+
1271 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1272 ` 2. Update the file of expected warnings by running:\n`+
1273 ` cp %s %s\n`+
1274 ` and submitting the updated file as part of your change.`,
Jihoon Kangee113282024-01-23 00:16:41 +00001275 d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross2207f872021-03-24 12:39:08 -07001276
1277 rule := android.NewRuleBuilder(pctx, ctx)
1278
1279 rule.Command().
1280 Text("(").
Jihoon Kangee113282024-01-23 00:16:41 +00001281 Text("diff").Input(checkNullabilityWarnings).Input(d.everythingArtifacts.nullabilityWarningsFile).
Colin Cross2207f872021-03-24 12:39:08 -07001282 Text("&&").
1283 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1284 Text(") || (").
1285 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1286 Text("; exit 38").
1287 Text(")")
1288
1289 rule.Build("nullabilityWarningsCheck", "nullability warnings check")
1290 }
LaMont Jonesafe7baf2024-01-09 22:47:39 +00001291 android.CollectDependencyAconfigFiles(ctx, &d.mergedAconfigFiles)
Colin Cross2207f872021-03-24 12:39:08 -07001292}
1293
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001294func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
1295 api_file := d.properties.Check_api.Current.Api_file
1296 api_surface := d.properties.Api_surface
1297
1298 props := struct {
1299 Name *string
1300 Api_surface *string
1301 Api_file *string
Jihoon Kang42b589c2023-02-03 22:56:13 +00001302 Visibility []string
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001303 }{}
1304
1305 props.Name = proptools.StringPtr(d.Name() + ".api.contribution")
1306 props.Api_surface = api_surface
1307 props.Api_file = api_file
Jihoon Kang42b589c2023-02-03 22:56:13 +00001308 props.Visibility = []string{"//visibility:override", "//visibility:public"}
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001309
1310 ctx.CreateModule(ApiContributionFactory, &props)
1311}
1312
Spandan Das0b555e32022-11-28 18:48:51 +00001313// TODO (b/262014796): Export the API contributions of CorePlatformApi
1314// A map to populate the api surface of a droidstub from a substring appearing in its name
1315// This map assumes that droidstubs (either checked-in or created by java_sdk_library)
1316// use a strict naming convention
1317var (
1318 droidstubsModuleNamingToSdkKind = map[string]android.SdkKind{
1319 //public is commented out since the core libraries use public in their java_sdk_library names
1320 "intracore": android.SdkIntraCore,
1321 "intra.core": android.SdkIntraCore,
1322 "system_server": android.SdkSystemServer,
1323 "system-server": android.SdkSystemServer,
1324 "system": android.SdkSystem,
1325 "module_lib": android.SdkModule,
1326 "module-lib": android.SdkModule,
Spandan Dasda977552023-01-26 20:45:16 +00001327 "platform.api": android.SdkCorePlatform,
Spandan Das0b555e32022-11-28 18:48:51 +00001328 "test": android.SdkTest,
Spandan Das4ac2aed2022-12-28 01:54:29 +00001329 "toolchain": android.SdkToolchain,
Spandan Das0b555e32022-11-28 18:48:51 +00001330 }
1331)
1332
Colin Cross2207f872021-03-24 12:39:08 -07001333func StubsDefaultsFactory() android.Module {
1334 module := &DocDefaults{}
1335
1336 module.AddProperties(
1337 &JavadocProperties{},
1338 &DroidstubsProperties{},
1339 )
1340
1341 android.InitDefaultsModule(module)
1342
1343 return module
1344}
1345
1346var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
1347
1348type PrebuiltStubsSourcesProperties struct {
1349 Srcs []string `android:"path"`
Spandan Das23956d12024-01-19 00:22:22 +00001350
1351 // Name of the source soong module that gets shadowed by this prebuilt
1352 // If unspecified, follows the naming convention that the source module of
1353 // the prebuilt is Name() without "prebuilt_" prefix
1354 Source_module_name *string
1355
1356 // Non-nil if this prebuilt stub srcs module was dynamically created by a java_sdk_library_import
1357 // The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
1358 // (without any prebuilt_ prefix)
1359 Created_by_java_sdk_library_name *string `blueprint:"mutated"`
1360}
1361
1362func (j *PrebuiltStubsSources) BaseModuleName() string {
1363 return proptools.StringDefault(j.properties.Source_module_name, j.ModuleBase.Name())
1364}
1365
1366func (j *PrebuiltStubsSources) CreatedByJavaSdkLibraryName() *string {
1367 return j.properties.Created_by_java_sdk_library_name
Colin Cross2207f872021-03-24 12:39:08 -07001368}
1369
1370type PrebuiltStubsSources struct {
1371 android.ModuleBase
1372 android.DefaultableModuleBase
Spandan Das2cc80ba2023-10-27 17:21:52 +00001373 embeddableInModuleAndImport
1374
Colin Cross2207f872021-03-24 12:39:08 -07001375 prebuilt android.Prebuilt
Colin Cross2207f872021-03-24 12:39:08 -07001376
1377 properties PrebuiltStubsSourcesProperties
1378
kgui67007242022-01-25 13:50:25 +08001379 stubsSrcJar android.Path
Colin Cross2207f872021-03-24 12:39:08 -07001380}
1381
1382func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
1383 switch tag {
Jihoon Kangfa4a90d2023-12-20 02:53:38 +00001384 // prebuilt droidstubs does not output "exportable" stubs.
1385 // Output the "everything" stubs srcjar file if the tag is ".exportable".
1386 case "", ".exportable":
Colin Cross2207f872021-03-24 12:39:08 -07001387 return android.Paths{p.stubsSrcJar}, nil
1388 default:
1389 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1390 }
1391}
1392
Jihoon Kangee113282024-01-23 00:16:41 +00001393func (d *PrebuiltStubsSources) StubsSrcJar(_ StubsType) (android.Path, error) {
1394 return d.stubsSrcJar, nil
Colin Cross2207f872021-03-24 12:39:08 -07001395}
1396
1397func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross2207f872021-03-24 12:39:08 -07001398 if len(p.properties.Srcs) != 1 {
Anton Hansson86758ac2021-11-03 14:44:12 +00001399 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 -07001400 return
1401 }
1402
Anton Hansson86758ac2021-11-03 14:44:12 +00001403 src := p.properties.Srcs[0]
1404 if filepath.Ext(src) == ".srcjar" {
1405 // This is a srcjar. We can use it directly.
1406 p.stubsSrcJar = android.PathForModuleSrc(ctx, src)
1407 } else {
1408 outPath := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Colin Cross2207f872021-03-24 12:39:08 -07001409
Anton Hansson86758ac2021-11-03 14:44:12 +00001410 // This is a directory. Glob the contents just in case the directory does not exist.
1411 srcGlob := src + "/**/*"
1412 srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})
Colin Cross2207f872021-03-24 12:39:08 -07001413
Anton Hansson86758ac2021-11-03 14:44:12 +00001414 // Although PathForModuleSrc can return nil if either the path doesn't exist or
1415 // the path components are invalid it won't in this case because no components
1416 // are specified and the module directory must exist in order to get this far.
1417 srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, src)
Colin Cross2207f872021-03-24 12:39:08 -07001418
Anton Hansson86758ac2021-11-03 14:44:12 +00001419 rule := android.NewRuleBuilder(pctx, ctx)
1420 rule.Command().
1421 BuiltTool("soong_zip").
1422 Flag("-write_if_changed").
1423 Flag("-jar").
1424 FlagWithOutput("-o ", outPath).
1425 FlagWithArg("-C ", srcDir.String()).
1426 FlagWithRspFileInputList("-r ", outPath.ReplaceExtension(ctx, "rsp"), srcPaths)
1427 rule.Restat()
1428 rule.Build("zip src", "Create srcjar from prebuilt source")
1429 p.stubsSrcJar = outPath
1430 }
Colin Cross2207f872021-03-24 12:39:08 -07001431}
1432
1433func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
1434 return &p.prebuilt
1435}
1436
1437func (p *PrebuiltStubsSources) Name() string {
1438 return p.prebuilt.Name(p.ModuleBase.Name())
1439}
1440
1441// prebuilt_stubs_sources imports a set of java source files as if they were
1442// generated by droidstubs.
1443//
1444// By default, a prebuilt_stubs_sources has a single variant that expects a
1445// set of `.java` files generated by droidstubs.
1446//
1447// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
1448// for host modules.
1449//
1450// Intended only for use by sdk snapshots.
1451func PrebuiltStubsSourcesFactory() android.Module {
1452 module := &PrebuiltStubsSources{}
1453
1454 module.AddProperties(&module.properties)
Spandan Das2cc80ba2023-10-27 17:21:52 +00001455 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -07001456
1457 android.InitPrebuiltModule(module, &module.properties.Srcs)
Colin Cross2207f872021-03-24 12:39:08 -07001458 InitDroiddocModule(module, android.HostAndDeviceSupported)
1459 return module
1460}