blob: c2e822df8254f74417594a80ca4f60873f781d5d [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 Kangee113282024-01-23 00:16:41 +0000540 apiVersions = d.everythingArtifacts.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 Kangee113282024-01-23 00:16:41 +0000544 apiVersions = s.everythingArtifacts.apiVersionsXml
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000545 } else {
546 ctx.PropertyErrorf("api_levels_module",
547 "module %q is not a droidstubs module", ctx.OtherModuleName(m))
548 }
549 })
Colin Cross2207f872021-03-24 12:39:08 -0700550 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000551 if apiVersions != nil {
552 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
553 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
554 cmd.FlagWithInput("--apply-api-levels ", apiVersions)
555 }
556}
Colin Cross2207f872021-03-24 12:39:08 -0700557
Jihoon Kang3c89f042023-12-19 02:40:22 +0000558func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Colin Cross2207f872021-03-24 12:39:08 -0700559 if len(d.properties.Api_levels_annotations_dirs) == 0 {
560 ctx.PropertyErrorf("api_levels_annotations_dirs",
561 "has to be non-empty if api levels annotations was enabled!")
562 }
563
Jihoon Kang3c89f042023-12-19 02:40:22 +0000564 cmd.FlagWithOutput("--generate-api-levels ", apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700565
566 filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
567
satayev783195c2021-06-23 21:49:57 +0100568 var dirs []string
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200569 var extensions_dir string
Colin Cross2207f872021-03-24 12:39:08 -0700570 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
571 if t, ok := m.(*ExportedDroiddocDir); ok {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200572 extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
573
574 // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
575 // ideally this should be read from prebuiltApis.properties.Extensions_*
Colin Cross2207f872021-03-24 12:39:08 -0700576 for _, dep := range t.deps {
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200577 if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
578 if extensions_dir == "" {
579 extensions_dir = t.dir.String() + "/extensions"
580 }
581 cmd.Implicit(dep)
582 }
Colin Cross5f6ffc72021-03-29 21:54:45 -0700583 if dep.Base() == filename {
584 cmd.Implicit(dep)
585 }
586 if filename != "android.jar" && dep.Base() == "android.jar" {
587 // Metalava implicitly searches these patterns:
588 // prebuilts/tools/common/api-versions/android-%/android.jar
589 // prebuilts/sdk/%/public/android.jar
590 // Add android.jar files from the api_levels_annotations_dirs directories to try
591 // to satisfy these patterns. If Metalava can't find a match for an API level
592 // between 1 and 28 in at least one pattern it will fail.
Colin Cross2207f872021-03-24 12:39:08 -0700593 cmd.Implicit(dep)
594 }
595 }
satayev783195c2021-06-23 21:49:57 +0100596
597 dirs = append(dirs, t.dir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700598 } else {
599 ctx.PropertyErrorf("api_levels_annotations_dirs",
600 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
601 }
602 })
satayev783195c2021-06-23 21:49:57 +0100603
604 // Add all relevant --android-jar-pattern patterns for Metalava.
605 // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
606 // an actual file present on disk (in the order the patterns were passed). For system APIs for
607 // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
Pedro Loureirocc203502021-10-04 17:24:00 +0000608 // for older releases. Similarly, module-lib falls back to system API.
609 var sdkDirs []string
610 switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
Cole Faust051fa912022-10-05 12:45:42 -0700611 case "system-server":
612 sdkDirs = []string{"system-server", "module-lib", "system", "public"}
Pedro Loureirocc203502021-10-04 17:24:00 +0000613 case "module-lib":
614 sdkDirs = []string{"module-lib", "system", "public"}
615 case "system":
616 sdkDirs = []string{"system", "public"}
617 case "public":
618 sdkDirs = []string{"public"}
619 default:
620 ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
621 return
satayev783195c2021-06-23 21:49:57 +0100622 }
Pedro Loureirocc203502021-10-04 17:24:00 +0000623
624 for _, sdkDir := range sdkDirs {
625 for _, dir := range dirs {
626 cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
627 }
satayev783195c2021-06-23 21:49:57 +0100628 }
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200629
630 if d.properties.Extensions_info_file != nil {
631 if extensions_dir == "" {
632 ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
633 }
634 info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
635 cmd.Implicit(info_file)
636 cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
637 cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
638 }
Colin Cross2207f872021-03-24 12:39:08 -0700639}
640
Colin Crosse52c2ac2022-03-28 17:03:35 -0700641func metalavaUseRbe(ctx android.ModuleContext) bool {
642 return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
643}
644
Colin Cross2207f872021-03-24 12:39:08 -0700645func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Anton Hansson556e8142021-06-04 16:20:25 +0100646 srcJarList android.Path, bootclasspath, classpath classpath, homeDir android.WritablePath) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700647 rule.Command().Text("rm -rf").Flag(homeDir.String())
648 rule.Command().Text("mkdir -p").Flag(homeDir.String())
649
Anton Hansson556e8142021-06-04 16:20:25 +0100650 cmd := rule.Command()
Colin Cross2207f872021-03-24 12:39:08 -0700651 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())
652
Colin Crosse52c2ac2022-03-28 17:03:35 -0700653 if metalavaUseRbe(ctx) {
Colin Cross2207f872021-03-24 12:39:08 -0700654 rule.Remoteable(android.RemoteRuleSupports{RBE: true})
Colin Cross8095c292021-03-30 16:40:48 -0700655 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000656 compare := ctx.Config().IsEnvTrue("RBE_METALAVA_COMPARE")
657 remoteUpdateCache := !ctx.Config().IsEnvFalse("RBE_METALAVA_REMOTE_UPDATE_CACHE")
Colin Cross8095c292021-03-30 16:40:48 -0700658 labels := map[string]string{"type": "tool", "name": "metalava"}
659 // TODO: metalava pool rejects these jobs
660 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
661 rule.Rewrapper(&remoteexec.REParams{
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000662 Labels: labels,
663 ExecStrategy: execStrategy,
664 ToolchainInputs: []string{config.JavaCmd(ctx).String()},
665 Platform: map[string]string{remoteexec.PoolKey: pool},
666 Compare: compare,
667 NumLocalRuns: 1,
668 NumRemoteRuns: 1,
669 NoRemoteUpdateCache: !remoteUpdateCache,
Colin Cross8095c292021-03-30 16:40:48 -0700670 })
Colin Cross2207f872021-03-24 12:39:08 -0700671 }
672
Colin Cross6aa5c402021-03-24 12:28:50 -0700673 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
Colin Cross2207f872021-03-24 12:39:08 -0700674 Flag(config.JavacVmFlags).
Liz Kammere09e20e2023-10-16 15:07:54 -0400675 Flag(config.MetalavaAddOpens).
Paul Duffin808211e2023-08-09 12:36:08 +0100676 FlagWithArg("--java-source ", javaVersion.String()).
Colin Cross2207f872021-03-24 12:39:08 -0700677 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
678 FlagWithInput("@", srcJarList)
679
Paul Duffinf8aaaa12023-08-10 15:16:35 +0100680 // Metalava does not differentiate between bootclasspath and classpath and has not done so for
681 // years, so it is unlikely to change any time soon.
682 combinedPaths := append(([]android.Path)(nil), bootclasspath.Paths()...)
683 combinedPaths = append(combinedPaths, classpath.Paths()...)
684 if len(combinedPaths) > 0 {
685 cmd.FlagWithInputList("--classpath ", combinedPaths, ":")
Colin Cross2207f872021-03-24 12:39:08 -0700686 }
687
Liz Kammere09e20e2023-10-16 15:07:54 -0400688 cmd.Flag(config.MetalavaFlags)
Jihoon Kangc8313892023-09-20 00:54:47 +0000689
Colin Cross2207f872021-03-24 12:39:08 -0700690 return cmd
691}
692
Jihoon Kang3c89f042023-12-19 02:40:22 +0000693// Pass flagged apis related flags to metalava. When aconfig_declarations property is not
694// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
695// property is defined, apply transformations and only revert the flagged apis that are not
696// enabled via release configurations and are not specified in aconfig_declarations
697func (d *Droidstubs) generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
698
699 if len(aconfigFlagsPaths) == 0 {
700 cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
701 return
702 }
Jihoon Kang6592e872023-12-19 01:13:16 +0000703
704 releasedFlaggedApisFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flagged-apis-%s.txt", stubsType.String()))
705 revertAnnotationsFile := android.PathForModuleOut(ctx, fmt.Sprintf("revert-annotations-%s.txt", stubsType.String()))
706
707 var filterArgs string
708 switch stubsType {
709 // No flagged apis specific flags need to be passed to metalava when generating
710 // everything stubs
711 case Everything:
712 return
713
714 case Runtime:
715 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
716
717 case Exportable:
718 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY'"
719
720 }
721
722 ctx.Build(pctx, android.BuildParams{
723 Rule: gatherReleasedFlaggedApisRule,
724 Inputs: aconfigFlagsPaths,
725 Output: releasedFlaggedApisFile,
726 Description: fmt.Sprintf("%s gather aconfig flags", stubsType),
727 Args: map[string]string{
728 "flags_path": android.JoinPathsWithPrefix(aconfigFlagsPaths, "--cache "),
729 "filter_args": filterArgs,
730 },
731 })
732
733 ctx.Build(pctx, android.BuildParams{
734 Rule: generateMetalavaRevertAnnotationsRule,
735 Input: releasedFlaggedApisFile,
736 Output: revertAnnotationsFile,
737 Description: fmt.Sprintf("%s revert annotations", stubsType),
738 })
Jihoon Kang3c89f042023-12-19 02:40:22 +0000739
740 cmd.FlagWithInput("@", revertAnnotationsFile)
Jihoon Kang6592e872023-12-19 01:13:16 +0000741}
742
Jihoon Kang3c89f042023-12-19 02:40:22 +0000743func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
744 params stubsCommandParams) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700745 if BoolDefault(d.properties.High_mem, false) {
746 // This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
747 rule.HighMem()
748 }
749
Jihoon Kang3c89f042023-12-19 02:40:22 +0000750 if params.stubConfig.generateStubs {
751 rule.Command().Text("rm -rf").Text(params.stubsDir.String())
752 rule.Command().Text("mkdir -p").Text(params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700753 }
754
Jihoon Kang3c89f042023-12-19 02:40:22 +0000755 srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars)
Colin Cross2207f872021-03-24 12:39:08 -0700756
Jihoon Kang3c89f042023-12-19 02:40:22 +0000757 homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home")
758 cmd := metalavaCmd(ctx, rule, params.stubConfig.javaVersion, d.Javadoc.srcFiles, srcJarList,
759 params.stubConfig.deps.bootClasspath, params.stubConfig.deps.classpath, homeDir)
Colin Cross2207f872021-03-24 12:39:08 -0700760 cmd.Implicits(d.Javadoc.implicits)
761
Jihoon Kang3c89f042023-12-19 02:40:22 +0000762 d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
Colin Cross2207f872021-03-24 12:39:08 -0700763
Jihoon Kang3c89f042023-12-19 02:40:22 +0000764 if params.stubConfig.writeSdkValues {
765 d.sdkValuesFlags(ctx, cmd, params.metadataDir)
766 }
767
768 annotationParams := annotationFlagsParams{
769 migratingNullability: params.stubConfig.migratingNullability,
770 validatingNullability: params.stubConfig.validatingNullability,
771 nullabilityWarningsFile: params.nullabilityWarningsFile,
772 annotationsZip: params.annotationsZip,
773 }
774
775 d.annotationsFlags(ctx, cmd, annotationParams)
Colin Cross2207f872021-03-24 12:39:08 -0700776 d.inclusionAnnotationsFlags(ctx, cmd)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000777 d.apiLevelsAnnotationsFlags(ctx, cmd, params.stubConfig.stubsType, params.apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700778
Colin Crossbc139922021-03-25 18:33:16 -0700779 d.expandArgs(ctx, cmd)
Colin Cross2207f872021-03-24 12:39:08 -0700780
Colin Cross2207f872021-03-24 12:39:08 -0700781 for _, o := range d.Javadoc.properties.Out {
782 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
783 }
784
Jihoon Kang3c89f042023-12-19 02:40:22 +0000785 return cmd
786}
Colin Cross2207f872021-03-24 12:39:08 -0700787
Jihoon Kang3c89f042023-12-19 02:40:22 +0000788// Sandbox rule for generating the everything stubs and other artifacts
789func (d *Droidstubs) everythingStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
790 srcJarDir := android.PathForModuleOut(ctx, Everything.String(), "srcjars")
791 rule := android.NewRuleBuilder(pctx, ctx)
792 rule.Sbox(android.PathForModuleOut(ctx, Everything.String()),
793 android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
794 SandboxInputs()
795
796 var stubsDir android.OptionalPath
797 if params.generateStubs {
798 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, Everything.String(), "stubsDir"))
799 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
800 }
801
802 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +0000803 d.everythingArtifacts.metadataDir = android.PathForModuleOut(ctx, Everything.String(), "metadata")
804 d.everythingArtifacts.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000805 }
806
807 if Bool(d.properties.Annotations_enabled) {
808 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +0000809 d.everythingArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000810 }
Jihoon Kangee113282024-01-23 00:16:41 +0000811 d.everythingArtifacts.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000812 }
813 if Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kangee113282024-01-23 00:16:41 +0000814 d.everythingArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000815 }
816
817 commonCmdParams := stubsCommandParams{
818 srcJarDir: srcJarDir,
819 stubsDir: stubsDir,
820 stubsSrcJar: d.Javadoc.stubsSrcJar,
Jihoon Kangee113282024-01-23 00:16:41 +0000821 metadataDir: d.everythingArtifacts.metadataDir,
822 apiVersionsXml: d.everythingArtifacts.apiVersionsXml,
823 nullabilityWarningsFile: d.everythingArtifacts.nullabilityWarningsFile,
824 annotationsZip: d.everythingArtifacts.annotationsZip,
Jihoon Kang3c89f042023-12-19 02:40:22 +0000825 stubConfig: params,
826 }
827
828 cmd := d.commonMetalavaStubCmd(ctx, rule, commonCmdParams)
829
830 d.everythingOptionalCmd(ctx, cmd, params.doApiLint, params.doCheckReleased)
831
832 if params.generateStubs {
833 rule.Command().
834 BuiltTool("soong_zip").
835 Flag("-write_if_changed").
836 Flag("-jar").
837 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
838 FlagWithArg("-C ", stubsDir.String()).
839 FlagWithArg("-D ", stubsDir.String())
840 }
841
842 if params.writeSdkValues {
843 rule.Command().
844 BuiltTool("soong_zip").
845 Flag("-write_if_changed").
846 Flag("-d").
Jihoon Kangee113282024-01-23 00:16:41 +0000847 FlagWithOutput("-o ", d.everythingArtifacts.metadataZip).
848 FlagWithArg("-C ", d.everythingArtifacts.metadataDir.String()).
849 FlagWithArg("-D ", d.everythingArtifacts.metadataDir.String())
Jihoon Kang3c89f042023-12-19 02:40:22 +0000850 }
851
852 // TODO: We don't really need two separate API files, but this is a reminiscence of how
853 // we used to run metalava separately for API lint and the "last_released" check. Unify them.
854 if params.doApiLint {
855 rule.Command().Text("touch").Output(d.apiLintTimestamp)
856 }
857 if params.doCheckReleased {
858 rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
859 }
860
861 // TODO(b/183630617): rewrapper doesn't support restat rules
862 if !metalavaUseRbe(ctx) {
863 rule.Restat()
864 }
865
866 zipSyncCleanupCmd(rule, srcJarDir)
867
868 rule.Build("metalava", "metalava merged")
869}
870
871// Sandbox rule for generating the everything artifacts that are not run by
872// default but only run based on the module configurations
873func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, doApiLint bool, doCheckReleased bool) {
Colin Cross2207f872021-03-24 12:39:08 -0700874
875 // Add API lint options.
Jihoon Kang3c89f042023-12-19 02:40:22 +0000876 if doApiLint {
Colin Cross2207f872021-03-24 12:39:08 -0700877 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
878 if newSince.Valid() {
879 cmd.FlagWithInput("--api-lint ", newSince.Path())
880 } else {
881 cmd.Flag("--api-lint")
882 }
Jihoon Kang3c89f042023-12-19 02:40:22 +0000883 d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700884 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
885
Colin Cross0d532412021-03-25 09:38:45 -0700886 // TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
Colin Cross2207f872021-03-24 12:39:08 -0700887 if d.Name() != "android.car-system-stubs-docs" &&
888 d.Name() != "android.car-stubs-docs" {
889 cmd.Flag("--lints-as-errors")
890 cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
891 }
892
893 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000894 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "api_lint_baseline.txt")
895 d.apiLintTimestamp = android.PathForModuleOut(ctx, Everything.String(), "api_lint.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700896
897 // Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
Colin Cross2207f872021-03-24 12:39:08 -0700898 //
899 // TODO: metalava also has a slightly different message hardcoded. Should we unify this
900 // message and metalava's one?
901 msg := `$'` + // Enclose with $' ... '
902 `************************************************************\n` +
903 `Your API changes are triggering API Lint warnings or errors.\n` +
904 `To make these errors go away, fix the code according to the\n` +
905 `error and/or warning messages above.\n` +
906 `\n` +
907 `If it is not possible to do so, there are workarounds:\n` +
908 `\n` +
Aurimas Liutikasb23b7452021-05-24 18:00:37 +0000909 `1. You can suppress the errors with @SuppressLint("<id>")\n` +
910 ` where the <id> is given in brackets in the error message above.\n`
Colin Cross2207f872021-03-24 12:39:08 -0700911
912 if baselineFile.Valid() {
913 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
914 cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)
915
916 msg += fmt.Sprintf(``+
917 `2. You can update the baseline by executing the following\n`+
918 ` command:\n`+
Colin Cross63eeda02021-04-15 19:01:57 -0700919 ` (cd $ANDROID_BUILD_TOP && cp \\\n`+
920 ` "%s" \\\n`+
921 ` "%s")\n`+
Colin Cross2207f872021-03-24 12:39:08 -0700922 ` To submit the revised baseline.txt to the main Android\n`+
923 ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
924 } else {
925 msg += fmt.Sprintf(``+
926 `2. You can add a baseline file of existing lint failures\n`+
927 ` to the build rule of %s.\n`, d.Name())
928 }
929 // Note the message ends with a ' (single quote), to close the $' ... ' .
930 msg += `************************************************************\n'`
931
932 cmd.FlagWithArg("--error-message:api-lint ", msg)
933 }
934
935 // Add "check released" options. (Detect incompatible API changes from the last public release)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000936 if doCheckReleased {
Colin Cross2207f872021-03-24 12:39:08 -0700937 if len(d.Javadoc.properties.Out) > 0 {
938 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
939 }
940
941 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
942 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
943 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000944 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700945
Jihoon Kang3c89f042023-12-19 02:40:22 +0000946 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700947
948 cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
949 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
950
951 if baselineFile.Valid() {
952 cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
953 cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
954 }
955
956 // Note this string includes quote ($' ... '), which decodes the "\n"s.
957 msg := `$'\n******************************\n` +
958 `You have tried to change the API from what has been previously released in\n` +
959 `an SDK. Please fix the errors listed above.\n` +
960 `******************************\n'`
961
962 cmd.FlagWithArg("--error-message:compatibility:released ", msg)
963 }
964
Paul Duffin10a23c22023-08-11 22:47:31 +0100965 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
966 // Pass the current API file into metalava so it can use it as the basis for determining how to
967 // generate the output signature files (both api and removed).
968 currentApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
969 cmd.FlagWithInput("--use-same-format-as ", currentApiFile)
970 }
Jihoon Kang3c89f042023-12-19 02:40:22 +0000971}
Paul Duffin10a23c22023-08-11 22:47:31 +0100972
Jihoon Kang3c89f042023-12-19 02:40:22 +0000973// Sandbox rule for generating exportable stubs and other artifacts
974func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
975 optionalCmdParams := stubsCommandParams{
976 stubConfig: params,
977 }
978
979 d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
980 optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
981 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +0000982 d.exportableArtifacts.metadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
983 d.exportableArtifacts.metadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
984 optionalCmdParams.metadataZip = d.exportableArtifacts.metadataZip
985 optionalCmdParams.metadataDir = d.exportableArtifacts.metadataDir
Jihoon Kang3c89f042023-12-19 02:40:22 +0000986 }
987
988 if Bool(d.properties.Annotations_enabled) {
989 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +0000990 d.exportableArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
991 optionalCmdParams.nullabilityWarningsFile = d.exportableArtifacts.nullabilityWarningsFile
Jihoon Kang3c89f042023-12-19 02:40:22 +0000992 }
Jihoon Kangee113282024-01-23 00:16:41 +0000993 d.exportableArtifacts.annotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
994 optionalCmdParams.annotationsZip = d.exportableArtifacts.annotationsZip
Jihoon Kang3c89f042023-12-19 02:40:22 +0000995 }
996 if Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kangee113282024-01-23 00:16:41 +0000997 d.exportableArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
998 optionalCmdParams.apiVersionsXml = d.exportableArtifacts.apiVersionsXml
Jihoon Kang3c89f042023-12-19 02:40:22 +0000999 }
1000
1001 if params.checkApi || String(d.properties.Api_filename) != "" {
1002 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
1003 d.exportableApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1004 }
1005
1006 if params.checkApi || String(d.properties.Removed_api_filename) != "" {
1007 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_api.txt")
1008 d.exportableRemovedApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1009 }
1010
1011 d.optionalStubCmd(ctx, optionalCmdParams)
1012}
1013
1014func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsCommandParams) {
1015
1016 params.srcJarDir = android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "srcjars")
1017 rule := android.NewRuleBuilder(pctx, ctx)
1018 rule.Sbox(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String()),
1019 android.PathForModuleOut(ctx, fmt.Sprintf("metalava_%s.sbox.textproto", params.stubConfig.stubsType.String()))).
1020 SandboxInputs()
1021
1022 if params.stubConfig.generateStubs {
1023 params.stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "stubsDir"))
1024 }
1025
1026 cmd := d.commonMetalavaStubCmd(ctx, rule, params)
1027
1028 d.generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
1029
1030 if params.stubConfig.doApiLint {
1031 // Pass the lint baseline file as an input to resolve the lint errors.
1032 // The exportable stubs generation does not update the lint baseline file.
1033 // Lint baseline file update is handled by the everything stubs
1034 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1035 if baselineFile.Valid() {
1036 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
1037 }
1038 }
1039
1040 if params.stubConfig.generateStubs {
Colin Cross2207f872021-03-24 12:39:08 -07001041 rule.Command().
1042 BuiltTool("soong_zip").
1043 Flag("-write_if_changed").
1044 Flag("-jar").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001045 FlagWithOutput("-o ", params.stubsSrcJar).
1046 FlagWithArg("-C ", params.stubsDir.String()).
1047 FlagWithArg("-D ", params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001048 }
1049
Jihoon Kang3c89f042023-12-19 02:40:22 +00001050 if params.stubConfig.writeSdkValues {
Colin Cross2207f872021-03-24 12:39:08 -07001051 rule.Command().
1052 BuiltTool("soong_zip").
1053 Flag("-write_if_changed").
1054 Flag("-d").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001055 FlagWithOutput("-o ", params.metadataZip).
1056 FlagWithArg("-C ", params.metadataDir.String()).
1057 FlagWithArg("-D ", params.metadataDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001058 }
1059
Colin Cross6aa5c402021-03-24 12:28:50 -07001060 // TODO(b/183630617): rewrapper doesn't support restat rules
Colin Crosse52c2ac2022-03-28 17:03:35 -07001061 if !metalavaUseRbe(ctx) {
1062 rule.Restat()
1063 }
Colin Cross2207f872021-03-24 12:39:08 -07001064
Jihoon Kang3c89f042023-12-19 02:40:22 +00001065 zipSyncCleanupCmd(rule, params.srcJarDir)
Colin Cross2207f872021-03-24 12:39:08 -07001066
Jihoon Kang3c89f042023-12-19 02:40:22 +00001067 rule.Build(fmt.Sprintf("metalava_%s", params.stubConfig.stubsType.String()), "metalava merged")
1068}
1069
1070func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1071 deps := d.Javadoc.collectDeps(ctx)
1072
1073 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
1074 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
1075
1076 // Add options for the other optional tasks: API-lint and check-released.
1077 // We generate separate timestamp files for them.
1078 doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
1079 doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1080
1081 writeSdkValues := Bool(d.properties.Write_sdk_values)
1082
1083 annotationsEnabled := Bool(d.properties.Annotations_enabled)
1084
1085 migratingNullability := annotationsEnabled && String(d.properties.Previous_api) != ""
1086 validatingNullability := annotationsEnabled && (strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
1087 String(d.properties.Validate_nullability_from_list) != "")
1088
1089 checkApi := apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1090 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1091
1092 stubCmdParams := stubsCommandConfigParams{
1093 javaVersion: javaVersion,
1094 deps: deps,
1095 checkApi: checkApi,
1096 generateStubs: generateStubs,
1097 doApiLint: doApiLint,
1098 doCheckReleased: doCheckReleased,
1099 writeSdkValues: writeSdkValues,
1100 migratingNullability: migratingNullability,
1101 validatingNullability: validatingNullability,
1102 }
1103 stubCmdParams.stubsType = Everything
1104 // Create default (i.e. "everything" stubs) rule for metalava
1105 d.everythingStubCmd(ctx, stubCmdParams)
1106
1107 // The module generates "exportable" (and "runtime" eventually) stubs regardless of whether
1108 // aconfig_declarations property is defined or not. If the property is not defined, the module simply
1109 // strips all flagged apis to generate the "exportable" stubs
1110 stubCmdParams.stubsType = Exportable
1111 d.exportableStubCmd(ctx, stubCmdParams)
Paul Duffinc166b682022-05-27 12:23:08 +00001112
Paul Duffine7a86642022-08-16 15:43:20 +00001113 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1114
1115 if len(d.Javadoc.properties.Out) > 0 {
1116 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1117 }
1118
1119 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1120 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
1121 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1122
1123 if baselineFile.Valid() {
1124 ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
1125 }
1126
Jihoon Kang3c89f042023-12-19 02:40:22 +00001127 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001128
1129 rule := android.NewRuleBuilder(pctx, ctx)
1130
1131 // Diff command line.
1132 // -F matches the closest "opening" line, such as "package android {"
1133 // and " public class Intent {".
1134 diff := `diff -u -F '{ *$'`
1135
1136 rule.Command().Text("( true")
1137 rule.Command().
1138 Text(diff).
1139 Input(apiFile).Input(d.apiFile)
1140
1141 rule.Command().
1142 Text(diff).
1143 Input(removedApiFile).Input(d.removedApiFile)
1144
1145 msg := fmt.Sprintf(`\n******************************\n`+
1146 `You have tried to change the API from what has been previously approved.\n\n`+
1147 `To make these errors go away, you have two choices:\n`+
1148 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
1149 ` to the new methods, etc. shown in the above diff.\n\n`+
1150 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
1151 ` m %s-update-current-api\n\n`+
1152 ` To submit the revised current.txt to the main Android repository,\n`+
1153 ` you will need approval.\n`+
Jihoon Kang3ea64672023-11-03 00:40:26 +00001154 `If your build failed due to stub validation, you can resolve the errors with\n`+
1155 `either of the two choices above and try re-building the target.\n`+
1156 `If the mismatch between the stubs and the current.txt is intended,\n`+
1157 `you can try re-building the target by executing the following command:\n`+
1158 `m DISABLE_STUB_VALIDATION=true <your build target>\n`+
Paul Duffine7a86642022-08-16 15:43:20 +00001159 `******************************\n`, ctx.ModuleName())
1160
1161 rule.Command().
1162 Text("touch").Output(d.checkCurrentApiTimestamp).
1163 Text(") || (").
1164 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1165 Text("; exit 38").
1166 Text(")")
1167
1168 rule.Build("metalavaCurrentApiCheck", "check current API")
1169
Jihoon Kang3c89f042023-12-19 02:40:22 +00001170 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001171
1172 // update API rule
1173 rule = android.NewRuleBuilder(pctx, ctx)
1174
1175 rule.Command().Text("( true")
1176
1177 rule.Command().
1178 Text("cp").Flag("-f").
1179 Input(d.apiFile).Flag(apiFile.String())
1180
1181 rule.Command().
1182 Text("cp").Flag("-f").
1183 Input(d.removedApiFile).Flag(removedApiFile.String())
1184
1185 msg = "failed to update public API"
1186
1187 rule.Command().
1188 Text("touch").Output(d.updateCurrentApiTimestamp).
1189 Text(") || (").
1190 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1191 Text("; exit 38").
1192 Text(")")
1193
1194 rule.Build("metalavaCurrentApiUpdate", "update current API")
1195 }
1196
Colin Cross2207f872021-03-24 12:39:08 -07001197 if String(d.properties.Check_nullability_warnings) != "" {
Jihoon Kangee113282024-01-23 00:16:41 +00001198 if d.everythingArtifacts.nullabilityWarningsFile == nil {
Colin Cross2207f872021-03-24 12:39:08 -07001199 ctx.PropertyErrorf("check_nullability_warnings",
1200 "Cannot specify check_nullability_warnings unless validating nullability")
1201 }
1202
1203 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1204
Jihoon Kang3c89f042023-12-19 02:40:22 +00001205 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -07001206
1207 msg := fmt.Sprintf(`\n******************************\n`+
1208 `The warnings encountered during nullability annotation validation did\n`+
1209 `not match the checked in file of expected warnings. The diffs are shown\n`+
1210 `above. You have two options:\n`+
1211 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1212 ` 2. Update the file of expected warnings by running:\n`+
1213 ` cp %s %s\n`+
1214 ` and submitting the updated file as part of your change.`,
Jihoon Kangee113282024-01-23 00:16:41 +00001215 d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross2207f872021-03-24 12:39:08 -07001216
1217 rule := android.NewRuleBuilder(pctx, ctx)
1218
1219 rule.Command().
1220 Text("(").
Jihoon Kangee113282024-01-23 00:16:41 +00001221 Text("diff").Input(checkNullabilityWarnings).Input(d.everythingArtifacts.nullabilityWarningsFile).
Colin Cross2207f872021-03-24 12:39:08 -07001222 Text("&&").
1223 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1224 Text(") || (").
1225 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1226 Text("; exit 38").
1227 Text(")")
1228
1229 rule.Build("nullabilityWarningsCheck", "nullability warnings check")
1230 }
LaMont Jonesafe7baf2024-01-09 22:47:39 +00001231 android.CollectDependencyAconfigFiles(ctx, &d.mergedAconfigFiles)
Colin Cross2207f872021-03-24 12:39:08 -07001232}
1233
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001234func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
1235 api_file := d.properties.Check_api.Current.Api_file
1236 api_surface := d.properties.Api_surface
1237
1238 props := struct {
1239 Name *string
1240 Api_surface *string
1241 Api_file *string
Jihoon Kang42b589c2023-02-03 22:56:13 +00001242 Visibility []string
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001243 }{}
1244
1245 props.Name = proptools.StringPtr(d.Name() + ".api.contribution")
1246 props.Api_surface = api_surface
1247 props.Api_file = api_file
Jihoon Kang42b589c2023-02-03 22:56:13 +00001248 props.Visibility = []string{"//visibility:override", "//visibility:public"}
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001249
1250 ctx.CreateModule(ApiContributionFactory, &props)
1251}
1252
Spandan Das0b555e32022-11-28 18:48:51 +00001253// TODO (b/262014796): Export the API contributions of CorePlatformApi
1254// A map to populate the api surface of a droidstub from a substring appearing in its name
1255// This map assumes that droidstubs (either checked-in or created by java_sdk_library)
1256// use a strict naming convention
1257var (
1258 droidstubsModuleNamingToSdkKind = map[string]android.SdkKind{
1259 //public is commented out since the core libraries use public in their java_sdk_library names
1260 "intracore": android.SdkIntraCore,
1261 "intra.core": android.SdkIntraCore,
1262 "system_server": android.SdkSystemServer,
1263 "system-server": android.SdkSystemServer,
1264 "system": android.SdkSystem,
1265 "module_lib": android.SdkModule,
1266 "module-lib": android.SdkModule,
Spandan Dasda977552023-01-26 20:45:16 +00001267 "platform.api": android.SdkCorePlatform,
Spandan Das0b555e32022-11-28 18:48:51 +00001268 "test": android.SdkTest,
Spandan Das4ac2aed2022-12-28 01:54:29 +00001269 "toolchain": android.SdkToolchain,
Spandan Das0b555e32022-11-28 18:48:51 +00001270 }
1271)
1272
Colin Cross2207f872021-03-24 12:39:08 -07001273func StubsDefaultsFactory() android.Module {
1274 module := &DocDefaults{}
1275
1276 module.AddProperties(
1277 &JavadocProperties{},
1278 &DroidstubsProperties{},
1279 )
1280
1281 android.InitDefaultsModule(module)
1282
1283 return module
1284}
1285
1286var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
1287
1288type PrebuiltStubsSourcesProperties struct {
1289 Srcs []string `android:"path"`
1290}
1291
1292type PrebuiltStubsSources struct {
1293 android.ModuleBase
1294 android.DefaultableModuleBase
Spandan Das2cc80ba2023-10-27 17:21:52 +00001295 embeddableInModuleAndImport
1296
Colin Cross2207f872021-03-24 12:39:08 -07001297 prebuilt android.Prebuilt
Colin Cross2207f872021-03-24 12:39:08 -07001298
1299 properties PrebuiltStubsSourcesProperties
1300
kgui67007242022-01-25 13:50:25 +08001301 stubsSrcJar android.Path
Colin Cross2207f872021-03-24 12:39:08 -07001302}
1303
1304func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
1305 switch tag {
Jihoon Kangfa4a90d2023-12-20 02:53:38 +00001306 // prebuilt droidstubs does not output "exportable" stubs.
1307 // Output the "everything" stubs srcjar file if the tag is ".exportable".
1308 case "", ".exportable":
Colin Cross2207f872021-03-24 12:39:08 -07001309 return android.Paths{p.stubsSrcJar}, nil
1310 default:
1311 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1312 }
1313}
1314
Jihoon Kangee113282024-01-23 00:16:41 +00001315func (d *PrebuiltStubsSources) StubsSrcJar(_ StubsType) (android.Path, error) {
1316 return d.stubsSrcJar, nil
Colin Cross2207f872021-03-24 12:39:08 -07001317}
1318
1319func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross2207f872021-03-24 12:39:08 -07001320 if len(p.properties.Srcs) != 1 {
Anton Hansson86758ac2021-11-03 14:44:12 +00001321 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 -07001322 return
1323 }
1324
Anton Hansson86758ac2021-11-03 14:44:12 +00001325 src := p.properties.Srcs[0]
1326 if filepath.Ext(src) == ".srcjar" {
1327 // This is a srcjar. We can use it directly.
1328 p.stubsSrcJar = android.PathForModuleSrc(ctx, src)
1329 } else {
1330 outPath := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Colin Cross2207f872021-03-24 12:39:08 -07001331
Anton Hansson86758ac2021-11-03 14:44:12 +00001332 // This is a directory. Glob the contents just in case the directory does not exist.
1333 srcGlob := src + "/**/*"
1334 srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})
Colin Cross2207f872021-03-24 12:39:08 -07001335
Anton Hansson86758ac2021-11-03 14:44:12 +00001336 // Although PathForModuleSrc can return nil if either the path doesn't exist or
1337 // the path components are invalid it won't in this case because no components
1338 // are specified and the module directory must exist in order to get this far.
1339 srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, src)
Colin Cross2207f872021-03-24 12:39:08 -07001340
Anton Hansson86758ac2021-11-03 14:44:12 +00001341 rule := android.NewRuleBuilder(pctx, ctx)
1342 rule.Command().
1343 BuiltTool("soong_zip").
1344 Flag("-write_if_changed").
1345 Flag("-jar").
1346 FlagWithOutput("-o ", outPath).
1347 FlagWithArg("-C ", srcDir.String()).
1348 FlagWithRspFileInputList("-r ", outPath.ReplaceExtension(ctx, "rsp"), srcPaths)
1349 rule.Restat()
1350 rule.Build("zip src", "Create srcjar from prebuilt source")
1351 p.stubsSrcJar = outPath
1352 }
Colin Cross2207f872021-03-24 12:39:08 -07001353}
1354
1355func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
1356 return &p.prebuilt
1357}
1358
1359func (p *PrebuiltStubsSources) Name() string {
1360 return p.prebuilt.Name(p.ModuleBase.Name())
1361}
1362
1363// prebuilt_stubs_sources imports a set of java source files as if they were
1364// generated by droidstubs.
1365//
1366// By default, a prebuilt_stubs_sources has a single variant that expects a
1367// set of `.java` files generated by droidstubs.
1368//
1369// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
1370// for host modules.
1371//
1372// Intended only for use by sdk snapshots.
1373func PrebuiltStubsSourcesFactory() android.Module {
1374 module := &PrebuiltStubsSources{}
1375
1376 module.AddProperties(&module.properties)
Spandan Das2cc80ba2023-10-27 17:21:52 +00001377 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -07001378
1379 android.InitPrebuiltModule(module, &module.properties.Srcs)
Colin Cross2207f872021-03-24 12:39:08 -07001380 InitDroiddocModule(module, android.HostAndDeviceSupported)
1381 return module
1382}