blob: 6441c63346904e0bd26f7b60855fa10918bb5495 [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 {
Inseob Kim38449af2019-02-28 14:24:05 +0900457 Current ApiToCheck
458 Last_released ApiToCheck
459 Ignore_missing_latest_api *bool
Jiyong Park58c518b2018-05-12 22:29:12 +0900460 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900461 Aidl struct {
462 Include_dirs []string
463 Local_include_dirs []string
464 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900465 }{}
466
Jiyong Parkdf130542018-04-27 16:29:21 +0900467 props.Name = proptools.StringPtr(module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900468 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
469 props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900470 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900471 // A droiddoc module has only one Libs property and doesn't distinguish between
472 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900473 props.Libs = module.Library.Module.properties.Libs
474 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
475 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
476 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
477 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
478 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900479
Sundong Ahn054b19a2018-10-19 13:46:09 +0900480 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
481 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
482
483 droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
484 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
485 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900486 " --hide MissingPermission --hide BroadcastBehavior " +
487 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
488 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900489
Jiyong Parkdf130542018-04-27 16:29:21 +0900490 switch apiScope {
491 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900492 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900493 case apiScopeTest:
494 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900495 }
Paul Duffin11512472019-02-11 15:55:17 +0000496 props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
Jiyong Parkc678ad32018-04-10 13:07:10 +0900497 props.Args = proptools.StringPtr(droiddocArgs)
498
499 // List of APIs identified from the provided source files are created. They are later
500 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
501 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900502 currentApiFileName := "current.txt"
503 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900504 switch apiScope {
505 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900506 currentApiFileName = "system-" + currentApiFileName
507 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900508 case apiScopeTest:
509 currentApiFileName = "test-" + currentApiFileName
510 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900511 }
512 currentApiFileName = path.Join("api", currentApiFileName)
513 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900514 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900515 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900516 props.Api_filename = proptools.StringPtr(currentApiFileName)
517 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
518
Jiyong Park58c518b2018-05-12 22:29:12 +0900519 // check against the not-yet-release API
520 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
521 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900522
523 // check against the latest released API
524 props.Check_api.Last_released.Api_file = proptools.StringPtr(
525 module.latestApiFilegroupName(apiScope))
526 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
527 module.latestRemovedApiFilegroupName(apiScope))
Inseob Kim38449af2019-02-28 14:24:05 +0900528 props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900529 props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
530 props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
531 props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900532
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900533 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900534}
535
Jiyong Parkc678ad32018-04-10 13:07:10 +0900536// Creates the xml file that publicizes the runtime library
Inseob Kimc0907f12019-02-08 21:00:45 +0900537func (module *SdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900538 template := `
539<?xml version="1.0" encoding="utf-8"?>
540<!-- Copyright (C) 2018 The Android Open Source Project
541
542 Licensed under the Apache License, Version 2.0 (the "License");
543 you may not use this file except in compliance with the License.
544 You may obtain a copy of the License at
545
546 http://www.apache.org/licenses/LICENSE-2.0
547
548 Unless required by applicable law or agreed to in writing, software
549 distributed under the License is distributed on an "AS IS" BASIS,
550 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
551 See the License for the specific language governing permissions and
552 limitations under the License.
553-->
554
555<permissions>
556 <library name="%s" file="%s"/>
557</permissions>
558`
559 // genrule to generate the xml file content from the template above
560 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
561 // in the ninja file. Do we need to have an external tool for this?
562 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
563 genruleProps := struct {
564 Name *string
565 Cmd *string
566 Out []string
567 }{}
568 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
569 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
570 genruleProps.Out = []string{module.xmlFileName()}
571 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
572
573 // creates a prebuilt_etc module to actually place the xml file under
574 // <partition>/etc/permissions
575 etcProps := struct {
576 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900577 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900578 Sub_dir *string
579 Soc_specific *bool
580 Device_specific *bool
581 Product_specific *bool
582 }{}
583 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900584 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900585 etcProps.Sub_dir = proptools.StringPtr("permissions")
586 if module.SocSpecific() {
587 etcProps.Soc_specific = proptools.BoolPtr(true)
588 } else if module.DeviceSpecific() {
589 etcProps.Device_specific = proptools.BoolPtr(true)
590 } else if module.ProductSpecific() {
591 etcProps.Product_specific = proptools.BoolPtr(true)
592 }
593 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
594}
595
Inseob Kimc0907f12019-02-08 21:00:45 +0900596func (module *SdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900597 var api, v string
598 if sdkVersion == "" {
599 api = "system"
600 v = "current"
601 } else if strings.Contains(sdkVersion, "_") {
602 t := strings.Split(sdkVersion, "_")
603 api = t[0]
604 v = t[1]
Jiyong Parkc678ad32018-04-10 13:07:10 +0900605 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900606 api = "public"
607 v = sdkVersion
608 }
609 dir := filepath.Join("prebuilts", "sdk", v, api)
610 jar := filepath.Join(dir, module.BaseModuleName()+".jar")
611 jarPath := android.ExistentPathForSource(ctx, jar)
Sundong Ahnae418ac2019-02-28 15:01:28 +0900612 if !jarPath.Valid() {
613 ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", v, jar)
614 return nil
615 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900616 return android.Paths{jarPath.Path()}
617}
618
619// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900620func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900621 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800622 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900623 return module.PrebuiltJars(ctx, sdkVersion)
624 } else {
625 if strings.HasPrefix(sdkVersion, "system_") {
626 return module.systemApiStubsPath
627 } else if sdkVersion == "" {
628 return module.Library.HeaderJars()
629 } else {
630 return module.publicApiStubsPath
631 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900632 }
633}
634
Sundong Ahn241cd372018-07-13 16:16:44 +0900635// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900636func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn241cd372018-07-13 16:16:44 +0900637 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800638 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900639 return module.PrebuiltJars(ctx, sdkVersion)
Sundong Ahn241cd372018-07-13 16:16:44 +0900640 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900641 if strings.HasPrefix(sdkVersion, "system_") {
642 return module.systemApiStubsImplPath
643 } else if sdkVersion == "" {
644 return module.Library.ImplementationJars()
645 } else {
646 return module.publicApiStubsImplPath
647 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900648 }
649}
650
Colin Cross571cccf2019-02-04 11:22:08 -0800651var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
652
Jiyong Park82484c02018-04-23 21:41:26 +0900653func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -0800654 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +0900655 return &[]string{}
656 }).(*[]string)
657}
658
Jiyong Parkc678ad32018-04-10 13:07:10 +0900659// For a java_sdk_library module, create internal modules for stubs, docs,
660// runtime libs and xml file. If requested, the stubs and docs are created twice
661// once for public API level and once for system API level
Inseob Kimc0907f12019-02-08 21:00:45 +0900662func SdkLibraryMutator(mctx android.TopDownMutatorContext) {
663 if module, ok := mctx.Module().(*SdkLibrary); ok {
664 module.createInternalModules(mctx)
665 } else if module, ok := mctx.Module().(syspropLibraryInterface); ok {
666 module.SyspropJavaModule().createInternalModules(mctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900667 }
668}
669
Inseob Kimc0907f12019-02-08 21:00:45 +0900670func (module *SdkLibrary) createInternalModules(mctx android.TopDownMutatorContext) {
671 if module.Library.Module.properties.Srcs == nil {
672 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
673 }
674
675 if module.sdkLibraryProperties.Api_packages == nil {
676 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
677 }
678 // for public API stubs
679 module.createStubsLibrary(mctx, apiScopePublic)
680 module.createDocs(mctx, apiScopePublic)
681
682 if !Bool(module.properties.No_standard_libs) {
683 // for system API stubs
684 module.createStubsLibrary(mctx, apiScopeSystem)
685 module.createDocs(mctx, apiScopeSystem)
686
687 // for test API stubs
688 module.createStubsLibrary(mctx, apiScopeTest)
689 module.createDocs(mctx, apiScopeTest)
690
691 // for runtime
692 module.createXmlFile(mctx)
693 }
694
695 // record java_sdk_library modules so that they are exported to make
696 javaSdkLibraries := javaSdkLibraries(mctx.Config())
697 javaSdkLibrariesLock.Lock()
698 defer javaSdkLibrariesLock.Unlock()
699 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
700}
701
702func (module *SdkLibrary) InitSdkLibraryProperties() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900703 module.AddProperties(
704 &module.sdkLibraryProperties,
705 &module.Library.Module.properties,
706 &module.Library.Module.dexpreoptProperties,
707 &module.Library.Module.deviceProperties,
708 &module.Library.Module.protoProperties,
709 )
710
711 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
712 module.Library.Module.deviceProperties.IsSDKLibrary = true
Inseob Kimc0907f12019-02-08 21:00:45 +0900713}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900714
Inseob Kimc0907f12019-02-08 21:00:45 +0900715func SdkLibraryFactory() android.Module {
716 module := &SdkLibrary{}
717 module.InitSdkLibraryProperties()
Sundong Ahn054b19a2018-10-19 13:46:09 +0900718 InitJavaModule(module, android.HostAndDeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900719 return module
720}