blob: b13385ba42d6eab63d11a98d3bd6e765c9e25c5f [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
Yu Liucbb50c22025-01-15 20:57:49 +000023 "github.com/google/blueprint"
Colin Cross2207f872021-03-24 12:39:08 -070024 "github.com/google/blueprint/proptools"
25
26 "android/soong/android"
27 "android/soong/java/config"
28 "android/soong/remoteexec"
29)
30
Yu Liu3a892962025-01-15 23:14:27 +000031type StubsArtifactsInfo struct {
32 ApiVersionsXml android.WritablePath
33}
34
Yu Liucbb50c22025-01-15 20:57:49 +000035type DroidStubsInfo struct {
36 CurrentApiTimestamp android.Path
Yu Liu3a892962025-01-15 23:14:27 +000037 EverythingArtifacts StubsArtifactsInfo
38 ExportableArtifacts StubsArtifactsInfo
Yu Liucbb50c22025-01-15 20:57:49 +000039}
40
41var DroidStubsInfoProvider = blueprint.NewProvider[DroidStubsInfo]()
42
Pedro Loureirocc203502021-10-04 17:24:00 +000043// The values allowed for Droidstubs' Api_levels_sdk_type
Cole Faust051fa912022-10-05 12:45:42 -070044var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib", "system-server"}
Pedro Loureirocc203502021-10-04 17:24:00 +000045
Jihoon Kang6592e872023-12-19 01:13:16 +000046type StubsType int
47
48const (
49 Everything StubsType = iota
50 Runtime
51 Exportable
Jihoon Kang78f89142023-12-27 01:40:29 +000052 Unavailable
Jihoon Kang6592e872023-12-19 01:13:16 +000053)
54
55func (s StubsType) String() string {
56 switch s {
57 case Everything:
58 return "everything"
59 case Runtime:
60 return "runtime"
61 case Exportable:
62 return "exportable"
63 default:
64 return ""
65 }
66}
67
Jihoon Kang5d701272024-02-15 21:53:49 +000068func StringToStubsType(s string) StubsType {
69 switch strings.ToLower(s) {
70 case Everything.String():
71 return Everything
72 case Runtime.String():
73 return Runtime
74 case Exportable.String():
75 return Exportable
76 default:
77 return Unavailable
78 }
79}
80
Colin Cross2207f872021-03-24 12:39:08 -070081func init() {
82 RegisterStubsBuildComponents(android.InitRegistrationContext)
83}
84
85func RegisterStubsBuildComponents(ctx android.RegistrationContext) {
86 ctx.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
87
88 ctx.RegisterModuleType("droidstubs", DroidstubsFactory)
89 ctx.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
90
91 ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
92}
93
Jihoon Kangee113282024-01-23 00:16:41 +000094type stubsArtifacts struct {
95 nullabilityWarningsFile android.WritablePath
96 annotationsZip android.WritablePath
97 apiVersionsXml android.WritablePath
98 metadataZip android.WritablePath
99 metadataDir android.WritablePath
100}
101
Colin Cross2207f872021-03-24 12:39:08 -0700102// Droidstubs
Colin Cross2207f872021-03-24 12:39:08 -0700103type Droidstubs struct {
104 Javadoc
Spandan Das2cc80ba2023-10-27 17:21:52 +0000105 embeddableInModuleAndImport
Colin Cross2207f872021-03-24 12:39:08 -0700106
Jihoon Kangee113282024-01-23 00:16:41 +0000107 properties DroidstubsProperties
108 apiFile android.Path
109 removedApiFile android.Path
Colin Cross2207f872021-03-24 12:39:08 -0700110
111 checkCurrentApiTimestamp android.WritablePath
112 updateCurrentApiTimestamp android.WritablePath
113 checkLastReleasedApiTimestamp android.WritablePath
114 apiLintTimestamp android.WritablePath
115 apiLintReport android.WritablePath
116
117 checkNullabilityWarningsTimestamp android.WritablePath
118
Jihoon Kangee113282024-01-23 00:16:41 +0000119 everythingArtifacts stubsArtifacts
120 exportableArtifacts stubsArtifacts
Jihoon Kang3c89f042023-12-19 02:40:22 +0000121
Jihoon Kangee113282024-01-23 00:16:41 +0000122 exportableApiFile android.WritablePath
123 exportableRemovedApiFile android.WritablePath
Colin Cross2207f872021-03-24 12:39:08 -0700124}
125
126type DroidstubsProperties struct {
127 // The generated public API filename by Metalava, defaults to <module>_api.txt
128 Api_filename *string
129
130 // the generated removed API filename by Metalava, defaults to <module>_removed.txt
131 Removed_api_filename *string
132
Colin Cross2207f872021-03-24 12:39:08 -0700133 Check_api struct {
134 Last_released ApiToCheck
135
136 Current ApiToCheck
137
138 Api_lint struct {
139 Enabled *bool
140
141 // If set, performs api_lint on any new APIs not found in the given signature file
142 New_since *string `android:"path"`
143
144 // If not blank, path to the baseline txt file for approved API lint violations.
145 Baseline_file *string `android:"path"`
146 }
147 }
148
149 // user can specify the version of previous released API file in order to do compatibility check.
150 Previous_api *string `android:"path"`
151
152 // is set to true, Metalava will allow framework SDK to contain annotations.
153 Annotations_enabled *bool
154
155 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
156 Merge_annotations_dirs []string
157
158 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
159 Merge_inclusion_annotations_dirs []string
160
161 // a file containing a list of classes to do nullability validation for.
162 Validate_nullability_from_list *string
163
164 // a file containing expected warnings produced by validation of nullability annotations.
165 Check_nullability_warnings *string
166
167 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
168 Create_doc_stubs *bool
169
170 // if set to true, cause Metalava to output Javadoc comments in the stubs source files. Defaults to false.
171 // Has no effect if create_doc_stubs: true.
172 Output_javadoc_comments *bool
173
174 // if set to false then do not write out stubs. Defaults to true.
175 //
176 // TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately.
177 Generate_stubs *bool
178
179 // 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 -0400180 // which can be used for scheduling purposes
Colin Cross2207f872021-03-24 12:39:08 -0700181 High_mem *bool
182
satayev783195c2021-06-23 21:49:57 +0100183 // if set to true, Metalava will allow framework SDK to contain API levels annotations.
Colin Cross2207f872021-03-24 12:39:08 -0700184 Api_levels_annotations_enabled *bool
185
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000186 // Apply the api levels database created by this module rather than generating one in this droidstubs.
187 Api_levels_module *string
188
Colin Cross2207f872021-03-24 12:39:08 -0700189 // the dirs which Metalava extracts API levels annotations from.
190 Api_levels_annotations_dirs []string
191
Cole Faust051fa912022-10-05 12:45:42 -0700192 // 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 +0100193 Api_levels_sdk_type *string
194
Colin Cross2207f872021-03-24 12:39:08 -0700195 // the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
196 Api_levels_jar_filename *string
197
198 // if set to true, collect the values used by the Dev tools and
199 // write them in files packaged with the SDK. Defaults to false.
200 Write_sdk_values *bool
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200201
202 // path or filegroup to file defining extension an SDK name <-> numerical ID mapping and
203 // what APIs exist in which SDKs; passed to metalava via --sdk-extensions-info
204 Extensions_info_file *string `android:"path"`
Jihoon Kang3198f3c2023-01-26 08:08:52 +0000205
206 // API surface of this module. If set, the module contributes to an API surface.
207 // For the full list of available API surfaces, refer to soong/android/sdk_version.go
208 Api_surface *string
Jihoon Kang6592e872023-12-19 01:13:16 +0000209
210 // a list of aconfig_declarations module names that the stubs generated in this module
211 // depend on.
212 Aconfig_declarations []string
Paul Duffin27819362024-07-22 21:03:50 +0100213
214 // List of hard coded filegroups containing Metalava config files that are passed to every
215 // Metalava invocation that this module performs. See addMetalavaConfigFilesToCmd.
216 ConfigFiles []string `android:"path" blueprint:"mutated"`
Colin Cross2207f872021-03-24 12:39:08 -0700217}
218
Anton Hansson52609322021-05-05 10:36:05 +0100219// Used by xsd_config
220type ApiFilePath interface {
Jihoon Kangee113282024-01-23 00:16:41 +0000221 ApiFilePath(StubsType) (android.Path, error)
Anton Hansson52609322021-05-05 10:36:05 +0100222}
223
224type ApiStubsSrcProvider interface {
Jihoon Kangee113282024-01-23 00:16:41 +0000225 StubsSrcJar(StubsType) (android.Path, error)
Jihoon Kangf55a5f72024-01-08 08:56:20 +0000226}
227
Anton Hansson52609322021-05-05 10:36:05 +0100228// Provider of information about API stubs, used by java_sdk_library.
229type ApiStubsProvider interface {
Jihoon Kangee113282024-01-23 00:16:41 +0000230 AnnotationsZip(StubsType) (android.Path, error)
Anton Hansson52609322021-05-05 10:36:05 +0100231 ApiFilePath
Jihoon Kangee113282024-01-23 00:16:41 +0000232 RemovedApiFilePath(StubsType) (android.Path, error)
Anton Hansson52609322021-05-05 10:36:05 +0100233
234 ApiStubsSrcProvider
235}
236
Jihoon Kang063ec002023-06-28 01:16:23 +0000237type currentApiTimestampProvider interface {
238 CurrentApiTimestamp() android.Path
239}
240
Jihoon Kang3c89f042023-12-19 02:40:22 +0000241type annotationFlagsParams struct {
242 migratingNullability bool
243 validatingNullability bool
244 nullabilityWarningsFile android.WritablePath
245 annotationsZip android.WritablePath
246}
247type stubsCommandParams struct {
248 srcJarDir android.ModuleOutPath
249 stubsDir android.OptionalPath
250 stubsSrcJar android.WritablePath
251 metadataZip android.WritablePath
252 metadataDir android.WritablePath
253 apiVersionsXml android.WritablePath
254 nullabilityWarningsFile android.WritablePath
255 annotationsZip android.WritablePath
256 stubConfig stubsCommandConfigParams
257}
258type stubsCommandConfigParams struct {
Jihoon Kanga11d6792024-03-05 16:12:20 +0000259 stubsType StubsType
260 javaVersion javaVersion
261 deps deps
262 checkApi bool
263 generateStubs bool
264 doApiLint bool
265 doCheckReleased bool
266 writeSdkValues bool
267 migratingNullability bool
268 validatingNullability bool
Jihoon Kang3c89f042023-12-19 02:40:22 +0000269}
270
Colin Cross2207f872021-03-24 12:39:08 -0700271// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
272// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
273// a droiddoc module to generate documentation.
274func DroidstubsFactory() android.Module {
275 module := &Droidstubs{}
276
277 module.AddProperties(&module.properties,
278 &module.Javadoc.properties)
Paul Duffin27819362024-07-22 21:03:50 +0100279 module.properties.ConfigFiles = getMetalavaConfigFilegroupReference()
Spandan Das2cc80ba2023-10-27 17:21:52 +0000280 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -0700281
282 InitDroiddocModule(module, android.HostAndDeviceSupported)
Jihoon Kang3198f3c2023-01-26 08:08:52 +0000283
284 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
285 module.createApiContribution(ctx)
286 })
Colin Cross2207f872021-03-24 12:39:08 -0700287 return module
288}
289
290// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
291// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
292// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
293// module when symbols needed by the source files are provided by java_library_host modules.
294func DroidstubsHostFactory() android.Module {
295 module := &Droidstubs{}
296
297 module.AddProperties(&module.properties,
298 &module.Javadoc.properties)
299
Paul Duffin27819362024-07-22 21:03:50 +0100300 module.properties.ConfigFiles = getMetalavaConfigFilegroupReference()
Colin Cross2207f872021-03-24 12:39:08 -0700301 InitDroiddocModule(module, android.HostSupported)
302 return module
303}
304
Jihoon Kang246690a2024-02-01 21:55:01 +0000305func (d *Droidstubs) AnnotationsZip(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000306 switch stubsType {
307 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000308 ret, err = d.everythingArtifacts.annotationsZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000309 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000310 ret, err = d.exportableArtifacts.annotationsZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000311 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000312 ret, err = nil, fmt.Errorf("annotations zip not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000313 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000314 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000315}
316
Jihoon Kang246690a2024-02-01 21:55:01 +0000317func (d *Droidstubs) ApiFilePath(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000318 switch stubsType {
319 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000320 ret, err = d.apiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000321 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000322 ret, err = d.exportableApiFile, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000323 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000324 ret, err = nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000325 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000326 if ret == nil && err == nil {
Jihoon Kang36c3d962024-03-14 17:28:44 +0000327 err = fmt.Errorf("api file is null for the stub type %s", stubsType.String())
Jihoon Kang246690a2024-02-01 21:55:01 +0000328 }
329 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000330}
331
Jihoon Kang246690a2024-02-01 21:55:01 +0000332func (d *Droidstubs) ApiVersionsXmlFilePath(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000333 switch stubsType {
334 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000335 ret, err = d.everythingArtifacts.apiVersionsXml, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000336 case Exportable:
Jihoon Kang246690a2024-02-01 21:55:01 +0000337 ret, err = d.exportableArtifacts.apiVersionsXml, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000338 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000339 ret, err = nil, fmt.Errorf("api versions xml file path not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000340 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000341 if ret == nil && err == nil {
342 err = fmt.Errorf("api versions xml file is null for the stub type %s", stubsType.String())
343 }
344 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000345}
346
Jihoon Kang246690a2024-02-01 21:55:01 +0000347func (d *Droidstubs) DocZip(stubsType StubsType) (ret android.Path, err error) {
Jihoon Kang78f89142023-12-27 01:40:29 +0000348 switch stubsType {
349 case Everything:
Jihoon Kang246690a2024-02-01 21:55:01 +0000350 ret, err = d.docZip, nil
Jihoon Kang78f89142023-12-27 01:40:29 +0000351 default:
Jihoon Kang246690a2024-02-01 21:55:01 +0000352 ret, err = nil, fmt.Errorf("docs zip not supported for the stub type %s", stubsType.String())
Jihoon Kang78f89142023-12-27 01:40:29 +0000353 }
Jihoon Kang246690a2024-02-01 21:55:01 +0000354 if ret == nil && err == nil {
355 err = fmt.Errorf("docs zip is null for the stub type %s", stubsType.String())
356 }
357 return ret, err
358}
359
360func (d *Droidstubs) RemovedApiFilePath(stubsType StubsType) (ret android.Path, err error) {
361 switch stubsType {
362 case Everything:
363 ret, err = d.removedApiFile, nil
364 case Exportable:
365 ret, err = d.exportableRemovedApiFile, nil
366 default:
367 ret, err = nil, fmt.Errorf("removed api file path not supported for the stub type %s", stubsType.String())
368 }
369 if ret == nil && err == nil {
370 err = fmt.Errorf("removed api file is null for the stub type %s", stubsType.String())
371 }
372 return ret, err
373}
374
375func (d *Droidstubs) StubsSrcJar(stubsType StubsType) (ret android.Path, err error) {
376 switch stubsType {
377 case Everything:
378 ret, err = d.stubsSrcJar, nil
379 case Exportable:
380 ret, err = d.exportableStubsSrcJar, nil
381 default:
382 ret, err = nil, fmt.Errorf("stubs srcjar not supported for the stub type %s", stubsType.String())
383 }
384 if ret == nil && err == nil {
385 err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
386 }
387 return ret, err
Jihoon Kang78f89142023-12-27 01:40:29 +0000388}
389
Jihoon Kang063ec002023-06-28 01:16:23 +0000390func (d *Droidstubs) CurrentApiTimestamp() android.Path {
391 return d.checkCurrentApiTimestamp
392}
393
Colin Cross2207f872021-03-24 12:39:08 -0700394var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
395var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
396var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000397var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"}
Jihoon Kang063ec002023-06-28 01:16:23 +0000398var metalavaCurrentApiTimestampTag = dependencyTag{name: "metalava-current-api-timestamp-tag"}
Colin Cross2207f872021-03-24 12:39:08 -0700399
400func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
401 d.Javadoc.addDeps(ctx)
402
403 if len(d.properties.Merge_annotations_dirs) != 0 {
404 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
405 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
406 }
407 }
408
409 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
410 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
411 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
412 }
413 }
414
415 if len(d.properties.Api_levels_annotations_dirs) != 0 {
416 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
417 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
418 }
419 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000420
Jihoon Kang6592e872023-12-19 01:13:16 +0000421 if len(d.properties.Aconfig_declarations) != 0 {
422 for _, aconfigDeclarationModuleName := range d.properties.Aconfig_declarations {
423 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationModuleName)
424 }
425 }
426
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000427 if d.properties.Api_levels_module != nil {
428 ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
429 }
Colin Cross2207f872021-03-24 12:39:08 -0700430}
431
Jihoon Kang3c89f042023-12-19 02:40:22 +0000432func (d *Droidstubs) sdkValuesFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, metadataDir android.WritablePath) {
433 cmd.FlagWithArg("--sdk-values ", metadataDir.String())
434}
435
436func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath, stubsType StubsType, checkApi bool) {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000437
Jihoon Kang36c3d962024-03-14 17:28:44 +0000438 apiFileName := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
439 uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), apiFileName)
440 cmd.FlagWithOutput("--api ", uncheckedApiFile)
441 if checkApi || String(d.properties.Api_filename) != "" {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000442 if stubsType == Everything {
443 d.apiFile = uncheckedApiFile
444 } else if stubsType == Exportable {
445 d.exportableApiFile = uncheckedApiFile
446 }
Colin Cross2207f872021-03-24 12:39:08 -0700447 } else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
Jihoon Kang36c3d962024-03-14 17:28:44 +0000448 if stubsType == Everything {
449 // If check api is disabled then make the source file available for export.
450 d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
451 } else if stubsType == Exportable {
452 d.exportableApiFile = uncheckedApiFile
453 }
Colin Cross2207f872021-03-24 12:39:08 -0700454 }
455
Jihoon Kang36c3d962024-03-14 17:28:44 +0000456 removedApiFileName := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
457 uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), removedApiFileName)
458 cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000459 if checkApi || String(d.properties.Removed_api_filename) != "" {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000460 if stubsType == Everything {
461 d.removedApiFile = uncheckedRemovedFile
462 } else if stubsType == Exportable {
463 d.exportableRemovedApiFile = uncheckedRemovedFile
464 }
Colin Cross2207f872021-03-24 12:39:08 -0700465 } else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
Jihoon Kang36c3d962024-03-14 17:28:44 +0000466 if stubsType == Everything {
467 // If check api is disabled then make the source removed api file available for export.
468 d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
469 } else if stubsType == Exportable {
470 d.exportableRemovedApiFile = uncheckedRemovedFile
471 }
Colin Cross2207f872021-03-24 12:39:08 -0700472 }
473
Colin Cross2207f872021-03-24 12:39:08 -0700474 if stubsDir.Valid() {
475 if Bool(d.properties.Create_doc_stubs) {
476 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
477 } else {
478 cmd.FlagWithArg("--stubs ", stubsDir.String())
479 if !Bool(d.properties.Output_javadoc_comments) {
480 cmd.Flag("--exclude-documentation-from-stubs")
481 }
482 }
483 }
484}
485
Jihoon Kang3c89f042023-12-19 02:40:22 +0000486func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, params annotationFlagsParams) {
Jihoon Kanga11d6792024-03-05 16:12:20 +0000487 if Bool(d.properties.Annotations_enabled) {
488 cmd.Flag(config.MetalavaAnnotationsFlags)
Andrei Onea4985e512021-04-29 16:29:34 +0100489
Jihoon Kanga11d6792024-03-05 16:12:20 +0000490 if params.migratingNullability {
Jihoon Kang5623e542024-01-31 23:27:26 +0000491 previousApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Previous_api)})
492 cmd.FlagForEachInput("--migrate-nullness ", previousApiFiles)
Jihoon Kanga11d6792024-03-05 16:12:20 +0000493 }
Jihoon Kang6b93b382024-01-26 22:37:41 +0000494
Jihoon Kanga11d6792024-03-05 16:12:20 +0000495 if s := String(d.properties.Validate_nullability_from_list); s != "" {
496 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
497 }
Jihoon Kang6b93b382024-01-26 22:37:41 +0000498
Jihoon Kanga11d6792024-03-05 16:12:20 +0000499 if params.validatingNullability {
500 cmd.FlagWithOutput("--nullability-warnings-txt ", params.nullabilityWarningsFile)
501 }
Jihoon Kang6b93b382024-01-26 22:37:41 +0000502
Jihoon Kangca2f9e82024-01-26 01:45:12 +0000503 cmd.FlagWithOutput("--extract-annotations ", params.annotationsZip)
Jihoon Kang6b93b382024-01-26 22:37:41 +0000504
Jihoon Kanga11d6792024-03-05 16:12:20 +0000505 if len(d.properties.Merge_annotations_dirs) != 0 {
506 d.mergeAnnoDirFlags(ctx, cmd)
507 }
Jihoon Kang6b93b382024-01-26 22:37:41 +0000508
Jihoon Kanga11d6792024-03-05 16:12:20 +0000509 cmd.Flag(config.MetalavaAnnotationsWarningsFlags)
Colin Cross2207f872021-03-24 12:39:08 -0700510 }
Colin Cross2207f872021-03-24 12:39:08 -0700511}
512
513func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Yu Liu3a892962025-01-15 23:14:27 +0000514 ctx.VisitDirectDepsProxyWithTag(metalavaMergeAnnotationsDirTag, func(m android.ModuleProxy) {
515 if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok {
516 cmd.FlagWithArg("--merge-qualifier-annotations ", t.Dir.String()).Implicits(t.Deps)
Colin Cross2207f872021-03-24 12:39:08 -0700517 } else {
518 ctx.PropertyErrorf("merge_annotations_dirs",
519 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
520 }
521 })
522}
523
524func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Yu Liu3a892962025-01-15 23:14:27 +0000525 ctx.VisitDirectDepsProxyWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.ModuleProxy) {
526 if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok {
527 cmd.FlagWithArg("--merge-inclusion-annotations ", t.Dir.String()).Implicits(t.Deps)
Colin Cross2207f872021-03-24 12:39:08 -0700528 } else {
529 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
530 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
531 }
532 })
533}
534
Jihoon Kanga11d6792024-03-05 16:12:20 +0000535func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000536 var apiVersions android.Path
Jihoon Kanga11d6792024-03-05 16:12:20 +0000537 if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000538 d.apiLevelsGenerationFlags(ctx, cmd, stubsType, apiVersionsXml)
Jihoon Kangd9a06942024-01-26 01:49:20 +0000539 apiVersions = apiVersionsXml
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000540 } else {
Yu Liu3a892962025-01-15 23:14:27 +0000541 ctx.VisitDirectDepsProxyWithTag(metalavaAPILevelsModuleTag, func(m android.ModuleProxy) {
542 if s, ok := android.OtherModuleProvider(ctx, m, DroidStubsInfoProvider); ok {
Jihoon Kangd9a06942024-01-26 01:49:20 +0000543 if stubsType == Everything {
Yu Liu3a892962025-01-15 23:14:27 +0000544 apiVersions = s.EverythingArtifacts.ApiVersionsXml
Jihoon Kangd9a06942024-01-26 01:49:20 +0000545 } else if stubsType == Exportable {
Yu Liu3a892962025-01-15 23:14:27 +0000546 apiVersions = s.ExportableArtifacts.ApiVersionsXml
Jihoon Kangd9a06942024-01-26 01:49:20 +0000547 } else {
Jihoon Kangd40c5912024-03-05 16:12:20 +0000548 ctx.ModuleErrorf("%s stubs type does not generate api-versions.xml file", stubsType.String())
Jihoon Kangd9a06942024-01-26 01:49:20 +0000549 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000550 } else {
551 ctx.PropertyErrorf("api_levels_module",
552 "module %q is not a droidstubs module", ctx.OtherModuleName(m))
553 }
554 })
Colin Cross2207f872021-03-24 12:39:08 -0700555 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000556 if apiVersions != nil {
557 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
558 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
559 cmd.FlagWithInput("--apply-api-levels ", apiVersions)
560 }
561}
Colin Cross2207f872021-03-24 12:39:08 -0700562
Paul Duffin5a195f42024-05-01 12:52:35 +0100563// AndroidPlusUpdatableJar is the name of some extra jars added into `module-lib` and
564// `system-server` directories that contain all the APIs provided by the platform and updatable
565// modules because the `android.jar` files do not. See b/337836752.
566const AndroidPlusUpdatableJar = "android-plus-updatable.jar"
567
Jihoon Kang3c89f042023-12-19 02:40:22 +0000568func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, apiVersionsXml android.WritablePath) {
Colin Cross2207f872021-03-24 12:39:08 -0700569 if len(d.properties.Api_levels_annotations_dirs) == 0 {
570 ctx.PropertyErrorf("api_levels_annotations_dirs",
571 "has to be non-empty if api levels annotations was enabled!")
572 }
573
Jihoon Kang3c89f042023-12-19 02:40:22 +0000574 cmd.FlagWithOutput("--generate-api-levels ", apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700575
576 filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
577
Paul Duffin58cfc9a2024-04-25 17:01:49 +0100578 // TODO: Avoid the duplication of API surfaces, reuse apiScope.
579 // Add all relevant --android-jar-pattern patterns for Metalava.
580 // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
581 // an actual file present on disk (in the order the patterns were passed). For system APIs for
582 // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
583 // for older releases. Similarly, module-lib falls back to system API.
584 var sdkDirs []string
Paul Duffin92efc612024-05-02 17:18:05 +0100585 apiLevelsSdkType := proptools.StringDefault(d.properties.Api_levels_sdk_type, "public")
586 switch apiLevelsSdkType {
Paul Duffin58cfc9a2024-04-25 17:01:49 +0100587 case "system-server":
588 sdkDirs = []string{"system-server", "module-lib", "system", "public"}
589 case "module-lib":
590 sdkDirs = []string{"module-lib", "system", "public"}
591 case "system":
592 sdkDirs = []string{"system", "public"}
593 case "public":
594 sdkDirs = []string{"public"}
595 default:
596 ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
597 return
598 }
599
Paul Duffin92efc612024-05-02 17:18:05 +0100600 // Construct a pattern to match the appropriate extensions that should be included in the
601 // generated api-versions.xml file.
602 //
Paul Duffin58cfc9a2024-04-25 17:01:49 +0100603 // Use the first item in the sdkDirs array as that is the sdk type for the target API levels
604 // being generated but has the advantage over `Api_levels_sdk_type` as it has been validated.
Paul Duffin92efc612024-05-02 17:18:05 +0100605 // The exception is for system-server which needs to include module-lib and system-server. That
606 // is because while system-server extends module-lib the system-server extension directory only
607 // contains service-* modules which provide system-server APIs it does not list the modules which
608 // only provide a module-lib, so they have to be included separately.
609 extensionSurfacesPattern := sdkDirs[0]
610 if apiLevelsSdkType == "system-server" {
611 // Take the first two items in sdkDirs, which are system-server and module-lib, and construct
612 // a pattern that will match either.
613 extensionSurfacesPattern = strings.Join(sdkDirs[0:2], "|")
614 }
615 extensionsPattern := fmt.Sprintf(`/extensions/[0-9]+/(%s)/.*\.jar`, extensionSurfacesPattern)
Paul Duffin58cfc9a2024-04-25 17:01:49 +0100616
satayev783195c2021-06-23 21:49:57 +0100617 var dirs []string
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200618 var extensions_dir string
Yu Liu3a892962025-01-15 23:14:27 +0000619 ctx.VisitDirectDepsProxyWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.ModuleProxy) {
620 if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok {
621 extRegex := regexp.MustCompile(t.Dir.String() + extensionsPattern)
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200622
623 // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
624 // ideally this should be read from prebuiltApis.properties.Extensions_*
Yu Liu3a892962025-01-15 23:14:27 +0000625 for _, dep := range t.Deps {
Paul Duffin2ced2eb2024-05-01 13:13:51 +0100626 // Check to see if it matches an extension first.
627 depBase := dep.Base()
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200628 if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
629 if extensions_dir == "" {
Yu Liu3a892962025-01-15 23:14:27 +0000630 extensions_dir = t.Dir.String() + "/extensions"
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200631 }
632 cmd.Implicit(dep)
Paul Duffin2ced2eb2024-05-01 13:13:51 +0100633 } else if depBase == filename {
634 // Check to see if it matches a dessert release for an SDK, e.g. Android, Car, Wear, etc..
Colin Cross5f6ffc72021-03-29 21:54:45 -0700635 cmd.Implicit(dep)
Paul Duffin5a195f42024-05-01 12:52:35 +0100636 } else if depBase == AndroidPlusUpdatableJar && d.properties.Extensions_info_file != nil {
637 // The output api-versions.xml has been requested to include information on SDK
Paul Duffinee5e0932025-01-15 18:00:35 +0000638 // extensions, i.e. updatable Apis. That means it also needs to include the history of
639 // those updatable APIs. Usually, they would be included in the `android.jar` file but
640 // unfortunately, the `module-lib` and `system-server` cannot as it would lead to build
641 // cycles. So, the module-lib and system-server directories contain an
642 // `android-plus-updatable.jar` that should be used instead of `android.jar`. See
643 // AndroidPlusUpdatableJar for more information.
Paul Duffin5a195f42024-05-01 12:52:35 +0100644 cmd.Implicit(dep)
Colin Cross2207f872021-03-24 12:39:08 -0700645 }
646 }
satayev783195c2021-06-23 21:49:57 +0100647
Yu Liu3a892962025-01-15 23:14:27 +0000648 dirs = append(dirs, t.Dir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700649 } else {
650 ctx.PropertyErrorf("api_levels_annotations_dirs",
651 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
652 }
653 })
satayev783195c2021-06-23 21:49:57 +0100654
Paul Duffin5a195f42024-05-01 12:52:35 +0100655 // Generate the list of --android-jar-pattern options. The order matters so the first one which
Paul Duffin4c9d3052025-01-07 16:03:10 +0000656 // matches will be the one that is used for a specific api level.
Pedro Loureirocc203502021-10-04 17:24:00 +0000657 for _, sdkDir := range sdkDirs {
658 for _, dir := range dirs {
Paul Duffin5a195f42024-05-01 12:52:35 +0100659 addPattern := func(jarFilename string) {
Paul Duffin9820c1a2025-01-20 10:35:45 +0000660 cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:major.minor?}/%s/%s", dir, sdkDir, jarFilename))
Paul Duffin5a195f42024-05-01 12:52:35 +0100661 }
662
663 if sdkDir == "module-lib" || sdkDir == "system-server" {
664 // The module-lib and system-server android.jars do not include the updatable modules (as
665 // doing so in the source would introduce dependency cycles and the prebuilts have to
666 // match the sources). So, instead an additional `android-plus-updatable.jar` will be used
667 // that does include the updatable modules and this pattern will match that. This pattern
668 // is added in addition to the following pattern to decouple this change from the change
669 // to add the `android-plus-updatable.jar`.
670 addPattern(AndroidPlusUpdatableJar)
671 }
672
673 addPattern(filename)
Pedro Loureirocc203502021-10-04 17:24:00 +0000674 }
Paul Duffin4f707292025-01-16 14:12:31 +0000675
676 if extensions_dir != "" {
677 cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:extension}/%s/{module}.jar", extensions_dir, sdkDir))
678 }
satayev783195c2021-06-23 21:49:57 +0100679 }
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200680
681 if d.properties.Extensions_info_file != nil {
682 if extensions_dir == "" {
683 ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
684 }
685 info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
686 cmd.Implicit(info_file)
MÃ¥rten Kongstad802ae0f2022-07-27 13:47:32 +0200687 cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
688 }
Colin Cross2207f872021-03-24 12:39:08 -0700689}
690
Jihoon Kang472f73f2024-03-28 20:59:29 +0000691func (d *Droidstubs) apiCompatibilityFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType) {
692 if len(d.Javadoc.properties.Out) > 0 {
693 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
694 }
695
Jihoon Kang5623e542024-01-31 23:27:26 +0000696 apiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Api_file)})
697 removedApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Removed_api_file)})
Jihoon Kang472f73f2024-03-28 20:59:29 +0000698
Jihoon Kang5623e542024-01-31 23:27:26 +0000699 cmd.FlagForEachInput("--check-compatibility:api:released ", apiFiles)
700 cmd.FlagForEachInput("--check-compatibility:removed:released ", removedApiFiles)
Jihoon Kang472f73f2024-03-28 20:59:29 +0000701
702 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
703 if baselineFile.Valid() {
704 cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
705 }
706}
707
Colin Crosse52c2ac2022-03-28 17:03:35 -0700708func metalavaUseRbe(ctx android.ModuleContext) bool {
709 return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
710}
711
Jihoon Kang421c1cd2024-04-22 21:17:12 +0000712func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Paul Duffind71dc402025-01-24 16:10:09 +0000713 srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams,
714 configFiles android.Paths, apiSurface *string) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700715 rule.Command().Text("rm -rf").Flag(homeDir.String())
716 rule.Command().Text("mkdir -p").Flag(homeDir.String())
717
Anton Hansson556e8142021-06-04 16:20:25 +0100718 cmd := rule.Command()
Colin Cross2207f872021-03-24 12:39:08 -0700719 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())
720
Colin Crosse52c2ac2022-03-28 17:03:35 -0700721 if metalavaUseRbe(ctx) {
Colin Cross2207f872021-03-24 12:39:08 -0700722 rule.Remoteable(android.RemoteRuleSupports{RBE: true})
Colin Cross8095c292021-03-30 16:40:48 -0700723 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000724 compare := ctx.Config().IsEnvTrue("RBE_METALAVA_COMPARE")
725 remoteUpdateCache := !ctx.Config().IsEnvFalse("RBE_METALAVA_REMOTE_UPDATE_CACHE")
Colin Cross8095c292021-03-30 16:40:48 -0700726 labels := map[string]string{"type": "tool", "name": "metalava"}
727 // TODO: metalava pool rejects these jobs
728 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
729 rule.Rewrapper(&remoteexec.REParams{
Anas Sulaiman9d7a36d2023-11-21 23:00:07 +0000730 Labels: labels,
731 ExecStrategy: execStrategy,
732 ToolchainInputs: []string{config.JavaCmd(ctx).String()},
733 Platform: map[string]string{remoteexec.PoolKey: pool},
734 Compare: compare,
735 NumLocalRuns: 1,
736 NumRemoteRuns: 1,
737 NoRemoteUpdateCache: !remoteUpdateCache,
Colin Cross8095c292021-03-30 16:40:48 -0700738 })
Colin Cross2207f872021-03-24 12:39:08 -0700739 }
740
Colin Cross6aa5c402021-03-24 12:28:50 -0700741 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
Colin Cross2207f872021-03-24 12:39:08 -0700742 Flag(config.JavacVmFlags).
Liz Kammere09e20e2023-10-16 15:07:54 -0400743 Flag(config.MetalavaAddOpens).
Jihoon Kang421c1cd2024-04-22 21:17:12 +0000744 FlagWithArg("--java-source ", params.javaVersion.String()).
745 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, fmt.Sprintf("%s.metalava.rsp", params.stubsType.String())), srcs).
Colin Cross2207f872021-03-24 12:39:08 -0700746 FlagWithInput("@", srcJarList)
747
Paul Duffinf8aaaa12023-08-10 15:16:35 +0100748 // Metalava does not differentiate between bootclasspath and classpath and has not done so for
749 // years, so it is unlikely to change any time soon.
Jihoon Kang421c1cd2024-04-22 21:17:12 +0000750 combinedPaths := append(([]android.Path)(nil), params.deps.bootClasspath.Paths()...)
751 combinedPaths = append(combinedPaths, params.deps.classpath.Paths()...)
Paul Duffinf8aaaa12023-08-10 15:16:35 +0100752 if len(combinedPaths) > 0 {
753 cmd.FlagWithInputList("--classpath ", combinedPaths, ":")
Colin Cross2207f872021-03-24 12:39:08 -0700754 }
755
Liz Kammere09e20e2023-10-16 15:07:54 -0400756 cmd.Flag(config.MetalavaFlags)
Jihoon Kangc8313892023-09-20 00:54:47 +0000757
Paul Duffin27819362024-07-22 21:03:50 +0100758 addMetalavaConfigFilesToCmd(cmd, configFiles)
759
Paul Duffind71dc402025-01-24 16:10:09 +0000760 addOptionalApiSurfaceToCmd(cmd, apiSurface)
761
Colin Cross2207f872021-03-24 12:39:08 -0700762 return cmd
763}
764
Paul Duffin27819362024-07-22 21:03:50 +0100765// MetalavaConfigFilegroup is the name of the filegroup in build/soong/java/metalava that lists
766// the configuration files to pass to Metalava.
767const MetalavaConfigFilegroup = "metalava-config-files"
768
769// Get a reference to the MetalavaConfigFilegroup suitable for use in a property.
770func getMetalavaConfigFilegroupReference() []string {
771 return []string{":" + MetalavaConfigFilegroup}
772}
773
774// addMetalavaConfigFilesToCmd adds --config-file options to use the config files list in the
775// MetalavaConfigFilegroup filegroup.
776func addMetalavaConfigFilesToCmd(cmd *android.RuleBuilderCommand, configFiles android.Paths) {
777 cmd.FlagForEachInput("--config-file ", configFiles)
778}
779
Paul Duffind71dc402025-01-24 16:10:09 +0000780// addOptionalApiSurfaceToCmd adds --api-surface option is apiSurface is not `nil`.
781func addOptionalApiSurfaceToCmd(cmd *android.RuleBuilderCommand, apiSurface *string) {
782 if apiSurface != nil {
783 cmd.Flag("--api-surface")
784 cmd.Flag(*apiSurface)
785 }
786}
787
Jihoon Kang3c89f042023-12-19 02:40:22 +0000788// Pass flagged apis related flags to metalava. When aconfig_declarations property is not
789// defined for a module, simply revert all flagged apis annotations. If aconfig_declarations
790// property is defined, apply transformations and only revert the flagged apis that are not
791// enabled via release configurations and are not specified in aconfig_declarations
Jihoon Kang5d701272024-02-15 21:53:49 +0000792func generateRevertAnnotationArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType, aconfigFlagsPaths android.Paths) {
Jihoon Kang6592e872023-12-19 01:13:16 +0000793 var filterArgs string
794 switch stubsType {
795 // No flagged apis specific flags need to be passed to metalava when generating
796 // everything stubs
797 case Everything:
798 return
799
800 case Runtime:
801 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
802
803 case Exportable:
Jihoon Kang59198152024-02-06 22:43:18 +0000804 // When the build flag RELEASE_EXPORT_RUNTIME_APIS is set to true, apis marked with
805 // the flagged apis that have read_write permissions are exposed on top of the enabled
806 // and read_only apis. This is to support local override of flag values at runtime.
807 if ctx.Config().ReleaseExportRuntimeApis() {
808 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY' --filter='permission:READ_WRITE'"
809 } else {
810 filterArgs = "--filter='state:ENABLED+permission:READ_ONLY'"
811 }
Jihoon Kang6592e872023-12-19 01:13:16 +0000812 }
813
Jihoon Kangf1e0ff02024-11-20 21:10:40 +0000814 if len(aconfigFlagsPaths) == 0 {
815 // This argument should not be added for "everything" stubs
816 cmd.Flag("--revert-annotation android.annotation.FlaggedApi")
817 return
818 }
819
820 releasedFlaggedApisFile := android.PathForModuleOut(ctx, fmt.Sprintf("released-flagged-apis-%s.txt", stubsType.String()))
821 revertAnnotationsFile := android.PathForModuleOut(ctx, fmt.Sprintf("revert-annotations-%s.txt", stubsType.String()))
822
Jihoon Kang6592e872023-12-19 01:13:16 +0000823 ctx.Build(pctx, android.BuildParams{
824 Rule: gatherReleasedFlaggedApisRule,
825 Inputs: aconfigFlagsPaths,
826 Output: releasedFlaggedApisFile,
827 Description: fmt.Sprintf("%s gather aconfig flags", stubsType),
828 Args: map[string]string{
829 "flags_path": android.JoinPathsWithPrefix(aconfigFlagsPaths, "--cache "),
830 "filter_args": filterArgs,
831 },
832 })
833
834 ctx.Build(pctx, android.BuildParams{
835 Rule: generateMetalavaRevertAnnotationsRule,
836 Input: releasedFlaggedApisFile,
837 Output: revertAnnotationsFile,
838 Description: fmt.Sprintf("%s revert annotations", stubsType),
839 })
Jihoon Kang3c89f042023-12-19 02:40:22 +0000840
841 cmd.FlagWithInput("@", revertAnnotationsFile)
Jihoon Kang6592e872023-12-19 01:13:16 +0000842}
843
Jihoon Kang3c89f042023-12-19 02:40:22 +0000844func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
845 params stubsCommandParams) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700846 if BoolDefault(d.properties.High_mem, false) {
847 // This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
848 rule.HighMem()
849 }
850
Jihoon Kang3c89f042023-12-19 02:40:22 +0000851 if params.stubConfig.generateStubs {
852 rule.Command().Text("rm -rf").Text(params.stubsDir.String())
853 rule.Command().Text("mkdir -p").Text(params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700854 }
855
Jihoon Kang3c89f042023-12-19 02:40:22 +0000856 srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars)
Colin Cross2207f872021-03-24 12:39:08 -0700857
Jihoon Kang3c89f042023-12-19 02:40:22 +0000858 homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home")
Paul Duffin27819362024-07-22 21:03:50 +0100859
860 configFiles := android.PathsForModuleSrc(ctx, d.properties.ConfigFiles)
861
Paul Duffind71dc402025-01-24 16:10:09 +0000862 cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig,
863 configFiles, d.properties.Api_surface)
Colin Cross2207f872021-03-24 12:39:08 -0700864 cmd.Implicits(d.Javadoc.implicits)
865
Jihoon Kang3c89f042023-12-19 02:40:22 +0000866 d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi)
Colin Cross2207f872021-03-24 12:39:08 -0700867
Jihoon Kang3c89f042023-12-19 02:40:22 +0000868 if params.stubConfig.writeSdkValues {
869 d.sdkValuesFlags(ctx, cmd, params.metadataDir)
870 }
871
872 annotationParams := annotationFlagsParams{
873 migratingNullability: params.stubConfig.migratingNullability,
874 validatingNullability: params.stubConfig.validatingNullability,
875 nullabilityWarningsFile: params.nullabilityWarningsFile,
876 annotationsZip: params.annotationsZip,
877 }
878
Jihoon Kanga11d6792024-03-05 16:12:20 +0000879 d.annotationsFlags(ctx, cmd, annotationParams)
Colin Cross2207f872021-03-24 12:39:08 -0700880 d.inclusionAnnotationsFlags(ctx, cmd)
Jihoon Kanga11d6792024-03-05 16:12:20 +0000881 d.apiLevelsAnnotationsFlags(ctx, cmd, params.stubConfig.stubsType, params.apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700882
Jihoon Kang472f73f2024-03-28 20:59:29 +0000883 if params.stubConfig.doCheckReleased {
884 d.apiCompatibilityFlags(ctx, cmd, params.stubConfig.stubsType)
885 }
886
Colin Crossbc139922021-03-25 18:33:16 -0700887 d.expandArgs(ctx, cmd)
Colin Cross2207f872021-03-24 12:39:08 -0700888
Colin Cross2207f872021-03-24 12:39:08 -0700889 for _, o := range d.Javadoc.properties.Out {
890 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
891 }
892
Jihoon Kang3c89f042023-12-19 02:40:22 +0000893 return cmd
894}
Colin Cross2207f872021-03-24 12:39:08 -0700895
Jihoon Kang3c89f042023-12-19 02:40:22 +0000896// Sandbox rule for generating the everything stubs and other artifacts
897func (d *Droidstubs) everythingStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
898 srcJarDir := android.PathForModuleOut(ctx, Everything.String(), "srcjars")
899 rule := android.NewRuleBuilder(pctx, ctx)
900 rule.Sbox(android.PathForModuleOut(ctx, Everything.String()),
901 android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
902 SandboxInputs()
903
904 var stubsDir android.OptionalPath
905 if params.generateStubs {
906 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, Everything.String(), "stubsDir"))
907 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
908 }
909
910 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +0000911 d.everythingArtifacts.metadataDir = android.PathForModuleOut(ctx, Everything.String(), "metadata")
912 d.everythingArtifacts.metadataZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"-metadata.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000913 }
914
Jihoon Kanga11d6792024-03-05 16:12:20 +0000915 if Bool(d.properties.Annotations_enabled) {
Jihoon Kang3c89f042023-12-19 02:40:22 +0000916 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +0000917 d.everythingArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_nullability_warnings.txt")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000918 }
Jihoon Kangee113282024-01-23 00:16:41 +0000919 d.everythingArtifacts.annotationsZip = android.PathForModuleOut(ctx, Everything.String(), ctx.ModuleName()+"_annotations.zip")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000920 }
Jihoon Kanga11d6792024-03-05 16:12:20 +0000921 if Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kangee113282024-01-23 00:16:41 +0000922 d.everythingArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, Everything.String(), "api-versions.xml")
Jihoon Kang3c89f042023-12-19 02:40:22 +0000923 }
924
925 commonCmdParams := stubsCommandParams{
926 srcJarDir: srcJarDir,
927 stubsDir: stubsDir,
928 stubsSrcJar: d.Javadoc.stubsSrcJar,
Jihoon Kangee113282024-01-23 00:16:41 +0000929 metadataDir: d.everythingArtifacts.metadataDir,
930 apiVersionsXml: d.everythingArtifacts.apiVersionsXml,
931 nullabilityWarningsFile: d.everythingArtifacts.nullabilityWarningsFile,
932 annotationsZip: d.everythingArtifacts.annotationsZip,
Jihoon Kang3c89f042023-12-19 02:40:22 +0000933 stubConfig: params,
934 }
935
936 cmd := d.commonMetalavaStubCmd(ctx, rule, commonCmdParams)
937
938 d.everythingOptionalCmd(ctx, cmd, params.doApiLint, params.doCheckReleased)
939
940 if params.generateStubs {
941 rule.Command().
942 BuiltTool("soong_zip").
943 Flag("-write_if_changed").
944 Flag("-jar").
945 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
946 FlagWithArg("-C ", stubsDir.String()).
947 FlagWithArg("-D ", stubsDir.String())
948 }
949
950 if params.writeSdkValues {
951 rule.Command().
952 BuiltTool("soong_zip").
953 Flag("-write_if_changed").
954 Flag("-d").
Jihoon Kangee113282024-01-23 00:16:41 +0000955 FlagWithOutput("-o ", d.everythingArtifacts.metadataZip).
956 FlagWithArg("-C ", d.everythingArtifacts.metadataDir.String()).
957 FlagWithArg("-D ", d.everythingArtifacts.metadataDir.String())
Jihoon Kang3c89f042023-12-19 02:40:22 +0000958 }
959
960 // TODO: We don't really need two separate API files, but this is a reminiscence of how
961 // we used to run metalava separately for API lint and the "last_released" check. Unify them.
962 if params.doApiLint {
963 rule.Command().Text("touch").Output(d.apiLintTimestamp)
964 }
965 if params.doCheckReleased {
966 rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
967 }
968
969 // TODO(b/183630617): rewrapper doesn't support restat rules
970 if !metalavaUseRbe(ctx) {
971 rule.Restat()
972 }
973
974 zipSyncCleanupCmd(rule, srcJarDir)
975
976 rule.Build("metalava", "metalava merged")
977}
978
979// Sandbox rule for generating the everything artifacts that are not run by
980// default but only run based on the module configurations
981func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, doApiLint bool, doCheckReleased bool) {
Colin Cross2207f872021-03-24 12:39:08 -0700982
983 // Add API lint options.
Paul Duffinbaf34782024-05-28 17:27:22 +0100984 treatDocumentationIssuesAsErrors := false
Jihoon Kang3c89f042023-12-19 02:40:22 +0000985 if doApiLint {
Jihoon Kang5623e542024-01-31 23:27:26 +0000986 var newSince android.Paths
987 if d.properties.Check_api.Api_lint.New_since != nil {
988 newSince = android.PathsForModuleSrc(ctx, []string{proptools.String(d.properties.Check_api.Api_lint.New_since)})
989 }
Paul Duffin0a71d732024-04-22 13:22:56 +0100990 cmd.Flag("--api-lint")
991 cmd.FlagForEachInput("--api-lint-previous-api ", newSince)
Jihoon Kang3c89f042023-12-19 02:40:22 +0000992 d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700993 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
994
Paul Duffinc540bee2024-08-29 15:35:58 +0100995 // If UnflaggedApi issues have not already been configured then make sure that existing
996 // UnflaggedApi issues are reported as warnings but issues in new/changed code are treated as
997 // errors by the Build Warnings Aye Aye Analyzer in Gerrit.
Paul Duffin88d3b392024-08-28 17:37:36 +0100998 // Once existing issues have been fixed this will be changed to error.
Paul Duffinc540bee2024-08-29 15:35:58 +0100999 // TODO(b/362771529): Switch to --error
1000 if !strings.Contains(cmd.String(), " UnflaggedApi ") {
1001 cmd.Flag("--error-when-new UnflaggedApi")
1002 }
Paul Duffin88d3b392024-08-28 17:37:36 +01001003
Colin Cross0d532412021-03-25 09:38:45 -07001004 // TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
Colin Cross2207f872021-03-24 12:39:08 -07001005 if d.Name() != "android.car-system-stubs-docs" &&
1006 d.Name() != "android.car-stubs-docs" {
Paul Duffinbaf34782024-05-28 17:27:22 +01001007 treatDocumentationIssuesAsErrors = true
Colin Cross2207f872021-03-24 12:39:08 -07001008 cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
1009 }
1010
1011 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +00001012 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "api_lint_baseline.txt")
1013 d.apiLintTimestamp = android.PathForModuleOut(ctx, Everything.String(), "api_lint.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -07001014
1015 // Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
Colin Cross2207f872021-03-24 12:39:08 -07001016 //
1017 // TODO: metalava also has a slightly different message hardcoded. Should we unify this
1018 // message and metalava's one?
1019 msg := `$'` + // Enclose with $' ... '
1020 `************************************************************\n` +
1021 `Your API changes are triggering API Lint warnings or errors.\n` +
Colin Cross2207f872021-03-24 12:39:08 -07001022 `\n` +
Adrian Roos40be6472024-11-05 14:25:35 +00001023 `To make the failures go away:\n` +
Colin Cross2207f872021-03-24 12:39:08 -07001024 `\n` +
Adrian Roos40be6472024-11-05 14:25:35 +00001025 `1. REQUIRED: Read the messages carefully and address them by` +
1026 ` fixing the API if appropriate.\n` +
1027 `2. If the failure is a false positive, you can suppress it with:\n` +
1028 ` @SuppressLint("<id>")\n` +
Aurimas Liutikasb23b7452021-05-24 18:00:37 +00001029 ` where the <id> is given in brackets in the error message above.\n`
Colin Cross2207f872021-03-24 12:39:08 -07001030
1031 if baselineFile.Valid() {
1032 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
1033 cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)
1034
1035 msg += fmt.Sprintf(``+
Cole Faust5146e782024-11-15 14:47:49 -08001036 `3. FOR LSC ONLY: You can update the baseline by executing\n`+
Adrian Roos40be6472024-11-05 14:25:35 +00001037 ` the following command:\n`+
Colin Cross63eeda02021-04-15 19:01:57 -07001038 ` (cd $ANDROID_BUILD_TOP && cp \\\n`+
1039 ` "%s" \\\n`+
1040 ` "%s")\n`+
Colin Cross2207f872021-03-24 12:39:08 -07001041 ` To submit the revised baseline.txt to the main Android\n`+
1042 ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
1043 } else {
1044 msg += fmt.Sprintf(``+
Adrian Roos40be6472024-11-05 14:25:35 +00001045 `3. FOR LSC ONLY: You can add a baseline file of existing lint failures\n`+
Colin Cross2207f872021-03-24 12:39:08 -07001046 ` to the build rule of %s.\n`, d.Name())
1047 }
1048 // Note the message ends with a ' (single quote), to close the $' ... ' .
1049 msg += `************************************************************\n'`
1050
1051 cmd.FlagWithArg("--error-message:api-lint ", msg)
1052 }
1053
Paul Duffinbaf34782024-05-28 17:27:22 +01001054 if !treatDocumentationIssuesAsErrors {
Paul Duffinb679bdd2024-06-10 14:29:41 +01001055 treatDocumentationIssuesAsWarningErrorWhenNew(cmd)
Paul Duffinbaf34782024-05-28 17:27:22 +01001056 }
1057
Colin Cross2207f872021-03-24 12:39:08 -07001058 // Add "check released" options. (Detect incompatible API changes from the last public release)
Jihoon Kang3c89f042023-12-19 02:40:22 +00001059 if doCheckReleased {
Colin Cross2207f872021-03-24 12:39:08 -07001060 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
Jihoon Kang3c89f042023-12-19 02:40:22 +00001061 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -07001062 if baselineFile.Valid() {
Jihoon Kang472f73f2024-03-28 20:59:29 +00001063 updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
Colin Cross2207f872021-03-24 12:39:08 -07001064 cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
1065 }
Colin Cross2207f872021-03-24 12:39:08 -07001066 // Note this string includes quote ($' ... '), which decodes the "\n"s.
1067 msg := `$'\n******************************\n` +
1068 `You have tried to change the API from what has been previously released in\n` +
1069 `an SDK. Please fix the errors listed above.\n` +
1070 `******************************\n'`
1071
1072 cmd.FlagWithArg("--error-message:compatibility:released ", msg)
1073 }
1074
Paul Duffin10a23c22023-08-11 22:47:31 +01001075 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1076 // Pass the current API file into metalava so it can use it as the basis for determining how to
1077 // generate the output signature files (both api and removed).
1078 currentApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1079 cmd.FlagWithInput("--use-same-format-as ", currentApiFile)
1080 }
Jihoon Kang3c89f042023-12-19 02:40:22 +00001081}
Paul Duffin10a23c22023-08-11 22:47:31 +01001082
Paul Duffinb679bdd2024-06-10 14:29:41 +01001083// HIDDEN_DOCUMENTATION_ISSUES is the set of documentation related issues that should always be
1084// hidden as they are very noisy and provide little value.
1085var HIDDEN_DOCUMENTATION_ISSUES = []string{
1086 "Deprecated",
1087 "IntDef",
1088 "Nullable",
1089}
1090
1091func treatDocumentationIssuesAsWarningErrorWhenNew(cmd *android.RuleBuilderCommand) {
1092 // Treat documentation issues as warnings, but error when new.
1093 cmd.Flag("--error-when-new-category").Flag("Documentation")
1094
1095 // Hide some documentation issues that generated a lot of noise for little benefit.
1096 cmd.FlagForEachArg("--hide ", HIDDEN_DOCUMENTATION_ISSUES)
1097}
1098
Jihoon Kang3c89f042023-12-19 02:40:22 +00001099// Sandbox rule for generating exportable stubs and other artifacts
1100func (d *Droidstubs) exportableStubCmd(ctx android.ModuleContext, params stubsCommandConfigParams) {
1101 optionalCmdParams := stubsCommandParams{
1102 stubConfig: params,
1103 }
1104
Jihoon Kang246690a2024-02-01 21:55:01 +00001105 if params.generateStubs {
1106 d.Javadoc.exportableStubsSrcJar = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-"+"stubs.srcjar")
1107 optionalCmdParams.stubsSrcJar = d.Javadoc.exportableStubsSrcJar
1108 }
1109
Jihoon Kang3c89f042023-12-19 02:40:22 +00001110 if params.writeSdkValues {
Jihoon Kangee113282024-01-23 00:16:41 +00001111 d.exportableArtifacts.metadataZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"-metadata.zip")
1112 d.exportableArtifacts.metadataDir = android.PathForModuleOut(ctx, params.stubsType.String(), "metadata")
1113 optionalCmdParams.metadataZip = d.exportableArtifacts.metadataZip
1114 optionalCmdParams.metadataDir = d.exportableArtifacts.metadataDir
Jihoon Kang3c89f042023-12-19 02:40:22 +00001115 }
1116
Jihoon Kanga11d6792024-03-05 16:12:20 +00001117 if Bool(d.properties.Annotations_enabled) {
Jihoon Kang3c89f042023-12-19 02:40:22 +00001118 if params.validatingNullability {
Jihoon Kangee113282024-01-23 00:16:41 +00001119 d.exportableArtifacts.nullabilityWarningsFile = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_nullability_warnings.txt")
1120 optionalCmdParams.nullabilityWarningsFile = d.exportableArtifacts.nullabilityWarningsFile
Jihoon Kang3c89f042023-12-19 02:40:22 +00001121 }
Jihoon Kangee113282024-01-23 00:16:41 +00001122 d.exportableArtifacts.annotationsZip = android.PathForModuleOut(ctx, params.stubsType.String(), ctx.ModuleName()+"_annotations.zip")
1123 optionalCmdParams.annotationsZip = d.exportableArtifacts.annotationsZip
Jihoon Kang3c89f042023-12-19 02:40:22 +00001124 }
Jihoon Kanga11d6792024-03-05 16:12:20 +00001125 if Bool(d.properties.Api_levels_annotations_enabled) {
Jihoon Kangee113282024-01-23 00:16:41 +00001126 d.exportableArtifacts.apiVersionsXml = android.PathForModuleOut(ctx, params.stubsType.String(), "api-versions.xml")
1127 optionalCmdParams.apiVersionsXml = d.exportableArtifacts.apiVersionsXml
Jihoon Kang3c89f042023-12-19 02:40:22 +00001128 }
1129
1130 if params.checkApi || String(d.properties.Api_filename) != "" {
1131 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
1132 d.exportableApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1133 }
1134
1135 if params.checkApi || String(d.properties.Removed_api_filename) != "" {
1136 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_api.txt")
1137 d.exportableRemovedApiFile = android.PathForModuleOut(ctx, params.stubsType.String(), filename)
1138 }
1139
1140 d.optionalStubCmd(ctx, optionalCmdParams)
1141}
1142
1143func (d *Droidstubs) optionalStubCmd(ctx android.ModuleContext, params stubsCommandParams) {
1144
1145 params.srcJarDir = android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "srcjars")
1146 rule := android.NewRuleBuilder(pctx, ctx)
1147 rule.Sbox(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String()),
1148 android.PathForModuleOut(ctx, fmt.Sprintf("metalava_%s.sbox.textproto", params.stubConfig.stubsType.String()))).
1149 SandboxInputs()
1150
1151 if params.stubConfig.generateStubs {
1152 params.stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "stubsDir"))
1153 }
1154
1155 cmd := d.commonMetalavaStubCmd(ctx, rule, params)
1156
Jihoon Kang5d701272024-02-15 21:53:49 +00001157 generateRevertAnnotationArgs(ctx, cmd, params.stubConfig.stubsType, params.stubConfig.deps.aconfigProtoFiles)
Jihoon Kang3c89f042023-12-19 02:40:22 +00001158
1159 if params.stubConfig.doApiLint {
1160 // Pass the lint baseline file as an input to resolve the lint errors.
1161 // The exportable stubs generation does not update the lint baseline file.
1162 // Lint baseline file update is handled by the everything stubs
1163 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1164 if baselineFile.Valid() {
1165 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
1166 }
1167 }
1168
Paul Duffin71527b72024-05-31 13:30:32 +01001169 // Treat documentation issues as warnings, but error when new.
Paul Duffinb679bdd2024-06-10 14:29:41 +01001170 treatDocumentationIssuesAsWarningErrorWhenNew(cmd)
Paul Duffin71527b72024-05-31 13:30:32 +01001171
Jihoon Kang3c89f042023-12-19 02:40:22 +00001172 if params.stubConfig.generateStubs {
Colin Cross2207f872021-03-24 12:39:08 -07001173 rule.Command().
1174 BuiltTool("soong_zip").
1175 Flag("-write_if_changed").
1176 Flag("-jar").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001177 FlagWithOutput("-o ", params.stubsSrcJar).
1178 FlagWithArg("-C ", params.stubsDir.String()).
1179 FlagWithArg("-D ", params.stubsDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001180 }
1181
Jihoon Kang3c89f042023-12-19 02:40:22 +00001182 if params.stubConfig.writeSdkValues {
Colin Cross2207f872021-03-24 12:39:08 -07001183 rule.Command().
1184 BuiltTool("soong_zip").
1185 Flag("-write_if_changed").
1186 Flag("-d").
Jihoon Kang3c89f042023-12-19 02:40:22 +00001187 FlagWithOutput("-o ", params.metadataZip).
1188 FlagWithArg("-C ", params.metadataDir.String()).
1189 FlagWithArg("-D ", params.metadataDir.String())
Colin Cross2207f872021-03-24 12:39:08 -07001190 }
1191
Colin Cross6aa5c402021-03-24 12:28:50 -07001192 // TODO(b/183630617): rewrapper doesn't support restat rules
Colin Crosse52c2ac2022-03-28 17:03:35 -07001193 if !metalavaUseRbe(ctx) {
1194 rule.Restat()
1195 }
Colin Cross2207f872021-03-24 12:39:08 -07001196
Jihoon Kang3c89f042023-12-19 02:40:22 +00001197 zipSyncCleanupCmd(rule, params.srcJarDir)
Colin Cross2207f872021-03-24 12:39:08 -07001198
Jihoon Kang3c89f042023-12-19 02:40:22 +00001199 rule.Build(fmt.Sprintf("metalava_%s", params.stubConfig.stubsType.String()), "metalava merged")
1200}
1201
1202func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1203 deps := d.Javadoc.collectDeps(ctx)
1204
1205 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
1206 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
1207
1208 // Add options for the other optional tasks: API-lint and check-released.
1209 // We generate separate timestamp files for them.
1210 doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
1211 doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1212
1213 writeSdkValues := Bool(d.properties.Write_sdk_values)
1214
1215 annotationsEnabled := Bool(d.properties.Annotations_enabled)
1216
1217 migratingNullability := annotationsEnabled && String(d.properties.Previous_api) != ""
1218 validatingNullability := annotationsEnabled && (strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
1219 String(d.properties.Validate_nullability_from_list) != "")
1220
1221 checkApi := apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1222 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
1223
1224 stubCmdParams := stubsCommandConfigParams{
Jihoon Kanga11d6792024-03-05 16:12:20 +00001225 javaVersion: javaVersion,
1226 deps: deps,
1227 checkApi: checkApi,
1228 generateStubs: generateStubs,
1229 doApiLint: doApiLint,
1230 doCheckReleased: doCheckReleased,
1231 writeSdkValues: writeSdkValues,
1232 migratingNullability: migratingNullability,
1233 validatingNullability: validatingNullability,
Jihoon Kang3c89f042023-12-19 02:40:22 +00001234 }
1235 stubCmdParams.stubsType = Everything
1236 // Create default (i.e. "everything" stubs) rule for metalava
1237 d.everythingStubCmd(ctx, stubCmdParams)
1238
Jihoon Kangd40c5912024-03-05 16:12:20 +00001239 // The module generates "exportable" (and "runtime" eventually) stubs regardless of whether
Jihoon Kang3c89f042023-12-19 02:40:22 +00001240 // aconfig_declarations property is defined or not. If the property is not defined, the module simply
1241 // strips all flagged apis to generate the "exportable" stubs
1242 stubCmdParams.stubsType = Exportable
1243 d.exportableStubCmd(ctx, stubCmdParams)
Paul Duffinc166b682022-05-27 12:23:08 +00001244
Paul Duffine7a86642022-08-16 15:43:20 +00001245 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1246
1247 if len(d.Javadoc.properties.Out) > 0 {
1248 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1249 }
1250
1251 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1252 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
1253 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1254
1255 if baselineFile.Valid() {
1256 ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
1257 }
1258
Jihoon Kang3c89f042023-12-19 02:40:22 +00001259 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001260
1261 rule := android.NewRuleBuilder(pctx, ctx)
1262
1263 // Diff command line.
1264 // -F matches the closest "opening" line, such as "package android {"
1265 // and " public class Intent {".
1266 diff := `diff -u -F '{ *$'`
1267
1268 rule.Command().Text("( true")
1269 rule.Command().
1270 Text(diff).
1271 Input(apiFile).Input(d.apiFile)
1272
1273 rule.Command().
1274 Text(diff).
1275 Input(removedApiFile).Input(d.removedApiFile)
1276
1277 msg := fmt.Sprintf(`\n******************************\n`+
1278 `You have tried to change the API from what has been previously approved.\n\n`+
1279 `To make these errors go away, you have two choices:\n`+
1280 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
1281 ` to the new methods, etc. shown in the above diff.\n\n`+
1282 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
1283 ` m %s-update-current-api\n\n`+
1284 ` To submit the revised current.txt to the main Android repository,\n`+
1285 ` you will need approval.\n`+
Jihoon Kang3ea64672023-11-03 00:40:26 +00001286 `If your build failed due to stub validation, you can resolve the errors with\n`+
1287 `either of the two choices above and try re-building the target.\n`+
1288 `If the mismatch between the stubs and the current.txt is intended,\n`+
1289 `you can try re-building the target by executing the following command:\n`+
Jihoon Kang91bf3dd2024-01-24 00:40:23 +00001290 `m DISABLE_STUB_VALIDATION=true <your build target>.\n`+
1291 `Note that DISABLE_STUB_VALIDATION=true does not bypass checkapi.\n`+
Paul Duffine7a86642022-08-16 15:43:20 +00001292 `******************************\n`, ctx.ModuleName())
1293
1294 rule.Command().
1295 Text("touch").Output(d.checkCurrentApiTimestamp).
1296 Text(") || (").
1297 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1298 Text("; exit 38").
1299 Text(")")
1300
1301 rule.Build("metalavaCurrentApiCheck", "check current API")
1302
Jihoon Kang3c89f042023-12-19 02:40:22 +00001303 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")
Paul Duffine7a86642022-08-16 15:43:20 +00001304
1305 // update API rule
1306 rule = android.NewRuleBuilder(pctx, ctx)
1307
1308 rule.Command().Text("( true")
1309
1310 rule.Command().
1311 Text("cp").Flag("-f").
1312 Input(d.apiFile).Flag(apiFile.String())
1313
1314 rule.Command().
1315 Text("cp").Flag("-f").
1316 Input(d.removedApiFile).Flag(removedApiFile.String())
1317
1318 msg = "failed to update public API"
1319
1320 rule.Command().
1321 Text("touch").Output(d.updateCurrentApiTimestamp).
1322 Text(") || (").
1323 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1324 Text("; exit 38").
1325 Text(")")
1326
1327 rule.Build("metalavaCurrentApiUpdate", "update current API")
1328 }
1329
Colin Cross2207f872021-03-24 12:39:08 -07001330 if String(d.properties.Check_nullability_warnings) != "" {
Jihoon Kangee113282024-01-23 00:16:41 +00001331 if d.everythingArtifacts.nullabilityWarningsFile == nil {
Colin Cross2207f872021-03-24 12:39:08 -07001332 ctx.PropertyErrorf("check_nullability_warnings",
1333 "Cannot specify check_nullability_warnings unless validating nullability")
1334 }
1335
1336 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1337
Jihoon Kang3c89f042023-12-19 02:40:22 +00001338 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_nullability_warnings.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -07001339
1340 msg := fmt.Sprintf(`\n******************************\n`+
1341 `The warnings encountered during nullability annotation validation did\n`+
1342 `not match the checked in file of expected warnings. The diffs are shown\n`+
1343 `above. You have two options:\n`+
1344 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1345 ` 2. Update the file of expected warnings by running:\n`+
1346 ` cp %s %s\n`+
1347 ` and submitting the updated file as part of your change.`,
Jihoon Kangee113282024-01-23 00:16:41 +00001348 d.everythingArtifacts.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross2207f872021-03-24 12:39:08 -07001349
1350 rule := android.NewRuleBuilder(pctx, ctx)
1351
1352 rule.Command().
1353 Text("(").
Jihoon Kangee113282024-01-23 00:16:41 +00001354 Text("diff").Input(checkNullabilityWarnings).Input(d.everythingArtifacts.nullabilityWarningsFile).
Colin Cross2207f872021-03-24 12:39:08 -07001355 Text("&&").
1356 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1357 Text(") || (").
1358 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1359 Text("; exit 38").
1360 Text(")")
1361
1362 rule.Build("nullabilityWarningsCheck", "nullability warnings check")
1363 }
mrziwang39e68ff2024-07-01 16:35:32 -07001364
Yu Liucbb50c22025-01-15 20:57:49 +00001365 android.SetProvider(ctx, DroidStubsInfoProvider, DroidStubsInfo{
1366 CurrentApiTimestamp: d.CurrentApiTimestamp(),
Yu Liu3a892962025-01-15 23:14:27 +00001367 EverythingArtifacts: StubsArtifactsInfo{
1368 ApiVersionsXml: d.everythingArtifacts.apiVersionsXml,
1369 },
1370 ExportableArtifacts: StubsArtifactsInfo{
1371 ApiVersionsXml: d.exportableArtifacts.apiVersionsXml,
1372 },
Yu Liucbb50c22025-01-15 20:57:49 +00001373 })
1374
mrziwang39e68ff2024-07-01 16:35:32 -07001375 d.setOutputFiles(ctx)
1376}
1377
1378// This method sets the outputFiles property, which is used to set the
1379// OutputFilesProvider later.
1380// Droidstubs' tag supports specifying with the stubs type.
1381// While supporting the pre-existing tags, it also supports tags with
1382// the stubs type prefix. Some examples are shown below:
1383// {.annotations.zip} - pre-existing behavior. Returns the path to the
1384// annotation zip.
1385// {.exportable} - Returns the path to the exportable stubs src jar.
1386// {.exportable.annotations.zip} - Returns the path to the exportable
1387// annotations zip file.
1388// {.runtime.api_versions.xml} - Runtime stubs does not generate api versions
1389// xml file. For unsupported combinations, the default everything output file
1390// is returned.
1391func (d *Droidstubs) setOutputFiles(ctx android.ModuleContext) {
1392 tagToOutputFileFunc := map[string]func(StubsType) (android.Path, error){
1393 "": d.StubsSrcJar,
1394 ".docs.zip": d.DocZip,
1395 ".api.txt": d.ApiFilePath,
1396 android.DefaultDistTag: d.ApiFilePath,
1397 ".removed-api.txt": d.RemovedApiFilePath,
1398 ".annotations.zip": d.AnnotationsZip,
1399 ".api_versions.xml": d.ApiVersionsXmlFilePath,
1400 }
1401 stubsTypeToPrefix := map[StubsType]string{
1402 Everything: "",
1403 Exportable: ".exportable",
1404 }
1405 for _, tag := range android.SortedKeys(tagToOutputFileFunc) {
1406 for _, stubType := range android.SortedKeys(stubsTypeToPrefix) {
1407 tagWithPrefix := stubsTypeToPrefix[stubType] + tag
1408 outputFile, err := tagToOutputFileFunc[tag](stubType)
Cole Faust5146e782024-11-15 14:47:49 -08001409 if err == nil && outputFile != nil {
mrziwang39e68ff2024-07-01 16:35:32 -07001410 ctx.SetOutputFiles(android.Paths{outputFile}, tagWithPrefix)
1411 }
1412 }
1413 }
Colin Cross2207f872021-03-24 12:39:08 -07001414}
1415
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001416func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
1417 api_file := d.properties.Check_api.Current.Api_file
1418 api_surface := d.properties.Api_surface
1419
1420 props := struct {
1421 Name *string
1422 Api_surface *string
1423 Api_file *string
Jihoon Kang42b589c2023-02-03 22:56:13 +00001424 Visibility []string
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001425 }{}
1426
1427 props.Name = proptools.StringPtr(d.Name() + ".api.contribution")
1428 props.Api_surface = api_surface
1429 props.Api_file = api_file
Jihoon Kang42b589c2023-02-03 22:56:13 +00001430 props.Visibility = []string{"//visibility:override", "//visibility:public"}
Jihoon Kang3198f3c2023-01-26 08:08:52 +00001431
1432 ctx.CreateModule(ApiContributionFactory, &props)
1433}
1434
Spandan Das0b555e32022-11-28 18:48:51 +00001435// TODO (b/262014796): Export the API contributions of CorePlatformApi
1436// A map to populate the api surface of a droidstub from a substring appearing in its name
1437// This map assumes that droidstubs (either checked-in or created by java_sdk_library)
1438// use a strict naming convention
1439var (
1440 droidstubsModuleNamingToSdkKind = map[string]android.SdkKind{
Paul Duffin2ced2eb2024-05-01 13:13:51 +01001441 // public is commented out since the core libraries use public in their java_sdk_library names
Spandan Das0b555e32022-11-28 18:48:51 +00001442 "intracore": android.SdkIntraCore,
1443 "intra.core": android.SdkIntraCore,
1444 "system_server": android.SdkSystemServer,
1445 "system-server": android.SdkSystemServer,
1446 "system": android.SdkSystem,
1447 "module_lib": android.SdkModule,
1448 "module-lib": android.SdkModule,
Spandan Dasda977552023-01-26 20:45:16 +00001449 "platform.api": android.SdkCorePlatform,
Spandan Das0b555e32022-11-28 18:48:51 +00001450 "test": android.SdkTest,
Spandan Das4ac2aed2022-12-28 01:54:29 +00001451 "toolchain": android.SdkToolchain,
Spandan Das0b555e32022-11-28 18:48:51 +00001452 }
1453)
1454
Colin Cross2207f872021-03-24 12:39:08 -07001455func StubsDefaultsFactory() android.Module {
1456 module := &DocDefaults{}
1457
1458 module.AddProperties(
1459 &JavadocProperties{},
1460 &DroidstubsProperties{},
1461 )
1462
1463 android.InitDefaultsModule(module)
1464
1465 return module
1466}
1467
1468var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
1469
1470type PrebuiltStubsSourcesProperties struct {
1471 Srcs []string `android:"path"`
Spandan Das23956d12024-01-19 00:22:22 +00001472
1473 // Name of the source soong module that gets shadowed by this prebuilt
1474 // If unspecified, follows the naming convention that the source module of
1475 // the prebuilt is Name() without "prebuilt_" prefix
1476 Source_module_name *string
1477
1478 // Non-nil if this prebuilt stub srcs module was dynamically created by a java_sdk_library_import
1479 // The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
1480 // (without any prebuilt_ prefix)
1481 Created_by_java_sdk_library_name *string `blueprint:"mutated"`
1482}
1483
1484func (j *PrebuiltStubsSources) BaseModuleName() string {
1485 return proptools.StringDefault(j.properties.Source_module_name, j.ModuleBase.Name())
1486}
1487
1488func (j *PrebuiltStubsSources) CreatedByJavaSdkLibraryName() *string {
1489 return j.properties.Created_by_java_sdk_library_name
Colin Cross2207f872021-03-24 12:39:08 -07001490}
1491
1492type PrebuiltStubsSources struct {
1493 android.ModuleBase
1494 android.DefaultableModuleBase
Spandan Das2cc80ba2023-10-27 17:21:52 +00001495 embeddableInModuleAndImport
1496
Colin Cross2207f872021-03-24 12:39:08 -07001497 prebuilt android.Prebuilt
Colin Cross2207f872021-03-24 12:39:08 -07001498
1499 properties PrebuiltStubsSourcesProperties
1500
kgui67007242022-01-25 13:50:25 +08001501 stubsSrcJar android.Path
Colin Cross2207f872021-03-24 12:39:08 -07001502}
1503
Jihoon Kangee113282024-01-23 00:16:41 +00001504func (d *PrebuiltStubsSources) StubsSrcJar(_ StubsType) (android.Path, error) {
1505 return d.stubsSrcJar, nil
Colin Cross2207f872021-03-24 12:39:08 -07001506}
1507
1508func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross2207f872021-03-24 12:39:08 -07001509 if len(p.properties.Srcs) != 1 {
Anton Hansson86758ac2021-11-03 14:44:12 +00001510 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 -07001511 return
1512 }
1513
Anton Hansson86758ac2021-11-03 14:44:12 +00001514 src := p.properties.Srcs[0]
1515 if filepath.Ext(src) == ".srcjar" {
1516 // This is a srcjar. We can use it directly.
1517 p.stubsSrcJar = android.PathForModuleSrc(ctx, src)
1518 } else {
1519 outPath := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Colin Cross2207f872021-03-24 12:39:08 -07001520
Anton Hansson86758ac2021-11-03 14:44:12 +00001521 // This is a directory. Glob the contents just in case the directory does not exist.
1522 srcGlob := src + "/**/*"
1523 srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})
Colin Cross2207f872021-03-24 12:39:08 -07001524
Anton Hansson86758ac2021-11-03 14:44:12 +00001525 // Although PathForModuleSrc can return nil if either the path doesn't exist or
1526 // the path components are invalid it won't in this case because no components
1527 // are specified and the module directory must exist in order to get this far.
1528 srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, src)
Colin Cross2207f872021-03-24 12:39:08 -07001529
Anton Hansson86758ac2021-11-03 14:44:12 +00001530 rule := android.NewRuleBuilder(pctx, ctx)
1531 rule.Command().
1532 BuiltTool("soong_zip").
1533 Flag("-write_if_changed").
1534 Flag("-jar").
1535 FlagWithOutput("-o ", outPath).
1536 FlagWithArg("-C ", srcDir.String()).
1537 FlagWithRspFileInputList("-r ", outPath.ReplaceExtension(ctx, "rsp"), srcPaths)
1538 rule.Restat()
1539 rule.Build("zip src", "Create srcjar from prebuilt source")
1540 p.stubsSrcJar = outPath
1541 }
mrziwangaa2a2b62024-07-01 12:09:20 -07001542
1543 ctx.SetOutputFiles(android.Paths{p.stubsSrcJar}, "")
1544 // prebuilt droidstubs does not output "exportable" stubs.
1545 // Output the "everything" stubs srcjar file if the tag is ".exportable".
1546 ctx.SetOutputFiles(android.Paths{p.stubsSrcJar}, ".exportable")
Colin Cross2207f872021-03-24 12:39:08 -07001547}
1548
1549func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
1550 return &p.prebuilt
1551}
1552
1553func (p *PrebuiltStubsSources) Name() string {
1554 return p.prebuilt.Name(p.ModuleBase.Name())
1555}
1556
1557// prebuilt_stubs_sources imports a set of java source files as if they were
1558// generated by droidstubs.
1559//
1560// By default, a prebuilt_stubs_sources has a single variant that expects a
1561// set of `.java` files generated by droidstubs.
1562//
1563// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
1564// for host modules.
1565//
1566// Intended only for use by sdk snapshots.
1567func PrebuiltStubsSourcesFactory() android.Module {
1568 module := &PrebuiltStubsSources{}
1569
1570 module.AddProperties(&module.properties)
Spandan Das2cc80ba2023-10-27 17:21:52 +00001571 module.initModuleAndImport(module)
Colin Cross2207f872021-03-24 12:39:08 -07001572
1573 android.InitPrebuiltModule(module, &module.properties.Srcs)
Colin Cross2207f872021-03-24 12:39:08 -07001574 InitDroiddocModule(module, android.HostAndDeviceSupported)
1575 return module
1576}