blob: df4e08b536319227ed7f594af0585cb7bd6fe07b [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 (
18 "android/soong/android"
19 "android/soong/genrule"
20 "fmt"
Jiyong Park82484c02018-04-23 21:41:26 +090021 "io"
Jiyong Parkc678ad32018-04-10 13:07:10 +090022 "path"
Sundong Ahn054b19a2018-10-19 13:46:09 +090023 "path/filepath"
Jiyong Park82484c02018-04-23 21:41:26 +090024 "sort"
Jiyong Parkc678ad32018-04-10 13:07:10 +090025 "strings"
Jiyong Park82484c02018-04-23 21:41:26 +090026 "sync"
Jiyong Parkc678ad32018-04-10 13:07:10 +090027
28 "github.com/google/blueprint"
29 "github.com/google/blueprint/proptools"
30)
31
32var (
33 sdkStubsLibrarySuffix = ".stubs"
34 sdkSystemApiSuffix = ".system"
Jiyong Parkdf130542018-04-27 16:29:21 +090035 sdkTestApiSuffix = ".test"
Jiyong Parkc678ad32018-04-10 13:07:10 +090036 sdkDocsSuffix = ".docs"
Jiyong Parkc678ad32018-04-10 13:07:10 +090037 sdkXmlFileSuffix = ".xml"
38)
39
40type stubsLibraryDependencyTag struct {
41 blueprint.BaseDependencyTag
42 name string
43}
44
Inseob Kimc0907f12019-02-08 21:00:45 +090045type syspropLibraryInterface interface {
46 SyspropJavaModule() *SdkLibrary
47}
48
Jiyong Parkc678ad32018-04-10 13:07:10 +090049var (
50 publicApiStubsTag = dependencyTag{name: "public"}
51 systemApiStubsTag = dependencyTag{name: "system"}
Jiyong Parkdf130542018-04-27 16:29:21 +090052 testApiStubsTag = dependencyTag{name: "test"}
Sundong Ahn20e998b2018-07-24 11:19:26 +090053 publicApiFileTag = dependencyTag{name: "publicApi"}
54 systemApiFileTag = dependencyTag{name: "systemApi"}
55 testApiFileTag = dependencyTag{name: "testApi"}
Jiyong Parkdf130542018-04-27 16:29:21 +090056)
57
58type apiScope int
59
60const (
61 apiScopePublic apiScope = iota
62 apiScopeSystem
63 apiScopeTest
Jiyong Parkc678ad32018-04-10 13:07:10 +090064)
65
Jiyong Park82484c02018-04-23 21:41:26 +090066var (
67 javaSdkLibrariesLock sync.Mutex
68)
69
Jiyong Parkc678ad32018-04-10 13:07:10 +090070// java_sdk_library is to make a Java library that implements optional platform APIs to apps.
71// It is actually a wrapper of several modules: 1) stubs library that clients are linked against
72// to, 2) droiddoc module that internally generates API stubs source files, 3) the real runtime
73// shared library that implements the APIs, and 4) XML file for adding the runtime lib to the
74// classpath at runtime if requested via <uses-library>.
75//
76// TODO: these are big features that are currently missing
Jiyong Park1be96912018-05-28 18:02:19 +090077// 1) disallowing linking to the runtime shared lib
78// 2) HTML generation
Jiyong Parkc678ad32018-04-10 13:07:10 +090079
80func init() {
Inseob Kimc0907f12019-02-08 21:00:45 +090081 android.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
Jiyong Parkc678ad32018-04-10 13:07:10 +090082
83 android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
Inseob Kimc0907f12019-02-08 21:00:45 +090084 ctx.TopDown("java_sdk_library", SdkLibraryMutator).Parallel()
Jiyong Parkc678ad32018-04-10 13:07:10 +090085 })
Jiyong Park82484c02018-04-23 21:41:26 +090086
87 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
88 javaSdkLibraries := javaSdkLibraries(ctx.Config())
89 sort.Strings(*javaSdkLibraries)
90 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
91 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090092}
93
94type sdkLibraryProperties struct {
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +090095 // list of optional source files that are part of API but not part of runtime library.
96 Api_srcs []string `android:"arch_variant"`
97
Sundong Ahnf043cf62018-06-25 16:04:37 +090098 // List of Java libraries that will be in the classpath when building stubs
99 Stub_only_libs []string `android:"arch_variant"`
100
Jiyong Parkc678ad32018-04-10 13:07:10 +0900101 // list of package names that will be documented and publicized as API
102 Api_packages []string
103
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900104 // list of package names that must be hidden from the API
105 Hidden_api_packages []string
106
Paul Duffin11512472019-02-11 15:55:17 +0000107 // local files that are used within user customized droiddoc options.
108 Droiddoc_option_files []string
109
110 // additional droiddoc options
111 // Available variables for substitution:
112 //
113 // $(location <label>): the path to the droiddoc_option_files with name <label>
Sundong Ahndd567f92018-07-31 17:19:11 +0900114 Droiddoc_options []string
115
Sundong Ahnb952ba02019-01-08 16:32:12 +0900116 // the java library (in classpath) for documentation that provides java srcs and srcjars.
117 Srcs_lib *string
118
119 // the base dirs under srcs_lib will be scanned for java srcs.
120 Srcs_lib_whitelist_dirs []string
121
Sundong Ahndd567f92018-07-31 17:19:11 +0900122 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
123 // Defaults to "android.annotation".
124 Srcs_lib_whitelist_pkgs []string
125
Sundong Ahn054b19a2018-10-19 13:46:09 +0900126 // a list of top-level directories containing files to merge qualifier annotations
127 // (i.e. those intended to be included in the stubs written) from.
128 Merge_annotations_dirs []string
129
130 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
131 Merge_inclusion_annotations_dirs []string
132
133 // If set to true, the path of dist files is apistubs/core. Defaults to false.
134 Core_lib *bool
135
Jiyong Parkc678ad32018-04-10 13:07:10 +0900136 // TODO: determines whether to create HTML doc or not
137 //Html_doc *bool
138}
139
Inseob Kimc0907f12019-02-08 21:00:45 +0900140type SdkLibrary struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900141 Library
Jiyong Parkc678ad32018-04-10 13:07:10 +0900142
Sundong Ahn054b19a2018-10-19 13:46:09 +0900143 sdkLibraryProperties sdkLibraryProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900144
145 publicApiStubsPath android.Paths
146 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900147 testApiStubsPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900148
149 publicApiStubsImplPath android.Paths
150 systemApiStubsImplPath android.Paths
151 testApiStubsImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900152
153 publicApiFilePath android.Path
154 systemApiFilePath android.Path
155 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900156}
157
Inseob Kimc0907f12019-02-08 21:00:45 +0900158var _ Dependency = (*SdkLibrary)(nil)
159var _ SdkLibraryDependency = (*SdkLibrary)(nil)
Colin Cross897d2ed2019-02-11 14:03:51 -0800160
Inseob Kimc0907f12019-02-08 21:00:45 +0900161func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900162 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700163 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
Colin Cross42d48b72018-08-29 14:10:52 -0700164 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900165
166 if !Bool(module.properties.No_standard_libs) {
167 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
168 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
169 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
170 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
171 }
172
173 module.Library.deps(ctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900174}
175
Inseob Kimc0907f12019-02-08 21:00:45 +0900176func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900177 module.Library.GenerateAndroidBuildActions(ctx)
178
Sundong Ahn57368eb2018-07-06 11:20:23 +0900179 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900180 // When this java_sdk_library is dependened from others via "libs" property,
181 // the recorded paths will be returned depending on the link type of the caller.
182 ctx.VisitDirectDeps(func(to android.Module) {
183 otherName := ctx.OtherModuleName(to)
184 tag := ctx.OtherModuleDependencyTag(to)
185
Sundong Ahn57368eb2018-07-06 11:20:23 +0900186 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900187 switch tag {
188 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900189 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900190 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900191 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900192 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900193 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900194 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900195 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900196 module.testApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900197 }
198 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900199 if doc, ok := to.(ApiFilePath); ok {
200 switch tag {
201 case publicApiFileTag:
202 module.publicApiFilePath = doc.ApiFilePath()
203 case systemApiFileTag:
204 module.systemApiFilePath = doc.ApiFilePath()
205 case testApiFileTag:
206 module.testApiFilePath = doc.ApiFilePath()
207 default:
208 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
209 }
210 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900211 })
212}
213
Inseob Kimc0907f12019-02-08 21:00:45 +0900214func (module *SdkLibrary) AndroidMk() android.AndroidMkData {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900215 data := module.Library.AndroidMk()
216 data.Required = append(data.Required, module.xmlFileName())
217
218 data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
219 android.WriteAndroidMkData(w, data)
220
221 module.Library.AndroidMkHostDex(w, name, data)
222 // Create a phony module that installs the impl library, for the case when this lib is
223 // in PRODUCT_PACKAGES.
224 owner := module.ModuleBase.Owner()
225 if owner == "" {
226 if Bool(module.sdkLibraryProperties.Core_lib) {
227 owner = "core"
228 } else {
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900229 owner = "android"
230 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900231 }
232 // Create dist rules to install the stubs libs to the dist dir
233 if len(module.publicApiStubsPath) == 1 {
234 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
235 module.publicApiStubsImplPath.Strings()[0]+
236 ":"+path.Join("apistubs", owner, "public",
237 module.BaseModuleName()+".jar")+")")
238 }
239 if len(module.systemApiStubsPath) == 1 {
240 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
241 module.systemApiStubsImplPath.Strings()[0]+
242 ":"+path.Join("apistubs", owner, "system",
243 module.BaseModuleName()+".jar")+")")
244 }
245 if len(module.testApiStubsPath) == 1 {
246 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
247 module.testApiStubsImplPath.Strings()[0]+
248 ":"+path.Join("apistubs", owner, "test",
249 module.BaseModuleName()+".jar")+")")
250 }
251 if module.publicApiFilePath != nil {
252 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
253 module.publicApiFilePath.String()+
254 ":"+path.Join("apistubs", owner, "public", "api",
255 module.BaseModuleName()+".txt")+")")
256 }
257 if module.systemApiFilePath != nil {
258 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
259 module.systemApiFilePath.String()+
260 ":"+path.Join("apistubs", owner, "system", "api",
261 module.BaseModuleName()+".txt")+")")
262 }
263 if module.testApiFilePath != nil {
264 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
265 module.testApiFilePath.String()+
266 ":"+path.Join("apistubs", owner, "test", "api",
267 module.BaseModuleName()+".txt")+")")
268 }
Jiyong Park82484c02018-04-23 21:41:26 +0900269 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900270 return data
Jiyong Park82484c02018-04-23 21:41:26 +0900271}
272
Jiyong Parkc678ad32018-04-10 13:07:10 +0900273// Module name of the stubs library
Inseob Kimc0907f12019-02-08 21:00:45 +0900274func (module *SdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900275 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900276 switch apiScope {
277 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900278 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900279 case apiScopeTest:
280 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900281 }
282 return stubsName
283}
284
285// Module name of the docs
Inseob Kimc0907f12019-02-08 21:00:45 +0900286func (module *SdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900287 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900288 switch apiScope {
289 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900290 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900291 case apiScopeTest:
292 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900293 }
294 return docsName
295}
296
297// Module name of the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900298func (module *SdkLibrary) implName() string {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900299 return module.BaseModuleName()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900300}
301
302// File path to the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900303func (module *SdkLibrary) implPath() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900304 partition := "system"
305 if module.SocSpecific() {
306 partition = "vendor"
307 } else if module.DeviceSpecific() {
308 partition = "odm"
309 } else if module.ProductSpecific() {
310 partition = "product"
311 }
312 return "/" + partition + "/framework/" + module.implName() + ".jar"
313}
314
315// Module name of the XML file for the lib
Inseob Kimc0907f12019-02-08 21:00:45 +0900316func (module *SdkLibrary) xmlFileName() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900317 return module.BaseModuleName() + sdkXmlFileSuffix
318}
319
320// SDK version that the stubs library is built against. Note that this is always
321// *current. Older stubs library built with a numberd SDK version is created from
322// the prebuilt jar.
Inseob Kimc0907f12019-02-08 21:00:45 +0900323func (module *SdkLibrary) sdkVersion(apiScope apiScope) string {
Jiyong Parkdf130542018-04-27 16:29:21 +0900324 switch apiScope {
325 case apiScopePublic:
326 return "current"
327 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900328 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900329 case apiScopeTest:
330 return "test_current"
331 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900332 return "current"
333 }
334}
335
336// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
337// api file for the current source
338// TODO: remove this when apicheck is done in soong
Inseob Kimc0907f12019-02-08 21:00:45 +0900339func (module *SdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900340 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900341 switch apiScope {
342 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900343 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900344 case apiScopeTest:
345 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900346 }
347 return apiTagName
348}
349
Inseob Kimc0907f12019-02-08 21:00:45 +0900350func (module *SdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
Jiyong Park58c518b2018-05-12 22:29:12 +0900351 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900352 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900353 case apiScopePublic:
354 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900355 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900356 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900357 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900358 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900359 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900360 name = name + ".latest"
361 return name
362}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900363
Inseob Kimc0907f12019-02-08 21:00:45 +0900364func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
Jiyong Park58c518b2018-05-12 22:29:12 +0900365 name := ":" + module.BaseModuleName() + "-removed.api."
366 switch apiScope {
367 case apiScopePublic:
368 name = name + "public"
369 case apiScopeSystem:
370 name = name + "system"
371 case apiScopeTest:
372 name = name + "test"
373 }
374 name = name + ".latest"
375 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900376}
377
378// Creates a static java library that has API stubs
Inseob Kimc0907f12019-02-08 21:00:45 +0900379func (module *SdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900380 props := struct {
381 Name *string
382 Srcs []string
383 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900384 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900385 Soc_specific *bool
386 Device_specific *bool
387 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900388 Compile_dex *bool
Sundong Ahn054b19a2018-10-19 13:46:09 +0900389 No_standard_libs *bool
390 System_modules *string
391 Java_version *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900392 Product_variables struct {
393 Unbundled_build struct {
394 Enabled *bool
395 }
Jiyong Park82484c02018-04-23 21:41:26 +0900396 Pdk struct {
397 Enabled *bool
398 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900399 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900400 Openjdk9 struct {
401 Srcs []string
402 Javacflags []string
403 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900404 }{}
405
Jiyong Parkdf130542018-04-27 16:29:21 +0900406 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900407 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900408 props.Srcs = []string{":" + module.docsName(apiScope)}
409 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900410 props.Libs = module.sdkLibraryProperties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900411 // Unbundled apps will use the prebult one from /prebuilts/sdk
Colin Cross2c77ceb2019-01-21 11:56:21 -0800412 if mctx.Config().UnbundledBuildPrebuiltSdks() {
413 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
414 }
Jiyong Park82484c02018-04-23 21:41:26 +0900415 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900416 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
417 props.System_modules = module.Library.Module.deviceProperties.System_modules
418 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
419 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
420 props.Java_version = module.Library.Module.properties.Java_version
421 if module.Library.Module.deviceProperties.Compile_dex != nil {
422 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900423 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900424
425 if module.SocSpecific() {
426 props.Soc_specific = proptools.BoolPtr(true)
427 } else if module.DeviceSpecific() {
428 props.Device_specific = proptools.BoolPtr(true)
429 } else if module.ProductSpecific() {
430 props.Product_specific = proptools.BoolPtr(true)
431 }
432
Colin Cross9ae1b922018-06-26 17:59:05 -0700433 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900434}
435
436// Creates a droiddoc module that creates stubs source files from the given full source
437// files
Inseob Kimc0907f12019-02-08 21:00:45 +0900438func (module *SdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900439 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900440 Name *string
441 Srcs []string
442 Installable *bool
443 Srcs_lib *string
444 Srcs_lib_whitelist_dirs []string
445 Srcs_lib_whitelist_pkgs []string
446 Libs []string
Paul Duffin11512472019-02-11 15:55:17 +0000447 Arg_files []string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900448 Args *string
449 Api_tag_name *string
450 Api_filename *string
451 Removed_api_filename *string
452 No_standard_libs *bool
453 Java_version *string
454 Merge_annotations_dirs []string
455 Merge_inclusion_annotations_dirs []string
456 Check_api struct {
Jiyong Park58c518b2018-05-12 22:29:12 +0900457 Current ApiToCheck
458 Last_released ApiToCheck
459 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900460 Aidl struct {
461 Include_dirs []string
462 Local_include_dirs []string
463 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900464 }{}
465
Jiyong Parkdf130542018-04-27 16:29:21 +0900466 props.Name = proptools.StringPtr(module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900467 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
468 props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900469 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900470 // A droiddoc module has only one Libs property and doesn't distinguish between
471 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900472 props.Libs = module.Library.Module.properties.Libs
473 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
474 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
475 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
476 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
477 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900478
Sundong Ahn054b19a2018-10-19 13:46:09 +0900479 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
480 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
481
482 droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
483 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
484 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900485 " --hide MissingPermission --hide BroadcastBehavior " +
486 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
487 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900488
Jiyong Parkdf130542018-04-27 16:29:21 +0900489 switch apiScope {
490 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900491 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900492 case apiScopeTest:
493 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900494 }
Paul Duffin11512472019-02-11 15:55:17 +0000495 props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
Jiyong Parkc678ad32018-04-10 13:07:10 +0900496 props.Args = proptools.StringPtr(droiddocArgs)
497
498 // List of APIs identified from the provided source files are created. They are later
499 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
500 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900501 currentApiFileName := "current.txt"
502 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900503 switch apiScope {
504 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900505 currentApiFileName = "system-" + currentApiFileName
506 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900507 case apiScopeTest:
508 currentApiFileName = "test-" + currentApiFileName
509 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900510 }
511 currentApiFileName = path.Join("api", currentApiFileName)
512 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900513 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900514 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900515 props.Api_filename = proptools.StringPtr(currentApiFileName)
516 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
517
Jiyong Park58c518b2018-05-12 22:29:12 +0900518 // check against the not-yet-release API
519 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
520 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900521
522 // check against the latest released API
523 props.Check_api.Last_released.Api_file = proptools.StringPtr(
524 module.latestApiFilegroupName(apiScope))
525 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
526 module.latestRemovedApiFilegroupName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900527 props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
528 props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
529 props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900530
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900531 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900532}
533
Jiyong Parkc678ad32018-04-10 13:07:10 +0900534// Creates the xml file that publicizes the runtime library
Inseob Kimc0907f12019-02-08 21:00:45 +0900535func (module *SdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900536 template := `
537<?xml version="1.0" encoding="utf-8"?>
538<!-- Copyright (C) 2018 The Android Open Source Project
539
540 Licensed under the Apache License, Version 2.0 (the "License");
541 you may not use this file except in compliance with the License.
542 You may obtain a copy of the License at
543
544 http://www.apache.org/licenses/LICENSE-2.0
545
546 Unless required by applicable law or agreed to in writing, software
547 distributed under the License is distributed on an "AS IS" BASIS,
548 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
549 See the License for the specific language governing permissions and
550 limitations under the License.
551-->
552
553<permissions>
554 <library name="%s" file="%s"/>
555</permissions>
556`
557 // genrule to generate the xml file content from the template above
558 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
559 // in the ninja file. Do we need to have an external tool for this?
560 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
561 genruleProps := struct {
562 Name *string
563 Cmd *string
564 Out []string
565 }{}
566 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
567 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
568 genruleProps.Out = []string{module.xmlFileName()}
569 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
570
571 // creates a prebuilt_etc module to actually place the xml file under
572 // <partition>/etc/permissions
573 etcProps := struct {
574 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900575 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900576 Sub_dir *string
577 Soc_specific *bool
578 Device_specific *bool
579 Product_specific *bool
580 }{}
581 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900582 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900583 etcProps.Sub_dir = proptools.StringPtr("permissions")
584 if module.SocSpecific() {
585 etcProps.Soc_specific = proptools.BoolPtr(true)
586 } else if module.DeviceSpecific() {
587 etcProps.Device_specific = proptools.BoolPtr(true)
588 } else if module.ProductSpecific() {
589 etcProps.Product_specific = proptools.BoolPtr(true)
590 }
591 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
592}
593
Inseob Kimc0907f12019-02-08 21:00:45 +0900594func (module *SdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900595 var api, v string
596 if sdkVersion == "" {
597 api = "system"
598 v = "current"
599 } else if strings.Contains(sdkVersion, "_") {
600 t := strings.Split(sdkVersion, "_")
601 api = t[0]
602 v = t[1]
Jiyong Parkc678ad32018-04-10 13:07:10 +0900603 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900604 api = "public"
605 v = sdkVersion
606 }
607 dir := filepath.Join("prebuilts", "sdk", v, api)
608 jar := filepath.Join(dir, module.BaseModuleName()+".jar")
609 jarPath := android.ExistentPathForSource(ctx, jar)
Sundong Ahnae418ac2019-02-28 15:01:28 +0900610 if !jarPath.Valid() {
611 ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", v, jar)
612 return nil
613 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900614 return android.Paths{jarPath.Path()}
615}
616
617// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900618func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900619 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800620 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900621 return module.PrebuiltJars(ctx, sdkVersion)
622 } else {
623 if strings.HasPrefix(sdkVersion, "system_") {
624 return module.systemApiStubsPath
625 } else if sdkVersion == "" {
626 return module.Library.HeaderJars()
627 } else {
628 return module.publicApiStubsPath
629 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900630 }
631}
632
Sundong Ahn241cd372018-07-13 16:16:44 +0900633// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900634func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn241cd372018-07-13 16:16:44 +0900635 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800636 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900637 return module.PrebuiltJars(ctx, sdkVersion)
Sundong Ahn241cd372018-07-13 16:16:44 +0900638 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900639 if strings.HasPrefix(sdkVersion, "system_") {
640 return module.systemApiStubsImplPath
641 } else if sdkVersion == "" {
642 return module.Library.ImplementationJars()
643 } else {
644 return module.publicApiStubsImplPath
645 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900646 }
647}
648
Colin Cross571cccf2019-02-04 11:22:08 -0800649var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
650
Jiyong Park82484c02018-04-23 21:41:26 +0900651func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -0800652 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +0900653 return &[]string{}
654 }).(*[]string)
655}
656
Jiyong Parkc678ad32018-04-10 13:07:10 +0900657// For a java_sdk_library module, create internal modules for stubs, docs,
658// runtime libs and xml file. If requested, the stubs and docs are created twice
659// once for public API level and once for system API level
Inseob Kimc0907f12019-02-08 21:00:45 +0900660func SdkLibraryMutator(mctx android.TopDownMutatorContext) {
661 if module, ok := mctx.Module().(*SdkLibrary); ok {
662 module.createInternalModules(mctx)
663 } else if module, ok := mctx.Module().(syspropLibraryInterface); ok {
664 module.SyspropJavaModule().createInternalModules(mctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900665 }
666}
667
Inseob Kimc0907f12019-02-08 21:00:45 +0900668func (module *SdkLibrary) createInternalModules(mctx android.TopDownMutatorContext) {
669 if module.Library.Module.properties.Srcs == nil {
670 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
671 }
672
673 if module.sdkLibraryProperties.Api_packages == nil {
674 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
675 }
676 // for public API stubs
677 module.createStubsLibrary(mctx, apiScopePublic)
678 module.createDocs(mctx, apiScopePublic)
679
680 if !Bool(module.properties.No_standard_libs) {
681 // for system API stubs
682 module.createStubsLibrary(mctx, apiScopeSystem)
683 module.createDocs(mctx, apiScopeSystem)
684
685 // for test API stubs
686 module.createStubsLibrary(mctx, apiScopeTest)
687 module.createDocs(mctx, apiScopeTest)
688
689 // for runtime
690 module.createXmlFile(mctx)
691 }
692
693 // record java_sdk_library modules so that they are exported to make
694 javaSdkLibraries := javaSdkLibraries(mctx.Config())
695 javaSdkLibrariesLock.Lock()
696 defer javaSdkLibrariesLock.Unlock()
697 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
698}
699
700func (module *SdkLibrary) InitSdkLibraryProperties() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900701 module.AddProperties(
702 &module.sdkLibraryProperties,
703 &module.Library.Module.properties,
704 &module.Library.Module.dexpreoptProperties,
705 &module.Library.Module.deviceProperties,
706 &module.Library.Module.protoProperties,
707 )
708
709 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
710 module.Library.Module.deviceProperties.IsSDKLibrary = true
Inseob Kimc0907f12019-02-08 21:00:45 +0900711}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900712
Inseob Kimc0907f12019-02-08 21:00:45 +0900713func SdkLibraryFactory() android.Module {
714 module := &SdkLibrary{}
715 module.InitSdkLibraryProperties()
Sundong Ahn054b19a2018-10-19 13:46:09 +0900716 InitJavaModule(module, android.HostAndDeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900717 return module
718}