blob: 76c8d88902bf515fc1f88d0c120c4db4f57b6025 [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 Kanga11d6792024-03-05 16:12:20 +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
Jihoon Kang3c89f042023-12-19 02:40:22 +0000255}
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 Kangee113282024-01-23 00:16:41 +0000326 stubsSrcJar, err := d.StubsSrcJar(stubsType)
327 return android.Paths{stubsSrcJar}, err
Colin Cross2207f872021-03-24 12:39:08 -0700328 case ".docs.zip":
Jihoon Kangee113282024-01-23 00:16:41 +0000329 docZip, err := d.DocZip(stubsType)
330 return android.Paths{docZip}, err
Colin Cross2207f872021-03-24 12:39:08 -0700331 case ".api.txt", android.DefaultDistTag:
332 // This is the default dist path for dist properties that have no tag property.
Jihoon Kangee113282024-01-23 00:16:41 +0000333 apiFilePath, err := d.ApiFilePath(stubsType)
334 return android.Paths{apiFilePath}, err
Colin Cross2207f872021-03-24 12:39:08 -0700335 case ".removed-api.txt":
Jihoon Kangee113282024-01-23 00:16:41 +0000336 removedApiFilePath, err := d.RemovedApiFilePath(stubsType)
337 return android.Paths{removedApiFilePath}, err
Colin Cross2207f872021-03-24 12:39:08 -0700338 case ".annotations.zip":
Jihoon Kangee113282024-01-23 00:16:41 +0000339 annotationsZip, err := d.AnnotationsZip(stubsType)
340 return android.Paths{annotationsZip}, err
Colin Cross2207f872021-03-24 12:39:08 -0700341 case ".api_versions.xml":
Jihoon Kangee113282024-01-23 00:16:41 +0000342 apiVersionsXmlFilePath, err := d.ApiVersionsXmlFilePath(stubsType)
343 return android.Paths{apiVersionsXmlFilePath}, err
Colin Cross2207f872021-03-24 12:39:08 -0700344 default:
345 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
346 }
347}
348
Jihoon Kang246690a2024-02-01 21:55:01 +0000349func (d *Droidstubs) AnnotationsZip(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000350 switch stubsType {
351 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000352 ret, err = d.everythingArtifacts.annotationsZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000353 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000354 ret, err = d.exportableArtifacts.annotationsZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000355 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000356 ret, err = nil, fmt.Errorf("annotations zip not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000357 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000358 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000359}
360
Jihoon Kang246690a2024-02-01 21:55:01 +0000361func (d *Droidstubs) ApiFilePath(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000362 switch stubsType {
363 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000364 ret, err = d.apiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000365 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000366 ret, err = d.exportableApiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000367 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000368 ret, err = nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000369 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000370 if ret == nil && err == nil {
371 err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
372 }
373 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000374}
375
Jihoon Kang246690a2024-02-01 21:55:01 +0000376func (d *Droidstubs) ApiVersionsXmlFilePath(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000377 switch stubsType {
378 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000379 ret, err = d.everythingArtifacts.apiVersionsXml, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000380 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000381 ret, err = d.exportableArtifacts.apiVersionsXml, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000382 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000383 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 +0000384 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000385 if ret == nil && err == nil {
386 err = fmt.Errorf("api versions xml file is null for the stub type %s", stubsType.String())
387 }
388 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000389}
390
Jihoon Kang246690a2024-02-01 21:55:01 +0000391func (d *Droidstubs) DocZip(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000392 switch stubsType {
393 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000394 ret, err = d.docZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000395 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000396 ret, err = nil, fmt.Errorf("docs zip not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000397 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000398 if ret == nil && err == nil {
399 err = fmt.Errorf("docs zip is null for the stub type %s", stubsType.String())
400 }
401 return ret, err
402}
403
404func (d *Droidstubs) RemovedApiFilePath(stubsType StubsType) (ret android.Path, err error) {
405 switch stubsType {
406 case Everything:
407 ret, err = d.removedApiFile, nil
408 case Exportable:
409 ret, err = d.exportableRemovedApiFile, nil
410 default:
411 ret, err = nil, fmt.Errorf("removed api file path not supported for the stub type %s", stubsType.String())
412 }
413 if ret == nil && err == nil {
414 err = fmt.Errorf("removed api file is null for the stub type %s", stubsType.String())
415 }
416 return ret, err
417}
418
419func (d *Droidstubs) StubsSrcJar(stubsType StubsType) (ret android.Path, err error) {
420 switch stubsType {
421 case Everything:
422 ret, err = d.stubsSrcJar, nil
423 case Exportable:
424 ret, err = d.exportableStubsSrcJar, nil
425 default:
426 ret, err = nil, fmt.Errorf("stubs srcjar not supported for the stub type %s", stubsType.String())
427 }
428 if ret == nil && err == nil {
429 err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
430 }
431 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000432}
433
Jihoon Kang063ec002023-06-28 01:16:23 +0000434func (d *Droidstubs) CurrentApiTimestamp() android.Path {
435 return d.checkCurrentApiTimestamp
436}
437
Colin Cross2207f872021-03-24 12:39:08 -0700438var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
439var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
440var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000441var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"}
Jihoon Kang063ec002023-06-28 01:16:23 +0000442var metalavaCurrentApiTimestampTag = dependencyTag{name: "metalava-current-api-timestamp-tag"}
Colin Cross2207f872021-03-24 12:39:08 -0700443
444func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
445 d.Javadoc.addDeps(ctx)
446
447 if len(d.properties.Merge_annotations_dirs) != 0 {
448 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
449 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
450 }
451 }
452
453 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
454 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
455 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
456 }
457 }
458
459 if len(d.properties.Api_levels_annotations_dirs) != 0 {
460 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
461 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
462 }
463 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000464
Jihoon Kang6592e872023-12-19 01:13:16 +0000465 if len(d.properties.Aconfig_declarations) != 0 {
466 for _, aconfigDeclarationModuleName := range d.properties.Aconfig_declarations {
467 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationModuleName)
468 }
469 }
470
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000471 if d.properties.Api_levels_module != nil {
472 ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
473 }
Colin Cross2207f872021-03-24 12:39:08 -0700474}
475
Jihoon Kang3c89f042023-12-19 02:40:22 +0000476func (d *Droidstubs) sdkValuesFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, metadataDir android.WritablePath) {
477 cmd.FlagWithArg("--sdk-values ", metadataDir.String())
478}
479
480func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath, stubsType StubsType, checkApi bool) {
481 if checkApi || String(d.properties.Api_filename) != "" {
Colin Cross2207f872021-03-24 12:39:08 -0700482 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000483 uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
Paul Duffinc71d2b72022-08-16 15:24:01 +0000484 cmd.FlagWithOutput("--api ", uncheckedApiFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000485
486 if stubsType == Everything {
487 d.apiFile = uncheckedApiFile
488 } else if stubsType == Exportable {
489 d.exportableApiFile = uncheckedApiFile
490 }
Colin Cross2207f872021-03-24 12:39:08 -0700491 } else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
492 // If check api is disabled then make the source file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000493 d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700494 }
495
Jihoon Kang3c89f042023-12-19 02:40:22 +0000496 if checkApi || String(d.properties.Removed_api_filename) != "" {
Colin Cross2207f872021-03-24 12:39:08 -0700497 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000498 uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
Paul Duffinc71d2b72022-08-16 15:24:01 +0000499 cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000500
501 if stubsType == Everything {
502 d.removedApiFile = uncheckedRemovedFile
503 } else if stubsType == Exportable {
504 d.exportableRemovedApiFile = uncheckedRemovedFile
505 }
Colin Cross2207f872021-03-24 12:39:08 -0700506 } else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
507 // If check api is disabled then make the source removed api file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000508 d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700509 }
510
Colin Cross2207f872021-03-24 12:39:08 -0700511 if stubsDir.Valid() {
512 if Bool(d.properties.Create_doc_stubs) {
513 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
514 } else {
515 cmd.FlagWithArg("--stubs ", stubsDir.String())
516 if !Bool(d.properties.Output_javadoc_comments) {
517 cmd.Flag("--exclude-documentation-from-stubs")
518 }
519 }
520 }
521}
522
Jihoon Kang3c89f042023-12-19 02:40:22 +0000523func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, params annotationFlagsParams) {
Jihoon Kanga11d6792024-03-05 16:12:20 +0000524 if Bool(d.properties.Annotations_enabled) {
525 cmd.Flag(config.MetalavaAnnotationsFlags)
Andrei Onea4985e512021-04-29 16:29:34 +0100526
Jihoon Kanga11d6792024-03-05 16:12:20 +0000527 if params.migratingNullability {
528 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
529 cmd.FlagWithInput("--migrate-nullness ", previousApi)
530 }
Jihoon Kang6b93b382024-01-26 22:37:41 +0000531
Jihoon Kanga11d6792024-03-05 16:12:20 +0000532 if s := String(d.properties.Validate_nullability_from_list); s != "" {
533 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
534 }
Jihoon Kang6b93b382024-01-26 22:37:41 +0000535
Jihoon Kanga11d6792024-03-05 16:12:20 +0000536 if params.validatingNullability {
537 cmd.FlagWithOutput("--nullability-warnings-txt ", params.nullabilityWarningsFile)
538 }
Jihoon Kang6b93b382024-01-26 22:37:41 +0000539
Jihoon Kangca2f9e82024-01-26 01:45:12 +0000540 cmd.FlagWithOutput("--extract-annotations ", params.annotationsZip)
Jihoon Kang6b93b382024-01-26 22:37:41 +0000541
Jihoon Kanga11d6792024-03-05 16:12:20 +0000542 if len(d.properties.Merge_annotations_dirs) != 0 {
543 d.mergeAnnoDirFlags(ctx, cmd)
544 }
Jihoon Kang6b93b382024-01-26 22:37:41 +0000545
Jihoon Kanga11d6792024-03-05 16:12:20 +0000546 cmd.Flag(config.MetalavaAnnotationsWarningsFlags)
Colin Cross2207f872021-03-24 12:39:08 -0700547 }
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 Kanga11d6792024-03-05 16:12:20 +0000572func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000573 var apiVersions android.Path
Jihoon Kanga11d6792024-03-05 16:12:20 +0000574 if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000575 d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
Jihoon Kangd9a06942024-01-26 01:49:20 +0000576 apiVersions = apiVersionsXml
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000577 } else {
578 ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
579 if s, ok := m.(*Droidstubs); ok {
Jihoon Kangd9a06942024-01-26 01:49:20 +0000580 if stubsType == Everything {
581 apiVersions = s.everythingArtifacts.apiVersionsXml
582 } else if stubsType == Exportable {
583 apiVersions = s.exportableArtifacts.apiVersionsXml
584 } else {
Jihoon Kangd40c5912024-03-05 16:12:20 +0000585 ctx.ModuleErrorf("%s stubs type does not generate api-versions.xml file", stubsType.String())
Jihoon Kangd9a06942024-01-26 01:49:20 +0000586 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000587 } else {
588 ctx.PropertyErrorf("api_levels_module",
589 "module %q is not a droidstubs module", ctx.OtherModuleName(m))
590 }
591 })
Colin Cross2207f872021-03-24 12:39:08 -0700592 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000593 if apiVersions != nil {
594 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
595 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
596 cmd.FlagWithInput("--apply-api-levels ", apiVersions)
597 }
598}
Colin Cross2207f872021-03-24 12:39:08 -0700599
Jihoon Kang3c89f042023-12-19 02:40:22 +0000600func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Colin Cross2207f872021-03-24 12:39:08 -0700601 if len(d.properties.Api_levels_annotations_dirs) == 0 {
602 ctx.PropertyErrorf("api_levels_annotations_dirs",
603 "has to be non-empty if api levels annotations was enabled!")
604 }
605
Jihoon Kang3c89f042023-12-19 02:40:22 +0000606 cmd.FlagWithOutput("--generate-api-levels ", apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700607
608 filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
609
satayev783195c2021-06-23 21:49:57 +0100610 var dirs []string
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200611 var extensions_dir string
Colin Cross2207f872021-03-24 12:39:08 -0700612 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
613 if t, ok := m.(*ExportedDroiddocDir); ok {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200614 extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
615
616 // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
617 // ideally this should be read from prebuiltApis.properties.Extensions_*
Colin Cross2207f872021-03-24 12:39:08 -0700618 for _, dep := range t.deps {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200619 if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
620 if extensions_dir == "" {
621 extensions_dir = t.dir.String() + "/extensions"
622 }
623 cmd.Implicit(dep)
624 }
Colin Cross5f6ffc72021-03-29 21:54:45 -0700625 if dep.Base() == filename {
626 cmd.Implicit(dep)
627 }
628 if filename != "android.jar" && dep.Base() == "android.jar" {
629 // Metalava implicitly searches these patterns:
630 // prebuilts/tools/common/api-versions/android-%/android.jar
631 // prebuilts/sdk/%/public/android.jar
632 // Add android.jar files from the api_levels_annotations_dirs directories to try
633 // to satisfy these patterns. If Metalava can't find a match for an API level
634 // between 1 and 28 in at least one pattern it will fail.
Colin Cross2207f872021-03-24 12:39:08 -0700635 cmd.Implicit(dep)
636 }
637 }
satayev783195c2021-06-23 21:49:57 +0100638
639 dirs = append(dirs, t.dir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700640 } else {
641 ctx.PropertyErrorf("api_levels_annotations_dirs",
642 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
643 }
644 })
satayev783195c2021-06-23 21:49:57 +0100645
646 // Add all relevant --android-jar-pattern patterns for Metalava.
647 // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
648 // an actual file present on disk (in the order the patterns were passed). For system APIs for
649 // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
Pedro Loureirocc203502021-10-04 17:24:00 +0000650 // for older releases. Similarly, module-lib falls back to system API.
651 var sdkDirs []string
652 switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
Cole Faust051fa912022-10-05 12:45:42 -0700653 case "system-server":
654 sdkDirs = []string{"system-server", "module-lib", "system", "public"}
Pedro Loureirocc203502021-10-04 17:24:00 +0000655 case "module-lib":
656 sdkDirs = []string{"module-lib", "system", "public"}
657 case "system":
658 sdkDirs = []string{"system", "public"}
659 case "public":
660 sdkDirs = []string{"public"}
661 default:
662 ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
663 return
satayev783195c2021-06-23 21:49:57 +0100664 }
Pedro Loureirocc203502021-10-04 17:24:00 +0000665
666 for _, sdkDir := range sdkDirs {
667 for _, dir := range dirs {
668 cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
669 }
satayev783195c2021-06-23 21:49:57 +0100670 }
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200671
672 if d.properties.Extensions_info_file != nil {
673 if extensions_dir == "" {
674 ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
675 }
676 info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
677 cmd.Implicit(info_file)
678 cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
679 cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
680 }
Colin Cross2207f872021-03-24 12:39:08 -0700681}
682
Colin Crosse52c2ac2022-03-28 17:03:35 -0700683func metalavaUseRbe(ctx android.ModuleContext) bool {
684 return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
685}
686
Colin Cross2207f872021-03-24 12:39:08 -0700687func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Anton Hansson556e8142021-06-04 16:20:25 +0100688 srcJarList android.Path, bootclasspath, classpath classpath, homeDir android.WritablePath) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700689 rule.Command().Text("rm -rf").Flag(homeDir.String())
690 rule.Command().Text("mkdir -p").Flag(homeDir.String())
691
Anton Hansson556e8142021-06-04 16:20:25 +0100692 cmd := rule.Command()
Colin Cross2207f872021-03-24 12:39:08 -0700693 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())
694
Colin Crosse52c2ac2022-03-28 17:03:35 -0700695 if metalavaUseRbe(ctx) {
Colin Cross2207f872021-03-24 12:39:08 -0700696 rule.Remoteable(android.RemoteRuleSupports{RBE: true})
Colin Cross8095c292021-03-30 16:40:48 -0700697 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000698 compare := ctx.Config().IsEnvTrue("RBE_METALAVA_COMPARE")
699 remoteUpdateCache := !ctx.Config().IsEnvFalse("RBE_METALAVA_REMOTE_UPDATE_CACHE")
Colin Cross8095c292021-03-30 16:40:48 -0700700 labels := map[string]string{"type": "tool", "name": "metalava"}
701 // TODO: metalava pool rejects these jobs
702 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
703 rule.Rewrapper(&remoteexec.REParams{
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000704 Labels: labels,
705 ExecStrategy: execStrategy,
706 ToolchainInputs: []string{config.JavaCmd(ctx).String()},
707 Platform: map[string]string{remoteexec.PoolKey: pool},
708 Compare: compare,
709 NumLocalRuns: 1,
710 NumRemoteRuns: 1,
711 NoRemoteUpdateCache: !remoteUpdateCache,
Colin Cross8095c292021-03-30 16:40:48 -0700712 })
Colin Cross2207f872021-03-24 12:39:08 -0700713 }
714
Colin Cross6aa5c402021-03-24 12:28:50 -0700715 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
Colin Cross2207f872021-03-24 12:39:08 -0700716 Flag(config.JavacVmFlags).
Liz Kammere09e20e2023-10-16 15:07:54 -0400717 Flag(config.MetalavaAddOpens).
Paul Duffin808211e2023-08-09 12:36:08 +0100718 FlagWithArg("--java-source ", javaVersion.String()).
Colin Cross2207f872021-03-24 12:39:08 -0700719 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
720 FlagWithInput("@", srcJarList)
721
Paul Duffinf8aaaa12023-08-10 15:16:35 +0100722 // Metalava does not differentiate between bootclasspath and classpath and has not done so for
723 // years, so it is unlikely to change any time soon.
724 combinedPaths := append(([]android.Path)(nil), bootclasspath.Paths()...)
725 combinedPaths = append(combinedPaths, classpath.Paths()...)
726 if len(combinedPaths) > 0 {
727 cmd.FlagWithInputList("--classpath ", combinedPaths, ":")
Colin Cross2207f872021-03-24 12:39:08 -0700728 }
729
Liz Kammere09e20e2023-10-16 15:07:54 -0400730 cmd.Flag(config.MetalavaFlags)
Jihoon Kangc8313892023-09-20 00:54:47 +0000731
Colin Cross2207f872021-03-24 12:39:08 -0700732 return cmd
733}
734
Jihoon Kang3c89f042023-12-19 02:40:22 +0000735// Pass flagged apis related flags to metalava. When aconfig_declarations property is not
736// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
737// property is defined, apply transformations and only revert the flagged apis that are not
738// enabled via release configurations and are not specified in aconfig_declarations
Jihoon Kang5d701272024-02-15 21:53:49 +0000739func generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000740
741 if len(aconfigFlagsPaths) == 0 {
742 cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
743 return
744 }
Jihoon Kang6592e872023-12-19 01:13:16 +0000745
746 releasedFlaggedApisFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flagged-apis-%s.txt", stubsType.String()))
747 revertAnnotationsFile := android.PathForModuleOut(ctx, fmt.Sprintf("revert-annotations-%s.txt", stubsType.String()))
748
749 var filterArgs string
750 switch stubsType {
751 // No flagged apis specific flags need to be passed to metalava when generating
752 // everything stubs
753 case Everything:
754 return
755
756 case Runtime:
757 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
758
759 case Exportable:
Jihoon Kang59198152024-02-06 22:43:18 +0000760 // When the build flag RELEASE_EXPORT_RUNTIME_APIS is set to true, apis marked with
761 // the flagged apis that have read_write permissions are exposed on top of the enabled
762 // and read_only apis. This is to support local override of flag values at runtime.
763 if ctx.Config().ReleaseExportRuntimeApis() {
764 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
765 } else {
766 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY'"
767 }
Jihoon Kang6592e872023-12-19 01:13:16 +0000768 }
769
770 ctx.Build(pctx, android.BuildParams{
771 Rule: gatherReleasedFlaggedApisRule,
772 Inputs: aconfigFlagsPaths,
773 Output: releasedFlaggedApisFile,
774 Description: fmt.Sprintf("%s gather aconfig flags", stubsType),
775 Args: map[string]string{
776 "flags_path": android.JoinPathsWithPrefix(aconfigFlagsPaths, "--cache "),
777 "filter_args": filterArgs,
778 },
779 })
780
781 ctx.Build(pctx, android.BuildParams{
782 Rule: generateMetalavaRevertAnnotationsRule,
783 Input: releasedFlaggedApisFile,
784 Output: revertAnnotationsFile,
785 Description: fmt.Sprintf("%s revert annotations", stubsType),
786 })
Jihoon Kang3c89f042023-12-19 02:40:22 +0000787
788 cmd.FlagWithInput("@", revertAnnotationsFile)
Jihoon Kang6592e872023-12-19 01:13:16 +0000789}
790
Jihoon Kang3c89f042023-12-19 02:40:22 +0000791func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
792 params stubsCommandParams) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700793 if BoolDefault(d.properties.High_mem, false) {
794 // This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
795 rule.HighMem()
796 }
797
Jihoon Kang3c89f042023-12-19 02:40:22 +0000798 if params.stubConfig.generateStubs {
799 rule.Command().Text("rm -rf").Text(params.stubsDir.String())
800 rule.Command().Text("mkdir -p").Text(params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700801 }
802
Jihoon Kang3c89f042023-12-19 02:40:22 +0000803 srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars)
Colin Cross2207f872021-03-24 12:39:08 -0700804
Jihoon Kang3c89f042023-12-19 02:40:22 +0000805 homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home")
806 cmd := metalavaCmd(ctx, rule, params.stubConfig.javaVersion, d.Javadoc.srcFiles, srcJarList,
807 params.stubConfig.deps.bootClasspath, params.stubConfig.deps.classpath, homeDir)
Colin Cross2207f872021-03-24 12:39:08 -0700808 cmd.Implicits(d.Javadoc.implicits)
809
Jihoon Kang3c89f042023-12-19 02:40:22 +0000810 d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
Colin Cross2207f872021-03-24 12:39:08 -0700811
Jihoon Kang3c89f042023-12-19 02:40:22 +0000812 if params.stubConfig.writeSdkValues {
813 d.sdkValuesFlags(ctx, cmd, params.metadataDir)
814 }
815
816 annotationParams := annotationFlagsParams{
817 migratingNullability: params.stubConfig.migratingNullability,
818 validatingNullability: params.stubConfig.validatingNullability,
819 nullabilityWarningsFile: params.nullabilityWarningsFile,
820 annotationsZip: params.annotationsZip,
821 }
822
Jihoon Kanga11d6792024-03-05 16:12:20 +0000823 d.annotationsFlags(ctx, cmd, annotationParams)
Colin Cross2207f872021-03-24 12:39:08 -0700824 d.inclusionAnnotationsFlags(ctx, cmd)
Jihoon Kanga11d6792024-03-05 16:12:20 +0000825 d.apiLevelsAnnotationsFlags(ctx, cmd, params.stubConfig.stubsType, params.apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700826
Colin Crossbc139922021-03-25 18:33:16 -0700827 d.expandArgs(ctx, cmd)
Colin Cross2207f872021-03-24 12:39:08 -0700828
Colin Cross2207f872021-03-24 12:39:08 -0700829 for _, o := range d.Javadoc.properties.Out {
830 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
831 }
832
Jihoon Kang3c89f042023-12-19 02:40:22 +0000833 return cmd
834}
Colin Cross2207f872021-03-24 12:39:08 -0700835
Jihoon Kang3c89f042023-12-19 02:40:22 +0000836// Sandbox rule for generating the everything stubs and other artifacts
837func (d *Droidstubs) everythingStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
838 srcJarDir := android.PathForModuleOut(ctx, Everything.String(), "srcjars")
839 rule := android.NewRuleBuilder(pctx, ctx)
840 rule.Sbox(android.PathForModuleOut(ctx, Everything.String()),
841 android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
842 SandboxInputs()
843
844 var stubsDir android.OptionalPath
845 if params.generateStubs {
846 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, Everything.String(), "stubsDir"))
847 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
848 }
849
850 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +0000851 d.everythingArtifacts.metadataDir = android.PathForModuleOut(ctx, Everything.String(), "metadata")
852 d.everythingArtifacts.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000853 }
854
Jihoon Kanga11d6792024-03-05 16:12:20 +0000855 if Bool(d.properties.Annotations_enabled) {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000856 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +0000857 d.everythingArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000858 }
Jihoon Kangee113282024-01-23 00:16:41 +0000859 d.everythingArtifacts.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000860 }
Jihoon Kanga11d6792024-03-05 16:12:20 +0000861 if Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kangee113282024-01-23 00:16:41 +0000862 d.everythingArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000863 }
864
865 commonCmdParams := stubsCommandParams{
866 srcJarDir: srcJarDir,
867 stubsDir: stubsDir,
868 stubsSrcJar: d.Javadoc.stubsSrcJar,
Jihoon Kangee113282024-01-23 00:16:41 +0000869 metadataDir: d.everythingArtifacts.metadataDir,
870 apiVersionsXml: d.everythingArtifacts.apiVersionsXml,
871 nullabilityWarningsFile: d.everythingArtifacts.nullabilityWarningsFile,
872 annotationsZip: d.everythingArtifacts.annotationsZip,
Jihoon Kang3c89f042023-12-19 02:40:22 +0000873 stubConfig: params,
874 }
875
876 cmd := d.commonMetalavaStubCmd(ctx, rule, commonCmdParams)
877
878 d.everythingOptionalCmd(ctx, cmd, params.doApiLint, params.doCheckReleased)
879
880 if params.generateStubs {
881 rule.Command().
882 BuiltTool("soong_zip").
883 Flag("-write_if_changed").
884 Flag("-jar").
885 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
886 FlagWithArg("-C ", stubsDir.String()).
887 FlagWithArg("-D ", stubsDir.String())
888 }
889
890 if params.writeSdkValues {
891 rule.Command().
892 BuiltTool("soong_zip").
893 Flag("-write_if_changed").
894 Flag("-d").
Jihoon Kangee113282024-01-23 00:16:41 +0000895 FlagWithOutput("-o ", d.everythingArtifacts.metadataZip).
896 FlagWithArg("-C ", d.everythingArtifacts.metadataDir.String()).
897 FlagWithArg("-D ", d.everythingArtifacts.metadataDir.String())
Jihoon Kang3c89f042023-12-19 02:40:22 +0000898 }
899
900 // TODO: We don't really need two separate API files, but this is a reminiscence of how
901 // we used to run metalava separately for API lint and the "last_released" check. Unify them.
902 if params.doApiLint {
903 rule.Command().Text("touch").Output(d.apiLintTimestamp)
904 }
905 if params.doCheckReleased {
906 rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
907 }
908
909 // TODO(b/183630617): rewrapper doesn't support restat rules
910 if !metalavaUseRbe(ctx) {
911 rule.Restat()
912 }
913
914 zipSyncCleanupCmd(rule, srcJarDir)
915
916 rule.Build("metalava", "metalava merged")
917}
918
919// Sandbox rule for generating the everything artifacts that are not run by
920// default but only run based on the module configurations
921func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, doApiLint bool, doCheckReleased bool) {
Colin Cross2207f872021-03-24 12:39:08 -0700922
923 // Add API lint options.
Jihoon Kang3c89f042023-12-19 02:40:22 +0000924 if doApiLint {
Colin Cross2207f872021-03-24 12:39:08 -0700925 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
926 if newSince.Valid() {
927 cmd.FlagWithInput("--api-lint ", newSince.Path())
928 } else {
929 cmd.Flag("--api-lint")
930 }
Jihoon Kang3c89f042023-12-19 02:40:22 +0000931 d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700932 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
933
Colin Cross0d532412021-03-25 09:38:45 -0700934 // TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
Colin Cross2207f872021-03-24 12:39:08 -0700935 if d.Name() != "android.car-system-stubs-docs" &&
936 d.Name() != "android.car-stubs-docs" {
937 cmd.Flag("--lints-as-errors")
938 cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
939 }
940
941 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000942 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "api_lint_baseline.txt")
943 d.apiLintTimestamp = android.PathForModuleOut(ctx, Everything.String(), "api_lint.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700944
945 // Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
Colin Cross2207f872021-03-24 12:39:08 -0700946 //
947 // TODO: metalava also has a slightly different message hardcoded. Should we unify this
948 // message and metalava's one?
949 msg := `$'` + // Enclose with $' ... '
950 `************************************************************\n` +
951 `Your API changes are triggering API Lint warnings or errors.\n` +
952 `To make these errors go away, fix the code according to the\n` +
953 `error and/or warning messages above.\n` +
954 `\n` +
955 `If it is not possible to do so, there are workarounds:\n` +
956 `\n` +
Aurimas Liutikasb23b7452021-05-24 18:00:37 +0000957 `1. You can suppress the errors with @SuppressLint("<id>")\n` +
958 ` where the <id> is given in brackets in the error message above.\n`
Colin Cross2207f872021-03-24 12:39:08 -0700959
960 if baselineFile.Valid() {
961 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
962 cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)
963
964 msg += fmt.Sprintf(``+
965 `2. You can update the baseline by executing the following\n`+
966 ` command:\n`+
Colin Cross63eeda02021-04-15 19:01:57 -0700967 ` (cd $ANDROID_BUILD_TOP && cp \\\n`+
968 ` "%s" \\\n`+
969 ` "%s")\n`+
Colin Cross2207f872021-03-24 12:39:08 -0700970 ` To submit the revised baseline.txt to the main Android\n`+
971 ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
972 } else {
973 msg += fmt.Sprintf(``+
974 `2. You can add a baseline file of existing lint failures\n`+
975 ` to the build rule of %s.\n`, d.Name())
976 }
977 // Note the message ends with a ' (single quote), to close the $' ... ' .
978 msg += `************************************************************\n'`
979
980 cmd.FlagWithArg("--error-message:api-lint ", msg)
981 }
982
983 // Add "check released" options. (Detect incompatible API changes from the last public release)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000984 if doCheckReleased {
Colin Cross2207f872021-03-24 12:39:08 -0700985 if len(d.Javadoc.properties.Out) > 0 {
986 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
987 }
988
989 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
990 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
991 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000992 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700993
Jihoon Kang3c89f042023-12-19 02:40:22 +0000994 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700995
996 cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
997 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
998
999 if baselineFile.Valid() {
1000 cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
1001 cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
1002 }
1003
1004 // Note this string includes quote ($' ... '), which decodes the "\n"s.
1005 msg := `$'\n******************************\n` +
1006 `You have tried to change the API from what has been previously released in\n` +
1007 `an SDK. Please fix the errors listed above.\n` +
1008 `******************************\n'`
1009
1010 cmd.FlagWithArg("--error-message:compatibility:released ", msg)
1011 }
1012
Paul Duffin10a23c22023-08-11 22:47:31 +01001013 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1014 // Pass the current API file into metalava so it can use it as the basis for determining how to
1015 // generate the output signature files (both api and removed).
1016 currentApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1017 cmd.FlagWithInput("--use-same-format-as ", currentApiFile)
1018 }
Jihoon Kang3c89f042023-12-19 02:40:22 +00001019}
Paul Duffin10a23c22023-08-11 22:47:31 +01001020
Jihoon Kang3c89f042023-12-19 02:40:22 +00001021// Sandbox rule for generating exportable stubs and other artifacts
1022func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
1023 optionalCmdParams := stubsCommandParams{
1024 stubConfig: params,
1025 }
1026
Jihoon Kang246690a2024-02-01 21:55:01 +00001027 if params.generateStubs {
1028 d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
1029 optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
1030 }
1031
Jihoon Kang3c89f042023-12-19 02:40:22 +00001032 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +00001033 d.exportableArtifacts.metadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
1034 d.exportableArtifacts.metadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
1035 optionalCmdParams.metadataZip = d.exportableArtifacts.metadataZip
1036 optionalCmdParams.metadataDir = d.exportableArtifacts.metadataDir
Jihoon Kang3c89f042023-12-19 02:40:22 +00001037 }
1038
Jihoon Kanga11d6792024-03-05 16:12:20 +00001039 if Bool(d.properties.Annotations_enabled) {
Jihoon Kang3c89f042023-12-19 02:40:22 +00001040 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +00001041 d.exportableArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
1042 optionalCmdParams.nullabilityWarningsFile = d.exportableArtifacts.nullabilityWarningsFile
Jihoon Kang3c89f042023-12-19 02:40:22 +00001043 }
Jihoon Kangee113282024-01-23 00:16:41 +00001044 d.exportableArtifacts.annotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
1045 optionalCmdParams.annotationsZip = d.exportableArtifacts.annotationsZip
Jihoon Kang3c89f042023-12-19 02:40:22 +00001046 }
Jihoon Kanga11d6792024-03-05 16:12:20 +00001047 if Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kangee113282024-01-23 00:16:41 +00001048 d.exportableArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
1049 optionalCmdParams.apiVersionsXml = d.exportableArtifacts.apiVersionsXml
Jihoon Kang3c89f042023-12-19 02:40:22 +00001050 }
1051
1052 if params.checkApi || String(d.properties.Api_filename) != "" {
1053 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
1054 d.exportableApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1055 }
1056
1057 if params.checkApi || String(d.properties.Removed_api_filename) != "" {
1058 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_api.txt")
1059 d.exportableRemovedApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1060 }
1061
1062 d.optionalStubCmd(ctx, optionalCmdParams)
1063}
1064
1065func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsCommandParams) {
1066
1067 params.srcJarDir = android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "srcjars")
1068 rule := android.NewRuleBuilder(pctx, ctx)
1069 rule.Sbox(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String()),
1070 android.PathForModuleOut(ctx, fmt.Sprintf("metalava_%s.sbox.textproto", params.stubConfig.stubsType.String()))).
1071 SandboxInputs()
1072
1073 if params.stubConfig.generateStubs {
1074 params.stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "stubsDir"))
1075 }
1076
1077 cmd := d.commonMetalavaStubCmd(ctx, rule, params)
1078
Jihoon Kang5d701272024-02-15 21:53:49 +00001079 generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
Jihoon Kang3c89f042023-12-19 02:40:22 +00001080
1081 if params.stubConfig.doApiLint {
1082 // Pass the lint baseline file as an input to resolve the lint errors.
1083 // The exportable stubs generation does not update the lint baseline file.
1084 // Lint baseline file update is handled by the everything stubs
1085 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1086 if baselineFile.Valid() {
1087 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
1088 }
1089 }
1090
1091 if params.stubConfig.generateStubs {
Colin Cross2207f872021-03-24 12:39:08 -07001092 rule.Command().
1093 BuiltTool("soong_zip").
1094 Flag("-write_if_changed").
1095 Flag("-jar").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001096 FlagWithOutput("-o ", params.stubsSrcJar).
1097 FlagWithArg("-C ", params.stubsDir.String()).
1098 FlagWithArg("-D ", params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001099 }
1100
Jihoon Kang3c89f042023-12-19 02:40:22 +00001101 if params.stubConfig.writeSdkValues {
Colin Cross2207f872021-03-24 12:39:08 -07001102 rule.Command().
1103 BuiltTool("soong_zip").
1104 Flag("-write_if_changed").
1105 Flag("-d").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001106 FlagWithOutput("-o ", params.metadataZip).
1107 FlagWithArg("-C ", params.metadataDir.String()).
1108 FlagWithArg("-D ", params.metadataDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001109 }
1110
Colin Cross6aa5c402021-03-24 12:28:50 -07001111 // TODO(b/183630617): rewrapper doesn't support restat rules
Colin Crosse52c2ac2022-03-28 17:03:35 -07001112 if !metalavaUseRbe(ctx) {
1113 rule.Restat()
1114 }
Colin Cross2207f872021-03-24 12:39:08 -07001115
Jihoon Kang3c89f042023-12-19 02:40:22 +00001116 zipSyncCleanupCmd(rule, params.srcJarDir)
Colin Cross2207f872021-03-24 12:39:08 -07001117
Jihoon Kang3c89f042023-12-19 02:40:22 +00001118 rule.Build(fmt.Sprintf("metalava_%s", params.stubConfig.stubsType.String()), "metalava merged")
1119}
1120
1121func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1122 deps := d.Javadoc.collectDeps(ctx)
1123
1124 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
1125 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
1126
1127 // Add options for the other optional tasks: API-lint and check-released.
1128 // We generate separate timestamp files for them.
1129 doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
1130 doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1131
1132 writeSdkValues := Bool(d.properties.Write_sdk_values)
1133
1134 annotationsEnabled := Bool(d.properties.Annotations_enabled)
1135
1136 migratingNullability := annotationsEnabled && String(d.properties.Previous_api) != ""
1137 validatingNullability := annotationsEnabled && (strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
1138 String(d.properties.Validate_nullability_from_list) != "")
1139
1140 checkApi := apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1141 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1142
1143 stubCmdParams := stubsCommandConfigParams{
Jihoon Kanga11d6792024-03-05 16:12:20 +00001144 javaVersion: javaVersion,
1145 deps: deps,
1146 checkApi: checkApi,
1147 generateStubs: generateStubs,
1148 doApiLint: doApiLint,
1149 doCheckReleased: doCheckReleased,
1150 writeSdkValues: writeSdkValues,
1151 migratingNullability: migratingNullability,
1152 validatingNullability: validatingNullability,
Jihoon Kang3c89f042023-12-19 02:40:22 +00001153 }
1154 stubCmdParams.stubsType = Everything
1155 // Create default (i.e. "everything" stubs) rule for metalava
1156 d.everythingStubCmd(ctx, stubCmdParams)
1157
Jihoon Kangd40c5912024-03-05 16:12:20 +00001158 // The module generates "exportable" (and "runtime" eventually) stubs regardless of whether
Jihoon Kang3c89f042023-12-19 02:40:22 +00001159 // aconfig_declarations property is defined or not. If the property is not defined, the module simply
1160 // strips all flagged apis to generate the "exportable" stubs
1161 stubCmdParams.stubsType = Exportable
1162 d.exportableStubCmd(ctx, stubCmdParams)
Paul Duffinc166b682022-05-27 12:23:08 +00001163
Paul Duffine7a86642022-08-16 15:43:20 +00001164 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1165
1166 if len(d.Javadoc.properties.Out) > 0 {
1167 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1168 }
1169
1170 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1171 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
1172 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1173
1174 if baselineFile.Valid() {
1175 ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
1176 }
1177
Jihoon Kang3c89f042023-12-19 02:40:22 +00001178 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001179
1180 rule := android.NewRuleBuilder(pctx, ctx)
1181
1182 // Diff command line.
1183 // -F matches the closest "opening" line, such as "package android {"
1184 // and " public class Intent {".
1185 diff := `diff -u -F '{ *$'`
1186
1187 rule.Command().Text("( true")
1188 rule.Command().
1189 Text(diff).
1190 Input(apiFile).Input(d.apiFile)
1191
1192 rule.Command().
1193 Text(diff).
1194 Input(removedApiFile).Input(d.removedApiFile)
1195
1196 msg := fmt.Sprintf(`\n******************************\n`+
1197 `You have tried to change the API from what has been previously approved.\n\n`+
1198 `To make these errors go away, you have two choices:\n`+
1199 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
1200 ` to the new methods, etc. shown in the above diff.\n\n`+
1201 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
1202 ` m %s-update-current-api\n\n`+
1203 ` To submit the revised current.txt to the main Android repository,\n`+
1204 ` you will need approval.\n`+
Jihoon Kang3ea64672023-11-03 00:40:26 +00001205 `If your build failed due to stub validation, you can resolve the errors with\n`+
1206 `either of the two choices above and try re-building the target.\n`+
1207 `If the mismatch between the stubs and the current.txt is intended,\n`+
1208 `you can try re-building the target by executing the following command:\n`+
Jihoon Kang91bf3dd2024-01-24 00:40:23 +00001209 `m DISABLE_STUB_VALIDATION=true <your build target>.\n`+
1210 `Note that DISABLE_STUB_VALIDATION=true does not bypass checkapi.\n`+
Paul Duffine7a86642022-08-16 15:43:20 +00001211 `******************************\n`, ctx.ModuleName())
1212
1213 rule.Command().
1214 Text("touch").Output(d.checkCurrentApiTimestamp).
1215 Text(") || (").
1216 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1217 Text("; exit 38").
1218 Text(")")
1219
1220 rule.Build("metalavaCurrentApiCheck", "check current API")
1221
Jihoon Kang3c89f042023-12-19 02:40:22 +00001222 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001223
1224 // update API rule
1225 rule = android.NewRuleBuilder(pctx, ctx)
1226
1227 rule.Command().Text("( true")
1228
1229 rule.Command().
1230 Text("cp").Flag("-f").
1231 Input(d.apiFile).Flag(apiFile.String())
1232
1233 rule.Command().
1234 Text("cp").Flag("-f").
1235 Input(d.removedApiFile).Flag(removedApiFile.String())
1236
1237 msg = "failed to update public API"
1238
1239 rule.Command().
1240 Text("touch").Output(d.updateCurrentApiTimestamp).
1241 Text(") || (").
1242 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1243 Text("; exit 38").
1244 Text(")")
1245
1246 rule.Build("metalavaCurrentApiUpdate", "update current API")
1247 }
1248
Colin Cross2207f872021-03-24 12:39:08 -07001249 if String(d.properties.Check_nullability_warnings) != "" {
Jihoon Kangee113282024-01-23 00:16:41 +00001250 if d.everythingArtifacts.nullabilityWarningsFile == nil {
Colin Cross2207f872021-03-24 12:39:08 -07001251 ctx.PropertyErrorf("check_nullability_warnings",
1252 "Cannot specify check_nullability_warnings unless validating nullability")
1253 }
1254
1255 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1256
Jihoon Kang3c89f042023-12-19 02:40:22 +00001257 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -07001258
1259 msg := fmt.Sprintf(`\n******************************\n`+
1260 `The warnings encountered during nullability annotation validation did\n`+
1261 `not match the checked in file of expected warnings. The diffs are shown\n`+
1262 `above. You have two options:\n`+
1263 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1264 ` 2. Update the file of expected warnings by running:\n`+
1265 ` cp %s %s\n`+
1266 ` and submitting the updated file as part of your change.`,
Jihoon Kangee113282024-01-23 00:16:41 +00001267 d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross2207f872021-03-24 12:39:08 -07001268
1269 rule := android.NewRuleBuilder(pctx, ctx)
1270
1271 rule.Command().
1272 Text("(").
Jihoon Kangee113282024-01-23 00:16:41 +00001273 Text("diff").Input(checkNullabilityWarnings).Input(d.everythingArtifacts.nullabilityWarningsFile).
Colin Cross2207f872021-03-24 12:39:08 -07001274 Text("&&").
1275 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1276 Text(") || (").
1277 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1278 Text("; exit 38").
1279 Text(")")
1280
1281 rule.Build("nullabilityWarningsCheck", "nullability warnings check")
1282 }
LaMont Jonesafe7baf2024-01-09 22:47:39 +00001283 android.CollectDependencyAconfigFiles(ctx, &d.mergedAconfigFiles)
Colin Cross2207f872021-03-24 12:39:08 -07001284}
1285
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001286func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
1287 api_file := d.properties.Check_api.Current.Api_file
1288 api_surface := d.properties.Api_surface
1289
1290 props := struct {
1291 Name *string
1292 Api_surface *string
1293 Api_file *string
Jihoon Kang42b589c2023-02-03 22:56:13 +00001294 Visibility []string
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001295 }{}
1296
1297 props.Name = proptools.StringPtr(d.Name() + ".api.contribution")
1298 props.Api_surface = api_surface
1299 props.Api_file = api_file
Jihoon Kang42b589c2023-02-03 22:56:13 +00001300 props.Visibility = []string{"//visibility:override", "//visibility:public"}
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001301
1302 ctx.CreateModule(ApiContributionFactory, &props)
1303}
1304
Spandan Das0b555e32022-11-28 18:48:51 +00001305// TODO (b/262014796): Export the API contributions of CorePlatformApi
1306// A map to populate the api surface of a droidstub from a substring appearing in its name
1307// This map assumes that droidstubs (either checked-in or created by java_sdk_library)
1308// use a strict naming convention
1309var (
1310 droidstubsModuleNamingToSdkKind = map[string]android.SdkKind{
1311 //public is commented out since the core libraries use public in their java_sdk_library names
1312 "intracore": android.SdkIntraCore,
1313 "intra.core": android.SdkIntraCore,
1314 "system_server": android.SdkSystemServer,
1315 "system-server": android.SdkSystemServer,
1316 "system": android.SdkSystem,
1317 "module_lib": android.SdkModule,
1318 "module-lib": android.SdkModule,
Spandan Dasda977552023-01-26 20:45:16 +00001319 "platform.api": android.SdkCorePlatform,
Spandan Das0b555e32022-11-28 18:48:51 +00001320 "test": android.SdkTest,
Spandan Das4ac2aed2022-12-28 01:54:29 +00001321 "toolchain": android.SdkToolchain,
Spandan Das0b555e32022-11-28 18:48:51 +00001322 }
1323)
1324
Colin Cross2207f872021-03-24 12:39:08 -07001325func StubsDefaultsFactory() android.Module {
1326 module := &DocDefaults{}
1327
1328 module.AddProperties(
1329 &JavadocProperties{},
1330 &DroidstubsProperties{},
1331 )
1332
1333 android.InitDefaultsModule(module)
1334
1335 return module
1336}
1337
1338var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
1339
1340type PrebuiltStubsSourcesProperties struct {
1341 Srcs []string `android:"path"`
Spandan Das23956d12024-01-19 00:22:22 +00001342
1343 // Name of the source soong module that gets shadowed by this prebuilt
1344 // If unspecified, follows the naming convention that the source module of
1345 // the prebuilt is Name() without "prebuilt_" prefix
1346 Source_module_name *string
1347
1348 // Non-nil if this prebuilt stub srcs module was dynamically created by a java_sdk_library_import
1349 // The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
1350 // (without any prebuilt_ prefix)
1351 Created_by_java_sdk_library_name *string `blueprint:"mutated"`
1352}
1353
1354func (j *PrebuiltStubsSources) BaseModuleName() string {
1355 return proptools.StringDefault(j.properties.Source_module_name, j.ModuleBase.Name())
1356}
1357
1358func (j *PrebuiltStubsSources) CreatedByJavaSdkLibraryName() *string {
1359 return j.properties.Created_by_java_sdk_library_name
Colin Cross2207f872021-03-24 12:39:08 -07001360}
1361
1362type PrebuiltStubsSources struct {
1363 android.ModuleBase
1364 android.DefaultableModuleBase
Spandan Das2cc80ba2023-10-27 17:21:52 +00001365 embeddableInModuleAndImport
1366
Colin Cross2207f872021-03-24 12:39:08 -07001367 prebuilt android.Prebuilt
Colin Cross2207f872021-03-24 12:39:08 -07001368
1369 properties PrebuiltStubsSourcesProperties
1370
kgui67007242022-01-25 13:50:25 +08001371 stubsSrcJar android.Path
Colin Cross2207f872021-03-24 12:39:08 -07001372}
1373
1374func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
1375 switch tag {
Jihoon Kangfa4a90d2023-12-20 02:53:38 +00001376 // prebuilt droidstubs does not output "exportable" stubs.
1377 // Output the "everything" stubs srcjar file if the tag is ".exportable".
1378 case "", ".exportable":
Colin Cross2207f872021-03-24 12:39:08 -07001379 return android.Paths{p.stubsSrcJar}, nil
1380 default:
1381 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1382 }
1383}
1384
Jihoon Kangee113282024-01-23 00:16:41 +00001385func (d *PrebuiltStubsSources) StubsSrcJar(_ StubsType) (android.Path, error) {
1386 return d.stubsSrcJar, nil
Colin Cross2207f872021-03-24 12:39:08 -07001387}
1388
1389func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross2207f872021-03-24 12:39:08 -07001390 if len(p.properties.Srcs) != 1 {
Anton Hansson86758ac2021-11-03 14:44:12 +00001391 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 -07001392 return
1393 }
1394
Anton Hansson86758ac2021-11-03 14:44:12 +00001395 src := p.properties.Srcs[0]
1396 if filepath.Ext(src) == ".srcjar" {
1397 // This is a srcjar. We can use it directly.
1398 p.stubsSrcJar = android.PathForModuleSrc(ctx, src)
1399 } else {
1400 outPath := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Colin Cross2207f872021-03-24 12:39:08 -07001401
Anton Hansson86758ac2021-11-03 14:44:12 +00001402 // This is a directory. Glob the contents just in case the directory does not exist.
1403 srcGlob := src + "/**/*"
1404 srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})
Colin Cross2207f872021-03-24 12:39:08 -07001405
Anton Hansson86758ac2021-11-03 14:44:12 +00001406 // Although PathForModuleSrc can return nil if either the path doesn't exist or
1407 // the path components are invalid it won't in this case because no components
1408 // are specified and the module directory must exist in order to get this far.
1409 srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, src)
Colin Cross2207f872021-03-24 12:39:08 -07001410
Anton Hansson86758ac2021-11-03 14:44:12 +00001411 rule := android.NewRuleBuilder(pctx, ctx)
1412 rule.Command().
1413 BuiltTool("soong_zip").
1414 Flag("-write_if_changed").
1415 Flag("-jar").
1416 FlagWithOutput("-o ", outPath).
1417 FlagWithArg("-C ", srcDir.String()).
1418 FlagWithRspFileInputList("-r ", outPath.ReplaceExtension(ctx, "rsp"), srcPaths)
1419 rule.Restat()
1420 rule.Build("zip src", "Create srcjar from prebuilt source")
1421 p.stubsSrcJar = outPath
1422 }
Colin Cross2207f872021-03-24 12:39:08 -07001423}
1424
1425func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
1426 return &p.prebuilt
1427}
1428
1429func (p *PrebuiltStubsSources) Name() string {
1430 return p.prebuilt.Name(p.ModuleBase.Name())
1431}
1432
1433// prebuilt_stubs_sources imports a set of java source files as if they were
1434// generated by droidstubs.
1435//
1436// By default, a prebuilt_stubs_sources has a single variant that expects a
1437// set of `.java` files generated by droidstubs.
1438//
1439// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
1440// for host modules.
1441//
1442// Intended only for use by sdk snapshots.
1443func PrebuiltStubsSourcesFactory() android.Module {
1444 module := &PrebuiltStubsSources{}
1445
1446 module.AddProperties(&module.properties)
Spandan Das2cc80ba2023-10-27 17:21:52 +00001447 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -07001448
1449 android.InitPrebuiltModule(module, &module.properties.Srcs)
Colin Cross2207f872021-03-24 12:39:08 -07001450 InitDroiddocModule(module, android.HostAndDeviceSupported)
1451 return module
1452}