blob: d58880178f596f01b75827154e5101e8f1e65973 [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"
Jiyong Park82484c02018-04-23 21:41:26 +090023 "sort"
Jiyong Parkc678ad32018-04-10 13:07:10 +090024 "strings"
Jiyong Park82484c02018-04-23 21:41:26 +090025 "sync"
Jiyong Parkc678ad32018-04-10 13:07:10 +090026
27 "github.com/google/blueprint"
28 "github.com/google/blueprint/proptools"
29)
30
31var (
32 sdkStubsLibrarySuffix = ".stubs"
33 sdkSystemApiSuffix = ".system"
Jiyong Parkdf130542018-04-27 16:29:21 +090034 sdkTestApiSuffix = ".test"
Jiyong Parkc678ad32018-04-10 13:07:10 +090035 sdkDocsSuffix = ".docs"
36 sdkImplLibrarySuffix = ".impl"
37 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 Ahn57368eb2018-07-06 11:20:23 +090049 implLibTag = dependencyTag{name: "platform"}
Sundong Ahn20e998b2018-07-24 11:19:26 +090050 publicApiFileTag = dependencyTag{name: "publicApi"}
51 systemApiFileTag = dependencyTag{name: "systemApi"}
52 testApiFileTag = dependencyTag{name: "testApi"}
Jiyong Parkdf130542018-04-27 16:29:21 +090053)
54
55type apiScope int
56
57const (
58 apiScopePublic apiScope = iota
59 apiScopeSystem
60 apiScopeTest
Jiyong Parkc678ad32018-04-10 13:07:10 +090061)
62
Jiyong Park82484c02018-04-23 21:41:26 +090063var (
64 javaSdkLibrariesLock sync.Mutex
65)
66
Jiyong Parkc678ad32018-04-10 13:07:10 +090067// java_sdk_library is to make a Java library that implements optional platform APIs to apps.
68// It is actually a wrapper of several modules: 1) stubs library that clients are linked against
69// to, 2) droiddoc module that internally generates API stubs source files, 3) the real runtime
70// shared library that implements the APIs, and 4) XML file for adding the runtime lib to the
71// classpath at runtime if requested via <uses-library>.
72//
73// TODO: these are big features that are currently missing
Jiyong Park1be96912018-05-28 18:02:19 +090074// 1) disallowing linking to the runtime shared lib
75// 2) HTML generation
Jiyong Parkc678ad32018-04-10 13:07:10 +090076
77func init() {
78 android.RegisterModuleType("java_sdk_library", sdkLibraryFactory)
79
80 android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
81 ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
82 })
Jiyong Park82484c02018-04-23 21:41:26 +090083
84 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
85 javaSdkLibraries := javaSdkLibraries(ctx.Config())
86 sort.Strings(*javaSdkLibraries)
87 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
88 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090089}
90
91type sdkLibraryProperties struct {
92 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
93 // or .aidl files.
94 Srcs []string `android:"arch_variant"`
95
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +090096 // list of optional source files that are part of API but not part of runtime library.
97 Api_srcs []string `android:"arch_variant"`
98
Jiyong Parkc678ad32018-04-10 13:07:10 +090099 // list of of java libraries that will be in the classpath
100 Libs []string `android:"arch_variant"`
101
102 // list of java libraries that will be compiled into the resulting runtime jar.
103 // These libraries are not compiled into the stubs jar.
104 Static_libs []string `android:"arch_variant"`
105
Sundong Ahnf043cf62018-06-25 16:04:37 +0900106 // List of Java libraries that will be in the classpath when building stubs
107 Stub_only_libs []string `android:"arch_variant"`
108
Jiyong Parkc678ad32018-04-10 13:07:10 +0900109 // list of package names that will be documented and publicized as API
110 Api_packages []string
111
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900112 // list of package names that must be hidden from the API
113 Hidden_api_packages []string
114
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900115 Errorprone struct {
116 // List of javac flags that should only be used when running errorprone.
117 Javacflags []string
118 }
119
Sundong Ahndd567f92018-07-31 17:19:11 +0900120 // Additional droiddoc options
121 Droiddoc_options []string
122
123 // If set to true, compile dex regardless of installable. Defaults to false.
124 // This applies to the stubs lib.
125 Compile_dex *bool
126
127 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
128 // Defaults to "android.annotation".
129 Srcs_lib_whitelist_pkgs []string
130
Jiyong Parkc678ad32018-04-10 13:07:10 +0900131 // TODO: determines whether to create HTML doc or not
132 //Html_doc *bool
133}
134
135type sdkLibrary struct {
136 android.ModuleBase
137 android.DefaultableModuleBase
138
Jiyong Park441a47d2018-05-01 23:33:08 +0900139 properties sdkLibraryProperties
140 deviceProperties CompilerDeviceProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900141
142 publicApiStubsPath android.Paths
143 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900144 testApiStubsPath android.Paths
Sundong Ahn57368eb2018-07-06 11:20:23 +0900145 implLibPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900146
147 publicApiStubsImplPath android.Paths
148 systemApiStubsImplPath android.Paths
149 testApiStubsImplPath android.Paths
150 implLibImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900151
152 publicApiFilePath android.Path
153 systemApiFilePath android.Path
154 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900155}
156
157func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
158 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700159 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
160 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
161 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
162 ctx.AddVariationDependencies(nil, implLibTag, module.implName())
Sundong Ahn20e998b2018-07-24 11:19:26 +0900163
Colin Cross42d48b72018-08-29 14:10:52 -0700164 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
165 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
166 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900167}
168
169func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn57368eb2018-07-06 11:20:23 +0900170 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900171 // When this java_sdk_library is dependened from others via "libs" property,
172 // the recorded paths will be returned depending on the link type of the caller.
173 ctx.VisitDirectDeps(func(to android.Module) {
174 otherName := ctx.OtherModuleName(to)
175 tag := ctx.OtherModuleDependencyTag(to)
176
Sundong Ahn57368eb2018-07-06 11:20:23 +0900177 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900178 switch tag {
179 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900180 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900181 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900182 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900183 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900184 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900185 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900186 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900187 module.testApiStubsImplPath = lib.ImplementationJars()
Sundong Ahn57368eb2018-07-06 11:20:23 +0900188 case implLibTag:
189 module.implLibPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900190 module.implLibImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900191 default:
192 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
193 }
194 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900195 if doc, ok := to.(ApiFilePath); ok {
196 switch tag {
197 case publicApiFileTag:
198 module.publicApiFilePath = doc.ApiFilePath()
199 case systemApiFileTag:
200 module.systemApiFilePath = doc.ApiFilePath()
201 case testApiFileTag:
202 module.testApiFilePath = doc.ApiFilePath()
203 default:
204 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
205 }
206 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900207 })
208}
209
Jiyong Park82484c02018-04-23 21:41:26 +0900210func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900211 return android.AndroidMkData{
212 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900213 // Create a phony module that installs the impl library, for the case when this lib is
214 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900215 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
216 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
217 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
218 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
219 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Jiyong Park90078382018-05-02 19:30:15 +0900220 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900221 if len(module.publicApiStubsPath) == 1 {
222 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
223 module.publicApiStubsPath.Strings()[0]+
224 ":"+path.Join("apistubs", "public", module.BaseModuleName()+".jar")+")")
225 }
226 if len(module.systemApiStubsPath) == 1 {
227 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
228 module.systemApiStubsPath.Strings()[0]+
229 ":"+path.Join("apistubs", "system", module.BaseModuleName()+".jar")+")")
230 }
231 if len(module.testApiStubsPath) == 1 {
232 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
233 module.testApiStubsPath.Strings()[0]+
234 ":"+path.Join("apistubs", "test", module.BaseModuleName()+".jar")+")")
235 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900236 if module.publicApiFilePath != nil {
237 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
238 module.publicApiFilePath.String()+
239 ":"+path.Join("apistubs", "public", "api",
240 module.BaseModuleName()+".txt")+")")
241 }
242 if module.systemApiFilePath != nil {
243 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
244 module.systemApiFilePath.String()+
245 ":"+path.Join("apistubs", "system", "api",
246 module.BaseModuleName()+".txt")+")")
247 }
248 if module.testApiFilePath != nil {
249 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
250 module.testApiFilePath.String()+
251 ":"+path.Join("apistubs", "test", "api",
252 module.BaseModuleName()+".txt")+")")
253 }
Jiyong Park82484c02018-04-23 21:41:26 +0900254 },
255 }
256}
257
Jiyong Parkc678ad32018-04-10 13:07:10 +0900258// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900259func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900260 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900261 switch apiScope {
262 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900263 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900264 case apiScopeTest:
265 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900266 }
267 return stubsName
268}
269
270// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900271func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900272 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900273 switch apiScope {
274 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900275 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900276 case apiScopeTest:
277 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900278 }
279 return docsName
280}
281
282// Module name of the runtime implementation library
283func (module *sdkLibrary) implName() string {
284 return module.BaseModuleName() + sdkImplLibrarySuffix
285}
286
287// File path to the runtime implementation library
288func (module *sdkLibrary) implPath() string {
289 partition := "system"
290 if module.SocSpecific() {
291 partition = "vendor"
292 } else if module.DeviceSpecific() {
293 partition = "odm"
294 } else if module.ProductSpecific() {
295 partition = "product"
296 }
297 return "/" + partition + "/framework/" + module.implName() + ".jar"
298}
299
300// Module name of the XML file for the lib
301func (module *sdkLibrary) xmlFileName() string {
302 return module.BaseModuleName() + sdkXmlFileSuffix
303}
304
305// SDK version that the stubs library is built against. Note that this is always
306// *current. Older stubs library built with a numberd SDK version is created from
307// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900308func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
309 switch apiScope {
310 case apiScopePublic:
311 return "current"
312 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900313 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900314 case apiScopeTest:
315 return "test_current"
316 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900317 return "current"
318 }
319}
320
321// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
322// api file for the current source
323// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900324func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900325 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900326 switch apiScope {
327 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900328 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900329 case apiScopeTest:
330 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900331 }
332 return apiTagName
333}
334
Jiyong Park58c518b2018-05-12 22:29:12 +0900335func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
336 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900337 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900338 case apiScopePublic:
339 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900340 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900341 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900342 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900343 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900344 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900345 name = name + ".latest"
346 return name
347}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900348
Jiyong Park58c518b2018-05-12 22:29:12 +0900349func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
350 name := ":" + module.BaseModuleName() + "-removed.api."
351 switch apiScope {
352 case apiScopePublic:
353 name = name + "public"
354 case apiScopeSystem:
355 name = name + "system"
356 case apiScopeTest:
357 name = name + "test"
358 }
359 name = name + ".latest"
360 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900361}
362
363// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900364func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900365 props := struct {
366 Name *string
367 Srcs []string
368 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900369 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900370 Soc_specific *bool
371 Device_specific *bool
372 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900373 Compile_dex *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900374 Product_variables struct {
375 Unbundled_build struct {
376 Enabled *bool
377 }
Jiyong Park82484c02018-04-23 21:41:26 +0900378 Pdk struct {
379 Enabled *bool
380 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900381 }
382 }{}
383
Jiyong Parkdf130542018-04-27 16:29:21 +0900384 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900385 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900386 props.Srcs = []string{":" + module.docsName(apiScope)}
387 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahnf043cf62018-06-25 16:04:37 +0900388 props.Libs = module.properties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900389 // Unbundled apps will use the prebult one from /prebuilts/sdk
390 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900391 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahndd567f92018-07-31 17:19:11 +0900392 if module.properties.Compile_dex != nil {
393 props.Compile_dex = module.properties.Compile_dex
394 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900395
396 if module.SocSpecific() {
397 props.Soc_specific = proptools.BoolPtr(true)
398 } else if module.DeviceSpecific() {
399 props.Device_specific = proptools.BoolPtr(true)
400 } else if module.ProductSpecific() {
401 props.Product_specific = proptools.BoolPtr(true)
402 }
403
Colin Cross9ae1b922018-06-26 17:59:05 -0700404 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900405}
406
407// Creates a droiddoc module that creates stubs source files from the given full source
408// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900409func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900410 props := struct {
411 Name *string
412 Srcs []string
413 Custom_template *string
414 Installable *bool
415 Srcs_lib *string
416 Srcs_lib_whitelist_dirs []string
417 Srcs_lib_whitelist_pkgs []string
418 Libs []string
419 Args *string
420 Api_tag_name *string
421 Api_filename *string
422 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900423 Check_api struct {
424 Current ApiToCheck
425 Last_released ApiToCheck
426 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900427 Aidl struct {
428 Include_dirs []string
429 Local_include_dirs []string
430 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900431 }{}
432
Jiyong Parkdf130542018-04-27 16:29:21 +0900433 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900434 props.Srcs = append(props.Srcs, module.properties.Srcs...)
435 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900436 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
437 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900438 // A droiddoc module has only one Libs property and doesn't distinguish between
439 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900440 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900441 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900442 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
443 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900444
445 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
446 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900447 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Sundong Ahndd567f92018-07-31 17:19:11 +0900448 " " + android.JoinWithPrefix(module.properties.Droiddoc_options, "-") + " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900449 switch apiScope {
450 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900451 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900452 case apiScopeTest:
453 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900454 }
455 props.Args = proptools.StringPtr(droiddocArgs)
456
457 // List of APIs identified from the provided source files are created. They are later
458 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
459 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900460 currentApiFileName := "current.txt"
461 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900462 switch apiScope {
463 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900464 currentApiFileName = "system-" + currentApiFileName
465 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900466 case apiScopeTest:
467 currentApiFileName = "test-" + currentApiFileName
468 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900469 }
470 currentApiFileName = path.Join("api", currentApiFileName)
471 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900472 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900473 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900474 props.Api_filename = proptools.StringPtr(currentApiFileName)
475 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
476
Jiyong Park58c518b2018-05-12 22:29:12 +0900477 // check against the not-yet-release API
478 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
479 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
480 // any change is reported as error
481 props.Check_api.Current.Args = proptools.StringPtr("-error 2 -error 3 -error 4 -error 5 " +
482 "-error 6 -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 " +
483 "-error 14 -error 15 -error 16 -error 17 -error 18 -error 19 -error 20 " +
484 "-error 21 -error 23 -error 24 -error 25 -error 26 -error 27")
485
486 // check against the latest released API
487 props.Check_api.Last_released.Api_file = proptools.StringPtr(
488 module.latestApiFilegroupName(apiScope))
489 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
490 module.latestRemovedApiFilegroupName(apiScope))
491 // backward incompatible changes are reported as error
492 props.Check_api.Last_released.Args = proptools.StringPtr("-hide 2 -hide 3 -hide 4 -hide 5 " +
493 "-hide 6 -hide 24 -hide 25 -hide 26 -hide 27 " +
494 "-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 " +
495 "-error 15 -error 16 -error 17 -error 18")
496
Jiyong Park82484c02018-04-23 21:41:26 +0900497 // Include the part of the framework source. This is required for the case when
498 // API class is extending from the framework class. In that case, doclava needs
499 // to know whether the base class is hidden or not. Since that information is
500 // encoded as @hide string in the comment, we need source files for the classes,
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900501 // not the compiled ones.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900502 props.Srcs_lib = proptools.StringPtr("framework")
503 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900504 // Add android.annotation package to give access to the framework-defined
505 // annotations such as SystemApi, NonNull, etc.
Sundong Ahndd567f92018-07-31 17:19:11 +0900506 if module.properties.Srcs_lib_whitelist_pkgs != nil {
507 props.Srcs_lib_whitelist_pkgs = module.properties.Srcs_lib_whitelist_pkgs
508 } else {
509 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
510 }
Jiyong Park82484c02018-04-23 21:41:26 +0900511 // These libs are required by doclava to parse the framework sources add via
512 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900513 // If we don't add them to the classpath, errors messages are generated by doclava,
514 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900515 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900516
517 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
518}
519
520// Creates the runtime library. This is not directly linkable from other modules.
521func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
522 props := struct {
523 Name *string
524 Srcs []string
525 Libs []string
526 Static_libs []string
527 Soc_specific *bool
528 Device_specific *bool
529 Product_specific *bool
Colin Cross9ae1b922018-06-26 17:59:05 -0700530 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900531 Required []string
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900532 Errorprone struct {
533 Javacflags []string
534 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900535 }{}
536
537 props.Name = proptools.StringPtr(module.implName())
538 props.Srcs = module.properties.Srcs
539 props.Libs = module.properties.Libs
540 props.Static_libs = module.properties.Static_libs
Colin Cross9ae1b922018-06-26 17:59:05 -0700541 props.Installable = proptools.BoolPtr(true)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900542 // XML file is installed along with the impl lib
543 props.Required = []string{module.xmlFileName()}
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900544 props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
Jiyong Parkc678ad32018-04-10 13:07:10 +0900545
546 if module.SocSpecific() {
547 props.Soc_specific = proptools.BoolPtr(true)
548 } else if module.DeviceSpecific() {
549 props.Device_specific = proptools.BoolPtr(true)
550 } else if module.ProductSpecific() {
551 props.Product_specific = proptools.BoolPtr(true)
552 }
553
Colin Cross9ae1b922018-06-26 17:59:05 -0700554 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props, &module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900555}
556
557// Creates the xml file that publicizes the runtime library
558func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
559 template := `
560<?xml version="1.0" encoding="utf-8"?>
561<!-- Copyright (C) 2018 The Android Open Source Project
562
563 Licensed under the Apache License, Version 2.0 (the "License");
564 you may not use this file except in compliance with the License.
565 You may obtain a copy of the License at
566
567 http://www.apache.org/licenses/LICENSE-2.0
568
569 Unless required by applicable law or agreed to in writing, software
570 distributed under the License is distributed on an "AS IS" BASIS,
571 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
572 See the License for the specific language governing permissions and
573 limitations under the License.
574-->
575
576<permissions>
577 <library name="%s" file="%s"/>
578</permissions>
579`
580 // genrule to generate the xml file content from the template above
581 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
582 // in the ninja file. Do we need to have an external tool for this?
583 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
584 genruleProps := struct {
585 Name *string
586 Cmd *string
587 Out []string
588 }{}
589 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
590 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
591 genruleProps.Out = []string{module.xmlFileName()}
592 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
593
594 // creates a prebuilt_etc module to actually place the xml file under
595 // <partition>/etc/permissions
596 etcProps := struct {
597 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900598 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900599 Sub_dir *string
600 Soc_specific *bool
601 Device_specific *bool
602 Product_specific *bool
603 }{}
604 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900605 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900606 etcProps.Sub_dir = proptools.StringPtr("permissions")
607 if module.SocSpecific() {
608 etcProps.Soc_specific = proptools.BoolPtr(true)
609 } else if module.DeviceSpecific() {
610 etcProps.Device_specific = proptools.BoolPtr(true)
611 } else if module.ProductSpecific() {
612 etcProps.Product_specific = proptools.BoolPtr(true)
613 }
614 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
615}
616
617// to satisfy SdkLibraryDependency interface
618func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
619 // This module is just a wrapper for the stubs.
Sundong Ahn57368eb2018-07-06 11:20:23 +0900620 if linkType == javaSystem {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900621 return module.systemApiStubsPath
Sundong Ahn57368eb2018-07-06 11:20:23 +0900622 } else if linkType == javaPlatform {
623 return module.implLibPath
Jiyong Parkc678ad32018-04-10 13:07:10 +0900624 } else {
625 return module.publicApiStubsPath
626 }
627}
628
Sundong Ahn241cd372018-07-13 16:16:44 +0900629// to satisfy SdkLibraryDependency interface
630func (module *sdkLibrary) ImplementationJars(linkType linkType) android.Paths {
631 // This module is just a wrapper for the stubs.
632 if linkType == javaSystem {
633 return module.systemApiStubsImplPath
634 } else if linkType == javaPlatform {
635 return module.implLibImplPath
636 } else {
637 return module.publicApiStubsImplPath
638 }
639}
640
Jiyong Park82484c02018-04-23 21:41:26 +0900641func javaSdkLibraries(config android.Config) *[]string {
642 return config.Once("javaSdkLibraries", func() interface{} {
643 return &[]string{}
644 }).(*[]string)
645}
646
Jiyong Parkc678ad32018-04-10 13:07:10 +0900647// For a java_sdk_library module, create internal modules for stubs, docs,
648// runtime libs and xml file. If requested, the stubs and docs are created twice
649// once for public API level and once for system API level
650func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
651 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100652 if module.properties.Srcs == nil {
653 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
654 }
655 if module.properties.Api_packages == nil {
656 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
657 }
658
Jiyong Parkc678ad32018-04-10 13:07:10 +0900659 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900660 module.createStubsLibrary(mctx, apiScopePublic)
661 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900662
663 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900664 module.createStubsLibrary(mctx, apiScopeSystem)
665 module.createDocs(mctx, apiScopeSystem)
666
667 // for test API stubs
668 module.createStubsLibrary(mctx, apiScopeTest)
669 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900670
671 // for runtime
672 module.createXmlFile(mctx)
673 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900674
675 // record java_sdk_library modules so that they are exported to make
676 javaSdkLibraries := javaSdkLibraries(mctx.Config())
677 javaSdkLibrariesLock.Lock()
678 defer javaSdkLibrariesLock.Unlock()
679 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900680 }
681}
682
683func sdkLibraryFactory() android.Module {
684 module := &sdkLibrary{}
685 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900686 module.AddProperties(&module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900687 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
688 android.InitDefaultableModule(module)
689 return module
690}