blob: dc3a0ec19986fc8a5185a62d79f055eb8629f881 [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 Kangee113282024-01-23 00:16:41 +0000336func (d *Droidstubs) AnnotationsZip(stubsType StubsType) (android.Path, error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000337 switch stubsType {
338 case Everything:
Jihoon Kangee113282024-01-23 00:16:41 +0000339 return d.everythingArtifacts.annotationsZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000340 case Exportable:
Jihoon Kangee113282024-01-23 00:16:41 +0000341 return d.exportableArtifacts.annotationsZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000342 default:
343 return nil, fmt.Errorf("annotations zip not supported for the stub type %s", stubsType.String())
344 }
345}
346
Jihoon Kangee113282024-01-23 00:16:41 +0000347func (d *Droidstubs) ApiFilePath(stubsType StubsType) (android.Path, error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000348 switch stubsType {
349 case Everything:
Jihoon Kangee113282024-01-23 00:16:41 +0000350 return d.apiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000351 case Exportable:
Jihoon Kangee113282024-01-23 00:16:41 +0000352 return d.exportableApiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000353 default:
354 return nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
355 }
356}
357
Jihoon Kangee113282024-01-23 00:16:41 +0000358func (d *Droidstubs) ApiVersionsXmlFilePath(stubsType StubsType) (android.Path, error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000359 switch stubsType {
360 case Everything:
Jihoon Kangee113282024-01-23 00:16:41 +0000361 return d.everythingArtifacts.apiVersionsXml, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000362 default:
363 return nil, fmt.Errorf("api versions xml file path not supported for the stub type %s", stubsType.String())
364 }
365}
366
Jihoon Kangee113282024-01-23 00:16:41 +0000367func (d *Droidstubs) DocZip(stubsType StubsType) (android.Path, error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000368 switch stubsType {
369 case Everything:
Jihoon Kangee113282024-01-23 00:16:41 +0000370 return d.docZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000371 default:
372 return nil, fmt.Errorf("docs zip not supported for the stub type %s", stubsType.String())
373 }
374}
375
Jihoon Kangee113282024-01-23 00:16:41 +0000376func (d *Droidstubs) RemovedApiFilePath(stubsType StubsType) (android.Path, error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000377 switch stubsType {
378 case Everything:
Jihoon Kangee113282024-01-23 00:16:41 +0000379 return d.removedApiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000380 case Exportable:
Jihoon Kangee113282024-01-23 00:16:41 +0000381 return d.exportableRemovedApiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000382 default:
383 return nil, fmt.Errorf("removed api file path not supported for the stub type %s", stubsType.String())
384 }
385}
386
Jihoon Kangee113282024-01-23 00:16:41 +0000387func (d *Droidstubs) StubsSrcJar(stubsType StubsType) (android.Path, error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000388 switch stubsType {
389 case Everything:
Jihoon Kangee113282024-01-23 00:16:41 +0000390 return d.stubsSrcJar, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000391 case Exportable:
Jihoon Kangee113282024-01-23 00:16:41 +0000392 return d.exportableStubsSrcJar, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000393 default:
394 return nil, fmt.Errorf("stubs srcjar not supported for the stub type %s", stubsType.String())
395 }
396}
397
Jihoon Kang063ec002023-06-28 01:16:23 +0000398func (d *Droidstubs) CurrentApiTimestamp() android.Path {
399 return d.checkCurrentApiTimestamp
400}
401
Colin Cross2207f872021-03-24 12:39:08 -0700402var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
403var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
404var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000405var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"}
Jihoon Kang063ec002023-06-28 01:16:23 +0000406var metalavaCurrentApiTimestampTag = dependencyTag{name: "metalava-current-api-timestamp-tag"}
Colin Cross2207f872021-03-24 12:39:08 -0700407
408func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
409 d.Javadoc.addDeps(ctx)
410
411 if len(d.properties.Merge_annotations_dirs) != 0 {
412 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
413 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
414 }
415 }
416
417 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
418 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
419 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
420 }
421 }
422
423 if len(d.properties.Api_levels_annotations_dirs) != 0 {
424 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
425 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
426 }
427 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000428
Jihoon Kang6592e872023-12-19 01:13:16 +0000429 if len(d.properties.Aconfig_declarations) != 0 {
430 for _, aconfigDeclarationModuleName := range d.properties.Aconfig_declarations {
431 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationModuleName)
432 }
433 }
434
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000435 if d.properties.Api_levels_module != nil {
436 ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
437 }
Colin Cross2207f872021-03-24 12:39:08 -0700438}
439
Jihoon Kang3c89f042023-12-19 02:40:22 +0000440func (d *Droidstubs) sdkValuesFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, metadataDir android.WritablePath) {
441 cmd.FlagWithArg("--sdk-values ", metadataDir.String())
442}
443
444func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath, stubsType StubsType, checkApi bool) {
445 if checkApi || String(d.properties.Api_filename) != "" {
Colin Cross2207f872021-03-24 12:39:08 -0700446 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000447 uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
Paul Duffinc71d2b72022-08-16 15:24:01 +0000448 cmd.FlagWithOutput("--api ", uncheckedApiFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000449
450 if stubsType == Everything {
451 d.apiFile = uncheckedApiFile
452 } else if stubsType == Exportable {
453 d.exportableApiFile = uncheckedApiFile
454 }
Colin Cross2207f872021-03-24 12:39:08 -0700455 } else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
456 // If check api is disabled then make the source file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000457 d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700458 }
459
Jihoon Kang3c89f042023-12-19 02:40:22 +0000460 if checkApi || String(d.properties.Removed_api_filename) != "" {
Colin Cross2207f872021-03-24 12:39:08 -0700461 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000462 uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
Paul Duffinc71d2b72022-08-16 15:24:01 +0000463 cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000464
465 if stubsType == Everything {
466 d.removedApiFile = uncheckedRemovedFile
467 } else if stubsType == Exportable {
468 d.exportableRemovedApiFile = uncheckedRemovedFile
469 }
Colin Cross2207f872021-03-24 12:39:08 -0700470 } else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
471 // If check api is disabled then make the source removed api file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000472 d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700473 }
474
Colin Cross2207f872021-03-24 12:39:08 -0700475 if stubsDir.Valid() {
476 if Bool(d.properties.Create_doc_stubs) {
477 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
478 } else {
479 cmd.FlagWithArg("--stubs ", stubsDir.String())
480 if !Bool(d.properties.Output_javadoc_comments) {
481 cmd.Flag("--exclude-documentation-from-stubs")
482 }
483 }
484 }
485}
486
Jihoon Kang3c89f042023-12-19 02:40:22 +0000487func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, params annotationFlagsParams) {
Colin Cross2207f872021-03-24 12:39:08 -0700488 if Bool(d.properties.Annotations_enabled) {
Liz Kammere09e20e2023-10-16 15:07:54 -0400489 cmd.Flag(config.MetalavaAnnotationsFlags)
Andrei Onea4985e512021-04-29 16:29:34 +0100490
Jihoon Kang3c89f042023-12-19 02:40:22 +0000491 if params.migratingNullability {
Colin Cross2207f872021-03-24 12:39:08 -0700492 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
493 cmd.FlagWithInput("--migrate-nullness ", previousApi)
494 }
495
496 if s := String(d.properties.Validate_nullability_from_list); s != "" {
497 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
498 }
499
Jihoon Kang3c89f042023-12-19 02:40:22 +0000500 if params.validatingNullability {
501 cmd.FlagWithOutput("--nullability-warnings-txt ", params.nullabilityWarningsFile)
Colin Cross2207f872021-03-24 12:39:08 -0700502 }
503
Jihoon Kang3c89f042023-12-19 02:40:22 +0000504 cmd.FlagWithOutput("--extract-annotations ", params.annotationsZip)
Colin Cross2207f872021-03-24 12:39:08 -0700505
506 if len(d.properties.Merge_annotations_dirs) != 0 {
507 d.mergeAnnoDirFlags(ctx, cmd)
508 }
509
Liz Kammere09e20e2023-10-16 15:07:54 -0400510 cmd.Flag(config.MetalavaAnnotationsWarningsFlags)
Colin Cross2207f872021-03-24 12:39:08 -0700511 }
512}
513
514func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
515 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
516 if t, ok := m.(*ExportedDroiddocDir); ok {
517 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
518 } else {
519 ctx.PropertyErrorf("merge_annotations_dirs",
520 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
521 }
522 })
523}
524
525func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
526 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
527 if t, ok := m.(*ExportedDroiddocDir); ok {
528 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
529 } else {
530 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
531 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
532 }
533 })
534}
535
Jihoon Kang3c89f042023-12-19 02:40:22 +0000536func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000537 var apiVersions android.Path
538 if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000539 d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
Jihoon Kangd9a06942024-01-26 01:49:20 +0000540 apiVersions = apiVersionsXml
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000541 } else {
542 ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
543 if s, ok := m.(*Droidstubs); ok {
Jihoon Kangd9a06942024-01-26 01:49:20 +0000544 if stubsType == Everything {
545 apiVersions = s.everythingArtifacts.apiVersionsXml
546 } else if stubsType == Exportable {
547 apiVersions = s.exportableArtifacts.apiVersionsXml
548 } else {
549 ctx.ModuleErrorf("%s stubs type does not generate api-versions.xml file", stubsType.String())
550 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000551 } else {
552 ctx.PropertyErrorf("api_levels_module",
553 "module %q is not a droidstubs module", ctx.OtherModuleName(m))
554 }
555 })
Colin Cross2207f872021-03-24 12:39:08 -0700556 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000557 if apiVersions != nil {
558 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
559 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
560 cmd.FlagWithInput("--apply-api-levels ", apiVersions)
561 }
562}
Colin Cross2207f872021-03-24 12:39:08 -0700563
Jihoon Kang3c89f042023-12-19 02:40:22 +0000564func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Colin Cross2207f872021-03-24 12:39:08 -0700565 if len(d.properties.Api_levels_annotations_dirs) == 0 {
566 ctx.PropertyErrorf("api_levels_annotations_dirs",
567 "has to be non-empty if api levels annotations was enabled!")
568 }
569
Jihoon Kang3c89f042023-12-19 02:40:22 +0000570 cmd.FlagWithOutput("--generate-api-levels ", apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700571
572 filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
573
satayev783195c2021-06-23 21:49:57 +0100574 var dirs []string
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200575 var extensions_dir string
Colin Cross2207f872021-03-24 12:39:08 -0700576 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
577 if t, ok := m.(*ExportedDroiddocDir); ok {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200578 extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
579
580 // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
581 // ideally this should be read from prebuiltApis.properties.Extensions_*
Colin Cross2207f872021-03-24 12:39:08 -0700582 for _, dep := range t.deps {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200583 if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
584 if extensions_dir == "" {
585 extensions_dir = t.dir.String() + "/extensions"
586 }
587 cmd.Implicit(dep)
588 }
Colin Cross5f6ffc72021-03-29 21:54:45 -0700589 if dep.Base() == filename {
590 cmd.Implicit(dep)
591 }
592 if filename != "android.jar" && dep.Base() == "android.jar" {
593 // Metalava implicitly searches these patterns:
594 // prebuilts/tools/common/api-versions/android-%/android.jar
595 // prebuilts/sdk/%/public/android.jar
596 // Add android.jar files from the api_levels_annotations_dirs directories to try
597 // to satisfy these patterns. If Metalava can't find a match for an API level
598 // between 1 and 28 in at least one pattern it will fail.
Colin Cross2207f872021-03-24 12:39:08 -0700599 cmd.Implicit(dep)
600 }
601 }
satayev783195c2021-06-23 21:49:57 +0100602
603 dirs = append(dirs, t.dir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700604 } else {
605 ctx.PropertyErrorf("api_levels_annotations_dirs",
606 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
607 }
608 })
satayev783195c2021-06-23 21:49:57 +0100609
610 // Add all relevant --android-jar-pattern patterns for Metalava.
611 // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
612 // an actual file present on disk (in the order the patterns were passed). For system APIs for
613 // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
Pedro Loureirocc203502021-10-04 17:24:00 +0000614 // for older releases. Similarly, module-lib falls back to system API.
615 var sdkDirs []string
616 switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
Cole Faust051fa912022-10-05 12:45:42 -0700617 case "system-server":
618 sdkDirs = []string{"system-server", "module-lib", "system", "public"}
Pedro Loureirocc203502021-10-04 17:24:00 +0000619 case "module-lib":
620 sdkDirs = []string{"module-lib", "system", "public"}
621 case "system":
622 sdkDirs = []string{"system", "public"}
623 case "public":
624 sdkDirs = []string{"public"}
625 default:
626 ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
627 return
satayev783195c2021-06-23 21:49:57 +0100628 }
Pedro Loureirocc203502021-10-04 17:24:00 +0000629
630 for _, sdkDir := range sdkDirs {
631 for _, dir := range dirs {
632 cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
633 }
satayev783195c2021-06-23 21:49:57 +0100634 }
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200635
636 if d.properties.Extensions_info_file != nil {
637 if extensions_dir == "" {
638 ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
639 }
640 info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
641 cmd.Implicit(info_file)
642 cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
643 cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
644 }
Colin Cross2207f872021-03-24 12:39:08 -0700645}
646
Colin Crosse52c2ac2022-03-28 17:03:35 -0700647func metalavaUseRbe(ctx android.ModuleContext) bool {
648 return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
649}
650
Colin Cross2207f872021-03-24 12:39:08 -0700651func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Anton Hansson556e8142021-06-04 16:20:25 +0100652 srcJarList android.Path, bootclasspath, classpath classpath, homeDir android.WritablePath) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700653 rule.Command().Text("rm -rf").Flag(homeDir.String())
654 rule.Command().Text("mkdir -p").Flag(homeDir.String())
655
Anton Hansson556e8142021-06-04 16:20:25 +0100656 cmd := rule.Command()
Colin Cross2207f872021-03-24 12:39:08 -0700657 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())
658
Colin Crosse52c2ac2022-03-28 17:03:35 -0700659 if metalavaUseRbe(ctx) {
Colin Cross2207f872021-03-24 12:39:08 -0700660 rule.Remoteable(android.RemoteRuleSupports{RBE: true})
Colin Cross8095c292021-03-30 16:40:48 -0700661 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000662 compare := ctx.Config().IsEnvTrue("RBE_METALAVA_COMPARE")
663 remoteUpdateCache := !ctx.Config().IsEnvFalse("RBE_METALAVA_REMOTE_UPDATE_CACHE")
Colin Cross8095c292021-03-30 16:40:48 -0700664 labels := map[string]string{"type": "tool", "name": "metalava"}
665 // TODO: metalava pool rejects these jobs
666 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
667 rule.Rewrapper(&remoteexec.REParams{
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000668 Labels: labels,
669 ExecStrategy: execStrategy,
670 ToolchainInputs: []string{config.JavaCmd(ctx).String()},
671 Platform: map[string]string{remoteexec.PoolKey: pool},
672 Compare: compare,
673 NumLocalRuns: 1,
674 NumRemoteRuns: 1,
675 NoRemoteUpdateCache: !remoteUpdateCache,
Colin Cross8095c292021-03-30 16:40:48 -0700676 })
Colin Cross2207f872021-03-24 12:39:08 -0700677 }
678
Colin Cross6aa5c402021-03-24 12:28:50 -0700679 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
Colin Cross2207f872021-03-24 12:39:08 -0700680 Flag(config.JavacVmFlags).
Liz Kammere09e20e2023-10-16 15:07:54 -0400681 Flag(config.MetalavaAddOpens).
Paul Duffin808211e2023-08-09 12:36:08 +0100682 FlagWithArg("--java-source ", javaVersion.String()).
Colin Cross2207f872021-03-24 12:39:08 -0700683 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
684 FlagWithInput("@", srcJarList)
685
Paul Duffinf8aaaa12023-08-10 15:16:35 +0100686 // Metalava does not differentiate between bootclasspath and classpath and has not done so for
687 // years, so it is unlikely to change any time soon.
688 combinedPaths := append(([]android.Path)(nil), bootclasspath.Paths()...)
689 combinedPaths = append(combinedPaths, classpath.Paths()...)
690 if len(combinedPaths) > 0 {
691 cmd.FlagWithInputList("--classpath ", combinedPaths, ":")
Colin Cross2207f872021-03-24 12:39:08 -0700692 }
693
Liz Kammere09e20e2023-10-16 15:07:54 -0400694 cmd.Flag(config.MetalavaFlags)
Jihoon Kangc8313892023-09-20 00:54:47 +0000695
Colin Cross2207f872021-03-24 12:39:08 -0700696 return cmd
697}
698
Jihoon Kang3c89f042023-12-19 02:40:22 +0000699// Pass flagged apis related flags to metalava. When aconfig_declarations property is not
700// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
701// property is defined, apply transformations and only revert the flagged apis that are not
702// enabled via release configurations and are not specified in aconfig_declarations
703func (d *Droidstubs) generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
704
705 if len(aconfigFlagsPaths) == 0 {
706 cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
707 return
708 }
Jihoon Kang6592e872023-12-19 01:13:16 +0000709
710 releasedFlaggedApisFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flagged-apis-%s.txt", stubsType.String()))
711 revertAnnotationsFile := android.PathForModuleOut(ctx, fmt.Sprintf("revert-annotations-%s.txt", stubsType.String()))
712
713 var filterArgs string
714 switch stubsType {
715 // No flagged apis specific flags need to be passed to metalava when generating
716 // everything stubs
717 case Everything:
718 return
719
720 case Runtime:
721 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
722
723 case Exportable:
724 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY'"
725
726 }
727
728 ctx.Build(pctx, android.BuildParams{
729 Rule: gatherReleasedFlaggedApisRule,
730 Inputs: aconfigFlagsPaths,
731 Output: releasedFlaggedApisFile,
732 Description: fmt.Sprintf("%s gather aconfig flags", stubsType),
733 Args: map[string]string{
734 "flags_path": android.JoinPathsWithPrefix(aconfigFlagsPaths, "--cache "),
735 "filter_args": filterArgs,
736 },
737 })
738
739 ctx.Build(pctx, android.BuildParams{
740 Rule: generateMetalavaRevertAnnotationsRule,
741 Input: releasedFlaggedApisFile,
742 Output: revertAnnotationsFile,
743 Description: fmt.Sprintf("%s revert annotations", stubsType),
744 })
Jihoon Kang3c89f042023-12-19 02:40:22 +0000745
746 cmd.FlagWithInput("@", revertAnnotationsFile)
Jihoon Kang6592e872023-12-19 01:13:16 +0000747}
748
Jihoon Kang3c89f042023-12-19 02:40:22 +0000749func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
750 params stubsCommandParams) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700751 if BoolDefault(d.properties.High_mem, false) {
752 // This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
753 rule.HighMem()
754 }
755
Jihoon Kang3c89f042023-12-19 02:40:22 +0000756 if params.stubConfig.generateStubs {
757 rule.Command().Text("rm -rf").Text(params.stubsDir.String())
758 rule.Command().Text("mkdir -p").Text(params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700759 }
760
Jihoon Kang3c89f042023-12-19 02:40:22 +0000761 srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars)
Colin Cross2207f872021-03-24 12:39:08 -0700762
Jihoon Kang3c89f042023-12-19 02:40:22 +0000763 homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home")
764 cmd := metalavaCmd(ctx, rule, params.stubConfig.javaVersion, d.Javadoc.srcFiles, srcJarList,
765 params.stubConfig.deps.bootClasspath, params.stubConfig.deps.classpath, homeDir)
Colin Cross2207f872021-03-24 12:39:08 -0700766 cmd.Implicits(d.Javadoc.implicits)
767
Jihoon Kang3c89f042023-12-19 02:40:22 +0000768 d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
Colin Cross2207f872021-03-24 12:39:08 -0700769
Jihoon Kang3c89f042023-12-19 02:40:22 +0000770 if params.stubConfig.writeSdkValues {
771 d.sdkValuesFlags(ctx, cmd, params.metadataDir)
772 }
773
774 annotationParams := annotationFlagsParams{
775 migratingNullability: params.stubConfig.migratingNullability,
776 validatingNullability: params.stubConfig.validatingNullability,
777 nullabilityWarningsFile: params.nullabilityWarningsFile,
778 annotationsZip: params.annotationsZip,
779 }
780
781 d.annotationsFlags(ctx, cmd, annotationParams)
Colin Cross2207f872021-03-24 12:39:08 -0700782 d.inclusionAnnotationsFlags(ctx, cmd)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000783 d.apiLevelsAnnotationsFlags(ctx, cmd, params.stubConfig.stubsType, params.apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700784
Colin Crossbc139922021-03-25 18:33:16 -0700785 d.expandArgs(ctx, cmd)
Colin Cross2207f872021-03-24 12:39:08 -0700786
Colin Cross2207f872021-03-24 12:39:08 -0700787 for _, o := range d.Javadoc.properties.Out {
788 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
789 }
790
Jihoon Kang3c89f042023-12-19 02:40:22 +0000791 return cmd
792}
Colin Cross2207f872021-03-24 12:39:08 -0700793
Jihoon Kang3c89f042023-12-19 02:40:22 +0000794// Sandbox rule for generating the everything stubs and other artifacts
795func (d *Droidstubs) everythingStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
796 srcJarDir := android.PathForModuleOut(ctx, Everything.String(), "srcjars")
797 rule := android.NewRuleBuilder(pctx, ctx)
798 rule.Sbox(android.PathForModuleOut(ctx, Everything.String()),
799 android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
800 SandboxInputs()
801
802 var stubsDir android.OptionalPath
803 if params.generateStubs {
804 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, Everything.String(), "stubsDir"))
805 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
806 }
807
808 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +0000809 d.everythingArtifacts.metadataDir = android.PathForModuleOut(ctx, Everything.String(), "metadata")
810 d.everythingArtifacts.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000811 }
812
813 if Bool(d.properties.Annotations_enabled) {
814 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +0000815 d.everythingArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000816 }
Jihoon Kangee113282024-01-23 00:16:41 +0000817 d.everythingArtifacts.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000818 }
819 if Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kangee113282024-01-23 00:16:41 +0000820 d.everythingArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000821 }
822
823 commonCmdParams := stubsCommandParams{
824 srcJarDir: srcJarDir,
825 stubsDir: stubsDir,
826 stubsSrcJar: d.Javadoc.stubsSrcJar,
Jihoon Kangee113282024-01-23 00:16:41 +0000827 metadataDir: d.everythingArtifacts.metadataDir,
828 apiVersionsXml: d.everythingArtifacts.apiVersionsXml,
829 nullabilityWarningsFile: d.everythingArtifacts.nullabilityWarningsFile,
830 annotationsZip: d.everythingArtifacts.annotationsZip,
Jihoon Kang3c89f042023-12-19 02:40:22 +0000831 stubConfig: params,
832 }
833
834 cmd := d.commonMetalavaStubCmd(ctx, rule, commonCmdParams)
835
836 d.everythingOptionalCmd(ctx, cmd, params.doApiLint, params.doCheckReleased)
837
838 if params.generateStubs {
839 rule.Command().
840 BuiltTool("soong_zip").
841 Flag("-write_if_changed").
842 Flag("-jar").
843 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
844 FlagWithArg("-C ", stubsDir.String()).
845 FlagWithArg("-D ", stubsDir.String())
846 }
847
848 if params.writeSdkValues {
849 rule.Command().
850 BuiltTool("soong_zip").
851 Flag("-write_if_changed").
852 Flag("-d").
Jihoon Kangee113282024-01-23 00:16:41 +0000853 FlagWithOutput("-o ", d.everythingArtifacts.metadataZip).
854 FlagWithArg("-C ", d.everythingArtifacts.metadataDir.String()).
855 FlagWithArg("-D ", d.everythingArtifacts.metadataDir.String())
Jihoon Kang3c89f042023-12-19 02:40:22 +0000856 }
857
858 // TODO: We don't really need two separate API files, but this is a reminiscence of how
859 // we used to run metalava separately for API lint and the "last_released" check. Unify them.
860 if params.doApiLint {
861 rule.Command().Text("touch").Output(d.apiLintTimestamp)
862 }
863 if params.doCheckReleased {
864 rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
865 }
866
867 // TODO(b/183630617): rewrapper doesn't support restat rules
868 if !metalavaUseRbe(ctx) {
869 rule.Restat()
870 }
871
872 zipSyncCleanupCmd(rule, srcJarDir)
873
874 rule.Build("metalava", "metalava merged")
875}
876
877// Sandbox rule for generating the everything artifacts that are not run by
878// default but only run based on the module configurations
879func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, doApiLint bool, doCheckReleased bool) {
Colin Cross2207f872021-03-24 12:39:08 -0700880
881 // Add API lint options.
Jihoon Kang3c89f042023-12-19 02:40:22 +0000882 if doApiLint {
Colin Cross2207f872021-03-24 12:39:08 -0700883 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
884 if newSince.Valid() {
885 cmd.FlagWithInput("--api-lint ", newSince.Path())
886 } else {
887 cmd.Flag("--api-lint")
888 }
Jihoon Kang3c89f042023-12-19 02:40:22 +0000889 d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700890 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
891
Colin Cross0d532412021-03-25 09:38:45 -0700892 // TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
Colin Cross2207f872021-03-24 12:39:08 -0700893 if d.Name() != "android.car-system-stubs-docs" &&
894 d.Name() != "android.car-stubs-docs" {
895 cmd.Flag("--lints-as-errors")
896 cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
897 }
898
899 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000900 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "api_lint_baseline.txt")
901 d.apiLintTimestamp = android.PathForModuleOut(ctx, Everything.String(), "api_lint.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700902
903 // Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
Colin Cross2207f872021-03-24 12:39:08 -0700904 //
905 // TODO: metalava also has a slightly different message hardcoded. Should we unify this
906 // message and metalava's one?
907 msg := `$'` + // Enclose with $' ... '
908 `************************************************************\n` +
909 `Your API changes are triggering API Lint warnings or errors.\n` +
910 `To make these errors go away, fix the code according to the\n` +
911 `error and/or warning messages above.\n` +
912 `\n` +
913 `If it is not possible to do so, there are workarounds:\n` +
914 `\n` +
Aurimas Liutikasb23b7452021-05-24 18:00:37 +0000915 `1. You can suppress the errors with @SuppressLint("<id>")\n` +
916 ` where the <id> is given in brackets in the error message above.\n`
Colin Cross2207f872021-03-24 12:39:08 -0700917
918 if baselineFile.Valid() {
919 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
920 cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)
921
922 msg += fmt.Sprintf(``+
923 `2. You can update the baseline by executing the following\n`+
924 ` command:\n`+
Colin Cross63eeda02021-04-15 19:01:57 -0700925 ` (cd $ANDROID_BUILD_TOP && cp \\\n`+
926 ` "%s" \\\n`+
927 ` "%s")\n`+
Colin Cross2207f872021-03-24 12:39:08 -0700928 ` To submit the revised baseline.txt to the main Android\n`+
929 ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
930 } else {
931 msg += fmt.Sprintf(``+
932 `2. You can add a baseline file of existing lint failures\n`+
933 ` to the build rule of %s.\n`, d.Name())
934 }
935 // Note the message ends with a ' (single quote), to close the $' ... ' .
936 msg += `************************************************************\n'`
937
938 cmd.FlagWithArg("--error-message:api-lint ", msg)
939 }
940
941 // Add "check released" options. (Detect incompatible API changes from the last public release)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000942 if doCheckReleased {
Colin Cross2207f872021-03-24 12:39:08 -0700943 if len(d.Javadoc.properties.Out) > 0 {
944 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
945 }
946
947 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
948 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
949 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000950 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700951
Jihoon Kang3c89f042023-12-19 02:40:22 +0000952 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700953
954 cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
955 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
956
957 if baselineFile.Valid() {
958 cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
959 cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
960 }
961
962 // Note this string includes quote ($' ... '), which decodes the "\n"s.
963 msg := `$'\n******************************\n` +
964 `You have tried to change the API from what has been previously released in\n` +
965 `an SDK. Please fix the errors listed above.\n` +
966 `******************************\n'`
967
968 cmd.FlagWithArg("--error-message:compatibility:released ", msg)
969 }
970
Paul Duffin10a23c22023-08-11 22:47:31 +0100971 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
972 // Pass the current API file into metalava so it can use it as the basis for determining how to
973 // generate the output signature files (both api and removed).
974 currentApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
975 cmd.FlagWithInput("--use-same-format-as ", currentApiFile)
976 }
Jihoon Kang3c89f042023-12-19 02:40:22 +0000977}
Paul Duffin10a23c22023-08-11 22:47:31 +0100978
Jihoon Kang3c89f042023-12-19 02:40:22 +0000979// Sandbox rule for generating exportable stubs and other artifacts
980func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
981 optionalCmdParams := stubsCommandParams{
982 stubConfig: params,
983 }
984
985 d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
986 optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
987 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +0000988 d.exportableArtifacts.metadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
989 d.exportableArtifacts.metadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
990 optionalCmdParams.metadataZip = d.exportableArtifacts.metadataZip
991 optionalCmdParams.metadataDir = d.exportableArtifacts.metadataDir
Jihoon Kang3c89f042023-12-19 02:40:22 +0000992 }
993
994 if Bool(d.properties.Annotations_enabled) {
995 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +0000996 d.exportableArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
997 optionalCmdParams.nullabilityWarningsFile = d.exportableArtifacts.nullabilityWarningsFile
Jihoon Kang3c89f042023-12-19 02:40:22 +0000998 }
Jihoon Kangee113282024-01-23 00:16:41 +0000999 d.exportableArtifacts.annotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
1000 optionalCmdParams.annotationsZip = d.exportableArtifacts.annotationsZip
Jihoon Kang3c89f042023-12-19 02:40:22 +00001001 }
1002 if Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kangee113282024-01-23 00:16:41 +00001003 d.exportableArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
1004 optionalCmdParams.apiVersionsXml = d.exportableArtifacts.apiVersionsXml
Jihoon Kang3c89f042023-12-19 02:40:22 +00001005 }
1006
1007 if params.checkApi || String(d.properties.Api_filename) != "" {
1008 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
1009 d.exportableApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1010 }
1011
1012 if params.checkApi || String(d.properties.Removed_api_filename) != "" {
1013 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_api.txt")
1014 d.exportableRemovedApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1015 }
1016
1017 d.optionalStubCmd(ctx, optionalCmdParams)
1018}
1019
1020func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsCommandParams) {
1021
1022 params.srcJarDir = android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "srcjars")
1023 rule := android.NewRuleBuilder(pctx, ctx)
1024 rule.Sbox(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String()),
1025 android.PathForModuleOut(ctx, fmt.Sprintf("metalava_%s.sbox.textproto", params.stubConfig.stubsType.String()))).
1026 SandboxInputs()
1027
1028 if params.stubConfig.generateStubs {
1029 params.stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "stubsDir"))
1030 }
1031
1032 cmd := d.commonMetalavaStubCmd(ctx, rule, params)
1033
1034 d.generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
1035
1036 if params.stubConfig.doApiLint {
1037 // Pass the lint baseline file as an input to resolve the lint errors.
1038 // The exportable stubs generation does not update the lint baseline file.
1039 // Lint baseline file update is handled by the everything stubs
1040 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1041 if baselineFile.Valid() {
1042 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
1043 }
1044 }
1045
1046 if params.stubConfig.generateStubs {
Colin Cross2207f872021-03-24 12:39:08 -07001047 rule.Command().
1048 BuiltTool("soong_zip").
1049 Flag("-write_if_changed").
1050 Flag("-jar").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001051 FlagWithOutput("-o ", params.stubsSrcJar).
1052 FlagWithArg("-C ", params.stubsDir.String()).
1053 FlagWithArg("-D ", params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001054 }
1055
Jihoon Kang3c89f042023-12-19 02:40:22 +00001056 if params.stubConfig.writeSdkValues {
Colin Cross2207f872021-03-24 12:39:08 -07001057 rule.Command().
1058 BuiltTool("soong_zip").
1059 Flag("-write_if_changed").
1060 Flag("-d").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001061 FlagWithOutput("-o ", params.metadataZip).
1062 FlagWithArg("-C ", params.metadataDir.String()).
1063 FlagWithArg("-D ", params.metadataDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001064 }
1065
Colin Cross6aa5c402021-03-24 12:28:50 -07001066 // TODO(b/183630617): rewrapper doesn't support restat rules
Colin Crosse52c2ac2022-03-28 17:03:35 -07001067 if !metalavaUseRbe(ctx) {
1068 rule.Restat()
1069 }
Colin Cross2207f872021-03-24 12:39:08 -07001070
Jihoon Kang3c89f042023-12-19 02:40:22 +00001071 zipSyncCleanupCmd(rule, params.srcJarDir)
Colin Cross2207f872021-03-24 12:39:08 -07001072
Jihoon Kang3c89f042023-12-19 02:40:22 +00001073 rule.Build(fmt.Sprintf("metalava_%s", params.stubConfig.stubsType.String()), "metalava merged")
1074}
1075
1076func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1077 deps := d.Javadoc.collectDeps(ctx)
1078
1079 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
1080 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
1081
1082 // Add options for the other optional tasks: API-lint and check-released.
1083 // We generate separate timestamp files for them.
1084 doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
1085 doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1086
1087 writeSdkValues := Bool(d.properties.Write_sdk_values)
1088
1089 annotationsEnabled := Bool(d.properties.Annotations_enabled)
1090
1091 migratingNullability := annotationsEnabled && String(d.properties.Previous_api) != ""
1092 validatingNullability := annotationsEnabled && (strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
1093 String(d.properties.Validate_nullability_from_list) != "")
1094
1095 checkApi := apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1096 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1097
1098 stubCmdParams := stubsCommandConfigParams{
1099 javaVersion: javaVersion,
1100 deps: deps,
1101 checkApi: checkApi,
1102 generateStubs: generateStubs,
1103 doApiLint: doApiLint,
1104 doCheckReleased: doCheckReleased,
1105 writeSdkValues: writeSdkValues,
1106 migratingNullability: migratingNullability,
1107 validatingNullability: validatingNullability,
1108 }
1109 stubCmdParams.stubsType = Everything
1110 // Create default (i.e. "everything" stubs) rule for metalava
1111 d.everythingStubCmd(ctx, stubCmdParams)
1112
1113 // The module generates "exportable" (and "runtime" eventually) stubs regardless of whether
1114 // aconfig_declarations property is defined or not. If the property is not defined, the module simply
1115 // strips all flagged apis to generate the "exportable" stubs
1116 stubCmdParams.stubsType = Exportable
1117 d.exportableStubCmd(ctx, stubCmdParams)
Paul Duffinc166b682022-05-27 12:23:08 +00001118
Paul Duffine7a86642022-08-16 15:43:20 +00001119 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1120
1121 if len(d.Javadoc.properties.Out) > 0 {
1122 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1123 }
1124
1125 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1126 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
1127 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1128
1129 if baselineFile.Valid() {
1130 ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
1131 }
1132
Jihoon Kang3c89f042023-12-19 02:40:22 +00001133 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001134
1135 rule := android.NewRuleBuilder(pctx, ctx)
1136
1137 // Diff command line.
1138 // -F matches the closest "opening" line, such as "package android {"
1139 // and " public class Intent {".
1140 diff := `diff -u -F '{ *$'`
1141
1142 rule.Command().Text("( true")
1143 rule.Command().
1144 Text(diff).
1145 Input(apiFile).Input(d.apiFile)
1146
1147 rule.Command().
1148 Text(diff).
1149 Input(removedApiFile).Input(d.removedApiFile)
1150
1151 msg := fmt.Sprintf(`\n******************************\n`+
1152 `You have tried to change the API from what has been previously approved.\n\n`+
1153 `To make these errors go away, you have two choices:\n`+
1154 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
1155 ` to the new methods, etc. shown in the above diff.\n\n`+
1156 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
1157 ` m %s-update-current-api\n\n`+
1158 ` To submit the revised current.txt to the main Android repository,\n`+
1159 ` you will need approval.\n`+
Jihoon Kang3ea64672023-11-03 00:40:26 +00001160 `If your build failed due to stub validation, you can resolve the errors with\n`+
1161 `either of the two choices above and try re-building the target.\n`+
1162 `If the mismatch between the stubs and the current.txt is intended,\n`+
1163 `you can try re-building the target by executing the following command:\n`+
Jihoon Kang91bf3dd2024-01-24 00:40:23 +00001164 `m DISABLE_STUB_VALIDATION=true <your build target>.\n`+
1165 `Note that DISABLE_STUB_VALIDATION=true does not bypass checkapi.\n`+
Paul Duffine7a86642022-08-16 15:43:20 +00001166 `******************************\n`, ctx.ModuleName())
1167
1168 rule.Command().
1169 Text("touch").Output(d.checkCurrentApiTimestamp).
1170 Text(") || (").
1171 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1172 Text("; exit 38").
1173 Text(")")
1174
1175 rule.Build("metalavaCurrentApiCheck", "check current API")
1176
Jihoon Kang3c89f042023-12-19 02:40:22 +00001177 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001178
1179 // update API rule
1180 rule = android.NewRuleBuilder(pctx, ctx)
1181
1182 rule.Command().Text("( true")
1183
1184 rule.Command().
1185 Text("cp").Flag("-f").
1186 Input(d.apiFile).Flag(apiFile.String())
1187
1188 rule.Command().
1189 Text("cp").Flag("-f").
1190 Input(d.removedApiFile).Flag(removedApiFile.String())
1191
1192 msg = "failed to update public API"
1193
1194 rule.Command().
1195 Text("touch").Output(d.updateCurrentApiTimestamp).
1196 Text(") || (").
1197 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1198 Text("; exit 38").
1199 Text(")")
1200
1201 rule.Build("metalavaCurrentApiUpdate", "update current API")
1202 }
1203
Colin Cross2207f872021-03-24 12:39:08 -07001204 if String(d.properties.Check_nullability_warnings) != "" {
Jihoon Kangee113282024-01-23 00:16:41 +00001205 if d.everythingArtifacts.nullabilityWarningsFile == nil {
Colin Cross2207f872021-03-24 12:39:08 -07001206 ctx.PropertyErrorf("check_nullability_warnings",
1207 "Cannot specify check_nullability_warnings unless validating nullability")
1208 }
1209
1210 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1211
Jihoon Kang3c89f042023-12-19 02:40:22 +00001212 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -07001213
1214 msg := fmt.Sprintf(`\n******************************\n`+
1215 `The warnings encountered during nullability annotation validation did\n`+
1216 `not match the checked in file of expected warnings. The diffs are shown\n`+
1217 `above. You have two options:\n`+
1218 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1219 ` 2. Update the file of expected warnings by running:\n`+
1220 ` cp %s %s\n`+
1221 ` and submitting the updated file as part of your change.`,
Jihoon Kangee113282024-01-23 00:16:41 +00001222 d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross2207f872021-03-24 12:39:08 -07001223
1224 rule := android.NewRuleBuilder(pctx, ctx)
1225
1226 rule.Command().
1227 Text("(").
Jihoon Kangee113282024-01-23 00:16:41 +00001228 Text("diff").Input(checkNullabilityWarnings).Input(d.everythingArtifacts.nullabilityWarningsFile).
Colin Cross2207f872021-03-24 12:39:08 -07001229 Text("&&").
1230 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1231 Text(") || (").
1232 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1233 Text("; exit 38").
1234 Text(")")
1235
1236 rule.Build("nullabilityWarningsCheck", "nullability warnings check")
1237 }
LaMont Jonesafe7baf2024-01-09 22:47:39 +00001238 android.CollectDependencyAconfigFiles(ctx, &d.mergedAconfigFiles)
Colin Cross2207f872021-03-24 12:39:08 -07001239}
1240
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001241func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
1242 api_file := d.properties.Check_api.Current.Api_file
1243 api_surface := d.properties.Api_surface
1244
1245 props := struct {
1246 Name *string
1247 Api_surface *string
1248 Api_file *string
Jihoon Kang42b589c2023-02-03 22:56:13 +00001249 Visibility []string
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001250 }{}
1251
1252 props.Name = proptools.StringPtr(d.Name() + ".api.contribution")
1253 props.Api_surface = api_surface
1254 props.Api_file = api_file
Jihoon Kang42b589c2023-02-03 22:56:13 +00001255 props.Visibility = []string{"//visibility:override", "//visibility:public"}
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001256
1257 ctx.CreateModule(ApiContributionFactory, &props)
1258}
1259
Spandan Das0b555e32022-11-28 18:48:51 +00001260// TODO (b/262014796): Export the API contributions of CorePlatformApi
1261// A map to populate the api surface of a droidstub from a substring appearing in its name
1262// This map assumes that droidstubs (either checked-in or created by java_sdk_library)
1263// use a strict naming convention
1264var (
1265 droidstubsModuleNamingToSdkKind = map[string]android.SdkKind{
1266 //public is commented out since the core libraries use public in their java_sdk_library names
1267 "intracore": android.SdkIntraCore,
1268 "intra.core": android.SdkIntraCore,
1269 "system_server": android.SdkSystemServer,
1270 "system-server": android.SdkSystemServer,
1271 "system": android.SdkSystem,
1272 "module_lib": android.SdkModule,
1273 "module-lib": android.SdkModule,
Spandan Dasda977552023-01-26 20:45:16 +00001274 "platform.api": android.SdkCorePlatform,
Spandan Das0b555e32022-11-28 18:48:51 +00001275 "test": android.SdkTest,
Spandan Das4ac2aed2022-12-28 01:54:29 +00001276 "toolchain": android.SdkToolchain,
Spandan Das0b555e32022-11-28 18:48:51 +00001277 }
1278)
1279
Colin Cross2207f872021-03-24 12:39:08 -07001280func StubsDefaultsFactory() android.Module {
1281 module := &DocDefaults{}
1282
1283 module.AddProperties(
1284 &JavadocProperties{},
1285 &DroidstubsProperties{},
1286 )
1287
1288 android.InitDefaultsModule(module)
1289
1290 return module
1291}
1292
1293var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
1294
1295type PrebuiltStubsSourcesProperties struct {
1296 Srcs []string `android:"path"`
1297}
1298
1299type PrebuiltStubsSources struct {
1300 android.ModuleBase
1301 android.DefaultableModuleBase
Spandan Das2cc80ba2023-10-27 17:21:52 +00001302 embeddableInModuleAndImport
1303
Colin Cross2207f872021-03-24 12:39:08 -07001304 prebuilt android.Prebuilt
Colin Cross2207f872021-03-24 12:39:08 -07001305
1306 properties PrebuiltStubsSourcesProperties
1307
kgui67007242022-01-25 13:50:25 +08001308 stubsSrcJar android.Path
Colin Cross2207f872021-03-24 12:39:08 -07001309}
1310
1311func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
1312 switch tag {
Jihoon Kangfa4a90d2023-12-20 02:53:38 +00001313 // prebuilt droidstubs does not output "exportable" stubs.
1314 // Output the "everything" stubs srcjar file if the tag is ".exportable".
1315 case "", ".exportable":
Colin Cross2207f872021-03-24 12:39:08 -07001316 return android.Paths{p.stubsSrcJar}, nil
1317 default:
1318 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1319 }
1320}
1321
Jihoon Kangee113282024-01-23 00:16:41 +00001322func (d *PrebuiltStubsSources) StubsSrcJar(_ StubsType) (android.Path, error) {
1323 return d.stubsSrcJar, nil
Colin Cross2207f872021-03-24 12:39:08 -07001324}
1325
1326func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross2207f872021-03-24 12:39:08 -07001327 if len(p.properties.Srcs) != 1 {
Anton Hansson86758ac2021-11-03 14:44:12 +00001328 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 -07001329 return
1330 }
1331
Anton Hansson86758ac2021-11-03 14:44:12 +00001332 src := p.properties.Srcs[0]
1333 if filepath.Ext(src) == ".srcjar" {
1334 // This is a srcjar. We can use it directly.
1335 p.stubsSrcJar = android.PathForModuleSrc(ctx, src)
1336 } else {
1337 outPath := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Colin Cross2207f872021-03-24 12:39:08 -07001338
Anton Hansson86758ac2021-11-03 14:44:12 +00001339 // This is a directory. Glob the contents just in case the directory does not exist.
1340 srcGlob := src + "/**/*"
1341 srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})
Colin Cross2207f872021-03-24 12:39:08 -07001342
Anton Hansson86758ac2021-11-03 14:44:12 +00001343 // Although PathForModuleSrc can return nil if either the path doesn't exist or
1344 // the path components are invalid it won't in this case because no components
1345 // are specified and the module directory must exist in order to get this far.
1346 srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, src)
Colin Cross2207f872021-03-24 12:39:08 -07001347
Anton Hansson86758ac2021-11-03 14:44:12 +00001348 rule := android.NewRuleBuilder(pctx, ctx)
1349 rule.Command().
1350 BuiltTool("soong_zip").
1351 Flag("-write_if_changed").
1352 Flag("-jar").
1353 FlagWithOutput("-o ", outPath).
1354 FlagWithArg("-C ", srcDir.String()).
1355 FlagWithRspFileInputList("-r ", outPath.ReplaceExtension(ctx, "rsp"), srcPaths)
1356 rule.Restat()
1357 rule.Build("zip src", "Create srcjar from prebuilt source")
1358 p.stubsSrcJar = outPath
1359 }
Colin Cross2207f872021-03-24 12:39:08 -07001360}
1361
1362func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
1363 return &p.prebuilt
1364}
1365
1366func (p *PrebuiltStubsSources) Name() string {
1367 return p.prebuilt.Name(p.ModuleBase.Name())
1368}
1369
1370// prebuilt_stubs_sources imports a set of java source files as if they were
1371// generated by droidstubs.
1372//
1373// By default, a prebuilt_stubs_sources has a single variant that expects a
1374// set of `.java` files generated by droidstubs.
1375//
1376// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
1377// for host modules.
1378//
1379// Intended only for use by sdk snapshots.
1380func PrebuiltStubsSourcesFactory() android.Module {
1381 module := &PrebuiltStubsSources{}
1382
1383 module.AddProperties(&module.properties)
Spandan Das2cc80ba2023-10-27 17:21:52 +00001384 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -07001385
1386 android.InitPrebuiltModule(module, &module.properties.Srcs)
Colin Cross2207f872021-03-24 12:39:08 -07001387 InitDroiddocModule(module, android.HostAndDeviceSupported)
1388 return module
1389}