blob: 10e7138d04c78f280918172a0dfb62c9be7a4c87 [file] [log] [blame]
Jiyong Parkc678ad32018-04-10 13:07:10 +09001// Copyright 2018 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 (
Jiyong Parkc678ad32018-04-10 13:07:10 +090018 "fmt"
19 "path"
Sundong Ahn054b19a2018-10-19 13:46:09 +090020 "path/filepath"
Paul Duffin46a26a82020-04-07 19:27:04 +010021 "reflect"
Jiyong Park82484c02018-04-23 21:41:26 +090022 "sort"
Jiyong Parkc678ad32018-04-10 13:07:10 +090023 "strings"
Jiyong Park82484c02018-04-23 21:41:26 +090024 "sync"
Jiyong Parkc678ad32018-04-10 13:07:10 +090025
Paul Duffind1b3a922020-01-22 11:57:20 +000026 "github.com/google/blueprint"
Jiyong Parkc678ad32018-04-10 13:07:10 +090027 "github.com/google/blueprint/proptools"
Paul Duffin46a26a82020-04-07 19:27:04 +010028
29 "android/soong/android"
Jiyong Parkc678ad32018-04-10 13:07:10 +090030)
31
Jooyung Han58f26ab2019-12-18 15:34:32 +090032const (
Paul Duffindd9d0742020-05-08 15:52:37 +010033 sdkXmlFileSuffix = ".xml"
34 permissionsTemplate = `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n` +
Jooyung Han624058e2019-12-24 18:38:06 +090035 `<!-- Copyright (C) 2018 The Android Open Source Project\n` +
36 `\n` +
Jiyong Parke3833882020-02-17 17:28:10 +090037 ` Licensed under the Apache License, Version 2.0 (the \"License\");\n` +
Jooyung Han624058e2019-12-24 18:38:06 +090038 ` you may not use this file except in compliance with the License.\n` +
39 ` You may obtain a copy of the License at\n` +
40 `\n` +
41 ` http://www.apache.org/licenses/LICENSE-2.0\n` +
42 `\n` +
43 ` Unless required by applicable law or agreed to in writing, software\n` +
Jiyong Parke3833882020-02-17 17:28:10 +090044 ` distributed under the License is distributed on an \"AS IS\" BASIS,\n` +
Jooyung Han624058e2019-12-24 18:38:06 +090045 ` WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n` +
46 ` See the License for the specific language governing permissions and\n` +
47 ` limitations under the License.\n` +
48 `-->\n` +
49 `<permissions>\n` +
Jiyong Parke3833882020-02-17 17:28:10 +090050 ` <library name=\"%s\" file=\"%s\"/>\n` +
Jooyung Han624058e2019-12-24 18:38:06 +090051 `</permissions>\n`
Jiyong Parkc678ad32018-04-10 13:07:10 +090052)
53
Paul Duffind1b3a922020-01-22 11:57:20 +000054// A tag to associated a dependency with a specific api scope.
55type scopeDependencyTag struct {
56 blueprint.BaseDependencyTag
57 name string
58 apiScope *apiScope
Paul Duffinc8782502020-04-29 20:45:27 +010059
60 // Function for extracting appropriate path information from the dependency.
61 depInfoExtractor func(paths *scopePaths, dep android.Module) error
62}
63
64// Extract tag specific information from the dependency.
65func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep android.Module, paths *scopePaths) {
66 err := tag.depInfoExtractor(paths, dep)
67 if err != nil {
68 ctx.ModuleErrorf("has an invalid {scopeDependencyTag: %s} dependency on module %s: %s", tag.name, ctx.OtherModuleName(dep), err.Error())
69 }
Paul Duffind1b3a922020-01-22 11:57:20 +000070}
71
72// Provides information about an api scope, e.g. public, system, test.
73type apiScope struct {
74 // The name of the api scope, e.g. public, system, test
75 name string
76
Paul Duffin97b53b82020-05-05 14:40:52 +010077 // The api scope that this scope extends.
78 extends *apiScope
79
Paul Duffin3375e352020-04-28 10:44:03 +010080 // The legacy enabled status for a specific scope can be dependent on other
81 // properties that have been specified on the library so it is provided by
82 // a function that can determine the status by examining those properties.
83 legacyEnabledStatus func(module *SdkLibrary) bool
84
85 // The default enabled status for non-legacy behavior, which is triggered by
86 // explicitly enabling at least one api scope.
87 defaultEnabledStatus bool
88
89 // Gets a pointer to the scope specific properties.
90 scopeSpecificProperties func(module *SdkLibrary) *ApiScopeProperties
91
Paul Duffin46a26a82020-04-07 19:27:04 +010092 // The name of the field in the dynamically created structure.
93 fieldName string
94
Paul Duffind1b3a922020-01-22 11:57:20 +000095 // The tag to use to depend on the stubs library module.
96 stubsTag scopeDependencyTag
97
Paul Duffin0ff08bd2020-04-29 13:30:54 +010098 // The tag to use to depend on the stubs source module (if separate from the API module).
99 stubsSourceTag scopeDependencyTag
100
101 // The tag to use to depend on the API file generating module (if separate from the stubs source module).
102 apiFileTag scopeDependencyTag
103
Paul Duffinc8782502020-04-29 20:45:27 +0100104 // The tag to use to depend on the stubs source and API module.
105 stubsSourceAndApiTag scopeDependencyTag
Paul Duffind1b3a922020-01-22 11:57:20 +0000106
107 // The scope specific prefix to add to the api file base of "current.txt" or "removed.txt".
108 apiFilePrefix string
109
110 // The scope specific prefix to add to the sdk library module name to construct a scope specific
111 // module name.
112 moduleSuffix string
113
Paul Duffind1b3a922020-01-22 11:57:20 +0000114 // SDK version that the stubs library is built against. Note that this is always
115 // *current. Older stubs library built with a numbered SDK version is created from
116 // the prebuilt jar.
117 sdkVersion string
Paul Duffin1fb487d2020-04-07 18:50:10 +0100118
119 // Extra arguments to pass to droidstubs for this scope.
120 droidstubsArgs []string
Anton Hansson6478ac12020-05-02 11:19:36 +0100121
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100122 // The args that must be passed to droidstubs to generate the stubs source
123 // for this scope.
124 //
125 // The stubs source must include the definitions of everything that is in this
126 // api scope and all the scopes that this one extends.
127 droidstubsArgsForGeneratingStubsSource []string
128
129 // The args that must be passed to droidstubs to generate the API for this scope.
130 //
131 // The API only includes the additional members that this scope adds over the scope
132 // that it extends.
133 droidstubsArgsForGeneratingApi []string
134
135 // True if the stubs source and api can be created by the same metalava invocation.
136 createStubsSourceAndApiTogether bool
137
Anton Hansson6478ac12020-05-02 11:19:36 +0100138 // Whether the api scope can be treated as unstable, and should skip compat checks.
139 unstable bool
Paul Duffind1b3a922020-01-22 11:57:20 +0000140}
141
142// Initialize a scope, creating and adding appropriate dependency tags
143func initApiScope(scope *apiScope) *apiScope {
Paul Duffinc8782502020-04-29 20:45:27 +0100144 name := scope.name
145 scope.fieldName = proptools.FieldNameForProperty(name)
Paul Duffind1b3a922020-01-22 11:57:20 +0000146 scope.stubsTag = scopeDependencyTag{
Paul Duffinc8782502020-04-29 20:45:27 +0100147 name: name + "-stubs",
148 apiScope: scope,
149 depInfoExtractor: (*scopePaths).extractStubsLibraryInfoFromDependency,
Paul Duffind1b3a922020-01-22 11:57:20 +0000150 }
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100151 scope.stubsSourceTag = scopeDependencyTag{
152 name: name + "-stubs-source",
153 apiScope: scope,
154 depInfoExtractor: (*scopePaths).extractStubsSourceInfoFromDep,
155 }
156 scope.apiFileTag = scopeDependencyTag{
157 name: name + "-api",
158 apiScope: scope,
159 depInfoExtractor: (*scopePaths).extractApiInfoFromDep,
160 }
Paul Duffinc8782502020-04-29 20:45:27 +0100161 scope.stubsSourceAndApiTag = scopeDependencyTag{
162 name: name + "-stubs-source-and-api",
163 apiScope: scope,
164 depInfoExtractor: (*scopePaths).extractStubsSourceAndApiInfoFromApiStubsProvider,
Paul Duffind1b3a922020-01-22 11:57:20 +0000165 }
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100166
167 // To get the args needed to generate the stubs source append all the args from
168 // this scope and all the scopes it extends as each set of args adds additional
169 // members to the stubs.
170 var stubsSourceArgs []string
171 for s := scope; s != nil; s = s.extends {
172 stubsSourceArgs = append(stubsSourceArgs, s.droidstubsArgs...)
173 }
174 scope.droidstubsArgsForGeneratingStubsSource = stubsSourceArgs
175
176 // Currently the args needed to generate the API are the same as the args
177 // needed to add additional members.
178 apiArgs := scope.droidstubsArgs
179 scope.droidstubsArgsForGeneratingApi = apiArgs
180
181 // If the args needed to generate the stubs and API are the same then they
182 // can be generated in a single invocation of metalava, otherwise they will
183 // need separate invocations.
184 scope.createStubsSourceAndApiTogether = reflect.DeepEqual(stubsSourceArgs, apiArgs)
185
Paul Duffind1b3a922020-01-22 11:57:20 +0000186 return scope
187}
188
Paul Duffinc3091c82020-05-08 14:16:20 +0100189func (scope *apiScope) stubsLibraryModuleName(baseName string) string {
Paul Duffindd9d0742020-05-08 15:52:37 +0100190 return baseName + ".stubs" + scope.moduleSuffix
Paul Duffind1b3a922020-01-22 11:57:20 +0000191}
192
Paul Duffinc8782502020-04-29 20:45:27 +0100193func (scope *apiScope) stubsSourceModuleName(baseName string) string {
Paul Duffindd9d0742020-05-08 15:52:37 +0100194 return baseName + ".stubs.source" + scope.moduleSuffix
Paul Duffind1b3a922020-01-22 11:57:20 +0000195}
196
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100197func (scope *apiScope) apiModuleName(baseName string) string {
Paul Duffindd9d0742020-05-08 15:52:37 +0100198 return baseName + ".api" + scope.moduleSuffix
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100199}
200
Paul Duffin3375e352020-04-28 10:44:03 +0100201func (scope *apiScope) String() string {
202 return scope.name
203}
204
Paul Duffind1b3a922020-01-22 11:57:20 +0000205type apiScopes []*apiScope
206
207func (scopes apiScopes) Strings(accessor func(*apiScope) string) []string {
208 var list []string
209 for _, scope := range scopes {
210 list = append(list, accessor(scope))
211 }
212 return list
213}
214
Jiyong Parkc678ad32018-04-10 13:07:10 +0900215var (
Paul Duffind1b3a922020-01-22 11:57:20 +0000216 apiScopePublic = initApiScope(&apiScope{
Paul Duffin3375e352020-04-28 10:44:03 +0100217 name: "public",
218
219 // Public scope is enabled by default for both legacy and non-legacy modes.
220 legacyEnabledStatus: func(module *SdkLibrary) bool {
221 return true
222 },
223 defaultEnabledStatus: true,
224
225 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
226 return &module.sdkLibraryProperties.Public
227 },
Paul Duffind1b3a922020-01-22 11:57:20 +0000228 sdkVersion: "current",
229 })
230 apiScopeSystem = initApiScope(&apiScope{
Paul Duffin3375e352020-04-28 10:44:03 +0100231 name: "system",
232 extends: apiScopePublic,
233 legacyEnabledStatus: (*SdkLibrary).generateTestAndSystemScopesByDefault,
234 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
235 return &module.sdkLibraryProperties.System
236 },
Anton Hansson6affb1f2020-04-28 16:47:41 +0100237 apiFilePrefix: "system-",
Paul Duffindd9d0742020-05-08 15:52:37 +0100238 moduleSuffix: ".system",
Anton Hansson6affb1f2020-04-28 16:47:41 +0100239 sdkVersion: "system_current",
Paul Duffin0d543642020-04-29 22:18:41 +0100240 droidstubsArgs: []string{"-showAnnotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)"},
Paul Duffind1b3a922020-01-22 11:57:20 +0000241 })
242 apiScopeTest = initApiScope(&apiScope{
Paul Duffin3375e352020-04-28 10:44:03 +0100243 name: "test",
244 extends: apiScopePublic,
245 legacyEnabledStatus: (*SdkLibrary).generateTestAndSystemScopesByDefault,
246 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
247 return &module.sdkLibraryProperties.Test
248 },
Anton Hansson6affb1f2020-04-28 16:47:41 +0100249 apiFilePrefix: "test-",
Paul Duffindd9d0742020-05-08 15:52:37 +0100250 moduleSuffix: ".test",
Anton Hansson6affb1f2020-04-28 16:47:41 +0100251 sdkVersion: "test_current",
252 droidstubsArgs: []string{"-showAnnotation android.annotation.TestApi"},
Anton Hansson6478ac12020-05-02 11:19:36 +0100253 unstable: true,
Paul Duffind1b3a922020-01-22 11:57:20 +0000254 })
Paul Duffin8f265b92020-04-28 14:13:56 +0100255 apiScopeModuleLib = initApiScope(&apiScope{
256 name: "module_lib",
257 extends: apiScopeSystem,
258 // Module_lib scope is disabled by default in legacy mode.
259 //
260 // Enabling this would break existing usages.
261 legacyEnabledStatus: func(module *SdkLibrary) bool {
262 return false
263 },
264 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
265 return &module.sdkLibraryProperties.Module_lib
266 },
267 apiFilePrefix: "module-lib-",
268 moduleSuffix: ".module_lib",
269 sdkVersion: "module_current",
270 droidstubsArgs: []string{
271 "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES\\)",
272 },
273 })
Paul Duffind1b3a922020-01-22 11:57:20 +0000274 allApiScopes = apiScopes{
275 apiScopePublic,
276 apiScopeSystem,
277 apiScopeTest,
Paul Duffin8f265b92020-04-28 14:13:56 +0100278 apiScopeModuleLib,
Paul Duffind1b3a922020-01-22 11:57:20 +0000279 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900280)
281
Jiyong Park82484c02018-04-23 21:41:26 +0900282var (
283 javaSdkLibrariesLock sync.Mutex
284)
285
Jiyong Parkc678ad32018-04-10 13:07:10 +0900286// TODO: these are big features that are currently missing
Jiyong Park1be96912018-05-28 18:02:19 +0900287// 1) disallowing linking to the runtime shared lib
288// 2) HTML generation
Jiyong Parkc678ad32018-04-10 13:07:10 +0900289
290func init() {
Paul Duffin43dc1cc2019-12-19 11:18:54 +0000291 RegisterSdkLibraryBuildComponents(android.InitRegistrationContext)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900292
Jiyong Park82484c02018-04-23 21:41:26 +0900293 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
294 javaSdkLibraries := javaSdkLibraries(ctx.Config())
295 sort.Strings(*javaSdkLibraries)
296 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
297 })
Paul Duffindd46f712020-02-10 13:37:10 +0000298
299 // Register sdk member types.
300 android.RegisterSdkMemberType(&sdkLibrarySdkMemberType{
301 android.SdkMemberTypeBase{
302 PropertyName: "java_sdk_libs",
303 SupportsSdk: true,
304 },
305 })
Jiyong Parkc678ad32018-04-10 13:07:10 +0900306}
307
Paul Duffin43dc1cc2019-12-19 11:18:54 +0000308func RegisterSdkLibraryBuildComponents(ctx android.RegistrationContext) {
309 ctx.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
310 ctx.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory)
311}
312
Paul Duffin3375e352020-04-28 10:44:03 +0100313// Properties associated with each api scope.
314type ApiScopeProperties struct {
315 // Indicates whether the api surface is generated.
316 //
317 // If this is set for any scope then all scopes must explicitly specify if they
318 // are enabled. This is to prevent new usages from depending on legacy behavior.
319 //
320 // Otherwise, if this is not set for any scope then the default behavior is
321 // scope specific so please refer to the scope specific property documentation.
322 Enabled *bool
Paul Duffin87a05a32020-05-12 11:50:28 +0100323
324 // The sdk_version to use for building the stubs.
325 //
326 // If not specified then it will use an sdk_version determined as follows:
327 // 1) If the sdk_version specified on the java_sdk_library is none then this
328 // will be none. This is used for java_sdk_library instances that are used
329 // to create stubs that contribute to the core_current sdk version.
330 // 2) Otherwise, it is assumed that this library extends but does not contribute
331 // directly to a specific sdk_version and so this uses the sdk_version appropriate
332 // for the api scope. e.g. public will use sdk_version: current, system will use
333 // sdk_version: system_current, etc.
334 //
335 // This does not affect the sdk_version used for either generating the stubs source
336 // or the API file. They both have to use the same sdk_version as is used for
337 // compiling the implementation library.
338 Sdk_version *string
Paul Duffin3375e352020-04-28 10:44:03 +0100339}
340
Jiyong Parkc678ad32018-04-10 13:07:10 +0900341type sdkLibraryProperties struct {
Paul Duffin4911a892020-04-29 23:35:13 +0100342 // Visibility for stubs library modules. If not specified then defaults to the
343 // visibility property.
344 Stubs_library_visibility []string
345
346 // Visibility for stubs source modules. If not specified then defaults to the
347 // visibility property.
348 Stubs_source_visibility []string
349
Sundong Ahnf043cf62018-06-25 16:04:37 +0900350 // List of Java libraries that will be in the classpath when building stubs
351 Stub_only_libs []string `android:"arch_variant"`
352
Paul Duffin7a586d32019-12-30 17:09:34 +0000353 // list of package names that will be documented and publicized as API.
354 // This allows the API to be restricted to a subset of the source files provided.
355 // If this is unspecified then all the source files will be treated as being part
356 // of the API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900357 Api_packages []string
358
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900359 // list of package names that must be hidden from the API
360 Hidden_api_packages []string
361
Paul Duffin749f98f2019-12-30 17:23:46 +0000362 // the relative path to the directory containing the api specification files.
363 // Defaults to "api".
364 Api_dir *string
365
Paul Duffin43db9be2019-12-30 17:35:49 +0000366 // If set to true there is no runtime library.
367 Api_only *bool
368
Paul Duffin11512472019-02-11 15:55:17 +0000369 // local files that are used within user customized droiddoc options.
370 Droiddoc_option_files []string
371
372 // additional droiddoc options
373 // Available variables for substitution:
374 //
375 // $(location <label>): the path to the droiddoc_option_files with name <label>
Sundong Ahndd567f92018-07-31 17:19:11 +0900376 Droiddoc_options []string
377
Sundong Ahn054b19a2018-10-19 13:46:09 +0900378 // a list of top-level directories containing files to merge qualifier annotations
379 // (i.e. those intended to be included in the stubs written) from.
380 Merge_annotations_dirs []string
381
382 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
383 Merge_inclusion_annotations_dirs []string
384
385 // If set to true, the path of dist files is apistubs/core. Defaults to false.
386 Core_lib *bool
387
Sundong Ahn80a87b32019-05-13 15:02:50 +0900388 // don't create dist rules.
389 No_dist *bool `blueprint:"mutated"`
390
Paul Duffin3375e352020-04-28 10:44:03 +0100391 // indicates whether system and test apis should be generated.
392 Generate_system_and_test_apis bool `blueprint:"mutated"`
393
394 // The properties specific to the public api scope
395 //
396 // Unless explicitly specified by using public.enabled the public api scope is
397 // enabled by default in both legacy and non-legacy mode.
398 Public ApiScopeProperties
399
400 // The properties specific to the system api scope
401 //
402 // In legacy mode the system api scope is enabled by default when sdk_version
403 // is set to something other than "none".
404 //
405 // In non-legacy mode the system api scope is disabled by default.
406 System ApiScopeProperties
407
408 // The properties specific to the test api scope
409 //
410 // In legacy mode the test api scope is enabled by default when sdk_version
411 // is set to something other than "none".
412 //
413 // In non-legacy mode the test api scope is disabled by default.
414 Test ApiScopeProperties
Paul Duffin37e0b772019-12-30 17:20:10 +0000415
Paul Duffin8f265b92020-04-28 14:13:56 +0100416 // The properties specific to the module_lib api scope
417 //
418 // Unless explicitly specified by using test.enabled the module_lib api scope is
419 // disabled by default.
420 Module_lib ApiScopeProperties
421
Paul Duffin160fe412020-05-10 19:32:20 +0100422 // Properties related to api linting.
423 Api_lint struct {
424 // Enable api linting.
425 Enabled *bool
426 }
427
Jiyong Parkc678ad32018-04-10 13:07:10 +0900428 // TODO: determines whether to create HTML doc or not
429 //Html_doc *bool
430}
431
Paul Duffind1b3a922020-01-22 11:57:20 +0000432type scopePaths struct {
Paul Duffin1fd005d2020-04-09 01:08:11 +0100433 stubsHeaderPath android.Paths
434 stubsImplPath android.Paths
435 currentApiFilePath android.Path
436 removedApiFilePath android.Path
437 stubsSrcJar android.Path
Paul Duffind1b3a922020-01-22 11:57:20 +0000438}
439
Paul Duffinc8782502020-04-29 20:45:27 +0100440func (paths *scopePaths) extractStubsLibraryInfoFromDependency(dep android.Module) error {
441 if lib, ok := dep.(Dependency); ok {
442 paths.stubsHeaderPath = lib.HeaderJars()
443 paths.stubsImplPath = lib.ImplementationJars()
444 return nil
445 } else {
446 return fmt.Errorf("expected module that implements Dependency, e.g. java_library")
447 }
448}
449
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100450func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action func(provider ApiStubsProvider)) error {
451 if apiStubsProvider, ok := dep.(ApiStubsProvider); ok {
452 action(apiStubsProvider)
Paul Duffinc8782502020-04-29 20:45:27 +0100453 return nil
454 } else {
455 return fmt.Errorf("expected module that implements ApiStubsProvider, e.g. droidstubs")
456 }
457}
458
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100459func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider) {
460 paths.currentApiFilePath = provider.ApiFilePath()
461 paths.removedApiFilePath = provider.RemovedApiFilePath()
462}
463
464func (paths *scopePaths) extractApiInfoFromDep(dep android.Module) error {
465 return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
466 paths.extractApiInfoFromApiStubsProvider(provider)
467 })
468}
469
470func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsProvider) {
471 paths.stubsSrcJar = provider.StubsSrcJar()
472}
473
474func (paths *scopePaths) extractStubsSourceInfoFromDep(dep android.Module) error {
475 return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
476 paths.extractStubsSourceInfoFromApiStubsProviders(provider)
477 })
478}
479
480func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(dep android.Module) error {
481 return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
482 paths.extractApiInfoFromApiStubsProvider(provider)
483 paths.extractStubsSourceInfoFromApiStubsProviders(provider)
484 })
485}
486
487type commonToSdkLibraryAndImportProperties struct {
Paul Duffin1b1e8062020-05-08 13:44:43 +0100488 // The naming scheme to use for the components that this module creates.
489 //
Paul Duffin6c9c5fc2020-05-08 15:36:30 +0100490 // If not specified then it defaults to "default". The other allowable value is
491 // "framework-modules" which matches the scheme currently used by framework modules
492 // for the equivalent components represented as separate Soong modules.
Paul Duffin1b1e8062020-05-08 13:44:43 +0100493 //
494 // This is a temporary mechanism to simplify conversion from separate modules for each
495 // component that follow a different naming pattern to the default one.
496 //
497 // TODO(b/155480189) - Remove once naming inconsistencies have been resolved.
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100498 Naming_scheme *string
499}
500
Paul Duffin56d44902020-01-31 13:36:25 +0000501// Common code between sdk library and sdk library import
502type commonToSdkLibraryAndImport struct {
Paul Duffinc3091c82020-05-08 14:16:20 +0100503 moduleBase *android.ModuleBase
504
Paul Duffin56d44902020-01-31 13:36:25 +0000505 scopePaths map[*apiScope]*scopePaths
Paul Duffin1b1e8062020-05-08 13:44:43 +0100506
507 namingScheme sdkLibraryComponentNamingScheme
508
509 commonProperties commonToSdkLibraryAndImportProperties
Paul Duffin56d44902020-01-31 13:36:25 +0000510}
511
Paul Duffinc3091c82020-05-08 14:16:20 +0100512func (c *commonToSdkLibraryAndImport) initCommon(moduleBase *android.ModuleBase) {
513 c.moduleBase = moduleBase
Paul Duffin1b1e8062020-05-08 13:44:43 +0100514
515 moduleBase.AddProperties(&c.commonProperties)
516}
517
518func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android.DefaultableHookContext) bool {
519 schemeProperty := proptools.StringDefault(c.commonProperties.Naming_scheme, "default")
520 switch schemeProperty {
521 case "default":
522 c.namingScheme = &defaultNamingScheme{}
Paul Duffin6c9c5fc2020-05-08 15:36:30 +0100523 case "framework-modules":
524 c.namingScheme = &frameworkModulesNamingScheme{}
Paul Duffin1b1e8062020-05-08 13:44:43 +0100525 default:
526 ctx.PropertyErrorf("naming_scheme", "expected 'default' but was %q", schemeProperty)
527 return false
528 }
529
530 return true
Paul Duffinc3091c82020-05-08 14:16:20 +0100531}
532
533// Name of the java_library module that compiles the stubs source.
534func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope) string {
Paul Duffin1b1e8062020-05-08 13:44:43 +0100535 return c.namingScheme.stubsLibraryModuleName(apiScope, c.moduleBase.BaseModuleName())
Paul Duffinc3091c82020-05-08 14:16:20 +0100536}
537
538// Name of the droidstubs module that generates the stubs source and may also
539// generate/check the API.
540func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) string {
Paul Duffin1b1e8062020-05-08 13:44:43 +0100541 return c.namingScheme.stubsSourceModuleName(apiScope, c.moduleBase.BaseModuleName())
Paul Duffinc3091c82020-05-08 14:16:20 +0100542}
543
544// Name of the droidstubs module that generates/checks the API. Only used if it
545// requires different arts to the stubs source generating module.
546func (c *commonToSdkLibraryAndImport) apiModuleName(apiScope *apiScope) string {
Paul Duffin1b1e8062020-05-08 13:44:43 +0100547 return c.namingScheme.apiModuleName(apiScope, c.moduleBase.BaseModuleName())
Paul Duffinc3091c82020-05-08 14:16:20 +0100548}
549
Paul Duffin56d44902020-01-31 13:36:25 +0000550func (c *commonToSdkLibraryAndImport) getScopePaths(scope *apiScope) *scopePaths {
551 if c.scopePaths == nil {
552 c.scopePaths = make(map[*apiScope]*scopePaths)
553 }
554 paths := c.scopePaths[scope]
555 if paths == nil {
556 paths = &scopePaths{}
557 c.scopePaths[scope] = paths
558 }
559
560 return paths
561}
562
Inseob Kimc0907f12019-02-08 21:00:45 +0900563type SdkLibrary struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900564 Library
Jiyong Parkc678ad32018-04-10 13:07:10 +0900565
Sundong Ahn054b19a2018-10-19 13:46:09 +0900566 sdkLibraryProperties sdkLibraryProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900567
Paul Duffin3375e352020-04-28 10:44:03 +0100568 // Map from api scope to the scope specific property structure.
569 scopeToProperties map[*apiScope]*ApiScopeProperties
570
Paul Duffin56d44902020-01-31 13:36:25 +0000571 commonToSdkLibraryAndImport
Jiyong Parkc678ad32018-04-10 13:07:10 +0900572}
573
Inseob Kimc0907f12019-02-08 21:00:45 +0900574var _ Dependency = (*SdkLibrary)(nil)
575var _ SdkLibraryDependency = (*SdkLibrary)(nil)
Colin Cross897d2ed2019-02-11 14:03:51 -0800576
Paul Duffin3375e352020-04-28 10:44:03 +0100577func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool {
578 return module.sdkLibraryProperties.Generate_system_and_test_apis
579}
580
581func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext) apiScopes {
582 // Check to see if any scopes have been explicitly enabled. If any have then all
583 // must be.
584 anyScopesExplicitlyEnabled := false
585 for _, scope := range allApiScopes {
586 scopeProperties := module.scopeToProperties[scope]
587 if scopeProperties.Enabled != nil {
588 anyScopesExplicitlyEnabled = true
589 break
590 }
Paul Duffind1b3a922020-01-22 11:57:20 +0000591 }
Paul Duffin3375e352020-04-28 10:44:03 +0100592
593 var generatedScopes apiScopes
594 enabledScopes := make(map[*apiScope]struct{})
595 for _, scope := range allApiScopes {
596 scopeProperties := module.scopeToProperties[scope]
597 // If any scopes are explicitly enabled then ignore the legacy enabled status.
598 // This is to ensure that any new usages of this module type do not rely on legacy
599 // behaviour.
600 defaultEnabledStatus := false
601 if anyScopesExplicitlyEnabled {
602 defaultEnabledStatus = scope.defaultEnabledStatus
603 } else {
604 defaultEnabledStatus = scope.legacyEnabledStatus(module)
605 }
606 enabled := proptools.BoolDefault(scopeProperties.Enabled, defaultEnabledStatus)
607 if enabled {
608 enabledScopes[scope] = struct{}{}
609 generatedScopes = append(generatedScopes, scope)
610 }
611 }
612
613 // Now check to make sure that any scope that is extended by an enabled scope is also
614 // enabled.
615 for _, scope := range allApiScopes {
616 if _, ok := enabledScopes[scope]; ok {
617 extends := scope.extends
618 if extends != nil {
619 if _, ok := enabledScopes[extends]; !ok {
620 ctx.ModuleErrorf("enabled api scope %q depends on disabled scope %q", scope, extends)
621 }
622 }
623 }
624 }
625
626 return generatedScopes
Paul Duffind1b3a922020-01-22 11:57:20 +0000627}
628
Paul Duffine74ac732020-02-06 13:51:46 +0000629var xmlPermissionsFileTag = dependencyTag{name: "xml-permissions-file"}
630
Jiyong Parke3833882020-02-17 17:28:10 +0900631func IsXmlPermissionsFileDepTag(depTag blueprint.DependencyTag) bool {
632 if dt, ok := depTag.(dependencyTag); ok {
633 return dt == xmlPermissionsFileTag
634 }
635 return false
636}
637
Inseob Kimc0907f12019-02-08 21:00:45 +0900638func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
Paul Duffin3375e352020-04-28 10:44:03 +0100639 for _, apiScope := range module.getGeneratedApiScopes(ctx) {
Paul Duffind1b3a922020-01-22 11:57:20 +0000640 // Add dependencies to the stubs library
Paul Duffinc3091c82020-05-08 14:16:20 +0100641 ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope))
Paul Duffind1b3a922020-01-22 11:57:20 +0000642
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100643 // If the stubs source and API cannot be generated together then add an additional dependency on
644 // the API module.
645 if apiScope.createStubsSourceAndApiTogether {
646 // Add a dependency on the stubs source in order to access both stubs source and api information.
Paul Duffinc3091c82020-05-08 14:16:20 +0100647 ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.stubsSourceModuleName(apiScope))
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100648 } else {
649 // Add separate dependencies on the creators of the stubs source files and the API.
Paul Duffinc3091c82020-05-08 14:16:20 +0100650 ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope))
651 ctx.AddVariationDependencies(nil, apiScope.apiFileTag, module.apiModuleName(apiScope))
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100652 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900653 }
654
Paul Duffine74ac732020-02-06 13:51:46 +0000655 if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
656 // Add dependency to the rule for generating the xml permissions file
Jiyong Parke3833882020-02-17 17:28:10 +0900657 ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlFileName())
Paul Duffine74ac732020-02-06 13:51:46 +0000658 }
659
Sundong Ahn054b19a2018-10-19 13:46:09 +0900660 module.Library.deps(ctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900661}
662
Inseob Kimc0907f12019-02-08 21:00:45 +0900663func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Paul Duffin43db9be2019-12-30 17:35:49 +0000664 // Don't build an implementation library if this is api only.
665 if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
666 module.Library.GenerateAndroidBuildActions(ctx)
667 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900668
Sundong Ahn57368eb2018-07-06 11:20:23 +0900669 // Record the paths to the header jars of the library (stubs and impl).
Paul Duffind1b3a922020-01-22 11:57:20 +0000670 // When this java_sdk_library is depended upon from others via "libs" property,
Jiyong Parkc678ad32018-04-10 13:07:10 +0900671 // the recorded paths will be returned depending on the link type of the caller.
672 ctx.VisitDirectDeps(func(to android.Module) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900673 tag := ctx.OtherModuleDependencyTag(to)
674
Paul Duffinc8782502020-04-29 20:45:27 +0100675 // Extract information from any of the scope specific dependencies.
676 if scopeTag, ok := tag.(scopeDependencyTag); ok {
677 apiScope := scopeTag.apiScope
678 scopePaths := module.getScopePaths(apiScope)
679
680 // Extract information from the dependency. The exact information extracted
681 // is determined by the nature of the dependency which is determined by the tag.
682 scopeTag.extractDepInfo(ctx, to, scopePaths)
Sundong Ahn20e998b2018-07-24 11:19:26 +0900683 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900684 })
685}
686
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900687func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
Paul Duffin43db9be2019-12-30 17:35:49 +0000688 if proptools.Bool(module.sdkLibraryProperties.Api_only) {
689 return nil
690 }
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900691 entriesList := module.Library.AndroidMkEntries()
692 entries := &entriesList[0]
Jaewoong Jungb0c127c2019-08-29 14:56:03 -0700693 entries.Required = append(entries.Required, module.xmlFileName())
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900694 return entriesList
Jiyong Park82484c02018-04-23 21:41:26 +0900695}
696
Jiyong Parkc678ad32018-04-10 13:07:10 +0900697// Module name of the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900698func (module *SdkLibrary) implName() string {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900699 return module.BaseModuleName()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900700}
701
Jiyong Parkc678ad32018-04-10 13:07:10 +0900702// Module name of the XML file for the lib
Inseob Kimc0907f12019-02-08 21:00:45 +0900703func (module *SdkLibrary) xmlFileName() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900704 return module.BaseModuleName() + sdkXmlFileSuffix
705}
706
Anton Hansson5fd5d242020-03-27 19:43:19 +0000707// The dist path of the stub artifacts
708func (module *SdkLibrary) apiDistPath(apiScope *apiScope) string {
709 if module.ModuleBase.Owner() != "" {
710 return path.Join("apistubs", module.ModuleBase.Owner(), apiScope.name)
711 } else if Bool(module.sdkLibraryProperties.Core_lib) {
712 return path.Join("apistubs", "core", apiScope.name)
713 } else {
714 return path.Join("apistubs", "android", apiScope.name)
715 }
716}
717
Paul Duffin12ceb462019-12-24 20:31:31 +0000718// Get the sdk version for use when compiling the stubs library.
Paul Duffin780c5f42020-05-12 15:52:55 +0100719func (module *SdkLibrary) sdkVersionForStubsLibrary(mctx android.EarlyModuleContext, apiScope *apiScope) string {
Paul Duffin87a05a32020-05-12 11:50:28 +0100720 scopeProperties := module.scopeToProperties[apiScope]
721 if scopeProperties.Sdk_version != nil {
722 return proptools.String(scopeProperties.Sdk_version)
723 }
724
Paul Duffin12ceb462019-12-24 20:31:31 +0000725 sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
726 if sdkDep.hasStandardLibs() {
727 // If building against a standard sdk then use the sdk version appropriate for the scope.
Paul Duffind1b3a922020-01-22 11:57:20 +0000728 return apiScope.sdkVersion
Paul Duffin12ceb462019-12-24 20:31:31 +0000729 } else {
730 // Otherwise, use no system module.
731 return "none"
732 }
733}
734
Paul Duffind1b3a922020-01-22 11:57:20 +0000735func (module *SdkLibrary) latestApiFilegroupName(apiScope *apiScope) string {
736 return ":" + module.BaseModuleName() + ".api." + apiScope.name + ".latest"
Jiyong Park58c518b2018-05-12 22:29:12 +0900737}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900738
Paul Duffind1b3a922020-01-22 11:57:20 +0000739func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope *apiScope) string {
740 return ":" + module.BaseModuleName() + "-removed.api." + apiScope.name + ".latest"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900741}
742
743// Creates a static java library that has API stubs
Paul Duffinf0229202020-04-29 16:47:28 +0100744func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900745 props := struct {
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900746 Name *string
Paul Duffin4911a892020-04-29 23:35:13 +0100747 Visibility []string
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900748 Srcs []string
Paul Duffin367ab912019-12-23 19:40:36 +0000749 Installable *bool
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900750 Sdk_version *string
Paul Duffin12ceb462019-12-24 20:31:31 +0000751 System_modules *string
Paul Duffinab8da5d2020-02-07 16:12:04 +0000752 Patch_module *string
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900753 Libs []string
754 Soc_specific *bool
755 Device_specific *bool
756 Product_specific *bool
757 System_ext_specific *bool
758 Compile_dex *bool
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900759 Java_version *string
760 Product_variables struct {
Jiyong Park82484c02018-04-23 21:41:26 +0900761 Pdk struct {
762 Enabled *bool
763 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900764 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900765 Openjdk9 struct {
766 Srcs []string
767 Javacflags []string
768 }
Anton Hansson5fd5d242020-03-27 19:43:19 +0000769 Dist struct {
770 Targets []string
771 Dest *string
772 Dir *string
773 Tag *string
774 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900775 }{}
776
Paul Duffinc3091c82020-05-08 14:16:20 +0100777 props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
Paul Duffin4911a892020-04-29 23:35:13 +0100778
779 // If stubs_library_visibility is not set then the created module will use the
780 // visibility of this module.
781 visibility := module.sdkLibraryProperties.Stubs_library_visibility
782 props.Visibility = visibility
783
Jiyong Parkc678ad32018-04-10 13:07:10 +0900784 // sources are generated from the droiddoc
Paul Duffinc3091c82020-05-08 14:16:20 +0100785 props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
Paul Duffin12ceb462019-12-24 20:31:31 +0000786 sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
Paul Duffin52d398a2019-06-11 12:31:14 +0100787 props.Sdk_version = proptools.StringPtr(sdkVersion)
Paul Duffin12ceb462019-12-24 20:31:31 +0000788 props.System_modules = module.Library.Module.deviceProperties.System_modules
Paul Duffinab8da5d2020-02-07 16:12:04 +0000789 props.Patch_module = module.Library.Module.properties.Patch_module
Paul Duffin367ab912019-12-23 19:40:36 +0000790 props.Installable = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900791 props.Libs = module.sdkLibraryProperties.Stub_only_libs
Jiyong Park82484c02018-04-23 21:41:26 +0900792 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900793 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
794 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
795 props.Java_version = module.Library.Module.properties.Java_version
796 if module.Library.Module.deviceProperties.Compile_dex != nil {
797 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900798 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900799
800 if module.SocSpecific() {
801 props.Soc_specific = proptools.BoolPtr(true)
802 } else if module.DeviceSpecific() {
803 props.Device_specific = proptools.BoolPtr(true)
804 } else if module.ProductSpecific() {
805 props.Product_specific = proptools.BoolPtr(true)
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900806 } else if module.SystemExtSpecific() {
807 props.System_ext_specific = proptools.BoolPtr(true)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900808 }
Anton Hansson5fd5d242020-03-27 19:43:19 +0000809 // Dist the class jar artifact for sdk builds.
810 if !Bool(module.sdkLibraryProperties.No_dist) {
811 props.Dist.Targets = []string{"sdk", "win_sdk"}
812 props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.BaseModuleName()))
813 props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
814 props.Dist.Tag = proptools.StringPtr(".jar")
815 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900816
Colin Cross84dfc3d2019-09-25 11:33:01 -0700817 mctx.CreateModule(LibraryFactory, &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900818}
819
Paul Duffin6d0886e2020-04-07 18:49:53 +0100820// Creates a droidstubs module that creates stubs source files from the given full source
Paul Duffinc8782502020-04-29 20:45:27 +0100821// files and also updates and checks the API specification files.
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100822func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookContext, apiScope *apiScope, name string, createStubSources, createApi bool, scopeSpecificDroidstubsArgs []string) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900823 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900824 Name *string
Paul Duffin4911a892020-04-29 23:35:13 +0100825 Visibility []string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900826 Srcs []string
827 Installable *bool
Paul Duffin52d398a2019-06-11 12:31:14 +0100828 Sdk_version *string
Paul Duffin12ceb462019-12-24 20:31:31 +0000829 System_modules *string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900830 Libs []string
Paul Duffin11512472019-02-11 15:55:17 +0000831 Arg_files []string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900832 Args *string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900833 Java_version *string
834 Merge_annotations_dirs []string
835 Merge_inclusion_annotations_dirs []string
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100836 Generate_stubs *bool
Sundong Ahn054b19a2018-10-19 13:46:09 +0900837 Check_api struct {
Inseob Kim38449af2019-02-28 14:24:05 +0900838 Current ApiToCheck
839 Last_released ApiToCheck
840 Ignore_missing_latest_api *bool
Paul Duffin160fe412020-05-10 19:32:20 +0100841
842 Api_lint struct {
843 Enabled *bool
844 New_since *string
845 Baseline_file *string
846 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900847 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900848 Aidl struct {
849 Include_dirs []string
850 Local_include_dirs []string
851 }
Anton Hansson5fd5d242020-03-27 19:43:19 +0000852 Dist struct {
853 Targets []string
854 Dest *string
855 Dir *string
856 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900857 }{}
858
Paul Duffin7b78b4d2020-04-28 14:08:32 +0100859 // The stubs source processing uses the same compile time classpath when extracting the
860 // API from the implementation library as it does when compiling it. i.e. the same
861 // * sdk version
862 // * system_modules
863 // * libs (static_libs/libs)
Paul Duffin250e6192019-06-07 10:44:37 +0100864
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100865 props.Name = proptools.StringPtr(name)
Paul Duffin4911a892020-04-29 23:35:13 +0100866
867 // If stubs_source_visibility is not set then the created module will use the
868 // visibility of this module.
869 visibility := module.sdkLibraryProperties.Stubs_source_visibility
870 props.Visibility = visibility
871
Sundong Ahn054b19a2018-10-19 13:46:09 +0900872 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
Paul Duffin7b78b4d2020-04-28 14:08:32 +0100873 props.Sdk_version = module.Library.Module.deviceProperties.Sdk_version
Paul Duffin12ceb462019-12-24 20:31:31 +0000874 props.System_modules = module.Library.Module.deviceProperties.System_modules
Jiyong Parkc678ad32018-04-10 13:07:10 +0900875 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900876 // A droiddoc module has only one Libs property and doesn't distinguish between
877 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900878 props.Libs = module.Library.Module.properties.Libs
879 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
880 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
881 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
Sundong Ahn054b19a2018-10-19 13:46:09 +0900882 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900883
Sundong Ahn054b19a2018-10-19 13:46:09 +0900884 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
885 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
886
Paul Duffin6d0886e2020-04-07 18:49:53 +0100887 droidstubsArgs := []string{}
Paul Duffin235ffff2019-12-24 10:41:30 +0000888 if len(module.sdkLibraryProperties.Api_packages) != 0 {
Paul Duffin6d0886e2020-04-07 18:49:53 +0100889 droidstubsArgs = append(droidstubsArgs, "--stub-packages "+strings.Join(module.sdkLibraryProperties.Api_packages, ":"))
Paul Duffin235ffff2019-12-24 10:41:30 +0000890 }
891 if len(module.sdkLibraryProperties.Hidden_api_packages) != 0 {
Paul Duffin6d0886e2020-04-07 18:49:53 +0100892 droidstubsArgs = append(droidstubsArgs,
Paul Duffin235ffff2019-12-24 10:41:30 +0000893 android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package "))
894 }
Paul Duffin6d0886e2020-04-07 18:49:53 +0100895 droidstubsArgs = append(droidstubsArgs, module.sdkLibraryProperties.Droiddoc_options...)
Paul Duffin235ffff2019-12-24 10:41:30 +0000896 disabledWarnings := []string{
897 "MissingPermission",
898 "BroadcastBehavior",
899 "HiddenSuperclass",
900 "DeprecationMismatch",
901 "UnavailableSymbol",
902 "SdkConstant",
903 "HiddenTypeParameter",
904 "Todo",
905 "Typo",
906 }
Paul Duffin6d0886e2020-04-07 18:49:53 +0100907 droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900908
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100909 if !createStubSources {
910 // Stubs are not required.
911 props.Generate_stubs = proptools.BoolPtr(false)
912 }
913
Paul Duffin1fb487d2020-04-07 18:50:10 +0100914 // Add in scope specific arguments.
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100915 droidstubsArgs = append(droidstubsArgs, scopeSpecificDroidstubsArgs...)
Paul Duffin11512472019-02-11 15:55:17 +0000916 props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
Paul Duffin6d0886e2020-04-07 18:49:53 +0100917 props.Args = proptools.StringPtr(strings.Join(droidstubsArgs, " "))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900918
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100919 if createApi {
920 // List of APIs identified from the provided source files are created. They are later
921 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
922 // last-released (a.k.a numbered) list of API.
923 currentApiFileName := apiScope.apiFilePrefix + "current.txt"
924 removedApiFileName := apiScope.apiFilePrefix + "removed.txt"
925 apiDir := module.getApiDir()
926 currentApiFileName = path.Join(apiDir, currentApiFileName)
927 removedApiFileName = path.Join(apiDir, removedApiFileName)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900928
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100929 // check against the not-yet-release API
930 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
931 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900932
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100933 if !apiScope.unstable {
934 // check against the latest released API
935 latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
936 props.Check_api.Last_released.Api_file = latestApiFilegroupName
937 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
938 module.latestRemovedApiFilegroupName(apiScope))
939 props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
Paul Duffin160fe412020-05-10 19:32:20 +0100940
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100941 if proptools.Bool(module.sdkLibraryProperties.Api_lint.Enabled) {
942 // Enable api lint.
943 props.Check_api.Api_lint.Enabled = proptools.BoolPtr(true)
944 props.Check_api.Api_lint.New_since = latestApiFilegroupName
Paul Duffin160fe412020-05-10 19:32:20 +0100945
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100946 // If it exists then pass a lint-baseline.txt through to droidstubs.
947 baselinePath := path.Join(apiDir, apiScope.apiFilePrefix+"lint-baseline.txt")
948 baselinePathRelativeToRoot := path.Join(mctx.ModuleDir(), baselinePath)
949 paths, err := mctx.GlobWithDeps(baselinePathRelativeToRoot, nil)
950 if err != nil {
951 mctx.ModuleErrorf("error checking for presence of %s: %s", baselinePathRelativeToRoot, err)
952 }
953 if len(paths) == 1 {
954 props.Check_api.Api_lint.Baseline_file = proptools.StringPtr(baselinePath)
955 } else if len(paths) != 0 {
956 mctx.ModuleErrorf("error checking for presence of %s: expected one path, found: %v", baselinePathRelativeToRoot, paths)
957 }
Paul Duffin160fe412020-05-10 19:32:20 +0100958 }
959 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900960
Paul Duffin0ff08bd2020-04-29 13:30:54 +0100961 // Dist the api txt artifact for sdk builds.
962 if !Bool(module.sdkLibraryProperties.No_dist) {
963 props.Dist.Targets = []string{"sdk", "win_sdk"}
964 props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.txt", module.BaseModuleName()))
965 props.Dist.Dir = proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
966 }
Anton Hansson5fd5d242020-03-27 19:43:19 +0000967 }
968
Colin Cross84dfc3d2019-09-25 11:33:01 -0700969 mctx.CreateModule(DroidstubsFactory, &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900970}
971
Jooyung Han5e9013b2020-03-10 06:23:13 +0900972func (module *SdkLibrary) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool {
973 depTag := mctx.OtherModuleDependencyTag(dep)
974 if depTag == xmlPermissionsFileTag {
975 return true
976 }
977 return module.Library.DepIsInSameApex(mctx, dep)
978}
979
Jiyong Parkc678ad32018-04-10 13:07:10 +0900980// Creates the xml file that publicizes the runtime library
Paul Duffinf0229202020-04-29 16:47:28 +0100981func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
Jiyong Parke3833882020-02-17 17:28:10 +0900982 props := struct {
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900983 Name *string
Jiyong Parke3833882020-02-17 17:28:10 +0900984 Lib_name *string
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900985 Soc_specific *bool
986 Device_specific *bool
987 Product_specific *bool
988 System_ext_specific *bool
Jooyung Han5e9013b2020-03-10 06:23:13 +0900989 Apex_available []string
Jiyong Parke3833882020-02-17 17:28:10 +0900990 }{
Jooyung Han5e9013b2020-03-10 06:23:13 +0900991 Name: proptools.StringPtr(module.xmlFileName()),
992 Lib_name: proptools.StringPtr(module.BaseModuleName()),
993 Apex_available: module.ApexProperties.Apex_available,
Jiyong Parkc678ad32018-04-10 13:07:10 +0900994 }
Jiyong Parke3833882020-02-17 17:28:10 +0900995
996 if module.SocSpecific() {
997 props.Soc_specific = proptools.BoolPtr(true)
998 } else if module.DeviceSpecific() {
999 props.Device_specific = proptools.BoolPtr(true)
1000 } else if module.ProductSpecific() {
1001 props.Product_specific = proptools.BoolPtr(true)
1002 } else if module.SystemExtSpecific() {
1003 props.System_ext_specific = proptools.BoolPtr(true)
1004 }
1005
1006 mctx.CreateModule(sdkLibraryXmlFactory, &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +09001007}
1008
Paul Duffin50061512020-01-21 16:31:05 +00001009func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s sdkSpec) android.Paths {
Jiyong Park6a927c42020-01-21 02:03:43 +09001010 var ver sdkVersion
1011 var kind sdkKind
1012 if s.usePrebuilt(ctx) {
1013 ver = s.version
1014 kind = s.kind
Jiyong Parkc678ad32018-04-10 13:07:10 +09001015 } else {
Jiyong Park6a927c42020-01-21 02:03:43 +09001016 // We don't have prebuilt SDK for the specific sdkVersion.
1017 // Instead of breaking the build, fallback to use "system_current"
1018 ver = sdkVersionCurrent
1019 kind = sdkSystem
Sundong Ahn054b19a2018-10-19 13:46:09 +09001020 }
Jiyong Park6a927c42020-01-21 02:03:43 +09001021
1022 dir := filepath.Join("prebuilts", "sdk", ver.String(), kind.String())
Paul Duffin50061512020-01-21 16:31:05 +00001023 jar := filepath.Join(dir, baseName+".jar")
Sundong Ahn054b19a2018-10-19 13:46:09 +09001024 jarPath := android.ExistentPathForSource(ctx, jar)
Sundong Ahnae418ac2019-02-28 15:01:28 +09001025 if !jarPath.Valid() {
Colin Cross07c88562020-01-07 09:34:44 -08001026 if ctx.Config().AllowMissingDependencies() {
1027 return android.Paths{android.PathForSource(ctx, jar)}
1028 } else {
Jiyong Park6a927c42020-01-21 02:03:43 +09001029 ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", s.raw, jar)
Colin Cross07c88562020-01-07 09:34:44 -08001030 }
Sundong Ahnae418ac2019-02-28 15:01:28 +09001031 return nil
1032 }
Sundong Ahn054b19a2018-10-19 13:46:09 +09001033 return android.Paths{jarPath.Path()}
1034}
1035
Paul Duffind1b3a922020-01-22 11:57:20 +00001036func (module *SdkLibrary) sdkJars(
1037 ctx android.BaseModuleContext,
1038 sdkVersion sdkSpec,
1039 headerJars bool) android.Paths {
1040
Paul Duffin50061512020-01-21 16:31:05 +00001041 // If a specific numeric version has been requested then use prebuilt versions of the sdk.
1042 if sdkVersion.version.isNumbered() {
1043 return PrebuiltJars(ctx, module.BaseModuleName(), sdkVersion)
Sundong Ahn054b19a2018-10-19 13:46:09 +09001044 } else {
Paul Duffind1b3a922020-01-22 11:57:20 +00001045 if !sdkVersion.specified() {
1046 if headerJars {
1047 return module.Library.HeaderJars()
1048 } else {
1049 return module.Library.ImplementationJars()
1050 }
1051 }
Paul Duffin726d23c2020-01-22 16:30:37 +00001052 var apiScope *apiScope
Jiyong Park6a927c42020-01-21 02:03:43 +09001053 switch sdkVersion.kind {
1054 case sdkSystem:
Paul Duffin726d23c2020-01-22 16:30:37 +00001055 apiScope = apiScopeSystem
1056 case sdkTest:
1057 apiScope = apiScopeTest
Jiyong Park6a927c42020-01-21 02:03:43 +09001058 case sdkPrivate:
Sundong Ahn054b19a2018-10-19 13:46:09 +09001059 return module.Library.HeaderJars()
Jiyong Park6a927c42020-01-21 02:03:43 +09001060 default:
Paul Duffin726d23c2020-01-22 16:30:37 +00001061 apiScope = apiScopePublic
Paul Duffind1b3a922020-01-22 11:57:20 +00001062 }
1063
Paul Duffin726d23c2020-01-22 16:30:37 +00001064 paths := module.getScopePaths(apiScope)
Paul Duffind1b3a922020-01-22 11:57:20 +00001065 if headerJars {
1066 return paths.stubsHeaderPath
1067 } else {
1068 return paths.stubsImplPath
Sundong Ahn054b19a2018-10-19 13:46:09 +09001069 }
Jiyong Parkc678ad32018-04-10 13:07:10 +09001070 }
1071}
1072
Sundong Ahn241cd372018-07-13 16:16:44 +09001073// to satisfy SdkLibraryDependency interface
Paul Duffind1b3a922020-01-22 11:57:20 +00001074func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
1075 return module.sdkJars(ctx, sdkVersion, true /*headerJars*/)
1076}
1077
1078// to satisfy SdkLibraryDependency interface
Jiyong Park6a927c42020-01-21 02:03:43 +09001079func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
Paul Duffind1b3a922020-01-22 11:57:20 +00001080 return module.sdkJars(ctx, sdkVersion, false /*headerJars*/)
Sundong Ahn241cd372018-07-13 16:16:44 +09001081}
1082
Sundong Ahn80a87b32019-05-13 15:02:50 +09001083func (module *SdkLibrary) SetNoDist() {
1084 module.sdkLibraryProperties.No_dist = proptools.BoolPtr(true)
1085}
1086
Colin Cross571cccf2019-02-04 11:22:08 -08001087var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
1088
Jiyong Park82484c02018-04-23 21:41:26 +09001089func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -08001090 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +09001091 return &[]string{}
1092 }).(*[]string)
1093}
1094
Paul Duffin749f98f2019-12-30 17:23:46 +00001095func (module *SdkLibrary) getApiDir() string {
1096 return proptools.StringDefault(module.sdkLibraryProperties.Api_dir, "api")
1097}
1098
Jiyong Parkc678ad32018-04-10 13:07:10 +09001099// For a java_sdk_library module, create internal modules for stubs, docs,
1100// runtime libs and xml file. If requested, the stubs and docs are created twice
1101// once for public API level and once for system API level
Paul Duffinf0229202020-04-29 16:47:28 +01001102func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookContext) {
1103 // If the module has been disabled then don't create any child modules.
1104 if !module.Enabled() {
1105 return
1106 }
1107
Inseob Kim6e93ac92019-03-21 17:43:49 +09001108 if len(module.Library.Module.properties.Srcs) == 0 {
Inseob Kimc0907f12019-02-08 21:00:45 +09001109 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
Jooyung Han58f26ab2019-12-18 15:34:32 +09001110 return
Inseob Kimc0907f12019-02-08 21:00:45 +09001111 }
1112
Paul Duffin37e0b772019-12-30 17:20:10 +00001113 // If this builds against standard libraries (i.e. is not part of the core libraries)
1114 // then assume it provides both system and test apis. Otherwise, assume it does not and
1115 // also assume it does not contribute to the dist build.
1116 sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
1117 hasSystemAndTestApis := sdkDep.hasStandardLibs()
Paul Duffin3375e352020-04-28 10:44:03 +01001118 module.sdkLibraryProperties.Generate_system_and_test_apis = hasSystemAndTestApis
Paul Duffin37e0b772019-12-30 17:20:10 +00001119 module.sdkLibraryProperties.No_dist = proptools.BoolPtr(!hasSystemAndTestApis)
1120
Inseob Kim8098faa2019-03-18 10:19:51 +09001121 missing_current_api := false
1122
Paul Duffin3375e352020-04-28 10:44:03 +01001123 generatedScopes := module.getGeneratedApiScopes(mctx)
Paul Duffind1b3a922020-01-22 11:57:20 +00001124
Paul Duffin749f98f2019-12-30 17:23:46 +00001125 apiDir := module.getApiDir()
Paul Duffin3375e352020-04-28 10:44:03 +01001126 for _, scope := range generatedScopes {
Inseob Kim8098faa2019-03-18 10:19:51 +09001127 for _, api := range []string{"current.txt", "removed.txt"} {
Paul Duffind1b3a922020-01-22 11:57:20 +00001128 path := path.Join(mctx.ModuleDir(), apiDir, scope.apiFilePrefix+api)
Inseob Kim8098faa2019-03-18 10:19:51 +09001129 p := android.ExistentPathForSource(mctx, path)
1130 if !p.Valid() {
1131 mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
1132 missing_current_api = true
1133 }
1134 }
1135 }
1136
1137 if missing_current_api {
1138 script := "build/soong/scripts/gen-java-current-api-files.sh"
1139 p := android.ExistentPathForSource(mctx, script)
1140
1141 if !p.Valid() {
1142 panic(fmt.Sprintf("script file %s doesn't exist", script))
1143 }
1144
1145 mctx.ModuleErrorf("One or more current api files are missing. "+
1146 "You can update them by:\n"+
Paul Duffin37e0b772019-12-30 17:20:10 +00001147 "%s %q %s && m update-api",
Paul Duffind1b3a922020-01-22 11:57:20 +00001148 script, filepath.Join(mctx.ModuleDir(), apiDir),
Paul Duffin3375e352020-04-28 10:44:03 +01001149 strings.Join(generatedScopes.Strings(func(s *apiScope) string { return s.apiFilePrefix }), " "))
Inseob Kim8098faa2019-03-18 10:19:51 +09001150 return
1151 }
1152
Paul Duffin3375e352020-04-28 10:44:03 +01001153 for _, scope := range generatedScopes {
Paul Duffin0ff08bd2020-04-29 13:30:54 +01001154 stubsSourceArgs := scope.droidstubsArgsForGeneratingStubsSource
Paul Duffinc3091c82020-05-08 14:16:20 +01001155 stubsSourceModuleName := module.stubsSourceModuleName(scope)
Paul Duffin0ff08bd2020-04-29 13:30:54 +01001156
1157 // If the args needed to generate the stubs and API are the same then they
1158 // can be generated in a single invocation of metalava, otherwise they will
1159 // need separate invocations.
1160 if scope.createStubsSourceAndApiTogether {
1161 // Use the stubs source name for legacy reasons.
1162 module.createStubsSourcesAndApi(mctx, scope, stubsSourceModuleName, true, true, stubsSourceArgs)
1163 } else {
1164 module.createStubsSourcesAndApi(mctx, scope, stubsSourceModuleName, true, false, stubsSourceArgs)
1165
1166 apiArgs := scope.droidstubsArgsForGeneratingApi
Paul Duffinc3091c82020-05-08 14:16:20 +01001167 apiName := module.apiModuleName(scope)
Paul Duffin0ff08bd2020-04-29 13:30:54 +01001168 module.createStubsSourcesAndApi(mctx, scope, apiName, false, true, apiArgs)
1169 }
1170
Paul Duffind1b3a922020-01-22 11:57:20 +00001171 module.createStubsLibrary(mctx, scope)
Inseob Kimc0907f12019-02-08 21:00:45 +09001172 }
1173
Paul Duffin43db9be2019-12-30 17:35:49 +00001174 if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
1175 // for runtime
1176 module.createXmlFile(mctx)
1177
1178 // record java_sdk_library modules so that they are exported to make
1179 javaSdkLibraries := javaSdkLibraries(mctx.Config())
1180 javaSdkLibrariesLock.Lock()
1181 defer javaSdkLibrariesLock.Unlock()
1182 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
1183 }
Inseob Kimc0907f12019-02-08 21:00:45 +09001184}
1185
1186func (module *SdkLibrary) InitSdkLibraryProperties() {
Sundong Ahn054b19a2018-10-19 13:46:09 +09001187 module.AddProperties(
1188 &module.sdkLibraryProperties,
1189 &module.Library.Module.properties,
1190 &module.Library.Module.dexpreoptProperties,
1191 &module.Library.Module.deviceProperties,
1192 &module.Library.Module.protoProperties,
1193 )
1194
1195 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
1196 module.Library.Module.deviceProperties.IsSDKLibrary = true
Inseob Kimc0907f12019-02-08 21:00:45 +09001197}
Sundong Ahn054b19a2018-10-19 13:46:09 +09001198
Paul Duffin1b1e8062020-05-08 13:44:43 +01001199// Defines how to name the individual component modules the sdk library creates.
1200type sdkLibraryComponentNamingScheme interface {
1201 stubsLibraryModuleName(scope *apiScope, baseName string) string
1202
1203 stubsSourceModuleName(scope *apiScope, baseName string) string
1204
1205 apiModuleName(scope *apiScope, baseName string) string
1206}
1207
1208type defaultNamingScheme struct {
1209}
1210
1211func (s *defaultNamingScheme) stubsLibraryModuleName(scope *apiScope, baseName string) string {
1212 return scope.stubsLibraryModuleName(baseName)
1213}
1214
1215func (s *defaultNamingScheme) stubsSourceModuleName(scope *apiScope, baseName string) string {
1216 return scope.stubsSourceModuleName(baseName)
1217}
1218
1219func (s *defaultNamingScheme) apiModuleName(scope *apiScope, baseName string) string {
1220 return scope.apiModuleName(baseName)
1221}
1222
1223var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil)
1224
Paul Duffin6c9c5fc2020-05-08 15:36:30 +01001225type frameworkModulesNamingScheme struct {
1226}
1227
1228func (s *frameworkModulesNamingScheme) moduleSuffix(scope *apiScope) string {
1229 suffix := scope.name
1230 if scope == apiScopeModuleLib {
1231 suffix = "module_libs_"
1232 }
1233 return suffix
1234}
1235
1236func (s *frameworkModulesNamingScheme) stubsLibraryModuleName(scope *apiScope, baseName string) string {
1237 return fmt.Sprintf("%s-stubs-%sapi", baseName, s.moduleSuffix(scope))
1238}
1239
1240func (s *frameworkModulesNamingScheme) stubsSourceModuleName(scope *apiScope, baseName string) string {
1241 return fmt.Sprintf("%s-stubs-srcs-%sapi", baseName, s.moduleSuffix(scope))
1242}
1243
1244func (s *frameworkModulesNamingScheme) apiModuleName(scope *apiScope, baseName string) string {
1245 return fmt.Sprintf("%s-api-%sapi", baseName, s.moduleSuffix(scope))
1246}
1247
1248var _ sdkLibraryComponentNamingScheme = (*frameworkModulesNamingScheme)(nil)
1249
Jaewoong Jung4f158ee2019-07-11 10:05:35 -07001250// java_sdk_library is a special Java library that provides optional platform APIs to apps.
1251// In practice, it can be viewed as a combination of several modules: 1) stubs library that clients
1252// are linked against to, 2) droiddoc module that internally generates API stubs source files,
1253// 3) the real runtime shared library that implements the APIs, and 4) XML file for adding
1254// the runtime lib to the classpath at runtime if requested via <uses-library>.
Inseob Kimc0907f12019-02-08 21:00:45 +09001255func SdkLibraryFactory() android.Module {
1256 module := &SdkLibrary{}
Paul Duffinc3091c82020-05-08 14:16:20 +01001257
1258 // Initialize information common between source and prebuilt.
1259 module.initCommon(&module.ModuleBase)
1260
Inseob Kimc0907f12019-02-08 21:00:45 +09001261 module.InitSdkLibraryProperties()
Jooyung Han58f26ab2019-12-18 15:34:32 +09001262 android.InitApexModule(module)
Sundong Ahn054b19a2018-10-19 13:46:09 +09001263 InitJavaModule(module, android.HostAndDeviceSupported)
Paul Duffin3375e352020-04-28 10:44:03 +01001264
1265 // Initialize the map from scope to scope specific properties.
1266 scopeToProperties := make(map[*apiScope]*ApiScopeProperties)
1267 for _, scope := range allApiScopes {
1268 scopeToProperties[scope] = scope.scopeSpecificProperties(module)
1269 }
1270 module.scopeToProperties = scopeToProperties
1271
Paul Duffin4911a892020-04-29 23:35:13 +01001272 // Add the properties containing visibility rules so that they are checked.
1273 android.AddVisibilityProperty(module, "stubs_library_visibility", &module.sdkLibraryProperties.Stubs_library_visibility)
1274 android.AddVisibilityProperty(module, "stubs_source_visibility", &module.sdkLibraryProperties.Stubs_source_visibility)
1275
Paul Duffin1b1e8062020-05-08 13:44:43 +01001276 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
1277 if module.initCommonAfterDefaultsApplied(ctx) {
1278 module.CreateInternalModules(ctx)
1279 }
1280 })
Jiyong Parkc678ad32018-04-10 13:07:10 +09001281 return module
1282}
Colin Cross79c7c262019-04-17 11:11:46 -07001283
1284//
1285// SDK library prebuilts
1286//
1287
Paul Duffin56d44902020-01-31 13:36:25 +00001288// Properties associated with each api scope.
1289type sdkLibraryScopeProperties struct {
Colin Cross79c7c262019-04-17 11:11:46 -07001290 Jars []string `android:"path"`
1291
1292 Sdk_version *string
1293
Colin Cross79c7c262019-04-17 11:11:46 -07001294 // List of shared java libs that this module has dependencies to
1295 Libs []string
Paul Duffin3d1248c2020-04-09 00:10:17 +01001296
Paul Duffinc8782502020-04-29 20:45:27 +01001297 // The stubs source.
Paul Duffin3d1248c2020-04-09 00:10:17 +01001298 Stub_srcs []string `android:"path"`
Paul Duffin1fd005d2020-04-09 01:08:11 +01001299
1300 // The current.txt
1301 Current_api string `android:"path"`
1302
1303 // The removed.txt
1304 Removed_api string `android:"path"`
Colin Cross79c7c262019-04-17 11:11:46 -07001305}
1306
Paul Duffin56d44902020-01-31 13:36:25 +00001307type sdkLibraryImportProperties struct {
Paul Duffinfcfd7912020-01-31 17:54:30 +00001308 // List of shared java libs, common to all scopes, that this module has
1309 // dependencies to
1310 Libs []string
Paul Duffin56d44902020-01-31 13:36:25 +00001311}
1312
Colin Cross79c7c262019-04-17 11:11:46 -07001313type sdkLibraryImport struct {
1314 android.ModuleBase
1315 android.DefaultableModuleBase
1316 prebuilt android.Prebuilt
Paul Duffindd46f712020-02-10 13:37:10 +00001317 android.ApexModuleBase
1318 android.SdkBase
Colin Cross79c7c262019-04-17 11:11:46 -07001319
1320 properties sdkLibraryImportProperties
1321
Paul Duffin46a26a82020-04-07 19:27:04 +01001322 // Map from api scope to the scope specific property structure.
1323 scopeProperties map[*apiScope]*sdkLibraryScopeProperties
1324
Paul Duffin56d44902020-01-31 13:36:25 +00001325 commonToSdkLibraryAndImport
Colin Cross79c7c262019-04-17 11:11:46 -07001326}
1327
1328var _ SdkLibraryDependency = (*sdkLibraryImport)(nil)
1329
Paul Duffin46a26a82020-04-07 19:27:04 +01001330// The type of a structure that contains a field of type sdkLibraryScopeProperties
1331// for each apiscope in allApiScopes, e.g. something like:
1332// struct {
1333// Public sdkLibraryScopeProperties
1334// System sdkLibraryScopeProperties
1335// ...
1336// }
1337var allScopeStructType = createAllScopePropertiesStructType()
1338
1339// Dynamically create a structure type for each apiscope in allApiScopes.
1340func createAllScopePropertiesStructType() reflect.Type {
1341 var fields []reflect.StructField
1342 for _, apiScope := range allApiScopes {
1343 field := reflect.StructField{
1344 Name: apiScope.fieldName,
1345 Type: reflect.TypeOf(sdkLibraryScopeProperties{}),
1346 }
1347 fields = append(fields, field)
1348 }
1349
1350 return reflect.StructOf(fields)
1351}
1352
1353// Create an instance of the scope specific structure type and return a map
1354// from apiscope to a pointer to each scope specific field.
1355func createPropertiesInstance() (interface{}, map[*apiScope]*sdkLibraryScopeProperties) {
1356 allScopePropertiesPtr := reflect.New(allScopeStructType)
1357 allScopePropertiesStruct := allScopePropertiesPtr.Elem()
1358 scopeProperties := make(map[*apiScope]*sdkLibraryScopeProperties)
1359
1360 for _, apiScope := range allApiScopes {
1361 field := allScopePropertiesStruct.FieldByName(apiScope.fieldName)
1362 scopeProperties[apiScope] = field.Addr().Interface().(*sdkLibraryScopeProperties)
1363 }
1364
1365 return allScopePropertiesPtr.Interface(), scopeProperties
1366}
1367
Jaewoong Jung4f158ee2019-07-11 10:05:35 -07001368// java_sdk_library_import imports a prebuilt java_sdk_library.
Colin Cross79c7c262019-04-17 11:11:46 -07001369func sdkLibraryImportFactory() android.Module {
1370 module := &sdkLibraryImport{}
1371
Paul Duffin46a26a82020-04-07 19:27:04 +01001372 allScopeProperties, scopeToProperties := createPropertiesInstance()
1373 module.scopeProperties = scopeToProperties
1374 module.AddProperties(&module.properties, allScopeProperties)
Colin Cross79c7c262019-04-17 11:11:46 -07001375
Paul Duffinc3091c82020-05-08 14:16:20 +01001376 // Initialize information common between source and prebuilt.
1377 module.initCommon(&module.ModuleBase)
1378
Paul Duffin0bdcb272020-02-06 15:24:57 +00001379 android.InitPrebuiltModule(module, &[]string{""})
Paul Duffindd46f712020-02-10 13:37:10 +00001380 android.InitApexModule(module)
1381 android.InitSdkAwareModule(module)
Colin Cross79c7c262019-04-17 11:11:46 -07001382 InitJavaModule(module, android.HostAndDeviceSupported)
1383
Paul Duffin1b1e8062020-05-08 13:44:43 +01001384 module.SetDefaultableHook(func(mctx android.DefaultableHookContext) {
1385 if module.initCommonAfterDefaultsApplied(mctx) {
1386 module.createInternalModules(mctx)
1387 }
1388 })
Colin Cross79c7c262019-04-17 11:11:46 -07001389 return module
1390}
1391
1392func (module *sdkLibraryImport) Prebuilt() *android.Prebuilt {
1393 return &module.prebuilt
1394}
1395
1396func (module *sdkLibraryImport) Name() string {
1397 return module.prebuilt.Name(module.ModuleBase.Name())
1398}
1399
Paul Duffin6e7ecbf2020-05-08 15:01:19 +01001400func (module *sdkLibraryImport) createInternalModules(mctx android.DefaultableHookContext) {
Colin Cross79c7c262019-04-17 11:11:46 -07001401
Paul Duffin50061512020-01-21 16:31:05 +00001402 // If the build is configured to use prebuilts then force this to be preferred.
1403 if mctx.Config().UnbundledBuildUsePrebuiltSdks() {
1404 module.prebuilt.ForcePrefer()
1405 }
1406
Paul Duffin46a26a82020-04-07 19:27:04 +01001407 for apiScope, scopeProperties := range module.scopeProperties {
Paul Duffin56d44902020-01-31 13:36:25 +00001408 if len(scopeProperties.Jars) == 0 {
1409 continue
1410 }
1411
Paul Duffinbbb546b2020-04-09 00:07:11 +01001412 module.createJavaImportForStubs(mctx, apiScope, scopeProperties)
Paul Duffin3d1248c2020-04-09 00:10:17 +01001413
1414 module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties)
Paul Duffin56d44902020-01-31 13:36:25 +00001415 }
Colin Cross79c7c262019-04-17 11:11:46 -07001416
1417 javaSdkLibraries := javaSdkLibraries(mctx.Config())
1418 javaSdkLibrariesLock.Lock()
1419 defer javaSdkLibrariesLock.Unlock()
1420 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
1421}
1422
Paul Duffin6e7ecbf2020-05-08 15:01:19 +01001423func (module *sdkLibraryImport) createJavaImportForStubs(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
Paul Duffinbbb546b2020-04-09 00:07:11 +01001424 // Creates a java import for the jar with ".stubs" suffix
1425 props := struct {
1426 Name *string
1427 Soc_specific *bool
1428 Device_specific *bool
1429 Product_specific *bool
1430 System_ext_specific *bool
1431 Sdk_version *string
1432 Libs []string
1433 Jars []string
1434 Prefer *bool
1435 }{}
Paul Duffinc3091c82020-05-08 14:16:20 +01001436 props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
Paul Duffinbbb546b2020-04-09 00:07:11 +01001437 props.Sdk_version = scopeProperties.Sdk_version
1438 // Prepend any of the libs from the legacy public properties to the libs for each of the
1439 // scopes to avoid having to duplicate them in each scope.
1440 props.Libs = append(module.properties.Libs, scopeProperties.Libs...)
1441 props.Jars = scopeProperties.Jars
1442 if module.SocSpecific() {
1443 props.Soc_specific = proptools.BoolPtr(true)
1444 } else if module.DeviceSpecific() {
1445 props.Device_specific = proptools.BoolPtr(true)
1446 } else if module.ProductSpecific() {
1447 props.Product_specific = proptools.BoolPtr(true)
1448 } else if module.SystemExtSpecific() {
1449 props.System_ext_specific = proptools.BoolPtr(true)
1450 }
Paul Duffin38b57852020-05-13 16:08:09 +01001451 // The imports are preferred if the java_sdk_library_import is preferred.
1452 props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer())
Paul Duffinbbb546b2020-04-09 00:07:11 +01001453 mctx.CreateModule(ImportFactory, &props)
1454}
1455
Paul Duffin6e7ecbf2020-05-08 15:01:19 +01001456func (module *sdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
Paul Duffin3d1248c2020-04-09 00:10:17 +01001457 props := struct {
Paul Duffin38b57852020-05-13 16:08:09 +01001458 Name *string
1459 Srcs []string
1460 Prefer *bool
Paul Duffin3d1248c2020-04-09 00:10:17 +01001461 }{}
Paul Duffinc3091c82020-05-08 14:16:20 +01001462 props.Name = proptools.StringPtr(module.stubsSourceModuleName(apiScope))
Paul Duffin3d1248c2020-04-09 00:10:17 +01001463 props.Srcs = scopeProperties.Stub_srcs
1464 mctx.CreateModule(PrebuiltStubsSourcesFactory, &props)
Paul Duffin38b57852020-05-13 16:08:09 +01001465
1466 // The stubs source is preferred if the java_sdk_library_import is preferred.
1467 props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer())
Paul Duffin3d1248c2020-04-09 00:10:17 +01001468}
1469
Colin Cross79c7c262019-04-17 11:11:46 -07001470func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
Paul Duffin46a26a82020-04-07 19:27:04 +01001471 for apiScope, scopeProperties := range module.scopeProperties {
Paul Duffin56d44902020-01-31 13:36:25 +00001472 if len(scopeProperties.Jars) == 0 {
1473 continue
1474 }
1475
1476 // Add dependencies to the prebuilt stubs library
Paul Duffinc3091c82020-05-08 14:16:20 +01001477 ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope))
Paul Duffin56d44902020-01-31 13:36:25 +00001478 }
Colin Cross79c7c262019-04-17 11:11:46 -07001479}
1480
1481func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1482 // Record the paths to the prebuilt stubs library.
1483 ctx.VisitDirectDeps(func(to android.Module) {
1484 tag := ctx.OtherModuleDependencyTag(to)
1485
Paul Duffin56d44902020-01-31 13:36:25 +00001486 if lib, ok := to.(Dependency); ok {
1487 if scopeTag, ok := tag.(scopeDependencyTag); ok {
1488 apiScope := scopeTag.apiScope
1489 scopePaths := module.getScopePaths(apiScope)
1490 scopePaths.stubsHeaderPath = lib.HeaderJars()
1491 }
Colin Cross79c7c262019-04-17 11:11:46 -07001492 }
1493 })
1494}
1495
Paul Duffin56d44902020-01-31 13:36:25 +00001496func (module *sdkLibraryImport) sdkJars(
1497 ctx android.BaseModuleContext,
1498 sdkVersion sdkSpec) android.Paths {
1499
Paul Duffin50061512020-01-21 16:31:05 +00001500 // If a specific numeric version has been requested then use prebuilt versions of the sdk.
1501 if sdkVersion.version.isNumbered() {
1502 return PrebuiltJars(ctx, module.BaseModuleName(), sdkVersion)
1503 }
1504
Paul Duffin56d44902020-01-31 13:36:25 +00001505 var apiScope *apiScope
1506 switch sdkVersion.kind {
1507 case sdkSystem:
1508 apiScope = apiScopeSystem
1509 case sdkTest:
1510 apiScope = apiScopeTest
1511 default:
1512 apiScope = apiScopePublic
1513 }
1514
1515 paths := module.getScopePaths(apiScope)
1516 return paths.stubsHeaderPath
1517}
1518
Colin Cross79c7c262019-04-17 11:11:46 -07001519// to satisfy SdkLibraryDependency interface
Jiyong Park6a927c42020-01-21 02:03:43 +09001520func (module *sdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
Colin Cross79c7c262019-04-17 11:11:46 -07001521 // This module is just a wrapper for the prebuilt stubs.
Paul Duffin56d44902020-01-31 13:36:25 +00001522 return module.sdkJars(ctx, sdkVersion)
Colin Cross79c7c262019-04-17 11:11:46 -07001523}
1524
1525// to satisfy SdkLibraryDependency interface
Jiyong Park6a927c42020-01-21 02:03:43 +09001526func (module *sdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
Colin Cross79c7c262019-04-17 11:11:46 -07001527 // This module is just a wrapper for the stubs.
Paul Duffin56d44902020-01-31 13:36:25 +00001528 return module.sdkJars(ctx, sdkVersion)
Colin Cross79c7c262019-04-17 11:11:46 -07001529}
Jiyong Parke3833882020-02-17 17:28:10 +09001530
1531//
1532// java_sdk_library_xml
1533//
1534type sdkLibraryXml struct {
1535 android.ModuleBase
1536 android.DefaultableModuleBase
1537 android.ApexModuleBase
1538
1539 properties sdkLibraryXmlProperties
1540
1541 outputFilePath android.OutputPath
1542 installDirPath android.InstallPath
1543}
1544
1545type sdkLibraryXmlProperties struct {
1546 // canonical name of the lib
1547 Lib_name *string
1548}
1549
1550// java_sdk_library_xml builds the permission xml file for a java_sdk_library.
1551// Not to be used directly by users. java_sdk_library internally uses this.
1552func sdkLibraryXmlFactory() android.Module {
1553 module := &sdkLibraryXml{}
1554
1555 module.AddProperties(&module.properties)
1556
1557 android.InitApexModule(module)
1558 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
1559
1560 return module
1561}
1562
1563// from android.PrebuiltEtcModule
1564func (module *sdkLibraryXml) SubDir() string {
1565 return "permissions"
1566}
1567
1568// from android.PrebuiltEtcModule
1569func (module *sdkLibraryXml) OutputFile() android.OutputPath {
1570 return module.outputFilePath
1571}
1572
1573// from android.ApexModule
1574func (module *sdkLibraryXml) AvailableFor(what string) bool {
1575 return true
1576}
1577
1578func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) {
1579 // do nothing
1580}
1581
1582// File path to the runtime implementation library
1583func (module *sdkLibraryXml) implPath() string {
1584 implName := proptools.String(module.properties.Lib_name)
1585 if apexName := module.ApexName(); apexName != "" {
1586 // TODO(b/146468504): ApexName() is only a soong module name, not apex name.
1587 // In most cases, this works fine. But when apex_name is set or override_apex is used
1588 // this can be wrong.
1589 return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, implName)
1590 }
1591 partition := "system"
1592 if module.SocSpecific() {
1593 partition = "vendor"
1594 } else if module.DeviceSpecific() {
1595 partition = "odm"
1596 } else if module.ProductSpecific() {
1597 partition = "product"
1598 } else if module.SystemExtSpecific() {
1599 partition = "system_ext"
1600 }
1601 return "/" + partition + "/framework/" + implName + ".jar"
1602}
1603
1604func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1605 libName := proptools.String(module.properties.Lib_name)
1606 xmlContent := fmt.Sprintf(permissionsTemplate, libName, module.implPath())
1607
1608 module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath
1609 rule := android.NewRuleBuilder()
1610 rule.Command().
1611 Text("/bin/bash -c \"echo -e '" + xmlContent + "'\" > ").
1612 Output(module.outputFilePath)
1613
1614 rule.Build(pctx, ctx, "java_sdk_xml", "Permission XML")
1615
1616 module.installDirPath = android.PathForModuleInstall(ctx, "etc", module.SubDir())
1617}
1618
1619func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
1620 if !module.IsForPlatform() {
1621 return []android.AndroidMkEntries{android.AndroidMkEntries{
1622 Disabled: true,
1623 }}
1624 }
1625
1626 return []android.AndroidMkEntries{android.AndroidMkEntries{
1627 Class: "ETC",
1628 OutputFile: android.OptionalPathForPath(module.outputFilePath),
1629 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
1630 func(entries *android.AndroidMkEntries) {
1631 entries.SetString("LOCAL_MODULE_TAGS", "optional")
1632 entries.SetString("LOCAL_MODULE_PATH", module.installDirPath.ToMakePath().String())
1633 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", module.outputFilePath.Base())
1634 },
1635 },
1636 }}
1637}
Paul Duffindd46f712020-02-10 13:37:10 +00001638
1639type sdkLibrarySdkMemberType struct {
1640 android.SdkMemberTypeBase
1641}
1642
1643func (s *sdkLibrarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
1644 mctx.AddVariationDependencies(nil, dependencyTag, names...)
1645}
1646
1647func (s *sdkLibrarySdkMemberType) IsInstance(module android.Module) bool {
1648 _, ok := module.(*SdkLibrary)
1649 return ok
1650}
1651
1652func (s *sdkLibrarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
1653 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_sdk_library_import")
1654}
1655
1656func (s *sdkLibrarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
1657 return &sdkLibrarySdkMemberProperties{}
1658}
1659
1660type sdkLibrarySdkMemberProperties struct {
1661 android.SdkMemberPropertiesBase
1662
1663 // Scope to per scope properties.
1664 Scopes map[*apiScope]scopeProperties
1665
1666 // Additional libraries that the exported stubs libraries depend upon.
1667 Libs []string
Paul Duffin3d1248c2020-04-09 00:10:17 +01001668
1669 // The Java stubs source files.
1670 Stub_srcs []string
Paul Duffindd46f712020-02-10 13:37:10 +00001671}
1672
1673type scopeProperties struct {
Paul Duffin1fd005d2020-04-09 01:08:11 +01001674 Jars android.Paths
1675 StubsSrcJar android.Path
1676 CurrentApiFile android.Path
1677 RemovedApiFile android.Path
1678 SdkVersion string
Paul Duffindd46f712020-02-10 13:37:10 +00001679}
1680
1681func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
1682 sdk := variant.(*SdkLibrary)
1683
1684 s.Scopes = make(map[*apiScope]scopeProperties)
1685 for _, apiScope := range allApiScopes {
1686 paths := sdk.getScopePaths(apiScope)
1687 jars := paths.stubsImplPath
1688 if len(jars) > 0 {
1689 properties := scopeProperties{}
1690 properties.Jars = jars
Paul Duffin780c5f42020-05-12 15:52:55 +01001691 properties.SdkVersion = sdk.sdkVersionForStubsLibrary(ctx.SdkModuleContext(), apiScope)
Paul Duffin3d1248c2020-04-09 00:10:17 +01001692 properties.StubsSrcJar = paths.stubsSrcJar
Paul Duffin1fd005d2020-04-09 01:08:11 +01001693 properties.CurrentApiFile = paths.currentApiFilePath
1694 properties.RemovedApiFile = paths.removedApiFilePath
Paul Duffindd46f712020-02-10 13:37:10 +00001695 s.Scopes[apiScope] = properties
1696 }
1697 }
1698
1699 s.Libs = sdk.properties.Libs
1700}
1701
1702func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
1703 for _, apiScope := range allApiScopes {
1704 if properties, ok := s.Scopes[apiScope]; ok {
1705 scopeSet := propertySet.AddPropertySet(apiScope.name)
1706
Paul Duffin3d1248c2020-04-09 00:10:17 +01001707 scopeDir := filepath.Join("sdk_library", s.OsPrefix(), apiScope.name)
1708
Paul Duffindd46f712020-02-10 13:37:10 +00001709 var jars []string
1710 for _, p := range properties.Jars {
Paul Duffin3d1248c2020-04-09 00:10:17 +01001711 dest := filepath.Join(scopeDir, ctx.Name()+"-stubs.jar")
Paul Duffindd46f712020-02-10 13:37:10 +00001712 ctx.SnapshotBuilder().CopyToSnapshot(p, dest)
1713 jars = append(jars, dest)
1714 }
1715 scopeSet.AddProperty("jars", jars)
1716
Paul Duffin3d1248c2020-04-09 00:10:17 +01001717 // Merge the stubs source jar into the snapshot zip so that when it is unpacked
1718 // the source files are also unpacked.
1719 snapshotRelativeDir := filepath.Join(scopeDir, ctx.Name()+"_stub_sources")
1720 ctx.SnapshotBuilder().UnzipToSnapshot(properties.StubsSrcJar, snapshotRelativeDir)
1721 scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir})
1722
Paul Duffin1fd005d2020-04-09 01:08:11 +01001723 if properties.CurrentApiFile != nil {
1724 currentApiSnapshotPath := filepath.Join(scopeDir, ctx.Name()+".txt")
1725 ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, currentApiSnapshotPath)
1726 scopeSet.AddProperty("current_api", currentApiSnapshotPath)
1727 }
1728
1729 if properties.RemovedApiFile != nil {
1730 removedApiSnapshotPath := filepath.Join(scopeDir, ctx.Name()+"-removed.txt")
1731 ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, removedApiSnapshotPath)
1732 scopeSet.AddProperty("removed_api", removedApiSnapshotPath)
1733 }
1734
Paul Duffindd46f712020-02-10 13:37:10 +00001735 if properties.SdkVersion != "" {
1736 scopeSet.AddProperty("sdk_version", properties.SdkVersion)
1737 }
1738 }
1739 }
1740
1741 if len(s.Libs) > 0 {
1742 propertySet.AddPropertyWithTag("libs", s.Libs, ctx.SnapshotBuilder().SdkMemberReferencePropertyTag(false))
1743 }
1744}