blob: 361ac713586a218068a6da23511344d3e3902ce2 [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 (
Jiyong Parkc678ad32018-04-10 13:07:10 +090033 sdkStubsLibrarySuffix = ".stubs"
34 sdkSystemApiSuffix = ".system"
Jiyong Parkdf130542018-04-27 16:29:21 +090035 sdkTestApiSuffix = ".test"
Paul Duffin91b883d2020-02-11 13:05:28 +000036 sdkStubsSourceSuffix = ".stubs.source"
Jiyong Parkc678ad32018-04-10 13:07:10 +090037 sdkXmlFileSuffix = ".xml"
Jiyong Parke3833882020-02-17 17:28:10 +090038 permissionsTemplate = `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n` +
Jooyung Han624058e2019-12-24 18:38:06 +090039 `<!-- Copyright (C) 2018 The Android Open Source Project\n` +
40 `\n` +
Jiyong Parke3833882020-02-17 17:28:10 +090041 ` Licensed under the Apache License, Version 2.0 (the \"License\");\n` +
Jooyung Han624058e2019-12-24 18:38:06 +090042 ` you may not use this file except in compliance with the License.\n` +
43 ` You may obtain a copy of the License at\n` +
44 `\n` +
45 ` http://www.apache.org/licenses/LICENSE-2.0\n` +
46 `\n` +
47 ` Unless required by applicable law or agreed to in writing, software\n` +
Jiyong Parke3833882020-02-17 17:28:10 +090048 ` distributed under the License is distributed on an \"AS IS\" BASIS,\n` +
Jooyung Han624058e2019-12-24 18:38:06 +090049 ` WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n` +
50 ` See the License for the specific language governing permissions and\n` +
51 ` limitations under the License.\n` +
52 `-->\n` +
53 `<permissions>\n` +
Jiyong Parke3833882020-02-17 17:28:10 +090054 ` <library name=\"%s\" file=\"%s\"/>\n` +
Jooyung Han624058e2019-12-24 18:38:06 +090055 `</permissions>\n`
Jiyong Parkc678ad32018-04-10 13:07:10 +090056)
57
Paul Duffind1b3a922020-01-22 11:57:20 +000058// A tag to associated a dependency with a specific api scope.
59type scopeDependencyTag struct {
60 blueprint.BaseDependencyTag
61 name string
62 apiScope *apiScope
63}
64
65// Provides information about an api scope, e.g. public, system, test.
66type apiScope struct {
67 // The name of the api scope, e.g. public, system, test
68 name string
69
Paul Duffin97b53b82020-05-05 14:40:52 +010070 // The api scope that this scope extends.
71 extends *apiScope
72
Paul Duffin3375e352020-04-28 10:44:03 +010073 // The legacy enabled status for a specific scope can be dependent on other
74 // properties that have been specified on the library so it is provided by
75 // a function that can determine the status by examining those properties.
76 legacyEnabledStatus func(module *SdkLibrary) bool
77
78 // The default enabled status for non-legacy behavior, which is triggered by
79 // explicitly enabling at least one api scope.
80 defaultEnabledStatus bool
81
82 // Gets a pointer to the scope specific properties.
83 scopeSpecificProperties func(module *SdkLibrary) *ApiScopeProperties
84
Paul Duffin46a26a82020-04-07 19:27:04 +010085 // The name of the field in the dynamically created structure.
86 fieldName string
87
Paul Duffind1b3a922020-01-22 11:57:20 +000088 // The tag to use to depend on the stubs library module.
89 stubsTag scopeDependencyTag
90
91 // The tag to use to depend on the stubs
92 apiFileTag scopeDependencyTag
93
94 // The scope specific prefix to add to the api file base of "current.txt" or "removed.txt".
95 apiFilePrefix string
96
97 // The scope specific prefix to add to the sdk library module name to construct a scope specific
98 // module name.
99 moduleSuffix string
100
Paul Duffind1b3a922020-01-22 11:57:20 +0000101 // SDK version that the stubs library is built against. Note that this is always
102 // *current. Older stubs library built with a numbered SDK version is created from
103 // the prebuilt jar.
104 sdkVersion string
Paul Duffin1fb487d2020-04-07 18:50:10 +0100105
106 // Extra arguments to pass to droidstubs for this scope.
107 droidstubsArgs []string
Anton Hansson6478ac12020-05-02 11:19:36 +0100108
109 // Whether the api scope can be treated as unstable, and should skip compat checks.
110 unstable bool
Paul Duffind1b3a922020-01-22 11:57:20 +0000111}
112
113// Initialize a scope, creating and adding appropriate dependency tags
114func initApiScope(scope *apiScope) *apiScope {
Paul Duffin46a26a82020-04-07 19:27:04 +0100115 scope.fieldName = proptools.FieldNameForProperty(scope.name)
Paul Duffind1b3a922020-01-22 11:57:20 +0000116 scope.stubsTag = scopeDependencyTag{
117 name: scope.name + "-stubs",
118 apiScope: scope,
119 }
120 scope.apiFileTag = scopeDependencyTag{
121 name: scope.name + "-api",
122 apiScope: scope,
123 }
124 return scope
125}
126
127func (scope *apiScope) stubsModuleName(baseName string) string {
128 return baseName + sdkStubsLibrarySuffix + scope.moduleSuffix
129}
130
131func (scope *apiScope) docsModuleName(baseName string) string {
Paul Duffin91b883d2020-02-11 13:05:28 +0000132 return baseName + sdkStubsSourceSuffix + scope.moduleSuffix
Paul Duffind1b3a922020-01-22 11:57:20 +0000133}
134
Paul Duffin3375e352020-04-28 10:44:03 +0100135func (scope *apiScope) String() string {
136 return scope.name
137}
138
Paul Duffind1b3a922020-01-22 11:57:20 +0000139type apiScopes []*apiScope
140
141func (scopes apiScopes) Strings(accessor func(*apiScope) string) []string {
142 var list []string
143 for _, scope := range scopes {
144 list = append(list, accessor(scope))
145 }
146 return list
147}
148
Jiyong Parkc678ad32018-04-10 13:07:10 +0900149var (
Paul Duffind1b3a922020-01-22 11:57:20 +0000150 apiScopePublic = initApiScope(&apiScope{
Paul Duffin3375e352020-04-28 10:44:03 +0100151 name: "public",
152
153 // Public scope is enabled by default for both legacy and non-legacy modes.
154 legacyEnabledStatus: func(module *SdkLibrary) bool {
155 return true
156 },
157 defaultEnabledStatus: true,
158
159 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
160 return &module.sdkLibraryProperties.Public
161 },
Paul Duffind1b3a922020-01-22 11:57:20 +0000162 sdkVersion: "current",
163 })
164 apiScopeSystem = initApiScope(&apiScope{
Paul Duffin3375e352020-04-28 10:44:03 +0100165 name: "system",
166 extends: apiScopePublic,
167 legacyEnabledStatus: (*SdkLibrary).generateTestAndSystemScopesByDefault,
168 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
169 return &module.sdkLibraryProperties.System
170 },
Anton Hansson6affb1f2020-04-28 16:47:41 +0100171 apiFilePrefix: "system-",
172 moduleSuffix: sdkSystemApiSuffix,
173 sdkVersion: "system_current",
174 droidstubsArgs: []string{"-showAnnotation android.annotation.SystemApi"},
Paul Duffind1b3a922020-01-22 11:57:20 +0000175 })
176 apiScopeTest = initApiScope(&apiScope{
Paul Duffin3375e352020-04-28 10:44:03 +0100177 name: "test",
178 extends: apiScopePublic,
179 legacyEnabledStatus: (*SdkLibrary).generateTestAndSystemScopesByDefault,
180 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
181 return &module.sdkLibraryProperties.Test
182 },
Anton Hansson6affb1f2020-04-28 16:47:41 +0100183 apiFilePrefix: "test-",
184 moduleSuffix: sdkTestApiSuffix,
185 sdkVersion: "test_current",
186 droidstubsArgs: []string{"-showAnnotation android.annotation.TestApi"},
Anton Hansson6478ac12020-05-02 11:19:36 +0100187 unstable: true,
Paul Duffind1b3a922020-01-22 11:57:20 +0000188 })
Paul Duffin8f265b92020-04-28 14:13:56 +0100189 apiScopeModuleLib = initApiScope(&apiScope{
190 name: "module_lib",
191 extends: apiScopeSystem,
192 // Module_lib scope is disabled by default in legacy mode.
193 //
194 // Enabling this would break existing usages.
195 legacyEnabledStatus: func(module *SdkLibrary) bool {
196 return false
197 },
198 scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
199 return &module.sdkLibraryProperties.Module_lib
200 },
201 apiFilePrefix: "module-lib-",
202 moduleSuffix: ".module_lib",
203 sdkVersion: "module_current",
204 droidstubsArgs: []string{
205 "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES\\)",
206 },
207 })
Paul Duffind1b3a922020-01-22 11:57:20 +0000208 allApiScopes = apiScopes{
209 apiScopePublic,
210 apiScopeSystem,
211 apiScopeTest,
Paul Duffin8f265b92020-04-28 14:13:56 +0100212 apiScopeModuleLib,
Paul Duffind1b3a922020-01-22 11:57:20 +0000213 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900214)
215
Jiyong Park82484c02018-04-23 21:41:26 +0900216var (
217 javaSdkLibrariesLock sync.Mutex
218)
219
Jiyong Parkc678ad32018-04-10 13:07:10 +0900220// TODO: these are big features that are currently missing
Jiyong Park1be96912018-05-28 18:02:19 +0900221// 1) disallowing linking to the runtime shared lib
222// 2) HTML generation
Jiyong Parkc678ad32018-04-10 13:07:10 +0900223
224func init() {
Paul Duffin43dc1cc2019-12-19 11:18:54 +0000225 RegisterSdkLibraryBuildComponents(android.InitRegistrationContext)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900226
Jiyong Park82484c02018-04-23 21:41:26 +0900227 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
228 javaSdkLibraries := javaSdkLibraries(ctx.Config())
229 sort.Strings(*javaSdkLibraries)
230 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
231 })
Paul Duffindd46f712020-02-10 13:37:10 +0000232
233 // Register sdk member types.
234 android.RegisterSdkMemberType(&sdkLibrarySdkMemberType{
235 android.SdkMemberTypeBase{
236 PropertyName: "java_sdk_libs",
237 SupportsSdk: true,
238 },
239 })
Jiyong Parkc678ad32018-04-10 13:07:10 +0900240}
241
Paul Duffin43dc1cc2019-12-19 11:18:54 +0000242func RegisterSdkLibraryBuildComponents(ctx android.RegistrationContext) {
243 ctx.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
244 ctx.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory)
245}
246
Paul Duffin3375e352020-04-28 10:44:03 +0100247// Properties associated with each api scope.
248type ApiScopeProperties struct {
249 // Indicates whether the api surface is generated.
250 //
251 // If this is set for any scope then all scopes must explicitly specify if they
252 // are enabled. This is to prevent new usages from depending on legacy behavior.
253 //
254 // Otherwise, if this is not set for any scope then the default behavior is
255 // scope specific so please refer to the scope specific property documentation.
256 Enabled *bool
257}
258
Jiyong Parkc678ad32018-04-10 13:07:10 +0900259type sdkLibraryProperties struct {
Paul Duffin4911a892020-04-29 23:35:13 +0100260 // Visibility for stubs library modules. If not specified then defaults to the
261 // visibility property.
262 Stubs_library_visibility []string
263
264 // Visibility for stubs source modules. If not specified then defaults to the
265 // visibility property.
266 Stubs_source_visibility []string
267
Sundong Ahnf043cf62018-06-25 16:04:37 +0900268 // List of Java libraries that will be in the classpath when building stubs
269 Stub_only_libs []string `android:"arch_variant"`
270
Paul Duffin7a586d32019-12-30 17:09:34 +0000271 // list of package names that will be documented and publicized as API.
272 // This allows the API to be restricted to a subset of the source files provided.
273 // If this is unspecified then all the source files will be treated as being part
274 // of the API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900275 Api_packages []string
276
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900277 // list of package names that must be hidden from the API
278 Hidden_api_packages []string
279
Paul Duffin749f98f2019-12-30 17:23:46 +0000280 // the relative path to the directory containing the api specification files.
281 // Defaults to "api".
282 Api_dir *string
283
Paul Duffin43db9be2019-12-30 17:35:49 +0000284 // If set to true there is no runtime library.
285 Api_only *bool
286
Paul Duffin11512472019-02-11 15:55:17 +0000287 // local files that are used within user customized droiddoc options.
288 Droiddoc_option_files []string
289
290 // additional droiddoc options
291 // Available variables for substitution:
292 //
293 // $(location <label>): the path to the droiddoc_option_files with name <label>
Sundong Ahndd567f92018-07-31 17:19:11 +0900294 Droiddoc_options []string
295
Sundong Ahn054b19a2018-10-19 13:46:09 +0900296 // a list of top-level directories containing files to merge qualifier annotations
297 // (i.e. those intended to be included in the stubs written) from.
298 Merge_annotations_dirs []string
299
300 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
301 Merge_inclusion_annotations_dirs []string
302
303 // If set to true, the path of dist files is apistubs/core. Defaults to false.
304 Core_lib *bool
305
Sundong Ahn80a87b32019-05-13 15:02:50 +0900306 // don't create dist rules.
307 No_dist *bool `blueprint:"mutated"`
308
Paul Duffin3375e352020-04-28 10:44:03 +0100309 // indicates whether system and test apis should be generated.
310 Generate_system_and_test_apis bool `blueprint:"mutated"`
311
312 // The properties specific to the public api scope
313 //
314 // Unless explicitly specified by using public.enabled the public api scope is
315 // enabled by default in both legacy and non-legacy mode.
316 Public ApiScopeProperties
317
318 // The properties specific to the system api scope
319 //
320 // In legacy mode the system api scope is enabled by default when sdk_version
321 // is set to something other than "none".
322 //
323 // In non-legacy mode the system api scope is disabled by default.
324 System ApiScopeProperties
325
326 // The properties specific to the test api scope
327 //
328 // In legacy mode the test api scope is enabled by default when sdk_version
329 // is set to something other than "none".
330 //
331 // In non-legacy mode the test api scope is disabled by default.
332 Test ApiScopeProperties
Paul Duffin37e0b772019-12-30 17:20:10 +0000333
Paul Duffin8f265b92020-04-28 14:13:56 +0100334 // The properties specific to the module_lib api scope
335 //
336 // Unless explicitly specified by using test.enabled the module_lib api scope is
337 // disabled by default.
338 Module_lib ApiScopeProperties
339
Jiyong Parkc678ad32018-04-10 13:07:10 +0900340 // TODO: determines whether to create HTML doc or not
341 //Html_doc *bool
342}
343
Paul Duffind1b3a922020-01-22 11:57:20 +0000344type scopePaths struct {
Paul Duffin1fd005d2020-04-09 01:08:11 +0100345 stubsHeaderPath android.Paths
346 stubsImplPath android.Paths
347 currentApiFilePath android.Path
348 removedApiFilePath android.Path
349 stubsSrcJar android.Path
Paul Duffind1b3a922020-01-22 11:57:20 +0000350}
351
Paul Duffin56d44902020-01-31 13:36:25 +0000352// Common code between sdk library and sdk library import
353type commonToSdkLibraryAndImport struct {
354 scopePaths map[*apiScope]*scopePaths
355}
356
357func (c *commonToSdkLibraryAndImport) getScopePaths(scope *apiScope) *scopePaths {
358 if c.scopePaths == nil {
359 c.scopePaths = make(map[*apiScope]*scopePaths)
360 }
361 paths := c.scopePaths[scope]
362 if paths == nil {
363 paths = &scopePaths{}
364 c.scopePaths[scope] = paths
365 }
366
367 return paths
368}
369
Inseob Kimc0907f12019-02-08 21:00:45 +0900370type SdkLibrary struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900371 Library
Jiyong Parkc678ad32018-04-10 13:07:10 +0900372
Sundong Ahn054b19a2018-10-19 13:46:09 +0900373 sdkLibraryProperties sdkLibraryProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900374
Paul Duffin3375e352020-04-28 10:44:03 +0100375 // Map from api scope to the scope specific property structure.
376 scopeToProperties map[*apiScope]*ApiScopeProperties
377
Paul Duffin56d44902020-01-31 13:36:25 +0000378 commonToSdkLibraryAndImport
Jiyong Parkc678ad32018-04-10 13:07:10 +0900379}
380
Inseob Kimc0907f12019-02-08 21:00:45 +0900381var _ Dependency = (*SdkLibrary)(nil)
382var _ SdkLibraryDependency = (*SdkLibrary)(nil)
Colin Cross897d2ed2019-02-11 14:03:51 -0800383
Paul Duffin3375e352020-04-28 10:44:03 +0100384func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool {
385 return module.sdkLibraryProperties.Generate_system_and_test_apis
386}
387
388func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext) apiScopes {
389 // Check to see if any scopes have been explicitly enabled. If any have then all
390 // must be.
391 anyScopesExplicitlyEnabled := false
392 for _, scope := range allApiScopes {
393 scopeProperties := module.scopeToProperties[scope]
394 if scopeProperties.Enabled != nil {
395 anyScopesExplicitlyEnabled = true
396 break
397 }
Paul Duffind1b3a922020-01-22 11:57:20 +0000398 }
Paul Duffin3375e352020-04-28 10:44:03 +0100399
400 var generatedScopes apiScopes
401 enabledScopes := make(map[*apiScope]struct{})
402 for _, scope := range allApiScopes {
403 scopeProperties := module.scopeToProperties[scope]
404 // If any scopes are explicitly enabled then ignore the legacy enabled status.
405 // This is to ensure that any new usages of this module type do not rely on legacy
406 // behaviour.
407 defaultEnabledStatus := false
408 if anyScopesExplicitlyEnabled {
409 defaultEnabledStatus = scope.defaultEnabledStatus
410 } else {
411 defaultEnabledStatus = scope.legacyEnabledStatus(module)
412 }
413 enabled := proptools.BoolDefault(scopeProperties.Enabled, defaultEnabledStatus)
414 if enabled {
415 enabledScopes[scope] = struct{}{}
416 generatedScopes = append(generatedScopes, scope)
417 }
418 }
419
420 // Now check to make sure that any scope that is extended by an enabled scope is also
421 // enabled.
422 for _, scope := range allApiScopes {
423 if _, ok := enabledScopes[scope]; ok {
424 extends := scope.extends
425 if extends != nil {
426 if _, ok := enabledScopes[extends]; !ok {
427 ctx.ModuleErrorf("enabled api scope %q depends on disabled scope %q", scope, extends)
428 }
429 }
430 }
431 }
432
433 return generatedScopes
Paul Duffind1b3a922020-01-22 11:57:20 +0000434}
435
Paul Duffine74ac732020-02-06 13:51:46 +0000436var xmlPermissionsFileTag = dependencyTag{name: "xml-permissions-file"}
437
Jiyong Parke3833882020-02-17 17:28:10 +0900438func IsXmlPermissionsFileDepTag(depTag blueprint.DependencyTag) bool {
439 if dt, ok := depTag.(dependencyTag); ok {
440 return dt == xmlPermissionsFileTag
441 }
442 return false
443}
444
Inseob Kimc0907f12019-02-08 21:00:45 +0900445func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
Paul Duffin3375e352020-04-28 10:44:03 +0100446 for _, apiScope := range module.getGeneratedApiScopes(ctx) {
Paul Duffind1b3a922020-01-22 11:57:20 +0000447 // Add dependencies to the stubs library
Paul Duffin50061512020-01-21 16:31:05 +0000448 ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsName(apiScope))
Paul Duffind1b3a922020-01-22 11:57:20 +0000449
Paul Duffin50061512020-01-21 16:31:05 +0000450 // And the api file
Paul Duffind1b3a922020-01-22 11:57:20 +0000451 ctx.AddVariationDependencies(nil, apiScope.apiFileTag, module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900452 }
453
Paul Duffine74ac732020-02-06 13:51:46 +0000454 if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
455 // Add dependency to the rule for generating the xml permissions file
Jiyong Parke3833882020-02-17 17:28:10 +0900456 ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlFileName())
Paul Duffine74ac732020-02-06 13:51:46 +0000457 }
458
Sundong Ahn054b19a2018-10-19 13:46:09 +0900459 module.Library.deps(ctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900460}
461
Inseob Kimc0907f12019-02-08 21:00:45 +0900462func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Paul Duffin43db9be2019-12-30 17:35:49 +0000463 // Don't build an implementation library if this is api only.
464 if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
465 module.Library.GenerateAndroidBuildActions(ctx)
466 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900467
Sundong Ahn57368eb2018-07-06 11:20:23 +0900468 // Record the paths to the header jars of the library (stubs and impl).
Paul Duffind1b3a922020-01-22 11:57:20 +0000469 // When this java_sdk_library is depended upon from others via "libs" property,
Jiyong Parkc678ad32018-04-10 13:07:10 +0900470 // the recorded paths will be returned depending on the link type of the caller.
471 ctx.VisitDirectDeps(func(to android.Module) {
472 otherName := ctx.OtherModuleName(to)
473 tag := ctx.OtherModuleDependencyTag(to)
474
Sundong Ahn57368eb2018-07-06 11:20:23 +0900475 if lib, ok := to.(Dependency); ok {
Paul Duffind1b3a922020-01-22 11:57:20 +0000476 if scopeTag, ok := tag.(scopeDependencyTag); ok {
477 apiScope := scopeTag.apiScope
478 scopePaths := module.getScopePaths(apiScope)
479 scopePaths.stubsHeaderPath = lib.HeaderJars()
480 scopePaths.stubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900481 }
482 }
Paul Duffin3d1248c2020-04-09 00:10:17 +0100483 if doc, ok := to.(ApiStubsProvider); ok {
Paul Duffind1b3a922020-01-22 11:57:20 +0000484 if scopeTag, ok := tag.(scopeDependencyTag); ok {
485 apiScope := scopeTag.apiScope
486 scopePaths := module.getScopePaths(apiScope)
Paul Duffin1fd005d2020-04-09 01:08:11 +0100487 scopePaths.currentApiFilePath = doc.ApiFilePath()
488 scopePaths.removedApiFilePath = doc.RemovedApiFilePath()
Paul Duffin3d1248c2020-04-09 00:10:17 +0100489 scopePaths.stubsSrcJar = doc.StubsSrcJar()
Paul Duffind1b3a922020-01-22 11:57:20 +0000490 } else {
Sundong Ahn20e998b2018-07-24 11:19:26 +0900491 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
492 }
493 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900494 })
495}
496
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900497func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
Paul Duffin43db9be2019-12-30 17:35:49 +0000498 if proptools.Bool(module.sdkLibraryProperties.Api_only) {
499 return nil
500 }
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900501 entriesList := module.Library.AndroidMkEntries()
502 entries := &entriesList[0]
Jaewoong Jungb0c127c2019-08-29 14:56:03 -0700503 entries.Required = append(entries.Required, module.xmlFileName())
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900504 return entriesList
Jiyong Park82484c02018-04-23 21:41:26 +0900505}
506
Jiyong Parkc678ad32018-04-10 13:07:10 +0900507// Module name of the stubs library
Paul Duffind1b3a922020-01-22 11:57:20 +0000508func (module *SdkLibrary) stubsName(apiScope *apiScope) string {
509 return apiScope.stubsModuleName(module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900510}
511
512// Module name of the docs
Paul Duffind1b3a922020-01-22 11:57:20 +0000513func (module *SdkLibrary) docsName(apiScope *apiScope) string {
514 return apiScope.docsModuleName(module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900515}
516
517// Module name of the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900518func (module *SdkLibrary) implName() string {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900519 return module.BaseModuleName()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900520}
521
Jiyong Parkc678ad32018-04-10 13:07:10 +0900522// Module name of the XML file for the lib
Inseob Kimc0907f12019-02-08 21:00:45 +0900523func (module *SdkLibrary) xmlFileName() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900524 return module.BaseModuleName() + sdkXmlFileSuffix
525}
526
Anton Hansson5fd5d242020-03-27 19:43:19 +0000527// The dist path of the stub artifacts
528func (module *SdkLibrary) apiDistPath(apiScope *apiScope) string {
529 if module.ModuleBase.Owner() != "" {
530 return path.Join("apistubs", module.ModuleBase.Owner(), apiScope.name)
531 } else if Bool(module.sdkLibraryProperties.Core_lib) {
532 return path.Join("apistubs", "core", apiScope.name)
533 } else {
534 return path.Join("apistubs", "android", apiScope.name)
535 }
536}
537
Paul Duffin12ceb462019-12-24 20:31:31 +0000538// Get the sdk version for use when compiling the stubs library.
Paul Duffinf0229202020-04-29 16:47:28 +0100539func (module *SdkLibrary) sdkVersionForStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) string {
Paul Duffin12ceb462019-12-24 20:31:31 +0000540 sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
541 if sdkDep.hasStandardLibs() {
542 // If building against a standard sdk then use the sdk version appropriate for the scope.
Paul Duffind1b3a922020-01-22 11:57:20 +0000543 return apiScope.sdkVersion
Paul Duffin12ceb462019-12-24 20:31:31 +0000544 } else {
545 // Otherwise, use no system module.
546 return "none"
547 }
548}
549
Paul Duffind1b3a922020-01-22 11:57:20 +0000550func (module *SdkLibrary) latestApiFilegroupName(apiScope *apiScope) string {
551 return ":" + module.BaseModuleName() + ".api." + apiScope.name + ".latest"
Jiyong Park58c518b2018-05-12 22:29:12 +0900552}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900553
Paul Duffind1b3a922020-01-22 11:57:20 +0000554func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope *apiScope) string {
555 return ":" + module.BaseModuleName() + "-removed.api." + apiScope.name + ".latest"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900556}
557
558// Creates a static java library that has API stubs
Paul Duffinf0229202020-04-29 16:47:28 +0100559func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900560 props := struct {
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900561 Name *string
Paul Duffin4911a892020-04-29 23:35:13 +0100562 Visibility []string
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900563 Srcs []string
Paul Duffin367ab912019-12-23 19:40:36 +0000564 Installable *bool
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900565 Sdk_version *string
Paul Duffin12ceb462019-12-24 20:31:31 +0000566 System_modules *string
Paul Duffinab8da5d2020-02-07 16:12:04 +0000567 Patch_module *string
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900568 Libs []string
569 Soc_specific *bool
570 Device_specific *bool
571 Product_specific *bool
572 System_ext_specific *bool
573 Compile_dex *bool
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900574 Java_version *string
575 Product_variables struct {
Jiyong Park82484c02018-04-23 21:41:26 +0900576 Pdk struct {
577 Enabled *bool
578 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900579 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900580 Openjdk9 struct {
581 Srcs []string
582 Javacflags []string
583 }
Anton Hansson5fd5d242020-03-27 19:43:19 +0000584 Dist struct {
585 Targets []string
586 Dest *string
587 Dir *string
588 Tag *string
589 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900590 }{}
591
Jiyong Parkdf130542018-04-27 16:29:21 +0900592 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Paul Duffin4911a892020-04-29 23:35:13 +0100593
594 // If stubs_library_visibility is not set then the created module will use the
595 // visibility of this module.
596 visibility := module.sdkLibraryProperties.Stubs_library_visibility
597 props.Visibility = visibility
598
Jiyong Parkc678ad32018-04-10 13:07:10 +0900599 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900600 props.Srcs = []string{":" + module.docsName(apiScope)}
Paul Duffin12ceb462019-12-24 20:31:31 +0000601 sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
Paul Duffin52d398a2019-06-11 12:31:14 +0100602 props.Sdk_version = proptools.StringPtr(sdkVersion)
Paul Duffin12ceb462019-12-24 20:31:31 +0000603 props.System_modules = module.Library.Module.deviceProperties.System_modules
Paul Duffinab8da5d2020-02-07 16:12:04 +0000604 props.Patch_module = module.Library.Module.properties.Patch_module
Paul Duffin367ab912019-12-23 19:40:36 +0000605 props.Installable = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900606 props.Libs = module.sdkLibraryProperties.Stub_only_libs
Jiyong Park82484c02018-04-23 21:41:26 +0900607 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900608 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
609 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
610 props.Java_version = module.Library.Module.properties.Java_version
611 if module.Library.Module.deviceProperties.Compile_dex != nil {
612 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900613 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900614
615 if module.SocSpecific() {
616 props.Soc_specific = proptools.BoolPtr(true)
617 } else if module.DeviceSpecific() {
618 props.Device_specific = proptools.BoolPtr(true)
619 } else if module.ProductSpecific() {
620 props.Product_specific = proptools.BoolPtr(true)
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900621 } else if module.SystemExtSpecific() {
622 props.System_ext_specific = proptools.BoolPtr(true)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900623 }
Anton Hansson5fd5d242020-03-27 19:43:19 +0000624 // Dist the class jar artifact for sdk builds.
625 if !Bool(module.sdkLibraryProperties.No_dist) {
626 props.Dist.Targets = []string{"sdk", "win_sdk"}
627 props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.BaseModuleName()))
628 props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
629 props.Dist.Tag = proptools.StringPtr(".jar")
630 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900631
Colin Cross84dfc3d2019-09-25 11:33:01 -0700632 mctx.CreateModule(LibraryFactory, &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900633}
634
Paul Duffin6d0886e2020-04-07 18:49:53 +0100635// Creates a droidstubs module that creates stubs source files from the given full source
Jiyong Parkc678ad32018-04-10 13:07:10 +0900636// files
Paul Duffinf0229202020-04-29 16:47:28 +0100637func (module *SdkLibrary) createStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900638 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900639 Name *string
Paul Duffin4911a892020-04-29 23:35:13 +0100640 Visibility []string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900641 Srcs []string
642 Installable *bool
Paul Duffin52d398a2019-06-11 12:31:14 +0100643 Sdk_version *string
Paul Duffin12ceb462019-12-24 20:31:31 +0000644 System_modules *string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900645 Libs []string
Paul Duffin11512472019-02-11 15:55:17 +0000646 Arg_files []string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900647 Args *string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900648 Java_version *string
649 Merge_annotations_dirs []string
650 Merge_inclusion_annotations_dirs []string
651 Check_api struct {
Inseob Kim38449af2019-02-28 14:24:05 +0900652 Current ApiToCheck
653 Last_released ApiToCheck
654 Ignore_missing_latest_api *bool
Jiyong Park58c518b2018-05-12 22:29:12 +0900655 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900656 Aidl struct {
657 Include_dirs []string
658 Local_include_dirs []string
659 }
Anton Hansson5fd5d242020-03-27 19:43:19 +0000660 Dist struct {
661 Targets []string
662 Dest *string
663 Dir *string
664 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900665 }{}
666
Paul Duffin7b78b4d2020-04-28 14:08:32 +0100667 // The stubs source processing uses the same compile time classpath when extracting the
668 // API from the implementation library as it does when compiling it. i.e. the same
669 // * sdk version
670 // * system_modules
671 // * libs (static_libs/libs)
Paul Duffin250e6192019-06-07 10:44:37 +0100672
Jiyong Parkdf130542018-04-27 16:29:21 +0900673 props.Name = proptools.StringPtr(module.docsName(apiScope))
Paul Duffin4911a892020-04-29 23:35:13 +0100674
675 // If stubs_source_visibility is not set then the created module will use the
676 // visibility of this module.
677 visibility := module.sdkLibraryProperties.Stubs_source_visibility
678 props.Visibility = visibility
679
Sundong Ahn054b19a2018-10-19 13:46:09 +0900680 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
Paul Duffin7b78b4d2020-04-28 14:08:32 +0100681 props.Sdk_version = module.Library.Module.deviceProperties.Sdk_version
Paul Duffin12ceb462019-12-24 20:31:31 +0000682 props.System_modules = module.Library.Module.deviceProperties.System_modules
Jiyong Parkc678ad32018-04-10 13:07:10 +0900683 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900684 // A droiddoc module has only one Libs property and doesn't distinguish between
685 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900686 props.Libs = module.Library.Module.properties.Libs
687 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
688 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
689 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
Sundong Ahn054b19a2018-10-19 13:46:09 +0900690 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900691
Sundong Ahn054b19a2018-10-19 13:46:09 +0900692 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
693 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
694
Paul Duffin6d0886e2020-04-07 18:49:53 +0100695 droidstubsArgs := []string{}
Paul Duffin235ffff2019-12-24 10:41:30 +0000696 if len(module.sdkLibraryProperties.Api_packages) != 0 {
Paul Duffin6d0886e2020-04-07 18:49:53 +0100697 droidstubsArgs = append(droidstubsArgs, "--stub-packages "+strings.Join(module.sdkLibraryProperties.Api_packages, ":"))
Paul Duffin235ffff2019-12-24 10:41:30 +0000698 }
699 if len(module.sdkLibraryProperties.Hidden_api_packages) != 0 {
Paul Duffin6d0886e2020-04-07 18:49:53 +0100700 droidstubsArgs = append(droidstubsArgs,
Paul Duffin235ffff2019-12-24 10:41:30 +0000701 android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package "))
702 }
Paul Duffin6d0886e2020-04-07 18:49:53 +0100703 droidstubsArgs = append(droidstubsArgs, module.sdkLibraryProperties.Droiddoc_options...)
Paul Duffin235ffff2019-12-24 10:41:30 +0000704 disabledWarnings := []string{
705 "MissingPermission",
706 "BroadcastBehavior",
707 "HiddenSuperclass",
708 "DeprecationMismatch",
709 "UnavailableSymbol",
710 "SdkConstant",
711 "HiddenTypeParameter",
712 "Todo",
713 "Typo",
714 }
Paul Duffin6d0886e2020-04-07 18:49:53 +0100715 droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900716
Paul Duffin1fb487d2020-04-07 18:50:10 +0100717 // Add in scope specific arguments.
718 droidstubsArgs = append(droidstubsArgs, apiScope.droidstubsArgs...)
Paul Duffin11512472019-02-11 15:55:17 +0000719 props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
Paul Duffin6d0886e2020-04-07 18:49:53 +0100720 props.Args = proptools.StringPtr(strings.Join(droidstubsArgs, " "))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900721
722 // List of APIs identified from the provided source files are created. They are later
723 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
724 // last-released (a.k.a numbered) list of API.
Paul Duffind1b3a922020-01-22 11:57:20 +0000725 currentApiFileName := apiScope.apiFilePrefix + "current.txt"
726 removedApiFileName := apiScope.apiFilePrefix + "removed.txt"
Paul Duffin749f98f2019-12-30 17:23:46 +0000727 apiDir := module.getApiDir()
728 currentApiFileName = path.Join(apiDir, currentApiFileName)
729 removedApiFileName = path.Join(apiDir, removedApiFileName)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900730
Jiyong Park58c518b2018-05-12 22:29:12 +0900731 // check against the not-yet-release API
732 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
733 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900734
Anton Hansson6478ac12020-05-02 11:19:36 +0100735 if !apiScope.unstable {
736 // check against the latest released API
737 props.Check_api.Last_released.Api_file = proptools.StringPtr(
738 module.latestApiFilegroupName(apiScope))
739 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
740 module.latestRemovedApiFilegroupName(apiScope))
741 props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
742 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900743
Anton Hansson5fd5d242020-03-27 19:43:19 +0000744 // Dist the api txt artifact for sdk builds.
745 if !Bool(module.sdkLibraryProperties.No_dist) {
746 props.Dist.Targets = []string{"sdk", "win_sdk"}
747 props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.txt", module.BaseModuleName()))
748 props.Dist.Dir = proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
749 }
750
Colin Cross84dfc3d2019-09-25 11:33:01 -0700751 mctx.CreateModule(DroidstubsFactory, &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900752}
753
Jooyung Han5e9013b2020-03-10 06:23:13 +0900754func (module *SdkLibrary) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool {
755 depTag := mctx.OtherModuleDependencyTag(dep)
756 if depTag == xmlPermissionsFileTag {
757 return true
758 }
759 return module.Library.DepIsInSameApex(mctx, dep)
760}
761
Jiyong Parkc678ad32018-04-10 13:07:10 +0900762// Creates the xml file that publicizes the runtime library
Paul Duffinf0229202020-04-29 16:47:28 +0100763func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
Jiyong Parke3833882020-02-17 17:28:10 +0900764 props := struct {
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900765 Name *string
Jiyong Parke3833882020-02-17 17:28:10 +0900766 Lib_name *string
Sundong Ahn0d7dff42019-12-04 12:53:44 +0900767 Soc_specific *bool
768 Device_specific *bool
769 Product_specific *bool
770 System_ext_specific *bool
Jooyung Han5e9013b2020-03-10 06:23:13 +0900771 Apex_available []string
Jiyong Parke3833882020-02-17 17:28:10 +0900772 }{
Jooyung Han5e9013b2020-03-10 06:23:13 +0900773 Name: proptools.StringPtr(module.xmlFileName()),
774 Lib_name: proptools.StringPtr(module.BaseModuleName()),
775 Apex_available: module.ApexProperties.Apex_available,
Jiyong Parkc678ad32018-04-10 13:07:10 +0900776 }
Jiyong Parke3833882020-02-17 17:28:10 +0900777
778 if module.SocSpecific() {
779 props.Soc_specific = proptools.BoolPtr(true)
780 } else if module.DeviceSpecific() {
781 props.Device_specific = proptools.BoolPtr(true)
782 } else if module.ProductSpecific() {
783 props.Product_specific = proptools.BoolPtr(true)
784 } else if module.SystemExtSpecific() {
785 props.System_ext_specific = proptools.BoolPtr(true)
786 }
787
788 mctx.CreateModule(sdkLibraryXmlFactory, &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900789}
790
Paul Duffin50061512020-01-21 16:31:05 +0000791func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s sdkSpec) android.Paths {
Jiyong Park6a927c42020-01-21 02:03:43 +0900792 var ver sdkVersion
793 var kind sdkKind
794 if s.usePrebuilt(ctx) {
795 ver = s.version
796 kind = s.kind
Jiyong Parkc678ad32018-04-10 13:07:10 +0900797 } else {
Jiyong Park6a927c42020-01-21 02:03:43 +0900798 // We don't have prebuilt SDK for the specific sdkVersion.
799 // Instead of breaking the build, fallback to use "system_current"
800 ver = sdkVersionCurrent
801 kind = sdkSystem
Sundong Ahn054b19a2018-10-19 13:46:09 +0900802 }
Jiyong Park6a927c42020-01-21 02:03:43 +0900803
804 dir := filepath.Join("prebuilts", "sdk", ver.String(), kind.String())
Paul Duffin50061512020-01-21 16:31:05 +0000805 jar := filepath.Join(dir, baseName+".jar")
Sundong Ahn054b19a2018-10-19 13:46:09 +0900806 jarPath := android.ExistentPathForSource(ctx, jar)
Sundong Ahnae418ac2019-02-28 15:01:28 +0900807 if !jarPath.Valid() {
Colin Cross07c88562020-01-07 09:34:44 -0800808 if ctx.Config().AllowMissingDependencies() {
809 return android.Paths{android.PathForSource(ctx, jar)}
810 } else {
Jiyong Park6a927c42020-01-21 02:03:43 +0900811 ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", s.raw, jar)
Colin Cross07c88562020-01-07 09:34:44 -0800812 }
Sundong Ahnae418ac2019-02-28 15:01:28 +0900813 return nil
814 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900815 return android.Paths{jarPath.Path()}
816}
817
Paul Duffind1b3a922020-01-22 11:57:20 +0000818func (module *SdkLibrary) sdkJars(
819 ctx android.BaseModuleContext,
820 sdkVersion sdkSpec,
821 headerJars bool) android.Paths {
822
Paul Duffin50061512020-01-21 16:31:05 +0000823 // If a specific numeric version has been requested then use prebuilt versions of the sdk.
824 if sdkVersion.version.isNumbered() {
825 return PrebuiltJars(ctx, module.BaseModuleName(), sdkVersion)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900826 } else {
Paul Duffind1b3a922020-01-22 11:57:20 +0000827 if !sdkVersion.specified() {
828 if headerJars {
829 return module.Library.HeaderJars()
830 } else {
831 return module.Library.ImplementationJars()
832 }
833 }
Paul Duffin726d23c2020-01-22 16:30:37 +0000834 var apiScope *apiScope
Jiyong Park6a927c42020-01-21 02:03:43 +0900835 switch sdkVersion.kind {
836 case sdkSystem:
Paul Duffin726d23c2020-01-22 16:30:37 +0000837 apiScope = apiScopeSystem
838 case sdkTest:
839 apiScope = apiScopeTest
Jiyong Park6a927c42020-01-21 02:03:43 +0900840 case sdkPrivate:
Sundong Ahn054b19a2018-10-19 13:46:09 +0900841 return module.Library.HeaderJars()
Jiyong Park6a927c42020-01-21 02:03:43 +0900842 default:
Paul Duffin726d23c2020-01-22 16:30:37 +0000843 apiScope = apiScopePublic
Paul Duffind1b3a922020-01-22 11:57:20 +0000844 }
845
Paul Duffin726d23c2020-01-22 16:30:37 +0000846 paths := module.getScopePaths(apiScope)
Paul Duffind1b3a922020-01-22 11:57:20 +0000847 if headerJars {
848 return paths.stubsHeaderPath
849 } else {
850 return paths.stubsImplPath
Sundong Ahn054b19a2018-10-19 13:46:09 +0900851 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900852 }
853}
854
Sundong Ahn241cd372018-07-13 16:16:44 +0900855// to satisfy SdkLibraryDependency interface
Paul Duffind1b3a922020-01-22 11:57:20 +0000856func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
857 return module.sdkJars(ctx, sdkVersion, true /*headerJars*/)
858}
859
860// to satisfy SdkLibraryDependency interface
Jiyong Park6a927c42020-01-21 02:03:43 +0900861func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
Paul Duffind1b3a922020-01-22 11:57:20 +0000862 return module.sdkJars(ctx, sdkVersion, false /*headerJars*/)
Sundong Ahn241cd372018-07-13 16:16:44 +0900863}
864
Sundong Ahn80a87b32019-05-13 15:02:50 +0900865func (module *SdkLibrary) SetNoDist() {
866 module.sdkLibraryProperties.No_dist = proptools.BoolPtr(true)
867}
868
Colin Cross571cccf2019-02-04 11:22:08 -0800869var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
870
Jiyong Park82484c02018-04-23 21:41:26 +0900871func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -0800872 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +0900873 return &[]string{}
874 }).(*[]string)
875}
876
Paul Duffin749f98f2019-12-30 17:23:46 +0000877func (module *SdkLibrary) getApiDir() string {
878 return proptools.StringDefault(module.sdkLibraryProperties.Api_dir, "api")
879}
880
Jiyong Parkc678ad32018-04-10 13:07:10 +0900881// For a java_sdk_library module, create internal modules for stubs, docs,
882// runtime libs and xml file. If requested, the stubs and docs are created twice
883// once for public API level and once for system API level
Paul Duffinf0229202020-04-29 16:47:28 +0100884func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookContext) {
885 // If the module has been disabled then don't create any child modules.
886 if !module.Enabled() {
887 return
888 }
889
Inseob Kim6e93ac92019-03-21 17:43:49 +0900890 if len(module.Library.Module.properties.Srcs) == 0 {
Inseob Kimc0907f12019-02-08 21:00:45 +0900891 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
Jooyung Han58f26ab2019-12-18 15:34:32 +0900892 return
Inseob Kimc0907f12019-02-08 21:00:45 +0900893 }
894
Paul Duffin37e0b772019-12-30 17:20:10 +0000895 // If this builds against standard libraries (i.e. is not part of the core libraries)
896 // then assume it provides both system and test apis. Otherwise, assume it does not and
897 // also assume it does not contribute to the dist build.
898 sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
899 hasSystemAndTestApis := sdkDep.hasStandardLibs()
Paul Duffin3375e352020-04-28 10:44:03 +0100900 module.sdkLibraryProperties.Generate_system_and_test_apis = hasSystemAndTestApis
Paul Duffin37e0b772019-12-30 17:20:10 +0000901 module.sdkLibraryProperties.No_dist = proptools.BoolPtr(!hasSystemAndTestApis)
902
Inseob Kim8098faa2019-03-18 10:19:51 +0900903 missing_current_api := false
904
Paul Duffin3375e352020-04-28 10:44:03 +0100905 generatedScopes := module.getGeneratedApiScopes(mctx)
Paul Duffind1b3a922020-01-22 11:57:20 +0000906
Paul Duffin749f98f2019-12-30 17:23:46 +0000907 apiDir := module.getApiDir()
Paul Duffin3375e352020-04-28 10:44:03 +0100908 for _, scope := range generatedScopes {
Inseob Kim8098faa2019-03-18 10:19:51 +0900909 for _, api := range []string{"current.txt", "removed.txt"} {
Paul Duffind1b3a922020-01-22 11:57:20 +0000910 path := path.Join(mctx.ModuleDir(), apiDir, scope.apiFilePrefix+api)
Inseob Kim8098faa2019-03-18 10:19:51 +0900911 p := android.ExistentPathForSource(mctx, path)
912 if !p.Valid() {
913 mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
914 missing_current_api = true
915 }
916 }
917 }
918
919 if missing_current_api {
920 script := "build/soong/scripts/gen-java-current-api-files.sh"
921 p := android.ExistentPathForSource(mctx, script)
922
923 if !p.Valid() {
924 panic(fmt.Sprintf("script file %s doesn't exist", script))
925 }
926
927 mctx.ModuleErrorf("One or more current api files are missing. "+
928 "You can update them by:\n"+
Paul Duffin37e0b772019-12-30 17:20:10 +0000929 "%s %q %s && m update-api",
Paul Duffind1b3a922020-01-22 11:57:20 +0000930 script, filepath.Join(mctx.ModuleDir(), apiDir),
Paul Duffin3375e352020-04-28 10:44:03 +0100931 strings.Join(generatedScopes.Strings(func(s *apiScope) string { return s.apiFilePrefix }), " "))
Inseob Kim8098faa2019-03-18 10:19:51 +0900932 return
933 }
934
Paul Duffin3375e352020-04-28 10:44:03 +0100935 for _, scope := range generatedScopes {
Paul Duffind1b3a922020-01-22 11:57:20 +0000936 module.createStubsLibrary(mctx, scope)
937 module.createStubsSources(mctx, scope)
Inseob Kimc0907f12019-02-08 21:00:45 +0900938 }
939
Paul Duffin43db9be2019-12-30 17:35:49 +0000940 if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
941 // for runtime
942 module.createXmlFile(mctx)
943
944 // record java_sdk_library modules so that they are exported to make
945 javaSdkLibraries := javaSdkLibraries(mctx.Config())
946 javaSdkLibrariesLock.Lock()
947 defer javaSdkLibrariesLock.Unlock()
948 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
949 }
Inseob Kimc0907f12019-02-08 21:00:45 +0900950}
951
952func (module *SdkLibrary) InitSdkLibraryProperties() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900953 module.AddProperties(
954 &module.sdkLibraryProperties,
955 &module.Library.Module.properties,
956 &module.Library.Module.dexpreoptProperties,
957 &module.Library.Module.deviceProperties,
958 &module.Library.Module.protoProperties,
959 )
960
961 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
962 module.Library.Module.deviceProperties.IsSDKLibrary = true
Inseob Kimc0907f12019-02-08 21:00:45 +0900963}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900964
Jaewoong Jung4f158ee2019-07-11 10:05:35 -0700965// java_sdk_library is a special Java library that provides optional platform APIs to apps.
966// In practice, it can be viewed as a combination of several modules: 1) stubs library that clients
967// are linked against to, 2) droiddoc module that internally generates API stubs source files,
968// 3) the real runtime shared library that implements the APIs, and 4) XML file for adding
969// the runtime lib to the classpath at runtime if requested via <uses-library>.
Inseob Kimc0907f12019-02-08 21:00:45 +0900970func SdkLibraryFactory() android.Module {
971 module := &SdkLibrary{}
972 module.InitSdkLibraryProperties()
Jooyung Han58f26ab2019-12-18 15:34:32 +0900973 android.InitApexModule(module)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900974 InitJavaModule(module, android.HostAndDeviceSupported)
Paul Duffin3375e352020-04-28 10:44:03 +0100975
976 // Initialize the map from scope to scope specific properties.
977 scopeToProperties := make(map[*apiScope]*ApiScopeProperties)
978 for _, scope := range allApiScopes {
979 scopeToProperties[scope] = scope.scopeSpecificProperties(module)
980 }
981 module.scopeToProperties = scopeToProperties
982
Paul Duffin4911a892020-04-29 23:35:13 +0100983 // Add the properties containing visibility rules so that they are checked.
984 android.AddVisibilityProperty(module, "stubs_library_visibility", &module.sdkLibraryProperties.Stubs_library_visibility)
985 android.AddVisibilityProperty(module, "stubs_source_visibility", &module.sdkLibraryProperties.Stubs_source_visibility)
986
Paul Duffinf0229202020-04-29 16:47:28 +0100987 module.SetDefaultableHook(func(ctx android.DefaultableHookContext) { module.CreateInternalModules(ctx) })
Jiyong Parkc678ad32018-04-10 13:07:10 +0900988 return module
989}
Colin Cross79c7c262019-04-17 11:11:46 -0700990
991//
992// SDK library prebuilts
993//
994
Paul Duffin56d44902020-01-31 13:36:25 +0000995// Properties associated with each api scope.
996type sdkLibraryScopeProperties struct {
Colin Cross79c7c262019-04-17 11:11:46 -0700997 Jars []string `android:"path"`
998
999 Sdk_version *string
1000
Colin Cross79c7c262019-04-17 11:11:46 -07001001 // List of shared java libs that this module has dependencies to
1002 Libs []string
Paul Duffin3d1248c2020-04-09 00:10:17 +01001003
1004 // The stub sources.
1005 Stub_srcs []string `android:"path"`
Paul Duffin1fd005d2020-04-09 01:08:11 +01001006
1007 // The current.txt
1008 Current_api string `android:"path"`
1009
1010 // The removed.txt
1011 Removed_api string `android:"path"`
Colin Cross79c7c262019-04-17 11:11:46 -07001012}
1013
Paul Duffin56d44902020-01-31 13:36:25 +00001014type sdkLibraryImportProperties struct {
Paul Duffinfcfd7912020-01-31 17:54:30 +00001015 // List of shared java libs, common to all scopes, that this module has
1016 // dependencies to
1017 Libs []string
Paul Duffin56d44902020-01-31 13:36:25 +00001018}
1019
Colin Cross79c7c262019-04-17 11:11:46 -07001020type sdkLibraryImport struct {
1021 android.ModuleBase
1022 android.DefaultableModuleBase
1023 prebuilt android.Prebuilt
Paul Duffindd46f712020-02-10 13:37:10 +00001024 android.ApexModuleBase
1025 android.SdkBase
Colin Cross79c7c262019-04-17 11:11:46 -07001026
1027 properties sdkLibraryImportProperties
1028
Paul Duffin46a26a82020-04-07 19:27:04 +01001029 // Map from api scope to the scope specific property structure.
1030 scopeProperties map[*apiScope]*sdkLibraryScopeProperties
1031
Paul Duffin56d44902020-01-31 13:36:25 +00001032 commonToSdkLibraryAndImport
Colin Cross79c7c262019-04-17 11:11:46 -07001033}
1034
1035var _ SdkLibraryDependency = (*sdkLibraryImport)(nil)
1036
Paul Duffin46a26a82020-04-07 19:27:04 +01001037// The type of a structure that contains a field of type sdkLibraryScopeProperties
1038// for each apiscope in allApiScopes, e.g. something like:
1039// struct {
1040// Public sdkLibraryScopeProperties
1041// System sdkLibraryScopeProperties
1042// ...
1043// }
1044var allScopeStructType = createAllScopePropertiesStructType()
1045
1046// Dynamically create a structure type for each apiscope in allApiScopes.
1047func createAllScopePropertiesStructType() reflect.Type {
1048 var fields []reflect.StructField
1049 for _, apiScope := range allApiScopes {
1050 field := reflect.StructField{
1051 Name: apiScope.fieldName,
1052 Type: reflect.TypeOf(sdkLibraryScopeProperties{}),
1053 }
1054 fields = append(fields, field)
1055 }
1056
1057 return reflect.StructOf(fields)
1058}
1059
1060// Create an instance of the scope specific structure type and return a map
1061// from apiscope to a pointer to each scope specific field.
1062func createPropertiesInstance() (interface{}, map[*apiScope]*sdkLibraryScopeProperties) {
1063 allScopePropertiesPtr := reflect.New(allScopeStructType)
1064 allScopePropertiesStruct := allScopePropertiesPtr.Elem()
1065 scopeProperties := make(map[*apiScope]*sdkLibraryScopeProperties)
1066
1067 for _, apiScope := range allApiScopes {
1068 field := allScopePropertiesStruct.FieldByName(apiScope.fieldName)
1069 scopeProperties[apiScope] = field.Addr().Interface().(*sdkLibraryScopeProperties)
1070 }
1071
1072 return allScopePropertiesPtr.Interface(), scopeProperties
1073}
1074
Jaewoong Jung4f158ee2019-07-11 10:05:35 -07001075// java_sdk_library_import imports a prebuilt java_sdk_library.
Colin Cross79c7c262019-04-17 11:11:46 -07001076func sdkLibraryImportFactory() android.Module {
1077 module := &sdkLibraryImport{}
1078
Paul Duffin46a26a82020-04-07 19:27:04 +01001079 allScopeProperties, scopeToProperties := createPropertiesInstance()
1080 module.scopeProperties = scopeToProperties
1081 module.AddProperties(&module.properties, allScopeProperties)
Colin Cross79c7c262019-04-17 11:11:46 -07001082
Paul Duffin0bdcb272020-02-06 15:24:57 +00001083 android.InitPrebuiltModule(module, &[]string{""})
Paul Duffindd46f712020-02-10 13:37:10 +00001084 android.InitApexModule(module)
1085 android.InitSdkAwareModule(module)
Colin Cross79c7c262019-04-17 11:11:46 -07001086 InitJavaModule(module, android.HostAndDeviceSupported)
1087
Paul Duffin6e7ecbf2020-05-08 15:01:19 +01001088 module.SetDefaultableHook(func(mctx android.DefaultableHookContext) { module.createInternalModules(mctx) })
Colin Cross79c7c262019-04-17 11:11:46 -07001089 return module
1090}
1091
1092func (module *sdkLibraryImport) Prebuilt() *android.Prebuilt {
1093 return &module.prebuilt
1094}
1095
1096func (module *sdkLibraryImport) Name() string {
1097 return module.prebuilt.Name(module.ModuleBase.Name())
1098}
1099
Paul Duffin6e7ecbf2020-05-08 15:01:19 +01001100func (module *sdkLibraryImport) createInternalModules(mctx android.DefaultableHookContext) {
Colin Cross79c7c262019-04-17 11:11:46 -07001101
Paul Duffin50061512020-01-21 16:31:05 +00001102 // If the build is configured to use prebuilts then force this to be preferred.
1103 if mctx.Config().UnbundledBuildUsePrebuiltSdks() {
1104 module.prebuilt.ForcePrefer()
1105 }
1106
Paul Duffin46a26a82020-04-07 19:27:04 +01001107 for apiScope, scopeProperties := range module.scopeProperties {
Paul Duffin56d44902020-01-31 13:36:25 +00001108 if len(scopeProperties.Jars) == 0 {
1109 continue
1110 }
1111
Paul Duffinbbb546b2020-04-09 00:07:11 +01001112 module.createJavaImportForStubs(mctx, apiScope, scopeProperties)
Paul Duffin3d1248c2020-04-09 00:10:17 +01001113
1114 module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties)
Paul Duffin56d44902020-01-31 13:36:25 +00001115 }
Colin Cross79c7c262019-04-17 11:11:46 -07001116
1117 javaSdkLibraries := javaSdkLibraries(mctx.Config())
1118 javaSdkLibrariesLock.Lock()
1119 defer javaSdkLibrariesLock.Unlock()
1120 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
1121}
1122
Paul Duffin6e7ecbf2020-05-08 15:01:19 +01001123func (module *sdkLibraryImport) createJavaImportForStubs(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
Paul Duffinbbb546b2020-04-09 00:07:11 +01001124 // Creates a java import for the jar with ".stubs" suffix
1125 props := struct {
1126 Name *string
1127 Soc_specific *bool
1128 Device_specific *bool
1129 Product_specific *bool
1130 System_ext_specific *bool
1131 Sdk_version *string
1132 Libs []string
1133 Jars []string
1134 Prefer *bool
1135 }{}
1136 props.Name = proptools.StringPtr(apiScope.stubsModuleName(module.BaseModuleName()))
1137 props.Sdk_version = scopeProperties.Sdk_version
1138 // Prepend any of the libs from the legacy public properties to the libs for each of the
1139 // scopes to avoid having to duplicate them in each scope.
1140 props.Libs = append(module.properties.Libs, scopeProperties.Libs...)
1141 props.Jars = scopeProperties.Jars
1142 if module.SocSpecific() {
1143 props.Soc_specific = proptools.BoolPtr(true)
1144 } else if module.DeviceSpecific() {
1145 props.Device_specific = proptools.BoolPtr(true)
1146 } else if module.ProductSpecific() {
1147 props.Product_specific = proptools.BoolPtr(true)
1148 } else if module.SystemExtSpecific() {
1149 props.System_ext_specific = proptools.BoolPtr(true)
1150 }
1151 // If the build should use prebuilt sdks then set prefer to true on the stubs library.
1152 // That will cause the prebuilt version of the stubs to override the source version.
1153 if mctx.Config().UnbundledBuildUsePrebuiltSdks() {
1154 props.Prefer = proptools.BoolPtr(true)
1155 }
1156 mctx.CreateModule(ImportFactory, &props)
1157}
1158
Paul Duffin6e7ecbf2020-05-08 15:01:19 +01001159func (module *sdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
Paul Duffin3d1248c2020-04-09 00:10:17 +01001160 props := struct {
1161 Name *string
1162 Srcs []string
1163 }{}
1164 props.Name = proptools.StringPtr(apiScope.docsModuleName(module.BaseModuleName()))
1165 props.Srcs = scopeProperties.Stub_srcs
1166 mctx.CreateModule(PrebuiltStubsSourcesFactory, &props)
1167}
1168
Colin Cross79c7c262019-04-17 11:11:46 -07001169func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
Paul Duffin46a26a82020-04-07 19:27:04 +01001170 for apiScope, scopeProperties := range module.scopeProperties {
Paul Duffin56d44902020-01-31 13:36:25 +00001171 if len(scopeProperties.Jars) == 0 {
1172 continue
1173 }
1174
1175 // Add dependencies to the prebuilt stubs library
1176 ctx.AddVariationDependencies(nil, apiScope.stubsTag, apiScope.stubsModuleName(module.BaseModuleName()))
1177 }
Colin Cross79c7c262019-04-17 11:11:46 -07001178}
1179
1180func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1181 // Record the paths to the prebuilt stubs library.
1182 ctx.VisitDirectDeps(func(to android.Module) {
1183 tag := ctx.OtherModuleDependencyTag(to)
1184
Paul Duffin56d44902020-01-31 13:36:25 +00001185 if lib, ok := to.(Dependency); ok {
1186 if scopeTag, ok := tag.(scopeDependencyTag); ok {
1187 apiScope := scopeTag.apiScope
1188 scopePaths := module.getScopePaths(apiScope)
1189 scopePaths.stubsHeaderPath = lib.HeaderJars()
1190 }
Colin Cross79c7c262019-04-17 11:11:46 -07001191 }
1192 })
1193}
1194
Paul Duffin56d44902020-01-31 13:36:25 +00001195func (module *sdkLibraryImport) sdkJars(
1196 ctx android.BaseModuleContext,
1197 sdkVersion sdkSpec) android.Paths {
1198
Paul Duffin50061512020-01-21 16:31:05 +00001199 // If a specific numeric version has been requested then use prebuilt versions of the sdk.
1200 if sdkVersion.version.isNumbered() {
1201 return PrebuiltJars(ctx, module.BaseModuleName(), sdkVersion)
1202 }
1203
Paul Duffin56d44902020-01-31 13:36:25 +00001204 var apiScope *apiScope
1205 switch sdkVersion.kind {
1206 case sdkSystem:
1207 apiScope = apiScopeSystem
1208 case sdkTest:
1209 apiScope = apiScopeTest
1210 default:
1211 apiScope = apiScopePublic
1212 }
1213
1214 paths := module.getScopePaths(apiScope)
1215 return paths.stubsHeaderPath
1216}
1217
Colin Cross79c7c262019-04-17 11:11:46 -07001218// to satisfy SdkLibraryDependency interface
Jiyong Park6a927c42020-01-21 02:03:43 +09001219func (module *sdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
Colin Cross79c7c262019-04-17 11:11:46 -07001220 // This module is just a wrapper for the prebuilt stubs.
Paul Duffin56d44902020-01-31 13:36:25 +00001221 return module.sdkJars(ctx, sdkVersion)
Colin Cross79c7c262019-04-17 11:11:46 -07001222}
1223
1224// to satisfy SdkLibraryDependency interface
Jiyong Park6a927c42020-01-21 02:03:43 +09001225func (module *sdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
Colin Cross79c7c262019-04-17 11:11:46 -07001226 // This module is just a wrapper for the stubs.
Paul Duffin56d44902020-01-31 13:36:25 +00001227 return module.sdkJars(ctx, sdkVersion)
Colin Cross79c7c262019-04-17 11:11:46 -07001228}
Jiyong Parke3833882020-02-17 17:28:10 +09001229
1230//
1231// java_sdk_library_xml
1232//
1233type sdkLibraryXml struct {
1234 android.ModuleBase
1235 android.DefaultableModuleBase
1236 android.ApexModuleBase
1237
1238 properties sdkLibraryXmlProperties
1239
1240 outputFilePath android.OutputPath
1241 installDirPath android.InstallPath
1242}
1243
1244type sdkLibraryXmlProperties struct {
1245 // canonical name of the lib
1246 Lib_name *string
1247}
1248
1249// java_sdk_library_xml builds the permission xml file for a java_sdk_library.
1250// Not to be used directly by users. java_sdk_library internally uses this.
1251func sdkLibraryXmlFactory() android.Module {
1252 module := &sdkLibraryXml{}
1253
1254 module.AddProperties(&module.properties)
1255
1256 android.InitApexModule(module)
1257 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
1258
1259 return module
1260}
1261
1262// from android.PrebuiltEtcModule
1263func (module *sdkLibraryXml) SubDir() string {
1264 return "permissions"
1265}
1266
1267// from android.PrebuiltEtcModule
1268func (module *sdkLibraryXml) OutputFile() android.OutputPath {
1269 return module.outputFilePath
1270}
1271
1272// from android.ApexModule
1273func (module *sdkLibraryXml) AvailableFor(what string) bool {
1274 return true
1275}
1276
1277func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) {
1278 // do nothing
1279}
1280
1281// File path to the runtime implementation library
1282func (module *sdkLibraryXml) implPath() string {
1283 implName := proptools.String(module.properties.Lib_name)
1284 if apexName := module.ApexName(); apexName != "" {
1285 // TODO(b/146468504): ApexName() is only a soong module name, not apex name.
1286 // In most cases, this works fine. But when apex_name is set or override_apex is used
1287 // this can be wrong.
1288 return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, implName)
1289 }
1290 partition := "system"
1291 if module.SocSpecific() {
1292 partition = "vendor"
1293 } else if module.DeviceSpecific() {
1294 partition = "odm"
1295 } else if module.ProductSpecific() {
1296 partition = "product"
1297 } else if module.SystemExtSpecific() {
1298 partition = "system_ext"
1299 }
1300 return "/" + partition + "/framework/" + implName + ".jar"
1301}
1302
1303func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1304 libName := proptools.String(module.properties.Lib_name)
1305 xmlContent := fmt.Sprintf(permissionsTemplate, libName, module.implPath())
1306
1307 module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath
1308 rule := android.NewRuleBuilder()
1309 rule.Command().
1310 Text("/bin/bash -c \"echo -e '" + xmlContent + "'\" > ").
1311 Output(module.outputFilePath)
1312
1313 rule.Build(pctx, ctx, "java_sdk_xml", "Permission XML")
1314
1315 module.installDirPath = android.PathForModuleInstall(ctx, "etc", module.SubDir())
1316}
1317
1318func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
1319 if !module.IsForPlatform() {
1320 return []android.AndroidMkEntries{android.AndroidMkEntries{
1321 Disabled: true,
1322 }}
1323 }
1324
1325 return []android.AndroidMkEntries{android.AndroidMkEntries{
1326 Class: "ETC",
1327 OutputFile: android.OptionalPathForPath(module.outputFilePath),
1328 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
1329 func(entries *android.AndroidMkEntries) {
1330 entries.SetString("LOCAL_MODULE_TAGS", "optional")
1331 entries.SetString("LOCAL_MODULE_PATH", module.installDirPath.ToMakePath().String())
1332 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", module.outputFilePath.Base())
1333 },
1334 },
1335 }}
1336}
Paul Duffindd46f712020-02-10 13:37:10 +00001337
1338type sdkLibrarySdkMemberType struct {
1339 android.SdkMemberTypeBase
1340}
1341
1342func (s *sdkLibrarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
1343 mctx.AddVariationDependencies(nil, dependencyTag, names...)
1344}
1345
1346func (s *sdkLibrarySdkMemberType) IsInstance(module android.Module) bool {
1347 _, ok := module.(*SdkLibrary)
1348 return ok
1349}
1350
1351func (s *sdkLibrarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
1352 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_sdk_library_import")
1353}
1354
1355func (s *sdkLibrarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
1356 return &sdkLibrarySdkMemberProperties{}
1357}
1358
1359type sdkLibrarySdkMemberProperties struct {
1360 android.SdkMemberPropertiesBase
1361
1362 // Scope to per scope properties.
1363 Scopes map[*apiScope]scopeProperties
1364
1365 // Additional libraries that the exported stubs libraries depend upon.
1366 Libs []string
Paul Duffin3d1248c2020-04-09 00:10:17 +01001367
1368 // The Java stubs source files.
1369 Stub_srcs []string
Paul Duffindd46f712020-02-10 13:37:10 +00001370}
1371
1372type scopeProperties struct {
Paul Duffin1fd005d2020-04-09 01:08:11 +01001373 Jars android.Paths
1374 StubsSrcJar android.Path
1375 CurrentApiFile android.Path
1376 RemovedApiFile android.Path
1377 SdkVersion string
Paul Duffindd46f712020-02-10 13:37:10 +00001378}
1379
1380func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
1381 sdk := variant.(*SdkLibrary)
1382
1383 s.Scopes = make(map[*apiScope]scopeProperties)
1384 for _, apiScope := range allApiScopes {
1385 paths := sdk.getScopePaths(apiScope)
1386 jars := paths.stubsImplPath
1387 if len(jars) > 0 {
1388 properties := scopeProperties{}
1389 properties.Jars = jars
1390 properties.SdkVersion = apiScope.sdkVersion
Paul Duffin3d1248c2020-04-09 00:10:17 +01001391 properties.StubsSrcJar = paths.stubsSrcJar
Paul Duffin1fd005d2020-04-09 01:08:11 +01001392 properties.CurrentApiFile = paths.currentApiFilePath
1393 properties.RemovedApiFile = paths.removedApiFilePath
Paul Duffindd46f712020-02-10 13:37:10 +00001394 s.Scopes[apiScope] = properties
1395 }
1396 }
1397
1398 s.Libs = sdk.properties.Libs
1399}
1400
1401func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
1402 for _, apiScope := range allApiScopes {
1403 if properties, ok := s.Scopes[apiScope]; ok {
1404 scopeSet := propertySet.AddPropertySet(apiScope.name)
1405
Paul Duffin3d1248c2020-04-09 00:10:17 +01001406 scopeDir := filepath.Join("sdk_library", s.OsPrefix(), apiScope.name)
1407
Paul Duffindd46f712020-02-10 13:37:10 +00001408 var jars []string
1409 for _, p := range properties.Jars {
Paul Duffin3d1248c2020-04-09 00:10:17 +01001410 dest := filepath.Join(scopeDir, ctx.Name()+"-stubs.jar")
Paul Duffindd46f712020-02-10 13:37:10 +00001411 ctx.SnapshotBuilder().CopyToSnapshot(p, dest)
1412 jars = append(jars, dest)
1413 }
1414 scopeSet.AddProperty("jars", jars)
1415
Paul Duffin3d1248c2020-04-09 00:10:17 +01001416 // Merge the stubs source jar into the snapshot zip so that when it is unpacked
1417 // the source files are also unpacked.
1418 snapshotRelativeDir := filepath.Join(scopeDir, ctx.Name()+"_stub_sources")
1419 ctx.SnapshotBuilder().UnzipToSnapshot(properties.StubsSrcJar, snapshotRelativeDir)
1420 scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir})
1421
Paul Duffin1fd005d2020-04-09 01:08:11 +01001422 if properties.CurrentApiFile != nil {
1423 currentApiSnapshotPath := filepath.Join(scopeDir, ctx.Name()+".txt")
1424 ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, currentApiSnapshotPath)
1425 scopeSet.AddProperty("current_api", currentApiSnapshotPath)
1426 }
1427
1428 if properties.RemovedApiFile != nil {
1429 removedApiSnapshotPath := filepath.Join(scopeDir, ctx.Name()+"-removed.txt")
1430 ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, removedApiSnapshotPath)
1431 scopeSet.AddProperty("removed_api", removedApiSnapshotPath)
1432 }
1433
Paul Duffindd46f712020-02-10 13:37:10 +00001434 if properties.SdkVersion != "" {
1435 scopeSet.AddProperty("sdk_version", properties.SdkVersion)
1436 }
1437 }
1438 }
1439
1440 if len(s.Libs) > 0 {
1441 propertySet.AddPropertyWithTag("libs", s.Libs, ctx.SnapshotBuilder().SdkMemberReferencePropertyTag(false))
1442 }
1443}