blob: e6d6871c4175e9b90c8b6064d2ba5d662442a75b [file] [log] [blame]
Colin Cross2207f872021-03-24 12:39:08 -07001// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
18 "fmt"
Anton Hansson86758ac2021-11-03 14:44:12 +000019 "path/filepath"
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +020020 "regexp"
Colin Cross2207f872021-03-24 12:39:08 -070021 "strings"
22
23 "github.com/google/blueprint/proptools"
24
25 "android/soong/android"
26 "android/soong/java/config"
27 "android/soong/remoteexec"
28)
29
Pedro Loureirocc203502021-10-04 17:24:00 +000030// The values allowed for Droidstubs' Api_levels_sdk_type
Cole Faust051fa912022-10-05 12:45:42 -070031var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib", "system-server"}
Pedro Loureirocc203502021-10-04 17:24:00 +000032
Jihoon Kang6592e872023-12-19 01:13:16 +000033type StubsType int
34
35const (
36 Everything StubsType = iota
37 Runtime
38 Exportable
Jihoon Kang78f89142023-12-27 01:40:29 +000039 Unavailable
Jihoon Kang6592e872023-12-19 01:13:16 +000040)
41
42func (s StubsType) String() string {
43 switch s {
44 case Everything:
45 return "everything"
46 case Runtime:
47 return "runtime"
48 case Exportable:
49 return "exportable"
50 default:
51 return ""
52 }
53}
54
Colin Cross2207f872021-03-24 12:39:08 -070055func init() {
56 RegisterStubsBuildComponents(android.InitRegistrationContext)
57}
58
59func RegisterStubsBuildComponents(ctx android.RegistrationContext) {
60 ctx.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
61
62 ctx.RegisterModuleType("droidstubs", DroidstubsFactory)
63 ctx.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
64
65 ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
66}
67
Jihoon Kangee113282024-01-23 00:16:41 +000068type stubsArtifacts struct {
69 nullabilityWarningsFile android.WritablePath
70 annotationsZip android.WritablePath
71 apiVersionsXml android.WritablePath
72 metadataZip android.WritablePath
73 metadataDir android.WritablePath
74}
75
Colin Cross2207f872021-03-24 12:39:08 -070076// Droidstubs
Colin Cross2207f872021-03-24 12:39:08 -070077type Droidstubs struct {
78 Javadoc
Spandan Das2cc80ba2023-10-27 17:21:52 +000079 embeddableInModuleAndImport
Colin Cross2207f872021-03-24 12:39:08 -070080
Jihoon Kangee113282024-01-23 00:16:41 +000081 properties DroidstubsProperties
82 apiFile android.Path
83 removedApiFile android.Path
Colin Cross2207f872021-03-24 12:39:08 -070084
85 checkCurrentApiTimestamp android.WritablePath
86 updateCurrentApiTimestamp android.WritablePath
87 checkLastReleasedApiTimestamp android.WritablePath
88 apiLintTimestamp android.WritablePath
89 apiLintReport android.WritablePath
90
91 checkNullabilityWarningsTimestamp android.WritablePath
92
Jihoon Kangee113282024-01-23 00:16:41 +000093 everythingArtifacts stubsArtifacts
94 exportableArtifacts stubsArtifacts
Jihoon Kang3c89f042023-12-19 02:40:22 +000095
LaMont Jonesafe7baf2024-01-09 22:47:39 +000096 // Single aconfig "cache file" merged from this module and all dependencies.
97 mergedAconfigFiles map[string]android.Paths
98
Jihoon Kangee113282024-01-23 00:16:41 +000099 exportableApiFile android.WritablePath
100 exportableRemovedApiFile android.WritablePath
Colin Cross2207f872021-03-24 12:39:08 -0700101}
102
103type DroidstubsProperties struct {
104 // The generated public API filename by Metalava, defaults to <module>_api.txt
105 Api_filename *string
106
107 // the generated removed API filename by Metalava, defaults to <module>_removed.txt
108 Removed_api_filename *string
109
Colin Cross2207f872021-03-24 12:39:08 -0700110 Check_api struct {
111 Last_released ApiToCheck
112
113 Current ApiToCheck
114
115 Api_lint struct {
116 Enabled *bool
117
118 // If set, performs api_lint on any new APIs not found in the given signature file
119 New_since *string `android:"path"`
120
121 // If not blank, path to the baseline txt file for approved API lint violations.
122 Baseline_file *string `android:"path"`
123 }
124 }
125
126 // user can specify the version of previous released API file in order to do compatibility check.
127 Previous_api *string `android:"path"`
128
129 // is set to true, Metalava will allow framework SDK to contain annotations.
130 Annotations_enabled *bool
131
132 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
133 Merge_annotations_dirs []string
134
135 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
136 Merge_inclusion_annotations_dirs []string
137
138 // a file containing a list of classes to do nullability validation for.
139 Validate_nullability_from_list *string
140
141 // a file containing expected warnings produced by validation of nullability annotations.
142 Check_nullability_warnings *string
143
144 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
145 Create_doc_stubs *bool
146
147 // if set to true, cause Metalava to output Javadoc comments in the stubs source files. Defaults to false.
148 // Has no effect if create_doc_stubs: true.
149 Output_javadoc_comments *bool
150
151 // if set to false then do not write out stubs. Defaults to true.
152 //
153 // TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately.
154 Generate_stubs *bool
155
156 // 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 -0400157 // which can be used for scheduling purposes
Colin Cross2207f872021-03-24 12:39:08 -0700158 High_mem *bool
159
satayev783195c2021-06-23 21:49:57 +0100160 // if set to true, Metalava will allow framework SDK to contain API levels annotations.
Colin Cross2207f872021-03-24 12:39:08 -0700161 Api_levels_annotations_enabled *bool
162
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000163 // Apply the api levels database created by this module rather than generating one in this droidstubs.
164 Api_levels_module *string
165
Colin Cross2207f872021-03-24 12:39:08 -0700166 // the dirs which Metalava extracts API levels annotations from.
167 Api_levels_annotations_dirs []string
168
Cole Faust051fa912022-10-05 12:45:42 -0700169 // 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 +0100170 Api_levels_sdk_type *string
171
Colin Cross2207f872021-03-24 12:39:08 -0700172 // the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
173 Api_levels_jar_filename *string
174
175 // if set to true, collect the values used by the Dev tools and
176 // write them in files packaged with the SDK. Defaults to false.
177 Write_sdk_values *bool
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200178
179 // path or filegroup to file defining extension an SDK name <-> numerical ID mapping and
180 // what APIs exist in which SDKs; passed to metalava via --sdk-extensions-info
181 Extensions_info_file *string `android:"path"`
Jihoon Kang3198f3c2023-01-26 08:08:52 +0000182
183 // API surface of this module. If set, the module contributes to an API surface.
184 // For the full list of available API surfaces, refer to soong/android/sdk_version.go
185 Api_surface *string
Jihoon Kang6592e872023-12-19 01:13:16 +0000186
187 // a list of aconfig_declarations module names that the stubs generated in this module
188 // depend on.
189 Aconfig_declarations []string
Colin Cross2207f872021-03-24 12:39:08 -0700190}
191
Anton Hansson52609322021-05-05 10:36:05 +0100192// Used by xsd_config
193type ApiFilePath interface {
Jihoon Kangee113282024-01-23 00:16:41 +0000194 ApiFilePath(StubsType) (android.Path, error)
Anton Hansson52609322021-05-05 10:36:05 +0100195}
196
197type ApiStubsSrcProvider interface {
Jihoon Kangee113282024-01-23 00:16:41 +0000198 StubsSrcJar(StubsType) (android.Path, error)
Jihoon Kangf55a5f72024-01-08 08:56:20 +0000199}
200
Anton Hansson52609322021-05-05 10:36:05 +0100201// Provider of information about API stubs, used by java_sdk_library.
202type ApiStubsProvider interface {
Jihoon Kangee113282024-01-23 00:16:41 +0000203 AnnotationsZip(StubsType) (android.Path, error)
Anton Hansson52609322021-05-05 10:36:05 +0100204 ApiFilePath
Jihoon Kangee113282024-01-23 00:16:41 +0000205 RemovedApiFilePath(StubsType) (android.Path, error)
Anton Hansson52609322021-05-05 10:36:05 +0100206
207 ApiStubsSrcProvider
208}
209
Jihoon Kang063ec002023-06-28 01:16:23 +0000210type currentApiTimestampProvider interface {
211 CurrentApiTimestamp() android.Path
212}
213
Jihoon Kang3c89f042023-12-19 02:40:22 +0000214type annotationFlagsParams struct {
215 migratingNullability bool
216 validatingNullability bool
217 nullabilityWarningsFile android.WritablePath
218 annotationsZip android.WritablePath
219}
220type stubsCommandParams struct {
221 srcJarDir android.ModuleOutPath
222 stubsDir android.OptionalPath
223 stubsSrcJar android.WritablePath
224 metadataZip android.WritablePath
225 metadataDir android.WritablePath
226 apiVersionsXml android.WritablePath
227 nullabilityWarningsFile android.WritablePath
228 annotationsZip android.WritablePath
229 stubConfig stubsCommandConfigParams
230}
231type stubsCommandConfigParams struct {
232 stubsType StubsType
233 javaVersion javaVersion
234 deps deps
235 checkApi bool
236 generateStubs bool
237 doApiLint bool
238 doCheckReleased bool
239 writeSdkValues bool
240 migratingNullability bool
241 validatingNullability bool
242}
243
Colin Cross2207f872021-03-24 12:39:08 -0700244// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
245// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
246// a droiddoc module to generate documentation.
247func DroidstubsFactory() android.Module {
248 module := &Droidstubs{}
249
250 module.AddProperties(&module.properties,
251 &module.Javadoc.properties)
Spandan Das2cc80ba2023-10-27 17:21:52 +0000252 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -0700253
254 InitDroiddocModule(module, android.HostAndDeviceSupported)
Jihoon Kang3198f3c2023-01-26 08:08:52 +0000255
256 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
257 module.createApiContribution(ctx)
258 })
Colin Cross2207f872021-03-24 12:39:08 -0700259 return module
260}
261
262// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
263// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
264// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
265// module when symbols needed by the source files are provided by java_library_host modules.
266func DroidstubsHostFactory() android.Module {
267 module := &Droidstubs{}
268
269 module.AddProperties(&module.properties,
270 &module.Javadoc.properties)
271
272 InitDroiddocModule(module, android.HostSupported)
273 return module
274}
275
Jihoon Kang78f89142023-12-27 01:40:29 +0000276func getStubsTypeAndTag(tag string) (StubsType, string, error) {
277 if len(tag) == 0 {
278 return Everything, "", nil
279 }
280 if tag[0] != '.' {
281 return Unavailable, "", fmt.Errorf("tag must begin with \".\"")
282 }
283
284 stubsType := Everything
285 // Check if the tag has a stubs type prefix (e.g. ".exportable")
286 for st := Everything; st <= Exportable; st++ {
287 if strings.HasPrefix(tag, "."+st.String()) {
288 stubsType = st
289 }
290 }
291
292 return stubsType, strings.TrimPrefix(tag, "."+stubsType.String()), nil
293}
294
295// Droidstubs' tag supports specifying with the stubs type.
296// While supporting the pre-existing tags, it also supports tags with
297// the stubs type prefix. Some examples are shown below:
298// {.annotations.zip} - pre-existing behavior. Returns the path to the
299// annotation zip.
300// {.exportable} - Returns the path to the exportable stubs src jar.
301// {.exportable.annotations.zip} - Returns the path to the exportable
302// annotations zip file.
303// {.runtime.api_versions.xml} - Runtime stubs does not generate api versions
304// xml file. For unsupported combinations, the default everything output file
305// is returned.
Colin Cross2207f872021-03-24 12:39:08 -0700306func (d *Droidstubs) OutputFiles(tag string) (android.Paths, error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000307 stubsType, prefixRemovedTag, err := getStubsTypeAndTag(tag)
308 if err != nil {
309 return nil, err
310 }
311 switch prefixRemovedTag {
Colin Cross2207f872021-03-24 12:39:08 -0700312 case "":
Jihoon Kangee113282024-01-23 00:16:41 +0000313 stubsSrcJar, err := d.StubsSrcJar(stubsType)
314 return android.Paths{stubsSrcJar}, err
Colin Cross2207f872021-03-24 12:39:08 -0700315 case ".docs.zip":
Jihoon Kangee113282024-01-23 00:16:41 +0000316 docZip, err := d.DocZip(stubsType)
317 return android.Paths{docZip}, err
Colin Cross2207f872021-03-24 12:39:08 -0700318 case ".api.txt", android.DefaultDistTag:
319 // This is the default dist path for dist properties that have no tag property.
Jihoon Kangee113282024-01-23 00:16:41 +0000320 apiFilePath, err := d.ApiFilePath(stubsType)
321 return android.Paths{apiFilePath}, err
Colin Cross2207f872021-03-24 12:39:08 -0700322 case ".removed-api.txt":
Jihoon Kangee113282024-01-23 00:16:41 +0000323 removedApiFilePath, err := d.RemovedApiFilePath(stubsType)
324 return android.Paths{removedApiFilePath}, err
Colin Cross2207f872021-03-24 12:39:08 -0700325 case ".annotations.zip":
Jihoon Kangee113282024-01-23 00:16:41 +0000326 annotationsZip, err := d.AnnotationsZip(stubsType)
327 return android.Paths{annotationsZip}, err
Colin Cross2207f872021-03-24 12:39:08 -0700328 case ".api_versions.xml":
Jihoon Kangee113282024-01-23 00:16:41 +0000329 apiVersionsXmlFilePath, err := d.ApiVersionsXmlFilePath(stubsType)
330 return android.Paths{apiVersionsXmlFilePath}, err
Colin Cross2207f872021-03-24 12:39:08 -0700331 default:
332 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
333 }
334}
335
Jihoon Kang246690a2024-02-01 21:55:01 +0000336func (d *Droidstubs) AnnotationsZip(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000337 switch stubsType {
338 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000339 ret, err = d.everythingArtifacts.annotationsZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000340 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000341 ret, err = d.exportableArtifacts.annotationsZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000342 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000343 ret, err = nil, fmt.Errorf("annotations zip not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000344 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000345 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000346}
347
Jihoon Kang246690a2024-02-01 21:55:01 +0000348func (d *Droidstubs) ApiFilePath(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000349 switch stubsType {
350 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000351 ret, err = d.apiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000352 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000353 ret, err = d.exportableApiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000354 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000355 ret, err = nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000356 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000357 if ret == nil && err == nil {
358 err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
359 }
360 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000361}
362
Jihoon Kang246690a2024-02-01 21:55:01 +0000363func (d *Droidstubs) ApiVersionsXmlFilePath(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.everythingArtifacts.apiVersionsXml, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000367 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000368 ret, err = d.exportableArtifacts.apiVersionsXml, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000369 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000370 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 +0000371 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000372 if ret == nil && err == nil {
373 err = fmt.Errorf("api versions xml file 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) DocZip(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.docZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000382 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000383 ret, err = nil, fmt.Errorf("docs zip 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("docs zip is null for the stub type %s", stubsType.String())
387 }
388 return ret, err
389}
390
391func (d *Droidstubs) RemovedApiFilePath(stubsType StubsType) (ret android.Path, err error) {
392 switch stubsType {
393 case Everything:
394 ret, err = d.removedApiFile, nil
395 case Exportable:
396 ret, err = d.exportableRemovedApiFile, nil
397 default:
398 ret, err = nil, fmt.Errorf("removed api file path not supported for the stub type %s", stubsType.String())
399 }
400 if ret == nil && err == nil {
401 err = fmt.Errorf("removed api file is null for the stub type %s", stubsType.String())
402 }
403 return ret, err
404}
405
406func (d *Droidstubs) StubsSrcJar(stubsType StubsType) (ret android.Path, err error) {
407 switch stubsType {
408 case Everything:
409 ret, err = d.stubsSrcJar, nil
410 case Exportable:
411 ret, err = d.exportableStubsSrcJar, nil
412 default:
413 ret, err = nil, fmt.Errorf("stubs srcjar not supported for the stub type %s", stubsType.String())
414 }
415 if ret == nil && err == nil {
416 err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
417 }
418 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000419}
420
Jihoon Kang063ec002023-06-28 01:16:23 +0000421func (d *Droidstubs) CurrentApiTimestamp() android.Path {
422 return d.checkCurrentApiTimestamp
423}
424
Colin Cross2207f872021-03-24 12:39:08 -0700425var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
426var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
427var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000428var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"}
Jihoon Kang063ec002023-06-28 01:16:23 +0000429var metalavaCurrentApiTimestampTag = dependencyTag{name: "metalava-current-api-timestamp-tag"}
Colin Cross2207f872021-03-24 12:39:08 -0700430
431func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
432 d.Javadoc.addDeps(ctx)
433
434 if len(d.properties.Merge_annotations_dirs) != 0 {
435 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
436 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
437 }
438 }
439
440 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
441 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
442 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
443 }
444 }
445
446 if len(d.properties.Api_levels_annotations_dirs) != 0 {
447 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
448 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
449 }
450 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000451
Jihoon Kang6592e872023-12-19 01:13:16 +0000452 if len(d.properties.Aconfig_declarations) != 0 {
453 for _, aconfigDeclarationModuleName := range d.properties.Aconfig_declarations {
454 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationModuleName)
455 }
456 }
457
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000458 if d.properties.Api_levels_module != nil {
459 ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
460 }
Colin Cross2207f872021-03-24 12:39:08 -0700461}
462
Jihoon Kang3c89f042023-12-19 02:40:22 +0000463func (d *Droidstubs) sdkValuesFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, metadataDir android.WritablePath) {
464 cmd.FlagWithArg("--sdk-values ", metadataDir.String())
465}
466
467func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath, stubsType StubsType, checkApi bool) {
468 if checkApi || String(d.properties.Api_filename) != "" {
Colin Cross2207f872021-03-24 12:39:08 -0700469 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000470 uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
Paul Duffinc71d2b72022-08-16 15:24:01 +0000471 cmd.FlagWithOutput("--api ", uncheckedApiFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000472
473 if stubsType == Everything {
474 d.apiFile = uncheckedApiFile
475 } else if stubsType == Exportable {
476 d.exportableApiFile = uncheckedApiFile
477 }
Colin Cross2207f872021-03-24 12:39:08 -0700478 } else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
479 // If check api is disabled then make the source file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000480 d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700481 }
482
Jihoon Kang3c89f042023-12-19 02:40:22 +0000483 if checkApi || String(d.properties.Removed_api_filename) != "" {
Colin Cross2207f872021-03-24 12:39:08 -0700484 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000485 uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
Paul Duffinc71d2b72022-08-16 15:24:01 +0000486 cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000487
488 if stubsType == Everything {
489 d.removedApiFile = uncheckedRemovedFile
490 } else if stubsType == Exportable {
491 d.exportableRemovedApiFile = uncheckedRemovedFile
492 }
Colin Cross2207f872021-03-24 12:39:08 -0700493 } else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
494 // If check api is disabled then make the source removed api file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000495 d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700496 }
497
Colin Cross2207f872021-03-24 12:39:08 -0700498 if stubsDir.Valid() {
499 if Bool(d.properties.Create_doc_stubs) {
500 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
501 } else {
502 cmd.FlagWithArg("--stubs ", stubsDir.String())
503 if !Bool(d.properties.Output_javadoc_comments) {
504 cmd.Flag("--exclude-documentation-from-stubs")
505 }
506 }
507 }
508}
509
Jihoon Kang3c89f042023-12-19 02:40:22 +0000510func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, params annotationFlagsParams) {
Colin Cross2207f872021-03-24 12:39:08 -0700511 if Bool(d.properties.Annotations_enabled) {
Liz Kammere09e20e2023-10-16 15:07:54 -0400512 cmd.Flag(config.MetalavaAnnotationsFlags)
Andrei Onea4985e512021-04-29 16:29:34 +0100513
Jihoon Kang3c89f042023-12-19 02:40:22 +0000514 if params.migratingNullability {
Colin Cross2207f872021-03-24 12:39:08 -0700515 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
516 cmd.FlagWithInput("--migrate-nullness ", previousApi)
517 }
518
519 if s := String(d.properties.Validate_nullability_from_list); s != "" {
520 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
521 }
522
Jihoon Kang3c89f042023-12-19 02:40:22 +0000523 if params.validatingNullability {
524 cmd.FlagWithOutput("--nullability-warnings-txt ", params.nullabilityWarningsFile)
Colin Cross2207f872021-03-24 12:39:08 -0700525 }
526
Jihoon Kang3c89f042023-12-19 02:40:22 +0000527 cmd.FlagWithOutput("--extract-annotations ", params.annotationsZip)
Colin Cross2207f872021-03-24 12:39:08 -0700528
529 if len(d.properties.Merge_annotations_dirs) != 0 {
530 d.mergeAnnoDirFlags(ctx, cmd)
531 }
532
Liz Kammere09e20e2023-10-16 15:07:54 -0400533 cmd.Flag(config.MetalavaAnnotationsWarningsFlags)
Colin Cross2207f872021-03-24 12:39:08 -0700534 }
535}
536
537func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
538 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
539 if t, ok := m.(*ExportedDroiddocDir); ok {
540 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
541 } else {
542 ctx.PropertyErrorf("merge_annotations_dirs",
543 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
544 }
545 })
546}
547
548func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
549 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
550 if t, ok := m.(*ExportedDroiddocDir); ok {
551 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
552 } else {
553 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
554 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
555 }
556 })
557}
558
Jihoon Kang3c89f042023-12-19 02:40:22 +0000559func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000560 var apiVersions android.Path
561 if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000562 d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
Jihoon Kangee113282024-01-23 00:16:41 +0000563 apiVersions = d.everythingArtifacts.apiVersionsXml
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000564 } else {
565 ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
566 if s, ok := m.(*Droidstubs); ok {
Jihoon Kangee113282024-01-23 00:16:41 +0000567 apiVersions = s.everythingArtifacts.apiVersionsXml
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000568 } else {
569 ctx.PropertyErrorf("api_levels_module",
570 "module %q is not a droidstubs module", ctx.OtherModuleName(m))
571 }
572 })
Colin Cross2207f872021-03-24 12:39:08 -0700573 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000574 if apiVersions != nil {
575 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
576 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
577 cmd.FlagWithInput("--apply-api-levels ", apiVersions)
578 }
579}
Colin Cross2207f872021-03-24 12:39:08 -0700580
Jihoon Kang3c89f042023-12-19 02:40:22 +0000581func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Colin Cross2207f872021-03-24 12:39:08 -0700582 if len(d.properties.Api_levels_annotations_dirs) == 0 {
583 ctx.PropertyErrorf("api_levels_annotations_dirs",
584 "has to be non-empty if api levels annotations was enabled!")
585 }
586
Jihoon Kang3c89f042023-12-19 02:40:22 +0000587 cmd.FlagWithOutput("--generate-api-levels ", apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700588
589 filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
590
satayev783195c2021-06-23 21:49:57 +0100591 var dirs []string
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200592 var extensions_dir string
Colin Cross2207f872021-03-24 12:39:08 -0700593 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
594 if t, ok := m.(*ExportedDroiddocDir); ok {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200595 extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
596
597 // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
598 // ideally this should be read from prebuiltApis.properties.Extensions_*
Colin Cross2207f872021-03-24 12:39:08 -0700599 for _, dep := range t.deps {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200600 if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
601 if extensions_dir == "" {
602 extensions_dir = t.dir.String() + "/extensions"
603 }
604 cmd.Implicit(dep)
605 }
Colin Cross5f6ffc72021-03-29 21:54:45 -0700606 if dep.Base() == filename {
607 cmd.Implicit(dep)
608 }
609 if filename != "android.jar" && dep.Base() == "android.jar" {
610 // Metalava implicitly searches these patterns:
611 // prebuilts/tools/common/api-versions/android-%/android.jar
612 // prebuilts/sdk/%/public/android.jar
613 // Add android.jar files from the api_levels_annotations_dirs directories to try
614 // to satisfy these patterns. If Metalava can't find a match for an API level
615 // between 1 and 28 in at least one pattern it will fail.
Colin Cross2207f872021-03-24 12:39:08 -0700616 cmd.Implicit(dep)
617 }
618 }
satayev783195c2021-06-23 21:49:57 +0100619
620 dirs = append(dirs, t.dir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700621 } else {
622 ctx.PropertyErrorf("api_levels_annotations_dirs",
623 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
624 }
625 })
satayev783195c2021-06-23 21:49:57 +0100626
627 // Add all relevant --android-jar-pattern patterns for Metalava.
628 // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
629 // an actual file present on disk (in the order the patterns were passed). For system APIs for
630 // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
Pedro Loureirocc203502021-10-04 17:24:00 +0000631 // for older releases. Similarly, module-lib falls back to system API.
632 var sdkDirs []string
633 switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
Cole Faust051fa912022-10-05 12:45:42 -0700634 case "system-server":
635 sdkDirs = []string{"system-server", "module-lib", "system", "public"}
Pedro Loureirocc203502021-10-04 17:24:00 +0000636 case "module-lib":
637 sdkDirs = []string{"module-lib", "system", "public"}
638 case "system":
639 sdkDirs = []string{"system", "public"}
640 case "public":
641 sdkDirs = []string{"public"}
642 default:
643 ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
644 return
satayev783195c2021-06-23 21:49:57 +0100645 }
Pedro Loureirocc203502021-10-04 17:24:00 +0000646
647 for _, sdkDir := range sdkDirs {
648 for _, dir := range dirs {
649 cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
650 }
satayev783195c2021-06-23 21:49:57 +0100651 }
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200652
653 if d.properties.Extensions_info_file != nil {
654 if extensions_dir == "" {
655 ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
656 }
657 info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
658 cmd.Implicit(info_file)
659 cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
660 cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
661 }
Colin Cross2207f872021-03-24 12:39:08 -0700662}
663
Colin Crosse52c2ac2022-03-28 17:03:35 -0700664func metalavaUseRbe(ctx android.ModuleContext) bool {
665 return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
666}
667
Colin Cross2207f872021-03-24 12:39:08 -0700668func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Anton Hansson556e8142021-06-04 16:20:25 +0100669 srcJarList android.Path, bootclasspath, classpath classpath, homeDir android.WritablePath) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700670 rule.Command().Text("rm -rf").Flag(homeDir.String())
671 rule.Command().Text("mkdir -p").Flag(homeDir.String())
672
Anton Hansson556e8142021-06-04 16:20:25 +0100673 cmd := rule.Command()
Colin Cross2207f872021-03-24 12:39:08 -0700674 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())
675
Colin Crosse52c2ac2022-03-28 17:03:35 -0700676 if metalavaUseRbe(ctx) {
Colin Cross2207f872021-03-24 12:39:08 -0700677 rule.Remoteable(android.RemoteRuleSupports{RBE: true})
Colin Cross8095c292021-03-30 16:40:48 -0700678 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000679 compare := ctx.Config().IsEnvTrue("RBE_METALAVA_COMPARE")
680 remoteUpdateCache := !ctx.Config().IsEnvFalse("RBE_METALAVA_REMOTE_UPDATE_CACHE")
Colin Cross8095c292021-03-30 16:40:48 -0700681 labels := map[string]string{"type": "tool", "name": "metalava"}
682 // TODO: metalava pool rejects these jobs
683 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
684 rule.Rewrapper(&remoteexec.REParams{
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000685 Labels: labels,
686 ExecStrategy: execStrategy,
687 ToolchainInputs: []string{config.JavaCmd(ctx).String()},
688 Platform: map[string]string{remoteexec.PoolKey: pool},
689 Compare: compare,
690 NumLocalRuns: 1,
691 NumRemoteRuns: 1,
692 NoRemoteUpdateCache: !remoteUpdateCache,
Colin Cross8095c292021-03-30 16:40:48 -0700693 })
Colin Cross2207f872021-03-24 12:39:08 -0700694 }
695
Colin Cross6aa5c402021-03-24 12:28:50 -0700696 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
Colin Cross2207f872021-03-24 12:39:08 -0700697 Flag(config.JavacVmFlags).
Liz Kammere09e20e2023-10-16 15:07:54 -0400698 Flag(config.MetalavaAddOpens).
Paul Duffin808211e2023-08-09 12:36:08 +0100699 FlagWithArg("--java-source ", javaVersion.String()).
Colin Cross2207f872021-03-24 12:39:08 -0700700 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
701 FlagWithInput("@", srcJarList)
702
Paul Duffinf8aaaa12023-08-10 15:16:35 +0100703 // Metalava does not differentiate between bootclasspath and classpath and has not done so for
704 // years, so it is unlikely to change any time soon.
705 combinedPaths := append(([]android.Path)(nil), bootclasspath.Paths()...)
706 combinedPaths = append(combinedPaths, classpath.Paths()...)
707 if len(combinedPaths) > 0 {
708 cmd.FlagWithInputList("--classpath ", combinedPaths, ":")
Colin Cross2207f872021-03-24 12:39:08 -0700709 }
710
Liz Kammere09e20e2023-10-16 15:07:54 -0400711 cmd.Flag(config.MetalavaFlags)
Jihoon Kangc8313892023-09-20 00:54:47 +0000712
Colin Cross2207f872021-03-24 12:39:08 -0700713 return cmd
714}
715
Jihoon Kang3c89f042023-12-19 02:40:22 +0000716// Pass flagged apis related flags to metalava. When aconfig_declarations property is not
717// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
718// property is defined, apply transformations and only revert the flagged apis that are not
719// enabled via release configurations and are not specified in aconfig_declarations
720func (d *Droidstubs) generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
721
722 if len(aconfigFlagsPaths) == 0 {
723 cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
724 return
725 }
Jihoon Kang6592e872023-12-19 01:13:16 +0000726
727 releasedFlaggedApisFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flagged-apis-%s.txt", stubsType.String()))
728 revertAnnotationsFile := android.PathForModuleOut(ctx, fmt.Sprintf("revert-annotations-%s.txt", stubsType.String()))
729
730 var filterArgs string
731 switch stubsType {
732 // No flagged apis specific flags need to be passed to metalava when generating
733 // everything stubs
734 case Everything:
735 return
736
737 case Runtime:
738 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
739
740 case Exportable:
741 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY'"
742
743 }
744
745 ctx.Build(pctx, android.BuildParams{
746 Rule: gatherReleasedFlaggedApisRule,
747 Inputs: aconfigFlagsPaths,
748 Output: releasedFlaggedApisFile,
749 Description: fmt.Sprintf("%s gather aconfig flags", stubsType),
750 Args: map[string]string{
751 "flags_path": android.JoinPathsWithPrefix(aconfigFlagsPaths, "--cache "),
752 "filter_args": filterArgs,
753 },
754 })
755
756 ctx.Build(pctx, android.BuildParams{
757 Rule: generateMetalavaRevertAnnotationsRule,
758 Input: releasedFlaggedApisFile,
759 Output: revertAnnotationsFile,
760 Description: fmt.Sprintf("%s revert annotations", stubsType),
761 })
Jihoon Kang3c89f042023-12-19 02:40:22 +0000762
763 cmd.FlagWithInput("@", revertAnnotationsFile)
Jihoon Kang6592e872023-12-19 01:13:16 +0000764}
765
Jihoon Kang3c89f042023-12-19 02:40:22 +0000766func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
767 params stubsCommandParams) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700768 if BoolDefault(d.properties.High_mem, false) {
769 // This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
770 rule.HighMem()
771 }
772
Jihoon Kang3c89f042023-12-19 02:40:22 +0000773 if params.stubConfig.generateStubs {
774 rule.Command().Text("rm -rf").Text(params.stubsDir.String())
775 rule.Command().Text("mkdir -p").Text(params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700776 }
777
Jihoon Kang3c89f042023-12-19 02:40:22 +0000778 srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars)
Colin Cross2207f872021-03-24 12:39:08 -0700779
Jihoon Kang3c89f042023-12-19 02:40:22 +0000780 homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home")
781 cmd := metalavaCmd(ctx, rule, params.stubConfig.javaVersion, d.Javadoc.srcFiles, srcJarList,
782 params.stubConfig.deps.bootClasspath, params.stubConfig.deps.classpath, homeDir)
Colin Cross2207f872021-03-24 12:39:08 -0700783 cmd.Implicits(d.Javadoc.implicits)
784
Jihoon Kang3c89f042023-12-19 02:40:22 +0000785 d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
Colin Cross2207f872021-03-24 12:39:08 -0700786
Jihoon Kang3c89f042023-12-19 02:40:22 +0000787 if params.stubConfig.writeSdkValues {
788 d.sdkValuesFlags(ctx, cmd, params.metadataDir)
789 }
790
791 annotationParams := annotationFlagsParams{
792 migratingNullability: params.stubConfig.migratingNullability,
793 validatingNullability: params.stubConfig.validatingNullability,
794 nullabilityWarningsFile: params.nullabilityWarningsFile,
795 annotationsZip: params.annotationsZip,
796 }
797
798 d.annotationsFlags(ctx, cmd, annotationParams)
Colin Cross2207f872021-03-24 12:39:08 -0700799 d.inclusionAnnotationsFlags(ctx, cmd)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000800 d.apiLevelsAnnotationsFlags(ctx, cmd, params.stubConfig.stubsType, params.apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700801
Colin Crossbc139922021-03-25 18:33:16 -0700802 d.expandArgs(ctx, cmd)
Colin Cross2207f872021-03-24 12:39:08 -0700803
Colin Cross2207f872021-03-24 12:39:08 -0700804 for _, o := range d.Javadoc.properties.Out {
805 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
806 }
807
Jihoon Kang3c89f042023-12-19 02:40:22 +0000808 return cmd
809}
Colin Cross2207f872021-03-24 12:39:08 -0700810
Jihoon Kang3c89f042023-12-19 02:40:22 +0000811// Sandbox rule for generating the everything stubs and other artifacts
812func (d *Droidstubs) everythingStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
813 srcJarDir := android.PathForModuleOut(ctx, Everything.String(), "srcjars")
814 rule := android.NewRuleBuilder(pctx, ctx)
815 rule.Sbox(android.PathForModuleOut(ctx, Everything.String()),
816 android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
817 SandboxInputs()
818
819 var stubsDir android.OptionalPath
820 if params.generateStubs {
821 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, Everything.String(), "stubsDir"))
822 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
823 }
824
825 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +0000826 d.everythingArtifacts.metadataDir = android.PathForModuleOut(ctx, Everything.String(), "metadata")
827 d.everythingArtifacts.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000828 }
829
830 if Bool(d.properties.Annotations_enabled) {
831 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +0000832 d.everythingArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000833 }
Jihoon Kangee113282024-01-23 00:16:41 +0000834 d.everythingArtifacts.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000835 }
836 if Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kangee113282024-01-23 00:16:41 +0000837 d.everythingArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000838 }
839
840 commonCmdParams := stubsCommandParams{
841 srcJarDir: srcJarDir,
842 stubsDir: stubsDir,
843 stubsSrcJar: d.Javadoc.stubsSrcJar,
Jihoon Kangee113282024-01-23 00:16:41 +0000844 metadataDir: d.everythingArtifacts.metadataDir,
845 apiVersionsXml: d.everythingArtifacts.apiVersionsXml,
846 nullabilityWarningsFile: d.everythingArtifacts.nullabilityWarningsFile,
847 annotationsZip: d.everythingArtifacts.annotationsZip,
Jihoon Kang3c89f042023-12-19 02:40:22 +0000848 stubConfig: params,
849 }
850
851 cmd := d.commonMetalavaStubCmd(ctx, rule, commonCmdParams)
852
853 d.everythingOptionalCmd(ctx, cmd, params.doApiLint, params.doCheckReleased)
854
855 if params.generateStubs {
856 rule.Command().
857 BuiltTool("soong_zip").
858 Flag("-write_if_changed").
859 Flag("-jar").
860 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
861 FlagWithArg("-C ", stubsDir.String()).
862 FlagWithArg("-D ", stubsDir.String())
863 }
864
865 if params.writeSdkValues {
866 rule.Command().
867 BuiltTool("soong_zip").
868 Flag("-write_if_changed").
869 Flag("-d").
Jihoon Kangee113282024-01-23 00:16:41 +0000870 FlagWithOutput("-o ", d.everythingArtifacts.metadataZip).
871 FlagWithArg("-C ", d.everythingArtifacts.metadataDir.String()).
872 FlagWithArg("-D ", d.everythingArtifacts.metadataDir.String())
Jihoon Kang3c89f042023-12-19 02:40:22 +0000873 }
874
875 // TODO: We don't really need two separate API files, but this is a reminiscence of how
876 // we used to run metalava separately for API lint and the "last_released" check. Unify them.
877 if params.doApiLint {
878 rule.Command().Text("touch").Output(d.apiLintTimestamp)
879 }
880 if params.doCheckReleased {
881 rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
882 }
883
884 // TODO(b/183630617): rewrapper doesn't support restat rules
885 if !metalavaUseRbe(ctx) {
886 rule.Restat()
887 }
888
889 zipSyncCleanupCmd(rule, srcJarDir)
890
891 rule.Build("metalava", "metalava merged")
892}
893
894// Sandbox rule for generating the everything artifacts that are not run by
895// default but only run based on the module configurations
896func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, doApiLint bool, doCheckReleased bool) {
Colin Cross2207f872021-03-24 12:39:08 -0700897
898 // Add API lint options.
Jihoon Kang3c89f042023-12-19 02:40:22 +0000899 if doApiLint {
Colin Cross2207f872021-03-24 12:39:08 -0700900 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
901 if newSince.Valid() {
902 cmd.FlagWithInput("--api-lint ", newSince.Path())
903 } else {
904 cmd.Flag("--api-lint")
905 }
Jihoon Kang3c89f042023-12-19 02:40:22 +0000906 d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700907 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
908
Colin Cross0d532412021-03-25 09:38:45 -0700909 // TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
Colin Cross2207f872021-03-24 12:39:08 -0700910 if d.Name() != "android.car-system-stubs-docs" &&
911 d.Name() != "android.car-stubs-docs" {
912 cmd.Flag("--lints-as-errors")
913 cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
914 }
915
916 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000917 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "api_lint_baseline.txt")
918 d.apiLintTimestamp = android.PathForModuleOut(ctx, Everything.String(), "api_lint.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700919
920 // Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
Colin Cross2207f872021-03-24 12:39:08 -0700921 //
922 // TODO: metalava also has a slightly different message hardcoded. Should we unify this
923 // message and metalava's one?
924 msg := `$'` + // Enclose with $' ... '
925 `************************************************************\n` +
926 `Your API changes are triggering API Lint warnings or errors.\n` +
927 `To make these errors go away, fix the code according to the\n` +
928 `error and/or warning messages above.\n` +
929 `\n` +
930 `If it is not possible to do so, there are workarounds:\n` +
931 `\n` +
Aurimas Liutikasb23b7452021-05-24 18:00:37 +0000932 `1. You can suppress the errors with @SuppressLint("<id>")\n` +
933 ` where the <id> is given in brackets in the error message above.\n`
Colin Cross2207f872021-03-24 12:39:08 -0700934
935 if baselineFile.Valid() {
936 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
937 cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)
938
939 msg += fmt.Sprintf(``+
940 `2. You can update the baseline by executing the following\n`+
941 ` command:\n`+
Colin Cross63eeda02021-04-15 19:01:57 -0700942 ` (cd $ANDROID_BUILD_TOP && cp \\\n`+
943 ` "%s" \\\n`+
944 ` "%s")\n`+
Colin Cross2207f872021-03-24 12:39:08 -0700945 ` To submit the revised baseline.txt to the main Android\n`+
946 ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
947 } else {
948 msg += fmt.Sprintf(``+
949 `2. You can add a baseline file of existing lint failures\n`+
950 ` to the build rule of %s.\n`, d.Name())
951 }
952 // Note the message ends with a ' (single quote), to close the $' ... ' .
953 msg += `************************************************************\n'`
954
955 cmd.FlagWithArg("--error-message:api-lint ", msg)
956 }
957
958 // Add "check released" options. (Detect incompatible API changes from the last public release)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000959 if doCheckReleased {
Colin Cross2207f872021-03-24 12:39:08 -0700960 if len(d.Javadoc.properties.Out) > 0 {
961 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
962 }
963
964 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
965 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
966 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000967 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700968
Jihoon Kang3c89f042023-12-19 02:40:22 +0000969 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700970
971 cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
972 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
973
974 if baselineFile.Valid() {
975 cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
976 cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
977 }
978
979 // Note this string includes quote ($' ... '), which decodes the "\n"s.
980 msg := `$'\n******************************\n` +
981 `You have tried to change the API from what has been previously released in\n` +
982 `an SDK. Please fix the errors listed above.\n` +
983 `******************************\n'`
984
985 cmd.FlagWithArg("--error-message:compatibility:released ", msg)
986 }
987
Paul Duffin10a23c22023-08-11 22:47:31 +0100988 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
989 // Pass the current API file into metalava so it can use it as the basis for determining how to
990 // generate the output signature files (both api and removed).
991 currentApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
992 cmd.FlagWithInput("--use-same-format-as ", currentApiFile)
993 }
Jihoon Kang3c89f042023-12-19 02:40:22 +0000994}
Paul Duffin10a23c22023-08-11 22:47:31 +0100995
Jihoon Kang3c89f042023-12-19 02:40:22 +0000996// Sandbox rule for generating exportable stubs and other artifacts
997func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
998 optionalCmdParams := stubsCommandParams{
999 stubConfig: params,
1000 }
1001
Jihoon Kang246690a2024-02-01 21:55:01 +00001002 if params.generateStubs {
1003 d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
1004 optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
1005 }
1006
Jihoon Kang3c89f042023-12-19 02:40:22 +00001007 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +00001008 d.exportableArtifacts.metadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
1009 d.exportableArtifacts.metadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
1010 optionalCmdParams.metadataZip = d.exportableArtifacts.metadataZip
1011 optionalCmdParams.metadataDir = d.exportableArtifacts.metadataDir
Jihoon Kang3c89f042023-12-19 02:40:22 +00001012 }
1013
1014 if Bool(d.properties.Annotations_enabled) {
1015 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +00001016 d.exportableArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
1017 optionalCmdParams.nullabilityWarningsFile = d.exportableArtifacts.nullabilityWarningsFile
Jihoon Kang3c89f042023-12-19 02:40:22 +00001018 }
Jihoon Kangee113282024-01-23 00:16:41 +00001019 d.exportableArtifacts.annotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
1020 optionalCmdParams.annotationsZip = d.exportableArtifacts.annotationsZip
Jihoon Kang3c89f042023-12-19 02:40:22 +00001021 }
1022 if Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kangee113282024-01-23 00:16:41 +00001023 d.exportableArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
1024 optionalCmdParams.apiVersionsXml = d.exportableArtifacts.apiVersionsXml
Jihoon Kang3c89f042023-12-19 02:40:22 +00001025 }
1026
1027 if params.checkApi || String(d.properties.Api_filename) != "" {
1028 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
1029 d.exportableApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1030 }
1031
1032 if params.checkApi || String(d.properties.Removed_api_filename) != "" {
1033 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_api.txt")
1034 d.exportableRemovedApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1035 }
1036
1037 d.optionalStubCmd(ctx, optionalCmdParams)
1038}
1039
1040func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsCommandParams) {
1041
1042 params.srcJarDir = android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "srcjars")
1043 rule := android.NewRuleBuilder(pctx, ctx)
1044 rule.Sbox(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String()),
1045 android.PathForModuleOut(ctx, fmt.Sprintf("metalava_%s.sbox.textproto", params.stubConfig.stubsType.String()))).
1046 SandboxInputs()
1047
1048 if params.stubConfig.generateStubs {
1049 params.stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "stubsDir"))
1050 }
1051
1052 cmd := d.commonMetalavaStubCmd(ctx, rule, params)
1053
1054 d.generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
1055
1056 if params.stubConfig.doApiLint {
1057 // Pass the lint baseline file as an input to resolve the lint errors.
1058 // The exportable stubs generation does not update the lint baseline file.
1059 // Lint baseline file update is handled by the everything stubs
1060 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1061 if baselineFile.Valid() {
1062 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
1063 }
1064 }
1065
1066 if params.stubConfig.generateStubs {
Colin Cross2207f872021-03-24 12:39:08 -07001067 rule.Command().
1068 BuiltTool("soong_zip").
1069 Flag("-write_if_changed").
1070 Flag("-jar").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001071 FlagWithOutput("-o ", params.stubsSrcJar).
1072 FlagWithArg("-C ", params.stubsDir.String()).
1073 FlagWithArg("-D ", params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001074 }
1075
Jihoon Kang3c89f042023-12-19 02:40:22 +00001076 if params.stubConfig.writeSdkValues {
Colin Cross2207f872021-03-24 12:39:08 -07001077 rule.Command().
1078 BuiltTool("soong_zip").
1079 Flag("-write_if_changed").
1080 Flag("-d").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001081 FlagWithOutput("-o ", params.metadataZip).
1082 FlagWithArg("-C ", params.metadataDir.String()).
1083 FlagWithArg("-D ", params.metadataDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001084 }
1085
Colin Cross6aa5c402021-03-24 12:28:50 -07001086 // TODO(b/183630617): rewrapper doesn't support restat rules
Colin Crosse52c2ac2022-03-28 17:03:35 -07001087 if !metalavaUseRbe(ctx) {
1088 rule.Restat()
1089 }
Colin Cross2207f872021-03-24 12:39:08 -07001090
Jihoon Kang3c89f042023-12-19 02:40:22 +00001091 zipSyncCleanupCmd(rule, params.srcJarDir)
Colin Cross2207f872021-03-24 12:39:08 -07001092
Jihoon Kang3c89f042023-12-19 02:40:22 +00001093 rule.Build(fmt.Sprintf("metalava_%s", params.stubConfig.stubsType.String()), "metalava merged")
1094}
1095
1096func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1097 deps := d.Javadoc.collectDeps(ctx)
1098
1099 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
1100 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
1101
1102 // Add options for the other optional tasks: API-lint and check-released.
1103 // We generate separate timestamp files for them.
1104 doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
1105 doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1106
1107 writeSdkValues := Bool(d.properties.Write_sdk_values)
1108
1109 annotationsEnabled := Bool(d.properties.Annotations_enabled)
1110
1111 migratingNullability := annotationsEnabled && String(d.properties.Previous_api) != ""
1112 validatingNullability := annotationsEnabled && (strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
1113 String(d.properties.Validate_nullability_from_list) != "")
1114
1115 checkApi := apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1116 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1117
1118 stubCmdParams := stubsCommandConfigParams{
1119 javaVersion: javaVersion,
1120 deps: deps,
1121 checkApi: checkApi,
1122 generateStubs: generateStubs,
1123 doApiLint: doApiLint,
1124 doCheckReleased: doCheckReleased,
1125 writeSdkValues: writeSdkValues,
1126 migratingNullability: migratingNullability,
1127 validatingNullability: validatingNullability,
1128 }
1129 stubCmdParams.stubsType = Everything
1130 // Create default (i.e. "everything" stubs) rule for metalava
1131 d.everythingStubCmd(ctx, stubCmdParams)
1132
1133 // The module generates "exportable" (and "runtime" eventually) stubs regardless of whether
1134 // aconfig_declarations property is defined or not. If the property is not defined, the module simply
1135 // strips all flagged apis to generate the "exportable" stubs
1136 stubCmdParams.stubsType = Exportable
1137 d.exportableStubCmd(ctx, stubCmdParams)
Paul Duffinc166b682022-05-27 12:23:08 +00001138
Paul Duffine7a86642022-08-16 15:43:20 +00001139 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1140
1141 if len(d.Javadoc.properties.Out) > 0 {
1142 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1143 }
1144
1145 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1146 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
1147 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1148
1149 if baselineFile.Valid() {
1150 ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
1151 }
1152
Jihoon Kang3c89f042023-12-19 02:40:22 +00001153 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001154
1155 rule := android.NewRuleBuilder(pctx, ctx)
1156
1157 // Diff command line.
1158 // -F matches the closest "opening" line, such as "package android {"
1159 // and " public class Intent {".
1160 diff := `diff -u -F '{ *$'`
1161
1162 rule.Command().Text("( true")
1163 rule.Command().
1164 Text(diff).
1165 Input(apiFile).Input(d.apiFile)
1166
1167 rule.Command().
1168 Text(diff).
1169 Input(removedApiFile).Input(d.removedApiFile)
1170
1171 msg := fmt.Sprintf(`\n******************************\n`+
1172 `You have tried to change the API from what has been previously approved.\n\n`+
1173 `To make these errors go away, you have two choices:\n`+
1174 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
1175 ` to the new methods, etc. shown in the above diff.\n\n`+
1176 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
1177 ` m %s-update-current-api\n\n`+
1178 ` To submit the revised current.txt to the main Android repository,\n`+
1179 ` you will need approval.\n`+
Jihoon Kang3ea64672023-11-03 00:40:26 +00001180 `If your build failed due to stub validation, you can resolve the errors with\n`+
1181 `either of the two choices above and try re-building the target.\n`+
1182 `If the mismatch between the stubs and the current.txt is intended,\n`+
1183 `you can try re-building the target by executing the following command:\n`+
Jihoon Kang91bf3dd2024-01-24 00:40:23 +00001184 `m DISABLE_STUB_VALIDATION=true <your build target>.\n`+
1185 `Note that DISABLE_STUB_VALIDATION=true does not bypass checkapi.\n`+
Paul Duffine7a86642022-08-16 15:43:20 +00001186 `******************************\n`, ctx.ModuleName())
1187
1188 rule.Command().
1189 Text("touch").Output(d.checkCurrentApiTimestamp).
1190 Text(") || (").
1191 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1192 Text("; exit 38").
1193 Text(")")
1194
1195 rule.Build("metalavaCurrentApiCheck", "check current API")
1196
Jihoon Kang3c89f042023-12-19 02:40:22 +00001197 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001198
1199 // update API rule
1200 rule = android.NewRuleBuilder(pctx, ctx)
1201
1202 rule.Command().Text("( true")
1203
1204 rule.Command().
1205 Text("cp").Flag("-f").
1206 Input(d.apiFile).Flag(apiFile.String())
1207
1208 rule.Command().
1209 Text("cp").Flag("-f").
1210 Input(d.removedApiFile).Flag(removedApiFile.String())
1211
1212 msg = "failed to update public API"
1213
1214 rule.Command().
1215 Text("touch").Output(d.updateCurrentApiTimestamp).
1216 Text(") || (").
1217 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1218 Text("; exit 38").
1219 Text(")")
1220
1221 rule.Build("metalavaCurrentApiUpdate", "update current API")
1222 }
1223
Colin Cross2207f872021-03-24 12:39:08 -07001224 if String(d.properties.Check_nullability_warnings) != "" {
Jihoon Kangee113282024-01-23 00:16:41 +00001225 if d.everythingArtifacts.nullabilityWarningsFile == nil {
Colin Cross2207f872021-03-24 12:39:08 -07001226 ctx.PropertyErrorf("check_nullability_warnings",
1227 "Cannot specify check_nullability_warnings unless validating nullability")
1228 }
1229
1230 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1231
Jihoon Kang3c89f042023-12-19 02:40:22 +00001232 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -07001233
1234 msg := fmt.Sprintf(`\n******************************\n`+
1235 `The warnings encountered during nullability annotation validation did\n`+
1236 `not match the checked in file of expected warnings. The diffs are shown\n`+
1237 `above. You have two options:\n`+
1238 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1239 ` 2. Update the file of expected warnings by running:\n`+
1240 ` cp %s %s\n`+
1241 ` and submitting the updated file as part of your change.`,
Jihoon Kangee113282024-01-23 00:16:41 +00001242 d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross2207f872021-03-24 12:39:08 -07001243
1244 rule := android.NewRuleBuilder(pctx, ctx)
1245
1246 rule.Command().
1247 Text("(").
Jihoon Kangee113282024-01-23 00:16:41 +00001248 Text("diff").Input(checkNullabilityWarnings).Input(d.everythingArtifacts.nullabilityWarningsFile).
Colin Cross2207f872021-03-24 12:39:08 -07001249 Text("&&").
1250 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1251 Text(") || (").
1252 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1253 Text("; exit 38").
1254 Text(")")
1255
1256 rule.Build("nullabilityWarningsCheck", "nullability warnings check")
1257 }
LaMont Jonesafe7baf2024-01-09 22:47:39 +00001258 android.CollectDependencyAconfigFiles(ctx, &d.mergedAconfigFiles)
Colin Cross2207f872021-03-24 12:39:08 -07001259}
1260
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001261func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
1262 api_file := d.properties.Check_api.Current.Api_file
1263 api_surface := d.properties.Api_surface
1264
1265 props := struct {
1266 Name *string
1267 Api_surface *string
1268 Api_file *string
Jihoon Kang42b589c2023-02-03 22:56:13 +00001269 Visibility []string
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001270 }{}
1271
1272 props.Name = proptools.StringPtr(d.Name() + ".api.contribution")
1273 props.Api_surface = api_surface
1274 props.Api_file = api_file
Jihoon Kang42b589c2023-02-03 22:56:13 +00001275 props.Visibility = []string{"//visibility:override", "//visibility:public"}
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001276
1277 ctx.CreateModule(ApiContributionFactory, &props)
1278}
1279
Spandan Das0b555e32022-11-28 18:48:51 +00001280// TODO (b/262014796): Export the API contributions of CorePlatformApi
1281// A map to populate the api surface of a droidstub from a substring appearing in its name
1282// This map assumes that droidstubs (either checked-in or created by java_sdk_library)
1283// use a strict naming convention
1284var (
1285 droidstubsModuleNamingToSdkKind = map[string]android.SdkKind{
1286 //public is commented out since the core libraries use public in their java_sdk_library names
1287 "intracore": android.SdkIntraCore,
1288 "intra.core": android.SdkIntraCore,
1289 "system_server": android.SdkSystemServer,
1290 "system-server": android.SdkSystemServer,
1291 "system": android.SdkSystem,
1292 "module_lib": android.SdkModule,
1293 "module-lib": android.SdkModule,
Spandan Dasda977552023-01-26 20:45:16 +00001294 "platform.api": android.SdkCorePlatform,
Spandan Das0b555e32022-11-28 18:48:51 +00001295 "test": android.SdkTest,
Spandan Das4ac2aed2022-12-28 01:54:29 +00001296 "toolchain": android.SdkToolchain,
Spandan Das0b555e32022-11-28 18:48:51 +00001297 }
1298)
1299
Colin Cross2207f872021-03-24 12:39:08 -07001300func StubsDefaultsFactory() android.Module {
1301 module := &DocDefaults{}
1302
1303 module.AddProperties(
1304 &JavadocProperties{},
1305 &DroidstubsProperties{},
1306 )
1307
1308 android.InitDefaultsModule(module)
1309
1310 return module
1311}
1312
1313var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
1314
1315type PrebuiltStubsSourcesProperties struct {
1316 Srcs []string `android:"path"`
1317}
1318
1319type PrebuiltStubsSources struct {
1320 android.ModuleBase
1321 android.DefaultableModuleBase
Spandan Das2cc80ba2023-10-27 17:21:52 +00001322 embeddableInModuleAndImport
1323
Colin Cross2207f872021-03-24 12:39:08 -07001324 prebuilt android.Prebuilt
Colin Cross2207f872021-03-24 12:39:08 -07001325
1326 properties PrebuiltStubsSourcesProperties
1327
kgui67007242022-01-25 13:50:25 +08001328 stubsSrcJar android.Path
Colin Cross2207f872021-03-24 12:39:08 -07001329}
1330
1331func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
1332 switch tag {
Jihoon Kangfa4a90d2023-12-20 02:53:38 +00001333 // prebuilt droidstubs does not output "exportable" stubs.
1334 // Output the "everything" stubs srcjar file if the tag is ".exportable".
1335 case "", ".exportable":
Colin Cross2207f872021-03-24 12:39:08 -07001336 return android.Paths{p.stubsSrcJar}, nil
1337 default:
1338 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1339 }
1340}
1341
Jihoon Kangee113282024-01-23 00:16:41 +00001342func (d *PrebuiltStubsSources) StubsSrcJar(_ StubsType) (android.Path, error) {
1343 return d.stubsSrcJar, nil
Colin Cross2207f872021-03-24 12:39:08 -07001344}
1345
1346func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross2207f872021-03-24 12:39:08 -07001347 if len(p.properties.Srcs) != 1 {
Anton Hansson86758ac2021-11-03 14:44:12 +00001348 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 -07001349 return
1350 }
1351
Anton Hansson86758ac2021-11-03 14:44:12 +00001352 src := p.properties.Srcs[0]
1353 if filepath.Ext(src) == ".srcjar" {
1354 // This is a srcjar. We can use it directly.
1355 p.stubsSrcJar = android.PathForModuleSrc(ctx, src)
1356 } else {
1357 outPath := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Colin Cross2207f872021-03-24 12:39:08 -07001358
Anton Hansson86758ac2021-11-03 14:44:12 +00001359 // This is a directory. Glob the contents just in case the directory does not exist.
1360 srcGlob := src + "/**/*"
1361 srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})
Colin Cross2207f872021-03-24 12:39:08 -07001362
Anton Hansson86758ac2021-11-03 14:44:12 +00001363 // Although PathForModuleSrc can return nil if either the path doesn't exist or
1364 // the path components are invalid it won't in this case because no components
1365 // are specified and the module directory must exist in order to get this far.
1366 srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, src)
Colin Cross2207f872021-03-24 12:39:08 -07001367
Anton Hansson86758ac2021-11-03 14:44:12 +00001368 rule := android.NewRuleBuilder(pctx, ctx)
1369 rule.Command().
1370 BuiltTool("soong_zip").
1371 Flag("-write_if_changed").
1372 Flag("-jar").
1373 FlagWithOutput("-o ", outPath).
1374 FlagWithArg("-C ", srcDir.String()).
1375 FlagWithRspFileInputList("-r ", outPath.ReplaceExtension(ctx, "rsp"), srcPaths)
1376 rule.Restat()
1377 rule.Build("zip src", "Create srcjar from prebuilt source")
1378 p.stubsSrcJar = outPath
1379 }
Colin Cross2207f872021-03-24 12:39:08 -07001380}
1381
1382func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
1383 return &p.prebuilt
1384}
1385
1386func (p *PrebuiltStubsSources) Name() string {
1387 return p.prebuilt.Name(p.ModuleBase.Name())
1388}
1389
1390// prebuilt_stubs_sources imports a set of java source files as if they were
1391// generated by droidstubs.
1392//
1393// By default, a prebuilt_stubs_sources has a single variant that expects a
1394// set of `.java` files generated by droidstubs.
1395//
1396// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
1397// for host modules.
1398//
1399// Intended only for use by sdk snapshots.
1400func PrebuiltStubsSourcesFactory() android.Module {
1401 module := &PrebuiltStubsSources{}
1402
1403 module.AddProperties(&module.properties)
Spandan Das2cc80ba2023-10-27 17:21:52 +00001404 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -07001405
1406 android.InitPrebuiltModule(module, &module.properties.Srcs)
Colin Cross2207f872021-03-24 12:39:08 -07001407 InitDroiddocModule(module, android.HostAndDeviceSupported)
1408 return module
1409}