blob: 3bda9c7b83c1a6e5e9513cd136600aa71c6fe169 [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
45var (
46 publicApiStubsTag = dependencyTag{name: "public"}
47 systemApiStubsTag = dependencyTag{name: "system"}
Jiyong Parkdf130542018-04-27 16:29:21 +090048 testApiStubsTag = dependencyTag{name: "test"}
Sundong Ahn20e998b2018-07-24 11:19:26 +090049 publicApiFileTag = dependencyTag{name: "publicApi"}
50 systemApiFileTag = dependencyTag{name: "systemApi"}
51 testApiFileTag = dependencyTag{name: "testApi"}
Jiyong Parkdf130542018-04-27 16:29:21 +090052)
53
54type apiScope int
55
56const (
57 apiScopePublic apiScope = iota
58 apiScopeSystem
59 apiScopeTest
Jiyong Parkc678ad32018-04-10 13:07:10 +090060)
61
Jiyong Park82484c02018-04-23 21:41:26 +090062var (
63 javaSdkLibrariesLock sync.Mutex
64)
65
Jiyong Parkc678ad32018-04-10 13:07:10 +090066// java_sdk_library is to make a Java library that implements optional platform APIs to apps.
67// It is actually a wrapper of several modules: 1) stubs library that clients are linked against
68// to, 2) droiddoc module that internally generates API stubs source files, 3) the real runtime
69// shared library that implements the APIs, and 4) XML file for adding the runtime lib to the
70// classpath at runtime if requested via <uses-library>.
71//
72// TODO: these are big features that are currently missing
Jiyong Park1be96912018-05-28 18:02:19 +090073// 1) disallowing linking to the runtime shared lib
74// 2) HTML generation
Jiyong Parkc678ad32018-04-10 13:07:10 +090075
76func init() {
Inseob Kimc0907f12019-02-08 21:00:45 +090077 android.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
Jiyong Parkc678ad32018-04-10 13:07:10 +090078
Jiyong Park82484c02018-04-23 21:41:26 +090079 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
80 javaSdkLibraries := javaSdkLibraries(ctx.Config())
81 sort.Strings(*javaSdkLibraries)
82 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
83 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090084}
85
86type sdkLibraryProperties struct {
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +090087 // list of optional source files that are part of API but not part of runtime library.
88 Api_srcs []string `android:"arch_variant"`
89
Sundong Ahnf043cf62018-06-25 16:04:37 +090090 // List of Java libraries that will be in the classpath when building stubs
91 Stub_only_libs []string `android:"arch_variant"`
92
Jiyong Parkc678ad32018-04-10 13:07:10 +090093 // list of package names that will be documented and publicized as API
94 Api_packages []string
95
Jiyong Park5a2c9d72018-05-01 22:25:41 +090096 // list of package names that must be hidden from the API
97 Hidden_api_packages []string
98
Paul Duffin11512472019-02-11 15:55:17 +000099 // local files that are used within user customized droiddoc options.
100 Droiddoc_option_files []string
101
102 // additional droiddoc options
103 // Available variables for substitution:
104 //
105 // $(location <label>): the path to the droiddoc_option_files with name <label>
Sundong Ahndd567f92018-07-31 17:19:11 +0900106 Droiddoc_options []string
107
Sundong Ahnb952ba02019-01-08 16:32:12 +0900108 // the java library (in classpath) for documentation that provides java srcs and srcjars.
109 Srcs_lib *string
110
111 // the base dirs under srcs_lib will be scanned for java srcs.
112 Srcs_lib_whitelist_dirs []string
113
Sundong Ahndd567f92018-07-31 17:19:11 +0900114 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
115 // Defaults to "android.annotation".
116 Srcs_lib_whitelist_pkgs []string
117
Sundong Ahn054b19a2018-10-19 13:46:09 +0900118 // a list of top-level directories containing files to merge qualifier annotations
119 // (i.e. those intended to be included in the stubs written) from.
120 Merge_annotations_dirs []string
121
122 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
123 Merge_inclusion_annotations_dirs []string
124
125 // If set to true, the path of dist files is apistubs/core. Defaults to false.
126 Core_lib *bool
127
Jiyong Parkc678ad32018-04-10 13:07:10 +0900128 // TODO: determines whether to create HTML doc or not
129 //Html_doc *bool
130}
131
Inseob Kimc0907f12019-02-08 21:00:45 +0900132type SdkLibrary struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900133 Library
Jiyong Parkc678ad32018-04-10 13:07:10 +0900134
Sundong Ahn054b19a2018-10-19 13:46:09 +0900135 sdkLibraryProperties sdkLibraryProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900136
137 publicApiStubsPath android.Paths
138 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900139 testApiStubsPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900140
141 publicApiStubsImplPath android.Paths
142 systemApiStubsImplPath android.Paths
143 testApiStubsImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900144
145 publicApiFilePath android.Path
146 systemApiFilePath android.Path
147 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900148}
149
Inseob Kimc0907f12019-02-08 21:00:45 +0900150var _ Dependency = (*SdkLibrary)(nil)
151var _ SdkLibraryDependency = (*SdkLibrary)(nil)
Colin Cross897d2ed2019-02-11 14:03:51 -0800152
Inseob Kimc0907f12019-02-08 21:00:45 +0900153func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900154 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700155 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
Colin Cross42d48b72018-08-29 14:10:52 -0700156 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900157
158 if !Bool(module.properties.No_standard_libs) {
159 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
160 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
161 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
162 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
163 }
164
165 module.Library.deps(ctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900166}
167
Inseob Kimc0907f12019-02-08 21:00:45 +0900168func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900169 module.Library.GenerateAndroidBuildActions(ctx)
170
Sundong Ahn57368eb2018-07-06 11:20:23 +0900171 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900172 // When this java_sdk_library is dependened from others via "libs" property,
173 // the recorded paths will be returned depending on the link type of the caller.
174 ctx.VisitDirectDeps(func(to android.Module) {
175 otherName := ctx.OtherModuleName(to)
176 tag := ctx.OtherModuleDependencyTag(to)
177
Sundong Ahn57368eb2018-07-06 11:20:23 +0900178 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900179 switch tag {
180 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900181 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900182 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900183 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900184 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900185 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900186 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900187 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900188 module.testApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900189 }
190 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900191 if doc, ok := to.(ApiFilePath); ok {
192 switch tag {
193 case publicApiFileTag:
194 module.publicApiFilePath = doc.ApiFilePath()
195 case systemApiFileTag:
196 module.systemApiFilePath = doc.ApiFilePath()
197 case testApiFileTag:
198 module.testApiFilePath = doc.ApiFilePath()
199 default:
200 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
201 }
202 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900203 })
204}
205
Inseob Kimc0907f12019-02-08 21:00:45 +0900206func (module *SdkLibrary) AndroidMk() android.AndroidMkData {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900207 data := module.Library.AndroidMk()
208 data.Required = append(data.Required, module.xmlFileName())
209
210 data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
211 android.WriteAndroidMkData(w, data)
212
213 module.Library.AndroidMkHostDex(w, name, data)
214 // Create a phony module that installs the impl library, for the case when this lib is
215 // in PRODUCT_PACKAGES.
216 owner := module.ModuleBase.Owner()
217 if owner == "" {
218 if Bool(module.sdkLibraryProperties.Core_lib) {
219 owner = "core"
220 } else {
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900221 owner = "android"
222 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900223 }
224 // Create dist rules to install the stubs libs to the dist dir
225 if len(module.publicApiStubsPath) == 1 {
226 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
227 module.publicApiStubsImplPath.Strings()[0]+
228 ":"+path.Join("apistubs", owner, "public",
229 module.BaseModuleName()+".jar")+")")
230 }
231 if len(module.systemApiStubsPath) == 1 {
232 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
233 module.systemApiStubsImplPath.Strings()[0]+
234 ":"+path.Join("apistubs", owner, "system",
235 module.BaseModuleName()+".jar")+")")
236 }
237 if len(module.testApiStubsPath) == 1 {
238 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
239 module.testApiStubsImplPath.Strings()[0]+
240 ":"+path.Join("apistubs", owner, "test",
241 module.BaseModuleName()+".jar")+")")
242 }
243 if module.publicApiFilePath != nil {
244 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
245 module.publicApiFilePath.String()+
246 ":"+path.Join("apistubs", owner, "public", "api",
247 module.BaseModuleName()+".txt")+")")
248 }
249 if module.systemApiFilePath != nil {
250 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
251 module.systemApiFilePath.String()+
252 ":"+path.Join("apistubs", owner, "system", "api",
253 module.BaseModuleName()+".txt")+")")
254 }
255 if module.testApiFilePath != nil {
256 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
257 module.testApiFilePath.String()+
258 ":"+path.Join("apistubs", owner, "test", "api",
259 module.BaseModuleName()+".txt")+")")
260 }
Jiyong Park82484c02018-04-23 21:41:26 +0900261 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900262 return data
Jiyong Park82484c02018-04-23 21:41:26 +0900263}
264
Jiyong Parkc678ad32018-04-10 13:07:10 +0900265// Module name of the stubs library
Inseob Kimc0907f12019-02-08 21:00:45 +0900266func (module *SdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900267 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900268 switch apiScope {
269 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900270 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900271 case apiScopeTest:
272 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900273 }
274 return stubsName
275}
276
277// Module name of the docs
Inseob Kimc0907f12019-02-08 21:00:45 +0900278func (module *SdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900279 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900280 switch apiScope {
281 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900282 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900283 case apiScopeTest:
284 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900285 }
286 return docsName
287}
288
289// Module name of the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900290func (module *SdkLibrary) implName() string {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900291 return module.BaseModuleName()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900292}
293
294// File path to the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900295func (module *SdkLibrary) implPath() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900296 partition := "system"
297 if module.SocSpecific() {
298 partition = "vendor"
299 } else if module.DeviceSpecific() {
300 partition = "odm"
301 } else if module.ProductSpecific() {
302 partition = "product"
303 }
304 return "/" + partition + "/framework/" + module.implName() + ".jar"
305}
306
307// Module name of the XML file for the lib
Inseob Kimc0907f12019-02-08 21:00:45 +0900308func (module *SdkLibrary) xmlFileName() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900309 return module.BaseModuleName() + sdkXmlFileSuffix
310}
311
312// SDK version that the stubs library is built against. Note that this is always
313// *current. Older stubs library built with a numberd SDK version is created from
314// the prebuilt jar.
Inseob Kimc0907f12019-02-08 21:00:45 +0900315func (module *SdkLibrary) sdkVersion(apiScope apiScope) string {
Jiyong Parkdf130542018-04-27 16:29:21 +0900316 switch apiScope {
317 case apiScopePublic:
318 return "current"
319 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900320 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900321 case apiScopeTest:
322 return "test_current"
323 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900324 return "current"
325 }
326}
327
328// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
329// api file for the current source
330// TODO: remove this when apicheck is done in soong
Inseob Kimc0907f12019-02-08 21:00:45 +0900331func (module *SdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900332 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900333 switch apiScope {
334 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900335 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900336 case apiScopeTest:
337 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900338 }
339 return apiTagName
340}
341
Inseob Kimc0907f12019-02-08 21:00:45 +0900342func (module *SdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
Jiyong Park58c518b2018-05-12 22:29:12 +0900343 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900344 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900345 case apiScopePublic:
346 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900347 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900348 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900349 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900350 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900351 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900352 name = name + ".latest"
353 return name
354}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900355
Inseob Kimc0907f12019-02-08 21:00:45 +0900356func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
Jiyong Park58c518b2018-05-12 22:29:12 +0900357 name := ":" + module.BaseModuleName() + "-removed.api."
358 switch apiScope {
359 case apiScopePublic:
360 name = name + "public"
361 case apiScopeSystem:
362 name = name + "system"
363 case apiScopeTest:
364 name = name + "test"
365 }
366 name = name + ".latest"
367 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900368}
369
370// Creates a static java library that has API stubs
Colin Crossf8b860a2019-04-16 14:43:28 -0700371func (module *SdkLibrary) createStubsLibrary(mctx android.LoadHookContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900372 props := struct {
373 Name *string
374 Srcs []string
375 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900376 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900377 Soc_specific *bool
378 Device_specific *bool
379 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900380 Compile_dex *bool
Sundong Ahn054b19a2018-10-19 13:46:09 +0900381 No_standard_libs *bool
382 System_modules *string
383 Java_version *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900384 Product_variables struct {
385 Unbundled_build struct {
386 Enabled *bool
387 }
Jiyong Park82484c02018-04-23 21:41:26 +0900388 Pdk struct {
389 Enabled *bool
390 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900391 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900392 Openjdk9 struct {
393 Srcs []string
394 Javacflags []string
395 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900396 }{}
397
Jiyong Parkdf130542018-04-27 16:29:21 +0900398 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900399 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900400 props.Srcs = []string{":" + module.docsName(apiScope)}
401 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900402 props.Libs = module.sdkLibraryProperties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900403 // Unbundled apps will use the prebult one from /prebuilts/sdk
Colin Cross2c77ceb2019-01-21 11:56:21 -0800404 if mctx.Config().UnbundledBuildPrebuiltSdks() {
405 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
406 }
Jiyong Park82484c02018-04-23 21:41:26 +0900407 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900408 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
409 props.System_modules = module.Library.Module.deviceProperties.System_modules
410 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
411 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
412 props.Java_version = module.Library.Module.properties.Java_version
413 if module.Library.Module.deviceProperties.Compile_dex != nil {
414 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900415 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900416
417 if module.SocSpecific() {
418 props.Soc_specific = proptools.BoolPtr(true)
419 } else if module.DeviceSpecific() {
420 props.Device_specific = proptools.BoolPtr(true)
421 } else if module.ProductSpecific() {
422 props.Product_specific = proptools.BoolPtr(true)
423 }
424
Colin Cross9ae1b922018-06-26 17:59:05 -0700425 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900426}
427
428// Creates a droiddoc module that creates stubs source files from the given full source
429// files
Colin Crossf8b860a2019-04-16 14:43:28 -0700430func (module *SdkLibrary) createDocs(mctx android.LoadHookContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900431 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900432 Name *string
433 Srcs []string
434 Installable *bool
435 Srcs_lib *string
436 Srcs_lib_whitelist_dirs []string
437 Srcs_lib_whitelist_pkgs []string
438 Libs []string
Paul Duffin11512472019-02-11 15:55:17 +0000439 Arg_files []string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900440 Args *string
441 Api_tag_name *string
442 Api_filename *string
443 Removed_api_filename *string
444 No_standard_libs *bool
445 Java_version *string
446 Merge_annotations_dirs []string
447 Merge_inclusion_annotations_dirs []string
448 Check_api struct {
Inseob Kim38449af2019-02-28 14:24:05 +0900449 Current ApiToCheck
450 Last_released ApiToCheck
451 Ignore_missing_latest_api *bool
Jiyong Park58c518b2018-05-12 22:29:12 +0900452 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900453 Aidl struct {
454 Include_dirs []string
455 Local_include_dirs []string
456 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900457 }{}
458
Jiyong Parkdf130542018-04-27 16:29:21 +0900459 props.Name = proptools.StringPtr(module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900460 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
461 props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900462 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900463 // A droiddoc module has only one Libs property and doesn't distinguish between
464 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900465 props.Libs = module.Library.Module.properties.Libs
466 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
467 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
468 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
469 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
470 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900471
Sundong Ahn054b19a2018-10-19 13:46:09 +0900472 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
473 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
474
475 droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
476 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
477 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900478 " --hide MissingPermission --hide BroadcastBehavior " +
479 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
480 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900481
Jiyong Parkdf130542018-04-27 16:29:21 +0900482 switch apiScope {
483 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900484 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900485 case apiScopeTest:
486 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900487 }
Paul Duffin11512472019-02-11 15:55:17 +0000488 props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
Jiyong Parkc678ad32018-04-10 13:07:10 +0900489 props.Args = proptools.StringPtr(droiddocArgs)
490
491 // List of APIs identified from the provided source files are created. They are later
492 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
493 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900494 currentApiFileName := "current.txt"
495 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900496 switch apiScope {
497 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900498 currentApiFileName = "system-" + currentApiFileName
499 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900500 case apiScopeTest:
501 currentApiFileName = "test-" + currentApiFileName
502 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900503 }
504 currentApiFileName = path.Join("api", currentApiFileName)
505 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900506 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900507 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900508 props.Api_filename = proptools.StringPtr(currentApiFileName)
509 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
510
Jiyong Park58c518b2018-05-12 22:29:12 +0900511 // check against the not-yet-release API
512 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
513 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900514
515 // check against the latest released API
516 props.Check_api.Last_released.Api_file = proptools.StringPtr(
517 module.latestApiFilegroupName(apiScope))
518 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
519 module.latestRemovedApiFilegroupName(apiScope))
Inseob Kim38449af2019-02-28 14:24:05 +0900520 props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900521 props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
522 props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
523 props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900524
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900525 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900526}
527
Jiyong Parkc678ad32018-04-10 13:07:10 +0900528// Creates the xml file that publicizes the runtime library
Colin Crossf8b860a2019-04-16 14:43:28 -0700529func (module *SdkLibrary) createXmlFile(mctx android.LoadHookContext) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900530 template := `
531<?xml version="1.0" encoding="utf-8"?>
532<!-- Copyright (C) 2018 The Android Open Source Project
533
534 Licensed under the Apache License, Version 2.0 (the "License");
535 you may not use this file except in compliance with the License.
536 You may obtain a copy of the License at
537
538 http://www.apache.org/licenses/LICENSE-2.0
539
540 Unless required by applicable law or agreed to in writing, software
541 distributed under the License is distributed on an "AS IS" BASIS,
542 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
543 See the License for the specific language governing permissions and
544 limitations under the License.
545-->
546
547<permissions>
548 <library name="%s" file="%s"/>
549</permissions>
550`
551 // genrule to generate the xml file content from the template above
552 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
553 // in the ninja file. Do we need to have an external tool for this?
554 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
555 genruleProps := struct {
556 Name *string
557 Cmd *string
558 Out []string
559 }{}
560 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
561 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
562 genruleProps.Out = []string{module.xmlFileName()}
563 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
564
565 // creates a prebuilt_etc module to actually place the xml file under
566 // <partition>/etc/permissions
567 etcProps := struct {
568 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900569 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900570 Sub_dir *string
571 Soc_specific *bool
572 Device_specific *bool
573 Product_specific *bool
574 }{}
575 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900576 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900577 etcProps.Sub_dir = proptools.StringPtr("permissions")
578 if module.SocSpecific() {
579 etcProps.Soc_specific = proptools.BoolPtr(true)
580 } else if module.DeviceSpecific() {
581 etcProps.Device_specific = proptools.BoolPtr(true)
582 } else if module.ProductSpecific() {
583 etcProps.Product_specific = proptools.BoolPtr(true)
584 }
585 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
586}
587
Inseob Kimc0907f12019-02-08 21:00:45 +0900588func (module *SdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900589 var api, v string
590 if sdkVersion == "" {
591 api = "system"
592 v = "current"
593 } else if strings.Contains(sdkVersion, "_") {
594 t := strings.Split(sdkVersion, "_")
595 api = t[0]
596 v = t[1]
Jiyong Parkc678ad32018-04-10 13:07:10 +0900597 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900598 api = "public"
599 v = sdkVersion
600 }
601 dir := filepath.Join("prebuilts", "sdk", v, api)
602 jar := filepath.Join(dir, module.BaseModuleName()+".jar")
603 jarPath := android.ExistentPathForSource(ctx, jar)
Sundong Ahnae418ac2019-02-28 15:01:28 +0900604 if !jarPath.Valid() {
605 ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", v, jar)
606 return nil
607 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900608 return android.Paths{jarPath.Path()}
609}
610
611// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900612func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900613 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800614 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900615 return module.PrebuiltJars(ctx, sdkVersion)
616 } else {
617 if strings.HasPrefix(sdkVersion, "system_") {
618 return module.systemApiStubsPath
619 } else if sdkVersion == "" {
620 return module.Library.HeaderJars()
621 } else {
622 return module.publicApiStubsPath
623 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900624 }
625}
626
Sundong Ahn241cd372018-07-13 16:16:44 +0900627// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900628func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn241cd372018-07-13 16:16:44 +0900629 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800630 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900631 return module.PrebuiltJars(ctx, sdkVersion)
Sundong Ahn241cd372018-07-13 16:16:44 +0900632 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900633 if strings.HasPrefix(sdkVersion, "system_") {
634 return module.systemApiStubsImplPath
635 } else if sdkVersion == "" {
636 return module.Library.ImplementationJars()
637 } else {
638 return module.publicApiStubsImplPath
639 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900640 }
641}
642
Colin Cross571cccf2019-02-04 11:22:08 -0800643var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
644
Jiyong Park82484c02018-04-23 21:41:26 +0900645func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -0800646 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +0900647 return &[]string{}
648 }).(*[]string)
649}
650
Jiyong Parkc678ad32018-04-10 13:07:10 +0900651// For a java_sdk_library module, create internal modules for stubs, docs,
652// runtime libs and xml file. If requested, the stubs and docs are created twice
653// once for public API level and once for system API level
Colin Crossf8b860a2019-04-16 14:43:28 -0700654func (module *SdkLibrary) CreateInternalModules(mctx android.LoadHookContext) {
Inseob Kim6e93ac92019-03-21 17:43:49 +0900655 if len(module.Library.Module.properties.Srcs) == 0 {
Inseob Kimc0907f12019-02-08 21:00:45 +0900656 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
657 }
658
Inseob Kim6e93ac92019-03-21 17:43:49 +0900659 if len(module.sdkLibraryProperties.Api_packages) == 0 {
Inseob Kimc0907f12019-02-08 21:00:45 +0900660 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
661 }
Inseob Kim8098faa2019-03-18 10:19:51 +0900662
663 missing_current_api := false
664
665 for _, scope := range []string{"", "system-", "test-"} {
666 for _, api := range []string{"current.txt", "removed.txt"} {
667 path := path.Join(mctx.ModuleDir(), "api", scope+api)
668 p := android.ExistentPathForSource(mctx, path)
669 if !p.Valid() {
670 mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
671 missing_current_api = true
672 }
673 }
674 }
675
676 if missing_current_api {
677 script := "build/soong/scripts/gen-java-current-api-files.sh"
678 p := android.ExistentPathForSource(mctx, script)
679
680 if !p.Valid() {
681 panic(fmt.Sprintf("script file %s doesn't exist", script))
682 }
683
684 mctx.ModuleErrorf("One or more current api files are missing. "+
685 "You can update them by:\n"+
686 "%s %q && m update-api", script, mctx.ModuleDir())
687 return
688 }
689
Inseob Kimc0907f12019-02-08 21:00:45 +0900690 // for public API stubs
691 module.createStubsLibrary(mctx, apiScopePublic)
692 module.createDocs(mctx, apiScopePublic)
693
694 if !Bool(module.properties.No_standard_libs) {
695 // for system API stubs
696 module.createStubsLibrary(mctx, apiScopeSystem)
697 module.createDocs(mctx, apiScopeSystem)
698
699 // for test API stubs
700 module.createStubsLibrary(mctx, apiScopeTest)
701 module.createDocs(mctx, apiScopeTest)
702
703 // for runtime
704 module.createXmlFile(mctx)
705 }
706
707 // record java_sdk_library modules so that they are exported to make
708 javaSdkLibraries := javaSdkLibraries(mctx.Config())
709 javaSdkLibrariesLock.Lock()
710 defer javaSdkLibrariesLock.Unlock()
711 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
712}
713
714func (module *SdkLibrary) InitSdkLibraryProperties() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900715 module.AddProperties(
716 &module.sdkLibraryProperties,
717 &module.Library.Module.properties,
718 &module.Library.Module.dexpreoptProperties,
719 &module.Library.Module.deviceProperties,
720 &module.Library.Module.protoProperties,
721 )
722
723 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
724 module.Library.Module.deviceProperties.IsSDKLibrary = true
Inseob Kimc0907f12019-02-08 21:00:45 +0900725}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900726
Inseob Kimc0907f12019-02-08 21:00:45 +0900727func SdkLibraryFactory() android.Module {
728 module := &SdkLibrary{}
729 module.InitSdkLibraryProperties()
Sundong Ahn054b19a2018-10-19 13:46:09 +0900730 InitJavaModule(module, android.HostAndDeviceSupported)
Colin Crossf8b860a2019-04-16 14:43:28 -0700731 android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.CreateInternalModules(ctx) })
Jiyong Parkc678ad32018-04-10 13:07:10 +0900732 return module
733}