blob: 57a0c3ab85a5831ab5d7961a8a96dcc0e88b1f30 [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
Jiyong Parkc678ad32018-04-10 13:07:10 +0900120 // TODO: determines whether to create HTML doc or not
121 //Html_doc *bool
122}
123
124type sdkLibrary struct {
125 android.ModuleBase
126 android.DefaultableModuleBase
127
Jiyong Park441a47d2018-05-01 23:33:08 +0900128 properties sdkLibraryProperties
129 deviceProperties CompilerDeviceProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900130
131 publicApiStubsPath android.Paths
132 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900133 testApiStubsPath android.Paths
Sundong Ahn57368eb2018-07-06 11:20:23 +0900134 implLibPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900135
136 publicApiStubsImplPath android.Paths
137 systemApiStubsImplPath android.Paths
138 testApiStubsImplPath android.Paths
139 implLibImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900140
141 publicApiFilePath android.Path
142 systemApiFilePath android.Path
143 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900144}
145
146func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
147 // Add dependencies to the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900148 ctx.AddDependency(ctx.Module(), publicApiStubsTag, module.stubsName(apiScopePublic))
149 ctx.AddDependency(ctx.Module(), systemApiStubsTag, module.stubsName(apiScopeSystem))
150 ctx.AddDependency(ctx.Module(), testApiStubsTag, module.stubsName(apiScopeTest))
Sundong Ahn57368eb2018-07-06 11:20:23 +0900151 ctx.AddDependency(ctx.Module(), implLibTag, module.implName())
Sundong Ahn20e998b2018-07-24 11:19:26 +0900152
153 ctx.AddDependency(ctx.Module(), publicApiFileTag, module.docsName(apiScopePublic))
154 ctx.AddDependency(ctx.Module(), systemApiFileTag, module.docsName(apiScopeSystem))
155 ctx.AddDependency(ctx.Module(), testApiFileTag, module.docsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900156}
157
158func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn57368eb2018-07-06 11:20:23 +0900159 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900160 // When this java_sdk_library is dependened from others via "libs" property,
161 // the recorded paths will be returned depending on the link type of the caller.
162 ctx.VisitDirectDeps(func(to android.Module) {
163 otherName := ctx.OtherModuleName(to)
164 tag := ctx.OtherModuleDependencyTag(to)
165
Sundong Ahn57368eb2018-07-06 11:20:23 +0900166 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900167 switch tag {
168 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900169 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900170 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900171 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900172 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900173 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900174 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900175 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900176 module.testApiStubsImplPath = lib.ImplementationJars()
Sundong Ahn57368eb2018-07-06 11:20:23 +0900177 case implLibTag:
178 module.implLibPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900179 module.implLibImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900180 default:
181 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
182 }
183 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900184 if doc, ok := to.(ApiFilePath); ok {
185 switch tag {
186 case publicApiFileTag:
187 module.publicApiFilePath = doc.ApiFilePath()
188 case systemApiFileTag:
189 module.systemApiFilePath = doc.ApiFilePath()
190 case testApiFileTag:
191 module.testApiFilePath = doc.ApiFilePath()
192 default:
193 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
194 }
195 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900196 })
197}
198
Jiyong Park82484c02018-04-23 21:41:26 +0900199func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900200 return android.AndroidMkData{
201 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900202 // Create a phony module that installs the impl library, for the case when this lib is
203 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900204 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
205 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
206 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
207 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
208 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Jiyong Park90078382018-05-02 19:30:15 +0900209 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900210 if len(module.publicApiStubsPath) == 1 {
211 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
212 module.publicApiStubsPath.Strings()[0]+
213 ":"+path.Join("apistubs", "public", module.BaseModuleName()+".jar")+")")
214 }
215 if len(module.systemApiStubsPath) == 1 {
216 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
217 module.systemApiStubsPath.Strings()[0]+
218 ":"+path.Join("apistubs", "system", module.BaseModuleName()+".jar")+")")
219 }
220 if len(module.testApiStubsPath) == 1 {
221 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
222 module.testApiStubsPath.Strings()[0]+
223 ":"+path.Join("apistubs", "test", module.BaseModuleName()+".jar")+")")
224 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900225 if module.publicApiFilePath != nil {
226 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
227 module.publicApiFilePath.String()+
228 ":"+path.Join("apistubs", "public", "api",
229 module.BaseModuleName()+".txt")+")")
230 }
231 if module.systemApiFilePath != nil {
232 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
233 module.systemApiFilePath.String()+
234 ":"+path.Join("apistubs", "system", "api",
235 module.BaseModuleName()+".txt")+")")
236 }
237 if module.testApiFilePath != nil {
238 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
239 module.testApiFilePath.String()+
240 ":"+path.Join("apistubs", "test", "api",
241 module.BaseModuleName()+".txt")+")")
242 }
Jiyong Park82484c02018-04-23 21:41:26 +0900243 },
244 }
245}
246
Jiyong Parkc678ad32018-04-10 13:07:10 +0900247// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900248func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900249 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900250 switch apiScope {
251 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900252 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900253 case apiScopeTest:
254 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900255 }
256 return stubsName
257}
258
259// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900260func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900261 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900262 switch apiScope {
263 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900264 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900265 case apiScopeTest:
266 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900267 }
268 return docsName
269}
270
271// Module name of the runtime implementation library
272func (module *sdkLibrary) implName() string {
273 return module.BaseModuleName() + sdkImplLibrarySuffix
274}
275
276// File path to the runtime implementation library
277func (module *sdkLibrary) implPath() string {
278 partition := "system"
279 if module.SocSpecific() {
280 partition = "vendor"
281 } else if module.DeviceSpecific() {
282 partition = "odm"
283 } else if module.ProductSpecific() {
284 partition = "product"
285 }
286 return "/" + partition + "/framework/" + module.implName() + ".jar"
287}
288
289// Module name of the XML file for the lib
290func (module *sdkLibrary) xmlFileName() string {
291 return module.BaseModuleName() + sdkXmlFileSuffix
292}
293
294// SDK version that the stubs library is built against. Note that this is always
295// *current. Older stubs library built with a numberd SDK version is created from
296// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900297func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
298 switch apiScope {
299 case apiScopePublic:
300 return "current"
301 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900302 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900303 case apiScopeTest:
304 return "test_current"
305 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900306 return "current"
307 }
308}
309
310// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
311// api file for the current source
312// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900313func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900314 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900315 switch apiScope {
316 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900317 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900318 case apiScopeTest:
319 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900320 }
321 return apiTagName
322}
323
Jiyong Park58c518b2018-05-12 22:29:12 +0900324func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
325 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900326 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900327 case apiScopePublic:
328 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900329 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900330 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900331 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900332 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900333 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900334 name = name + ".latest"
335 return name
336}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900337
Jiyong Park58c518b2018-05-12 22:29:12 +0900338func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
339 name := ":" + module.BaseModuleName() + "-removed.api."
340 switch apiScope {
341 case apiScopePublic:
342 name = name + "public"
343 case apiScopeSystem:
344 name = name + "system"
345 case apiScopeTest:
346 name = name + "test"
347 }
348 name = name + ".latest"
349 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900350}
351
352// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900353func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900354 props := struct {
355 Name *string
356 Srcs []string
357 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900358 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900359 Soc_specific *bool
360 Device_specific *bool
361 Product_specific *bool
362 Product_variables struct {
363 Unbundled_build struct {
364 Enabled *bool
365 }
Jiyong Park82484c02018-04-23 21:41:26 +0900366 Pdk struct {
367 Enabled *bool
368 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900369 }
370 }{}
371
Jiyong Parkdf130542018-04-27 16:29:21 +0900372 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900373 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900374 props.Srcs = []string{":" + module.docsName(apiScope)}
375 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahnf043cf62018-06-25 16:04:37 +0900376 props.Libs = module.properties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900377 // Unbundled apps will use the prebult one from /prebuilts/sdk
378 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900379 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900380
381 if module.SocSpecific() {
382 props.Soc_specific = proptools.BoolPtr(true)
383 } else if module.DeviceSpecific() {
384 props.Device_specific = proptools.BoolPtr(true)
385 } else if module.ProductSpecific() {
386 props.Product_specific = proptools.BoolPtr(true)
387 }
388
Colin Cross9ae1b922018-06-26 17:59:05 -0700389 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900390}
391
392// Creates a droiddoc module that creates stubs source files from the given full source
393// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900394func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900395 props := struct {
396 Name *string
397 Srcs []string
398 Custom_template *string
399 Installable *bool
400 Srcs_lib *string
401 Srcs_lib_whitelist_dirs []string
402 Srcs_lib_whitelist_pkgs []string
403 Libs []string
404 Args *string
405 Api_tag_name *string
406 Api_filename *string
407 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900408 Check_api struct {
409 Current ApiToCheck
410 Last_released ApiToCheck
411 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900412 Aidl struct {
413 Include_dirs []string
414 Local_include_dirs []string
415 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900416 }{}
417
Jiyong Parkdf130542018-04-27 16:29:21 +0900418 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900419 props.Srcs = append(props.Srcs, module.properties.Srcs...)
420 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900421 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
422 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900423 // A droiddoc module has only one Libs property and doesn't distinguish between
424 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900425 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900426 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900427 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
428 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900429
430 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
431 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900432 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Jiyong Parkc678ad32018-04-10 13:07:10 +0900433 " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900434 switch apiScope {
435 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900436 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900437 case apiScopeTest:
438 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900439 }
440 props.Args = proptools.StringPtr(droiddocArgs)
441
442 // List of APIs identified from the provided source files are created. They are later
443 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
444 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900445 currentApiFileName := "current.txt"
446 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900447 switch apiScope {
448 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900449 currentApiFileName = "system-" + currentApiFileName
450 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900451 case apiScopeTest:
452 currentApiFileName = "test-" + currentApiFileName
453 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900454 }
455 currentApiFileName = path.Join("api", currentApiFileName)
456 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900457 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900458 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900459 props.Api_filename = proptools.StringPtr(currentApiFileName)
460 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
461
Jiyong Park58c518b2018-05-12 22:29:12 +0900462 // check against the not-yet-release API
463 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
464 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
465 // any change is reported as error
466 props.Check_api.Current.Args = proptools.StringPtr("-error 2 -error 3 -error 4 -error 5 " +
467 "-error 6 -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 " +
468 "-error 14 -error 15 -error 16 -error 17 -error 18 -error 19 -error 20 " +
469 "-error 21 -error 23 -error 24 -error 25 -error 26 -error 27")
470
471 // check against the latest released API
472 props.Check_api.Last_released.Api_file = proptools.StringPtr(
473 module.latestApiFilegroupName(apiScope))
474 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
475 module.latestRemovedApiFilegroupName(apiScope))
476 // backward incompatible changes are reported as error
477 props.Check_api.Last_released.Args = proptools.StringPtr("-hide 2 -hide 3 -hide 4 -hide 5 " +
478 "-hide 6 -hide 24 -hide 25 -hide 26 -hide 27 " +
479 "-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 " +
480 "-error 15 -error 16 -error 17 -error 18")
481
Jiyong Park82484c02018-04-23 21:41:26 +0900482 // Include the part of the framework source. This is required for the case when
483 // API class is extending from the framework class. In that case, doclava needs
484 // to know whether the base class is hidden or not. Since that information is
485 // encoded as @hide string in the comment, we need source files for the classes,
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900486 // not the compiled ones.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900487 props.Srcs_lib = proptools.StringPtr("framework")
488 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900489 // Add android.annotation package to give access to the framework-defined
490 // annotations such as SystemApi, NonNull, etc.
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900491 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
Jiyong Park82484c02018-04-23 21:41:26 +0900492 // These libs are required by doclava to parse the framework sources add via
493 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900494 // If we don't add them to the classpath, errors messages are generated by doclava,
495 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900496 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900497
498 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
499}
500
501// Creates the runtime library. This is not directly linkable from other modules.
502func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
503 props := struct {
504 Name *string
505 Srcs []string
506 Libs []string
507 Static_libs []string
508 Soc_specific *bool
509 Device_specific *bool
510 Product_specific *bool
Colin Cross9ae1b922018-06-26 17:59:05 -0700511 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900512 Required []string
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900513 Errorprone struct {
514 Javacflags []string
515 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900516 }{}
517
518 props.Name = proptools.StringPtr(module.implName())
519 props.Srcs = module.properties.Srcs
520 props.Libs = module.properties.Libs
521 props.Static_libs = module.properties.Static_libs
Colin Cross9ae1b922018-06-26 17:59:05 -0700522 props.Installable = proptools.BoolPtr(true)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900523 // XML file is installed along with the impl lib
524 props.Required = []string{module.xmlFileName()}
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900525 props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
Jiyong Parkc678ad32018-04-10 13:07:10 +0900526
527 if module.SocSpecific() {
528 props.Soc_specific = proptools.BoolPtr(true)
529 } else if module.DeviceSpecific() {
530 props.Device_specific = proptools.BoolPtr(true)
531 } else if module.ProductSpecific() {
532 props.Product_specific = proptools.BoolPtr(true)
533 }
534
Colin Cross9ae1b922018-06-26 17:59:05 -0700535 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props, &module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900536}
537
538// Creates the xml file that publicizes the runtime library
539func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
540 template := `
541<?xml version="1.0" encoding="utf-8"?>
542<!-- Copyright (C) 2018 The Android Open Source Project
543
544 Licensed under the Apache License, Version 2.0 (the "License");
545 you may not use this file except in compliance with the License.
546 You may obtain a copy of the License at
547
548 http://www.apache.org/licenses/LICENSE-2.0
549
550 Unless required by applicable law or agreed to in writing, software
551 distributed under the License is distributed on an "AS IS" BASIS,
552 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
553 See the License for the specific language governing permissions and
554 limitations under the License.
555-->
556
557<permissions>
558 <library name="%s" file="%s"/>
559</permissions>
560`
561 // genrule to generate the xml file content from the template above
562 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
563 // in the ninja file. Do we need to have an external tool for this?
564 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
565 genruleProps := struct {
566 Name *string
567 Cmd *string
568 Out []string
569 }{}
570 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
571 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
572 genruleProps.Out = []string{module.xmlFileName()}
573 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
574
575 // creates a prebuilt_etc module to actually place the xml file under
576 // <partition>/etc/permissions
577 etcProps := struct {
578 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900579 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900580 Sub_dir *string
581 Soc_specific *bool
582 Device_specific *bool
583 Product_specific *bool
584 }{}
585 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900586 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900587 etcProps.Sub_dir = proptools.StringPtr("permissions")
588 if module.SocSpecific() {
589 etcProps.Soc_specific = proptools.BoolPtr(true)
590 } else if module.DeviceSpecific() {
591 etcProps.Device_specific = proptools.BoolPtr(true)
592 } else if module.ProductSpecific() {
593 etcProps.Product_specific = proptools.BoolPtr(true)
594 }
595 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
596}
597
598// to satisfy SdkLibraryDependency interface
599func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
600 // This module is just a wrapper for the stubs.
Sundong Ahn57368eb2018-07-06 11:20:23 +0900601 if linkType == javaSystem {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900602 return module.systemApiStubsPath
Sundong Ahn57368eb2018-07-06 11:20:23 +0900603 } else if linkType == javaPlatform {
604 return module.implLibPath
Jiyong Parkc678ad32018-04-10 13:07:10 +0900605 } else {
606 return module.publicApiStubsPath
607 }
608}
609
Sundong Ahn241cd372018-07-13 16:16:44 +0900610// to satisfy SdkLibraryDependency interface
611func (module *sdkLibrary) ImplementationJars(linkType linkType) android.Paths {
612 // This module is just a wrapper for the stubs.
613 if linkType == javaSystem {
614 return module.systemApiStubsImplPath
615 } else if linkType == javaPlatform {
616 return module.implLibImplPath
617 } else {
618 return module.publicApiStubsImplPath
619 }
620}
621
Jiyong Park82484c02018-04-23 21:41:26 +0900622func javaSdkLibraries(config android.Config) *[]string {
623 return config.Once("javaSdkLibraries", func() interface{} {
624 return &[]string{}
625 }).(*[]string)
626}
627
Jiyong Parkc678ad32018-04-10 13:07:10 +0900628// For a java_sdk_library module, create internal modules for stubs, docs,
629// runtime libs and xml file. If requested, the stubs and docs are created twice
630// once for public API level and once for system API level
631func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
632 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100633 if module.properties.Srcs == nil {
634 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
635 }
636 if module.properties.Api_packages == nil {
637 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
638 }
639
Jiyong Parkc678ad32018-04-10 13:07:10 +0900640 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900641 module.createStubsLibrary(mctx, apiScopePublic)
642 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900643
644 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900645 module.createStubsLibrary(mctx, apiScopeSystem)
646 module.createDocs(mctx, apiScopeSystem)
647
648 // for test API stubs
649 module.createStubsLibrary(mctx, apiScopeTest)
650 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900651
652 // for runtime
653 module.createXmlFile(mctx)
654 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900655
656 // record java_sdk_library modules so that they are exported to make
657 javaSdkLibraries := javaSdkLibraries(mctx.Config())
658 javaSdkLibrariesLock.Lock()
659 defer javaSdkLibrariesLock.Unlock()
660 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900661 }
662}
663
664func sdkLibraryFactory() android.Module {
665 module := &sdkLibrary{}
666 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900667 module.AddProperties(&module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900668 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
669 android.InitDefaultableModule(module)
670 return module
671}