blob: 5777b185c5280124dbe5b2fcd2c95803768867f9 [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
Colin Cross2207f872021-03-24 12:39:08 -070033func init() {
34 RegisterStubsBuildComponents(android.InitRegistrationContext)
35}
36
37func RegisterStubsBuildComponents(ctx android.RegistrationContext) {
38 ctx.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
39
40 ctx.RegisterModuleType("droidstubs", DroidstubsFactory)
41 ctx.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
42
43 ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
44}
45
Colin Cross2207f872021-03-24 12:39:08 -070046// Droidstubs
Colin Cross2207f872021-03-24 12:39:08 -070047type Droidstubs struct {
48 Javadoc
49 android.SdkBase
50
51 properties DroidstubsProperties
Paul Duffinc71d2b72022-08-16 15:24:01 +000052 apiFile android.Path
53 removedApiFile android.Path
Colin Cross2207f872021-03-24 12:39:08 -070054 nullabilityWarningsFile android.WritablePath
55
56 checkCurrentApiTimestamp android.WritablePath
57 updateCurrentApiTimestamp android.WritablePath
58 checkLastReleasedApiTimestamp android.WritablePath
59 apiLintTimestamp android.WritablePath
60 apiLintReport android.WritablePath
61
62 checkNullabilityWarningsTimestamp android.WritablePath
63
64 annotationsZip android.WritablePath
65 apiVersionsXml android.WritablePath
66
Colin Cross2207f872021-03-24 12:39:08 -070067 metadataZip android.WritablePath
68 metadataDir android.WritablePath
69}
70
71type DroidstubsProperties struct {
72 // The generated public API filename by Metalava, defaults to <module>_api.txt
73 Api_filename *string
74
75 // the generated removed API filename by Metalava, defaults to <module>_removed.txt
76 Removed_api_filename *string
77
Colin Cross2207f872021-03-24 12:39:08 -070078 Check_api struct {
79 Last_released ApiToCheck
80
81 Current ApiToCheck
82
83 Api_lint struct {
84 Enabled *bool
85
86 // If set, performs api_lint on any new APIs not found in the given signature file
87 New_since *string `android:"path"`
88
89 // If not blank, path to the baseline txt file for approved API lint violations.
90 Baseline_file *string `android:"path"`
91 }
92 }
93
94 // user can specify the version of previous released API file in order to do compatibility check.
95 Previous_api *string `android:"path"`
96
97 // is set to true, Metalava will allow framework SDK to contain annotations.
98 Annotations_enabled *bool
99
100 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
101 Merge_annotations_dirs []string
102
103 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
104 Merge_inclusion_annotations_dirs []string
105
106 // a file containing a list of classes to do nullability validation for.
107 Validate_nullability_from_list *string
108
109 // a file containing expected warnings produced by validation of nullability annotations.
110 Check_nullability_warnings *string
111
112 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
113 Create_doc_stubs *bool
114
115 // if set to true, cause Metalava to output Javadoc comments in the stubs source files. Defaults to false.
116 // Has no effect if create_doc_stubs: true.
117 Output_javadoc_comments *bool
118
119 // if set to false then do not write out stubs. Defaults to true.
120 //
121 // TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately.
122 Generate_stubs *bool
123
124 // if set to true, provides a hint to the build system that this rule uses a lot of memory,
125 // whicih can be used for scheduling purposes
126 High_mem *bool
127
satayev783195c2021-06-23 21:49:57 +0100128 // if set to true, Metalava will allow framework SDK to contain API levels annotations.
Colin Cross2207f872021-03-24 12:39:08 -0700129 Api_levels_annotations_enabled *bool
130
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000131 // Apply the api levels database created by this module rather than generating one in this droidstubs.
132 Api_levels_module *string
133
Colin Cross2207f872021-03-24 12:39:08 -0700134 // the dirs which Metalava extracts API levels annotations from.
135 Api_levels_annotations_dirs []string
136
Cole Faust051fa912022-10-05 12:45:42 -0700137 // 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 +0100138 Api_levels_sdk_type *string
139
Colin Cross2207f872021-03-24 12:39:08 -0700140 // the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
141 Api_levels_jar_filename *string
142
143 // if set to true, collect the values used by the Dev tools and
144 // write them in files packaged with the SDK. Defaults to false.
145 Write_sdk_values *bool
Mårten Kongstad802ae0f2022-07-27 13:47:32 +0200146
147 // path or filegroup to file defining extension an SDK name <-> numerical ID mapping and
148 // what APIs exist in which SDKs; passed to metalava via --sdk-extensions-info
149 Extensions_info_file *string `android:"path"`
Colin Cross2207f872021-03-24 12:39:08 -0700150}
151
Anton Hansson52609322021-05-05 10:36:05 +0100152// Used by xsd_config
153type ApiFilePath interface {
154 ApiFilePath() android.Path
155}
156
157type ApiStubsSrcProvider interface {
158 StubsSrcJar() android.Path
159}
160
161// Provider of information about API stubs, used by java_sdk_library.
162type ApiStubsProvider interface {
Anton Hanssond78eb762021-09-21 15:25:12 +0100163 AnnotationsZip() android.Path
Anton Hansson52609322021-05-05 10:36:05 +0100164 ApiFilePath
165 RemovedApiFilePath() android.Path
166
167 ApiStubsSrcProvider
168}
169
Colin Cross2207f872021-03-24 12:39:08 -0700170// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
171// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
172// a droiddoc module to generate documentation.
173func DroidstubsFactory() android.Module {
174 module := &Droidstubs{}
175
176 module.AddProperties(&module.properties,
177 &module.Javadoc.properties)
178
179 InitDroiddocModule(module, android.HostAndDeviceSupported)
180 android.InitSdkAwareModule(module)
181 return module
182}
183
184// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
185// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
186// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
187// module when symbols needed by the source files are provided by java_library_host modules.
188func DroidstubsHostFactory() android.Module {
189 module := &Droidstubs{}
190
191 module.AddProperties(&module.properties,
192 &module.Javadoc.properties)
193
194 InitDroiddocModule(module, android.HostSupported)
195 return module
196}
197
198func (d *Droidstubs) OutputFiles(tag string) (android.Paths, error) {
199 switch tag {
200 case "":
201 return android.Paths{d.stubsSrcJar}, nil
202 case ".docs.zip":
203 return android.Paths{d.docZip}, nil
204 case ".api.txt", android.DefaultDistTag:
205 // This is the default dist path for dist properties that have no tag property.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000206 return android.Paths{d.apiFile}, nil
Colin Cross2207f872021-03-24 12:39:08 -0700207 case ".removed-api.txt":
Paul Duffinc71d2b72022-08-16 15:24:01 +0000208 return android.Paths{d.removedApiFile}, nil
Colin Cross2207f872021-03-24 12:39:08 -0700209 case ".annotations.zip":
210 return android.Paths{d.annotationsZip}, nil
211 case ".api_versions.xml":
212 return android.Paths{d.apiVersionsXml}, nil
213 default:
214 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
215 }
216}
217
Anton Hanssond78eb762021-09-21 15:25:12 +0100218func (d *Droidstubs) AnnotationsZip() android.Path {
219 return d.annotationsZip
220}
221
Colin Cross2207f872021-03-24 12:39:08 -0700222func (d *Droidstubs) ApiFilePath() android.Path {
Paul Duffinc71d2b72022-08-16 15:24:01 +0000223 return d.apiFile
Colin Cross2207f872021-03-24 12:39:08 -0700224}
225
226func (d *Droidstubs) RemovedApiFilePath() android.Path {
Paul Duffinc71d2b72022-08-16 15:24:01 +0000227 return d.removedApiFile
Colin Cross2207f872021-03-24 12:39:08 -0700228}
229
230func (d *Droidstubs) StubsSrcJar() android.Path {
231 return d.stubsSrcJar
232}
233
234var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
235var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
236var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000237var metalavaAPILevelsModuleTag = dependencyTag{name: "metalava-api-levels-module-tag"}
Colin Cross2207f872021-03-24 12:39:08 -0700238
239func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
240 d.Javadoc.addDeps(ctx)
241
242 if len(d.properties.Merge_annotations_dirs) != 0 {
243 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
244 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
245 }
246 }
247
248 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
249 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
250 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
251 }
252 }
253
254 if len(d.properties.Api_levels_annotations_dirs) != 0 {
255 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
256 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
257 }
258 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000259
260 if d.properties.Api_levels_module != nil {
261 ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
262 }
Colin Cross2207f872021-03-24 12:39:08 -0700263}
264
265func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) {
266 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
267 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
268 String(d.properties.Api_filename) != "" {
269 filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
Paul Duffinc71d2b72022-08-16 15:24:01 +0000270 uncheckedApiFile := android.PathForModuleOut(ctx, "metalava", filename)
271 cmd.FlagWithOutput("--api ", uncheckedApiFile)
272 d.apiFile = uncheckedApiFile
Colin Cross2207f872021-03-24 12:39:08 -0700273 } else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
274 // If check api is disabled then make the source file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000275 d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700276 }
277
278 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
279 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
280 String(d.properties.Removed_api_filename) != "" {
281 filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
Paul Duffinc71d2b72022-08-16 15:24:01 +0000282 uncheckedRemovedFile := android.PathForModuleOut(ctx, "metalava", filename)
283 cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
284 d.removedApiFile = uncheckedRemovedFile
Colin Cross2207f872021-03-24 12:39:08 -0700285 } else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
286 // If check api is disabled then make the source removed api file available for export.
Paul Duffinc71d2b72022-08-16 15:24:01 +0000287 d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
Colin Cross2207f872021-03-24 12:39:08 -0700288 }
289
Colin Cross2207f872021-03-24 12:39:08 -0700290 if Bool(d.properties.Write_sdk_values) {
Colin Crosscb77f752021-03-24 12:04:44 -0700291 d.metadataDir = android.PathForModuleOut(ctx, "metalava", "metadata")
Colin Cross2207f872021-03-24 12:39:08 -0700292 cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
293 }
294
295 if stubsDir.Valid() {
296 if Bool(d.properties.Create_doc_stubs) {
297 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
298 } else {
299 cmd.FlagWithArg("--stubs ", stubsDir.String())
300 if !Bool(d.properties.Output_javadoc_comments) {
301 cmd.Flag("--exclude-documentation-from-stubs")
302 }
303 }
304 }
305}
306
307func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
308 if Bool(d.properties.Annotations_enabled) {
309 cmd.Flag("--include-annotations")
310
Andrei Onea4985e512021-04-29 16:29:34 +0100311 cmd.FlagWithArg("--exclude-annotation ", "androidx.annotation.RequiresApi")
312
Colin Cross2207f872021-03-24 12:39:08 -0700313 validatingNullability :=
Colin Crossbc139922021-03-25 18:33:16 -0700314 strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
Colin Cross2207f872021-03-24 12:39:08 -0700315 String(d.properties.Validate_nullability_from_list) != ""
316
317 migratingNullability := String(d.properties.Previous_api) != ""
318 if migratingNullability {
319 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
320 cmd.FlagWithInput("--migrate-nullness ", previousApi)
321 }
322
323 if s := String(d.properties.Validate_nullability_from_list); s != "" {
324 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
325 }
326
327 if validatingNullability {
Colin Crosscb77f752021-03-24 12:04:44 -0700328 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700329 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
330 }
331
Colin Crosscb77f752021-03-24 12:04:44 -0700332 d.annotationsZip = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"_annotations.zip")
Colin Cross2207f872021-03-24 12:39:08 -0700333 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
334
335 if len(d.properties.Merge_annotations_dirs) != 0 {
336 d.mergeAnnoDirFlags(ctx, cmd)
337 }
338
339 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
340 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
341 FlagWithArg("--hide ", "SuperfluousPrefix").
Sam Gilbert049af112022-03-04 16:03:53 -0500342 FlagWithArg("--hide ", "AnnotationExtraction").
343 // b/222738070
Sam Gilbert675f0b42022-03-08 11:24:44 -0500344 FlagWithArg("--hide ", "BannedThrow").
345 // b/223382732
346 FlagWithArg("--hide ", "ChangedDefault")
Colin Cross2207f872021-03-24 12:39:08 -0700347 }
348}
349
350func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
351 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
352 if t, ok := m.(*ExportedDroiddocDir); ok {
353 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
354 } else {
355 ctx.PropertyErrorf("merge_annotations_dirs",
356 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
357 }
358 })
359}
360
361func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
362 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
363 if t, ok := m.(*ExportedDroiddocDir); ok {
364 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
365 } else {
366 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
367 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
368 }
369 })
370}
371
372func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000373 var apiVersions android.Path
374 if proptools.Bool(d.properties.Api_levels_annotations_enabled) {
375 d.apiLevelsGenerationFlags(ctx, cmd)
376 apiVersions = d.apiVersionsXml
377 } else {
378 ctx.VisitDirectDepsWithTag(metalavaAPILevelsModuleTag, func(m android.Module) {
379 if s, ok := m.(*Droidstubs); ok {
380 apiVersions = s.apiVersionsXml
381 } else {
382 ctx.PropertyErrorf("api_levels_module",
383 "module %q is not a droidstubs module", ctx.OtherModuleName(m))
384 }
385 })
Colin Cross2207f872021-03-24 12:39:08 -0700386 }
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000387 if apiVersions != nil {
388 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion().String())
389 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
390 cmd.FlagWithInput("--apply-api-levels ", apiVersions)
391 }
392}
Colin Cross2207f872021-03-24 12:39:08 -0700393
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000394func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Colin Cross2207f872021-03-24 12:39:08 -0700395 if len(d.properties.Api_levels_annotations_dirs) == 0 {
396 ctx.PropertyErrorf("api_levels_annotations_dirs",
397 "has to be non-empty if api levels annotations was enabled!")
398 }
399
Anton Hanssonc04a16e2022-05-09 09:30:26 +0000400 d.apiVersionsXml = android.PathForModuleOut(ctx, "metalava", "api-versions.xml")
Colin Cross2207f872021-03-24 12:39:08 -0700401 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
Colin Cross2207f872021-03-24 12:39:08 -0700402
403 filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
404
satayev783195c2021-06-23 21:49:57 +0100405 var dirs []string
Mårten Kongstad802ae0f2022-07-27 13:47:32 +0200406 var extensions_dir string
Colin Cross2207f872021-03-24 12:39:08 -0700407 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
408 if t, ok := m.(*ExportedDroiddocDir); ok {
Mårten Kongstad802ae0f2022-07-27 13:47:32 +0200409 extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
410
411 // Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
412 // ideally this should be read from prebuiltApis.properties.Extensions_*
Colin Cross2207f872021-03-24 12:39:08 -0700413 for _, dep := range t.deps {
Mårten Kongstad802ae0f2022-07-27 13:47:32 +0200414 if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
415 if extensions_dir == "" {
416 extensions_dir = t.dir.String() + "/extensions"
417 }
418 cmd.Implicit(dep)
419 }
Colin Cross5f6ffc72021-03-29 21:54:45 -0700420 if dep.Base() == filename {
421 cmd.Implicit(dep)
422 }
423 if filename != "android.jar" && dep.Base() == "android.jar" {
424 // Metalava implicitly searches these patterns:
425 // prebuilts/tools/common/api-versions/android-%/android.jar
426 // prebuilts/sdk/%/public/android.jar
427 // Add android.jar files from the api_levels_annotations_dirs directories to try
428 // to satisfy these patterns. If Metalava can't find a match for an API level
429 // between 1 and 28 in at least one pattern it will fail.
Colin Cross2207f872021-03-24 12:39:08 -0700430 cmd.Implicit(dep)
431 }
432 }
satayev783195c2021-06-23 21:49:57 +0100433
434 dirs = append(dirs, t.dir.String())
Colin Cross2207f872021-03-24 12:39:08 -0700435 } else {
436 ctx.PropertyErrorf("api_levels_annotations_dirs",
437 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
438 }
439 })
satayev783195c2021-06-23 21:49:57 +0100440
441 // Add all relevant --android-jar-pattern patterns for Metalava.
442 // When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
443 // an actual file present on disk (in the order the patterns were passed). For system APIs for
444 // privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
Pedro Loureirocc203502021-10-04 17:24:00 +0000445 // for older releases. Similarly, module-lib falls back to system API.
446 var sdkDirs []string
447 switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
Cole Faust051fa912022-10-05 12:45:42 -0700448 case "system-server":
449 sdkDirs = []string{"system-server", "module-lib", "system", "public"}
Pedro Loureirocc203502021-10-04 17:24:00 +0000450 case "module-lib":
451 sdkDirs = []string{"module-lib", "system", "public"}
452 case "system":
453 sdkDirs = []string{"system", "public"}
454 case "public":
455 sdkDirs = []string{"public"}
456 default:
457 ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
458 return
satayev783195c2021-06-23 21:49:57 +0100459 }
Pedro Loureirocc203502021-10-04 17:24:00 +0000460
461 for _, sdkDir := range sdkDirs {
462 for _, dir := range dirs {
463 cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
464 }
satayev783195c2021-06-23 21:49:57 +0100465 }
Mårten Kongstad802ae0f2022-07-27 13:47:32 +0200466
467 if d.properties.Extensions_info_file != nil {
468 if extensions_dir == "" {
469 ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
470 }
471 info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
472 cmd.Implicit(info_file)
473 cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
474 cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
475 }
Colin Cross2207f872021-03-24 12:39:08 -0700476}
477
Colin Crosse52c2ac2022-03-28 17:03:35 -0700478func metalavaUseRbe(ctx android.ModuleContext) bool {
479 return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
480}
481
Colin Cross2207f872021-03-24 12:39:08 -0700482func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Anton Hansson556e8142021-06-04 16:20:25 +0100483 srcJarList android.Path, bootclasspath, classpath classpath, homeDir android.WritablePath) *android.RuleBuilderCommand {
Colin Cross2207f872021-03-24 12:39:08 -0700484 rule.Command().Text("rm -rf").Flag(homeDir.String())
485 rule.Command().Text("mkdir -p").Flag(homeDir.String())
486
Anton Hansson556e8142021-06-04 16:20:25 +0100487 cmd := rule.Command()
Colin Cross2207f872021-03-24 12:39:08 -0700488 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())
489
Colin Crosse52c2ac2022-03-28 17:03:35 -0700490 if metalavaUseRbe(ctx) {
Colin Cross2207f872021-03-24 12:39:08 -0700491 rule.Remoteable(android.RemoteRuleSupports{RBE: true})
Colin Cross8095c292021-03-30 16:40:48 -0700492 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
493 labels := map[string]string{"type": "tool", "name": "metalava"}
494 // TODO: metalava pool rejects these jobs
495 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
496 rule.Rewrapper(&remoteexec.REParams{
497 Labels: labels,
498 ExecStrategy: execStrategy,
499 ToolchainInputs: []string{config.JavaCmd(ctx).String()},
500 Platform: map[string]string{remoteexec.PoolKey: pool},
501 })
Colin Cross2207f872021-03-24 12:39:08 -0700502 }
503
Colin Cross6aa5c402021-03-24 12:28:50 -0700504 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
Colin Cross2207f872021-03-24 12:39:08 -0700505 Flag(config.JavacVmFlags).
506 Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED").
507 FlagWithArg("-encoding ", "UTF-8").
508 FlagWithArg("-source ", javaVersion.String()).
509 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
510 FlagWithInput("@", srcJarList)
511
Colin Cross2207f872021-03-24 12:39:08 -0700512 if len(bootclasspath) > 0 {
513 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
514 }
515
516 if len(classpath) > 0 {
517 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
518 }
519
Colin Cross2207f872021-03-24 12:39:08 -0700520 cmd.Flag("--no-banner").
521 Flag("--color").
522 Flag("--quiet").
523 Flag("--format=v2").
524 FlagWithArg("--repeat-errors-max ", "10").
Sam Gilbert09cb5db2021-10-06 11:28:28 -0400525 FlagWithArg("--hide ", "UnresolvedImport").
Ember Rose7c57af32022-04-01 10:34:44 -0400526 FlagWithArg("--hide ", "InvalidNullabilityOverride").
Sam Gilbert28e41282022-03-09 15:24:48 +0000527 // b/223382732
528 FlagWithArg("--hide ", "ChangedDefault")
Colin Cross2207f872021-03-24 12:39:08 -0700529
530 return cmd
531}
532
533func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
534 deps := d.Javadoc.collectDeps(ctx)
535
Jiyong Parkf1691d22021-03-29 20:11:58 +0900536 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), android.SdkContext(d))
Colin Cross2207f872021-03-24 12:39:08 -0700537
538 // Create rule for metalava
539
Colin Crosscb77f752021-03-24 12:04:44 -0700540 srcJarDir := android.PathForModuleOut(ctx, "metalava", "srcjars")
Colin Cross2207f872021-03-24 12:39:08 -0700541
542 rule := android.NewRuleBuilder(pctx, ctx)
543
Colin Cross8095c292021-03-30 16:40:48 -0700544 rule.Sbox(android.PathForModuleOut(ctx, "metalava"),
545 android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
546 SandboxInputs()
Colin Cross6aa5c402021-03-24 12:28:50 -0700547
Colin Cross2207f872021-03-24 12:39:08 -0700548 if BoolDefault(d.properties.High_mem, false) {
549 // This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
550 rule.HighMem()
551 }
552
553 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
554 var stubsDir android.OptionalPath
555 if generateStubs {
Colin Crosscb77f752021-03-24 12:04:44 -0700556 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")
557 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, "metalava", "stubsDir"))
Colin Cross2207f872021-03-24 12:39:08 -0700558 rule.Command().Text("rm -rf").Text(stubsDir.String())
559 rule.Command().Text("mkdir -p").Text(stubsDir.String())
560 }
561
562 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
563
Colin Crosscb77f752021-03-24 12:04:44 -0700564 homeDir := android.PathForModuleOut(ctx, "metalava", "home")
Colin Cross2207f872021-03-24 12:39:08 -0700565 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
Anton Hansson556e8142021-06-04 16:20:25 +0100566 deps.bootClasspath, deps.classpath, homeDir)
Colin Cross2207f872021-03-24 12:39:08 -0700567 cmd.Implicits(d.Javadoc.implicits)
568
569 d.stubsFlags(ctx, cmd, stubsDir)
570
571 d.annotationsFlags(ctx, cmd)
572 d.inclusionAnnotationsFlags(ctx, cmd)
573 d.apiLevelsAnnotationsFlags(ctx, cmd)
574
Colin Crossbc139922021-03-25 18:33:16 -0700575 d.expandArgs(ctx, cmd)
Colin Cross2207f872021-03-24 12:39:08 -0700576
Colin Cross2207f872021-03-24 12:39:08 -0700577 for _, o := range d.Javadoc.properties.Out {
578 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
579 }
580
581 // Add options for the other optional tasks: API-lint and check-released.
582 // We generate separate timestamp files for them.
583
584 doApiLint := false
585 doCheckReleased := false
586
587 // Add API lint options.
588
589 if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) {
590 doApiLint = true
591
592 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
593 if newSince.Valid() {
594 cmd.FlagWithInput("--api-lint ", newSince.Path())
595 } else {
596 cmd.Flag("--api-lint")
597 }
Colin Crosscb77f752021-03-24 12:04:44 -0700598 d.apiLintReport = android.PathForModuleOut(ctx, "metalava", "api_lint_report.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700599 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
600
Colin Cross0d532412021-03-25 09:38:45 -0700601 // TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
Colin Cross2207f872021-03-24 12:39:08 -0700602 if d.Name() != "android.car-system-stubs-docs" &&
603 d.Name() != "android.car-stubs-docs" {
604 cmd.Flag("--lints-as-errors")
605 cmd.Flag("--warnings-as-errors") // Most lints are actually warnings.
606 }
607
608 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
Colin Crosscb77f752021-03-24 12:04:44 -0700609 updatedBaselineOutput := android.PathForModuleOut(ctx, "metalava", "api_lint_baseline.txt")
610 d.apiLintTimestamp = android.PathForModuleOut(ctx, "metalava", "api_lint.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700611
612 // Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
Colin Cross2207f872021-03-24 12:39:08 -0700613 //
614 // TODO: metalava also has a slightly different message hardcoded. Should we unify this
615 // message and metalava's one?
616 msg := `$'` + // Enclose with $' ... '
617 `************************************************************\n` +
618 `Your API changes are triggering API Lint warnings or errors.\n` +
619 `To make these errors go away, fix the code according to the\n` +
620 `error and/or warning messages above.\n` +
621 `\n` +
622 `If it is not possible to do so, there are workarounds:\n` +
623 `\n` +
Aurimas Liutikasb23b7452021-05-24 18:00:37 +0000624 `1. You can suppress the errors with @SuppressLint("<id>")\n` +
625 ` where the <id> is given in brackets in the error message above.\n`
Colin Cross2207f872021-03-24 12:39:08 -0700626
627 if baselineFile.Valid() {
628 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
629 cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)
630
631 msg += fmt.Sprintf(``+
632 `2. You can update the baseline by executing the following\n`+
633 ` command:\n`+
Colin Cross63eeda02021-04-15 19:01:57 -0700634 ` (cd $ANDROID_BUILD_TOP && cp \\\n`+
635 ` "%s" \\\n`+
636 ` "%s")\n`+
Colin Cross2207f872021-03-24 12:39:08 -0700637 ` To submit the revised baseline.txt to the main Android\n`+
638 ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
639 } else {
640 msg += fmt.Sprintf(``+
641 `2. You can add a baseline file of existing lint failures\n`+
642 ` to the build rule of %s.\n`, d.Name())
643 }
644 // Note the message ends with a ' (single quote), to close the $' ... ' .
645 msg += `************************************************************\n'`
646
647 cmd.FlagWithArg("--error-message:api-lint ", msg)
648 }
649
650 // Add "check released" options. (Detect incompatible API changes from the last public release)
651
652 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") {
653 doCheckReleased = true
654
655 if len(d.Javadoc.properties.Out) > 0 {
656 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
657 }
658
659 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
660 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
661 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
Colin Crosscb77f752021-03-24 12:04:44 -0700662 updatedBaselineOutput := android.PathForModuleOut(ctx, "metalava", "last_released_baseline.txt")
Colin Cross2207f872021-03-24 12:39:08 -0700663
Colin Crosscb77f752021-03-24 12:04:44 -0700664 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "metalava", "check_last_released_api.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700665
666 cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
667 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
668
669 if baselineFile.Valid() {
670 cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
671 cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
672 }
673
674 // Note this string includes quote ($' ... '), which decodes the "\n"s.
675 msg := `$'\n******************************\n` +
676 `You have tried to change the API from what has been previously released in\n` +
677 `an SDK. Please fix the errors listed above.\n` +
678 `******************************\n'`
679
680 cmd.FlagWithArg("--error-message:compatibility:released ", msg)
681 }
682
Colin Cross2207f872021-03-24 12:39:08 -0700683 if generateStubs {
684 rule.Command().
685 BuiltTool("soong_zip").
686 Flag("-write_if_changed").
687 Flag("-jar").
688 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
689 FlagWithArg("-C ", stubsDir.String()).
690 FlagWithArg("-D ", stubsDir.String())
691 }
692
693 if Bool(d.properties.Write_sdk_values) {
Colin Crosscb77f752021-03-24 12:04:44 -0700694 d.metadataZip = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-metadata.zip")
Colin Cross2207f872021-03-24 12:39:08 -0700695 rule.Command().
696 BuiltTool("soong_zip").
697 Flag("-write_if_changed").
698 Flag("-d").
699 FlagWithOutput("-o ", d.metadataZip).
700 FlagWithArg("-C ", d.metadataDir.String()).
701 FlagWithArg("-D ", d.metadataDir.String())
702 }
703
704 // TODO: We don't really need two separate API files, but this is a reminiscence of how
705 // we used to run metalava separately for API lint and the "last_released" check. Unify them.
706 if doApiLint {
707 rule.Command().Text("touch").Output(d.apiLintTimestamp)
708 }
709 if doCheckReleased {
710 rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
711 }
712
Colin Cross6aa5c402021-03-24 12:28:50 -0700713 // TODO(b/183630617): rewrapper doesn't support restat rules
Colin Crosse52c2ac2022-03-28 17:03:35 -0700714 if !metalavaUseRbe(ctx) {
715 rule.Restat()
716 }
Colin Cross2207f872021-03-24 12:39:08 -0700717
718 zipSyncCleanupCmd(rule, srcJarDir)
719
Paul Duffinc166b682022-05-27 12:23:08 +0000720 rule.Build("metalava", "metalava merged")
721
Paul Duffine7a86642022-08-16 15:43:20 +0000722 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
723
724 if len(d.Javadoc.properties.Out) > 0 {
725 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
726 }
727
728 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
729 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
730 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
731
732 if baselineFile.Valid() {
733 ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
734 }
735
736 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "metalava", "check_current_api.timestamp")
737
738 rule := android.NewRuleBuilder(pctx, ctx)
739
740 // Diff command line.
741 // -F matches the closest "opening" line, such as "package android {"
742 // and " public class Intent {".
743 diff := `diff -u -F '{ *$'`
744
745 rule.Command().Text("( true")
746 rule.Command().
747 Text(diff).
748 Input(apiFile).Input(d.apiFile)
749
750 rule.Command().
751 Text(diff).
752 Input(removedApiFile).Input(d.removedApiFile)
753
754 msg := fmt.Sprintf(`\n******************************\n`+
755 `You have tried to change the API from what has been previously approved.\n\n`+
756 `To make these errors go away, you have two choices:\n`+
757 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
758 ` to the new methods, etc. shown in the above diff.\n\n`+
759 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
760 ` m %s-update-current-api\n\n`+
761 ` To submit the revised current.txt to the main Android repository,\n`+
762 ` you will need approval.\n`+
763 `******************************\n`, ctx.ModuleName())
764
765 rule.Command().
766 Text("touch").Output(d.checkCurrentApiTimestamp).
767 Text(") || (").
768 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
769 Text("; exit 38").
770 Text(")")
771
772 rule.Build("metalavaCurrentApiCheck", "check current API")
773
774 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "metalava", "update_current_api.timestamp")
775
776 // update API rule
777 rule = android.NewRuleBuilder(pctx, ctx)
778
779 rule.Command().Text("( true")
780
781 rule.Command().
782 Text("cp").Flag("-f").
783 Input(d.apiFile).Flag(apiFile.String())
784
785 rule.Command().
786 Text("cp").Flag("-f").
787 Input(d.removedApiFile).Flag(removedApiFile.String())
788
789 msg = "failed to update public API"
790
791 rule.Command().
792 Text("touch").Output(d.updateCurrentApiTimestamp).
793 Text(") || (").
794 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
795 Text("; exit 38").
796 Text(")")
797
798 rule.Build("metalavaCurrentApiUpdate", "update current API")
799 }
800
Colin Cross2207f872021-03-24 12:39:08 -0700801 if String(d.properties.Check_nullability_warnings) != "" {
802 if d.nullabilityWarningsFile == nil {
803 ctx.PropertyErrorf("check_nullability_warnings",
804 "Cannot specify check_nullability_warnings unless validating nullability")
805 }
806
807 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
808
Colin Crosscb77f752021-03-24 12:04:44 -0700809 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "metalava", "check_nullability_warnings.timestamp")
Colin Cross2207f872021-03-24 12:39:08 -0700810
811 msg := fmt.Sprintf(`\n******************************\n`+
812 `The warnings encountered during nullability annotation validation did\n`+
813 `not match the checked in file of expected warnings. The diffs are shown\n`+
814 `above. You have two options:\n`+
815 ` 1. Resolve the differences by editing the nullability annotations.\n`+
816 ` 2. Update the file of expected warnings by running:\n`+
817 ` cp %s %s\n`+
818 ` and submitting the updated file as part of your change.`,
819 d.nullabilityWarningsFile, checkNullabilityWarnings)
820
821 rule := android.NewRuleBuilder(pctx, ctx)
822
823 rule.Command().
824 Text("(").
825 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
826 Text("&&").
827 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
828 Text(") || (").
829 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
830 Text("; exit 38").
831 Text(")")
832
833 rule.Build("nullabilityWarningsCheck", "nullability warnings check")
834 }
835}
836
837func StubsDefaultsFactory() android.Module {
838 module := &DocDefaults{}
839
840 module.AddProperties(
841 &JavadocProperties{},
842 &DroidstubsProperties{},
843 )
844
845 android.InitDefaultsModule(module)
846
847 return module
848}
849
850var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
851
852type PrebuiltStubsSourcesProperties struct {
853 Srcs []string `android:"path"`
854}
855
856type PrebuiltStubsSources struct {
857 android.ModuleBase
858 android.DefaultableModuleBase
859 prebuilt android.Prebuilt
860 android.SdkBase
861
862 properties PrebuiltStubsSourcesProperties
863
kgui67007242022-01-25 13:50:25 +0800864 stubsSrcJar android.Path
Colin Cross2207f872021-03-24 12:39:08 -0700865}
866
867func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
868 switch tag {
869 case "":
870 return android.Paths{p.stubsSrcJar}, nil
871 default:
872 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
873 }
874}
875
876func (d *PrebuiltStubsSources) StubsSrcJar() android.Path {
877 return d.stubsSrcJar
878}
879
880func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross2207f872021-03-24 12:39:08 -0700881 if len(p.properties.Srcs) != 1 {
Anton Hansson86758ac2021-11-03 14:44:12 +0000882 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 -0700883 return
884 }
885
Anton Hansson86758ac2021-11-03 14:44:12 +0000886 src := p.properties.Srcs[0]
887 if filepath.Ext(src) == ".srcjar" {
888 // This is a srcjar. We can use it directly.
889 p.stubsSrcJar = android.PathForModuleSrc(ctx, src)
890 } else {
891 outPath := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Colin Cross2207f872021-03-24 12:39:08 -0700892
Anton Hansson86758ac2021-11-03 14:44:12 +0000893 // This is a directory. Glob the contents just in case the directory does not exist.
894 srcGlob := src + "/**/*"
895 srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})
Colin Cross2207f872021-03-24 12:39:08 -0700896
Anton Hansson86758ac2021-11-03 14:44:12 +0000897 // Although PathForModuleSrc can return nil if either the path doesn't exist or
898 // the path components are invalid it won't in this case because no components
899 // are specified and the module directory must exist in order to get this far.
900 srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, src)
Colin Cross2207f872021-03-24 12:39:08 -0700901
Anton Hansson86758ac2021-11-03 14:44:12 +0000902 rule := android.NewRuleBuilder(pctx, ctx)
903 rule.Command().
904 BuiltTool("soong_zip").
905 Flag("-write_if_changed").
906 Flag("-jar").
907 FlagWithOutput("-o ", outPath).
908 FlagWithArg("-C ", srcDir.String()).
909 FlagWithRspFileInputList("-r ", outPath.ReplaceExtension(ctx, "rsp"), srcPaths)
910 rule.Restat()
911 rule.Build("zip src", "Create srcjar from prebuilt source")
912 p.stubsSrcJar = outPath
913 }
Colin Cross2207f872021-03-24 12:39:08 -0700914}
915
916func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
917 return &p.prebuilt
918}
919
920func (p *PrebuiltStubsSources) Name() string {
921 return p.prebuilt.Name(p.ModuleBase.Name())
922}
923
924// prebuilt_stubs_sources imports a set of java source files as if they were
925// generated by droidstubs.
926//
927// By default, a prebuilt_stubs_sources has a single variant that expects a
928// set of `.java` files generated by droidstubs.
929//
930// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
931// for host modules.
932//
933// Intended only for use by sdk snapshots.
934func PrebuiltStubsSourcesFactory() android.Module {
935 module := &PrebuiltStubsSources{}
936
937 module.AddProperties(&module.properties)
938
939 android.InitPrebuiltModule(module, &module.properties.Srcs)
940 android.InitSdkAwareModule(module)
941 InitDroiddocModule(module, android.HostAndDeviceSupported)
942 return module
943}