blob: 877abe48916c4d9583f328833cf00db7345d7c6e [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
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900131 // if set to true, create stubs through Metalava instead of Doclava. Javadoc/Doclava is
132 // currently still used for documentation generation, and will be replaced by Dokka soon.
133 // Defaults to true.
134 Metalava_enabled *bool
135
Jiyong Parkc678ad32018-04-10 13:07:10 +0900136 // TODO: determines whether to create HTML doc or not
137 //Html_doc *bool
138}
139
140type sdkLibrary struct {
141 android.ModuleBase
142 android.DefaultableModuleBase
143
Colin Cross43f08db2018-11-12 10:13:39 -0800144 properties sdkLibraryProperties
145 deviceProperties CompilerDeviceProperties
146 dexpreoptProperties DexpreoptProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900147
148 publicApiStubsPath android.Paths
149 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900150 testApiStubsPath android.Paths
Sundong Ahn57368eb2018-07-06 11:20:23 +0900151 implLibPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900152
153 publicApiStubsImplPath android.Paths
154 systemApiStubsImplPath android.Paths
155 testApiStubsImplPath android.Paths
156 implLibImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900157
158 publicApiFilePath android.Path
159 systemApiFilePath android.Path
160 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900161}
162
163func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
164 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700165 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
166 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
167 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
168 ctx.AddVariationDependencies(nil, implLibTag, module.implName())
Sundong Ahn20e998b2018-07-24 11:19:26 +0900169
Colin Cross42d48b72018-08-29 14:10:52 -0700170 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
171 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
172 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900173}
174
175func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn57368eb2018-07-06 11:20:23 +0900176 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900177 // When this java_sdk_library is dependened from others via "libs" property,
178 // the recorded paths will be returned depending on the link type of the caller.
179 ctx.VisitDirectDeps(func(to android.Module) {
180 otherName := ctx.OtherModuleName(to)
181 tag := ctx.OtherModuleDependencyTag(to)
182
Sundong Ahn57368eb2018-07-06 11:20:23 +0900183 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900184 switch tag {
185 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900186 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900187 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900188 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900189 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900190 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900191 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900192 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900193 module.testApiStubsImplPath = lib.ImplementationJars()
Sundong Ahn57368eb2018-07-06 11:20:23 +0900194 case implLibTag:
195 module.implLibPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900196 module.implLibImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900197 default:
198 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
199 }
200 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900201 if doc, ok := to.(ApiFilePath); ok {
202 switch tag {
203 case publicApiFileTag:
204 module.publicApiFilePath = doc.ApiFilePath()
205 case systemApiFileTag:
206 module.systemApiFilePath = doc.ApiFilePath()
207 case testApiFileTag:
208 module.testApiFilePath = doc.ApiFilePath()
209 default:
210 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
211 }
212 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900213 })
214}
215
Jiyong Park82484c02018-04-23 21:41:26 +0900216func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900217 return android.AndroidMkData{
218 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900219 // Create a phony module that installs the impl library, for the case when this lib is
220 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900221 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
222 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
223 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
224 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
225 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900226 owner := module.ModuleBase.Owner()
227 if owner == "" {
228 owner = "android"
229 }
Jiyong Park90078382018-05-02 19:30:15 +0900230 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900231 if len(module.publicApiStubsPath) == 1 {
232 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
Colin Crossac502722018-11-21 20:33:56 -0800233 module.publicApiStubsImplPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900234 ":"+path.Join("apistubs", owner, "public",
235 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900236 }
237 if len(module.systemApiStubsPath) == 1 {
238 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
Colin Crossac502722018-11-21 20:33:56 -0800239 module.systemApiStubsImplPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900240 ":"+path.Join("apistubs", owner, "system",
241 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900242 }
243 if len(module.testApiStubsPath) == 1 {
244 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
Colin Crossac502722018-11-21 20:33:56 -0800245 module.testApiStubsImplPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900246 ":"+path.Join("apistubs", owner, "test",
247 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900248 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900249 if module.publicApiFilePath != nil {
250 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
251 module.publicApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900252 ":"+path.Join("apistubs", owner, "public", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900253 module.BaseModuleName()+".txt")+")")
254 }
255 if module.systemApiFilePath != nil {
256 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
257 module.systemApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900258 ":"+path.Join("apistubs", owner, "system", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900259 module.BaseModuleName()+".txt")+")")
260 }
261 if module.testApiFilePath != nil {
262 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
263 module.testApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900264 ":"+path.Join("apistubs", owner, "test", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900265 module.BaseModuleName()+".txt")+")")
266 }
Jiyong Park82484c02018-04-23 21:41:26 +0900267 },
268 }
269}
270
Jiyong Parkc678ad32018-04-10 13:07:10 +0900271// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900272func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900273 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900274 switch apiScope {
275 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900276 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900277 case apiScopeTest:
278 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900279 }
280 return stubsName
281}
282
283// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900284func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900285 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900286 switch apiScope {
287 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900288 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900289 case apiScopeTest:
290 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900291 }
292 return docsName
293}
294
295// Module name of the runtime implementation library
296func (module *sdkLibrary) implName() string {
297 return module.BaseModuleName() + sdkImplLibrarySuffix
298}
299
300// File path to the runtime implementation library
301func (module *sdkLibrary) implPath() string {
302 partition := "system"
303 if module.SocSpecific() {
304 partition = "vendor"
305 } else if module.DeviceSpecific() {
306 partition = "odm"
307 } else if module.ProductSpecific() {
308 partition = "product"
309 }
310 return "/" + partition + "/framework/" + module.implName() + ".jar"
311}
312
313// Module name of the XML file for the lib
314func (module *sdkLibrary) xmlFileName() string {
315 return module.BaseModuleName() + sdkXmlFileSuffix
316}
317
318// SDK version that the stubs library is built against. Note that this is always
319// *current. Older stubs library built with a numberd SDK version is created from
320// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900321func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
322 switch apiScope {
323 case apiScopePublic:
324 return "current"
325 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900326 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900327 case apiScopeTest:
328 return "test_current"
329 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900330 return "current"
331 }
332}
333
334// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
335// api file for the current source
336// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900337func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900338 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900339 switch apiScope {
340 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900341 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900342 case apiScopeTest:
343 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900344 }
345 return apiTagName
346}
347
Jiyong Park58c518b2018-05-12 22:29:12 +0900348func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
349 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900350 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900351 case apiScopePublic:
352 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900353 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900354 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900355 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900356 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900357 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900358 name = name + ".latest"
359 return name
360}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900361
Jiyong Park58c518b2018-05-12 22:29:12 +0900362func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
363 name := ":" + module.BaseModuleName() + "-removed.api."
364 switch apiScope {
365 case apiScopePublic:
366 name = name + "public"
367 case apiScopeSystem:
368 name = name + "system"
369 case apiScopeTest:
370 name = name + "test"
371 }
372 name = name + ".latest"
373 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900374}
375
376// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900377func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900378 props := struct {
379 Name *string
380 Srcs []string
381 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900382 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900383 Soc_specific *bool
384 Device_specific *bool
385 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900386 Compile_dex *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900387 Product_variables struct {
388 Unbundled_build struct {
389 Enabled *bool
390 }
Jiyong Park82484c02018-04-23 21:41:26 +0900391 Pdk struct {
392 Enabled *bool
393 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900394 }
395 }{}
396
Jiyong Parkdf130542018-04-27 16:29:21 +0900397 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900398 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900399 props.Srcs = []string{":" + module.docsName(apiScope)}
400 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahnf043cf62018-06-25 16:04:37 +0900401 props.Libs = module.properties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900402 // Unbundled apps will use the prebult one from /prebuilts/sdk
403 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900404 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahndd567f92018-07-31 17:19:11 +0900405 if module.properties.Compile_dex != nil {
406 props.Compile_dex = module.properties.Compile_dex
407 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900408
409 if module.SocSpecific() {
410 props.Soc_specific = proptools.BoolPtr(true)
411 } else if module.DeviceSpecific() {
412 props.Device_specific = proptools.BoolPtr(true)
413 } else if module.ProductSpecific() {
414 props.Product_specific = proptools.BoolPtr(true)
415 }
416
Colin Cross9ae1b922018-06-26 17:59:05 -0700417 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900418}
419
420// Creates a droiddoc module that creates stubs source files from the given full source
421// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900422func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900423 props := struct {
424 Name *string
425 Srcs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900426 Installable *bool
427 Srcs_lib *string
428 Srcs_lib_whitelist_dirs []string
429 Srcs_lib_whitelist_pkgs []string
430 Libs []string
431 Args *string
432 Api_tag_name *string
433 Api_filename *string
434 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900435 Check_api struct {
436 Current ApiToCheck
437 Last_released ApiToCheck
438 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900439 Aidl struct {
440 Include_dirs []string
441 Local_include_dirs []string
442 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900443 }{}
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900444 droiddocProps := struct {
445 Custom_template *string
446 }{}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900447
Jiyong Parkdf130542018-04-27 16:29:21 +0900448 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900449 props.Srcs = append(props.Srcs, module.properties.Srcs...)
450 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900451 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900452 // A droiddoc module has only one Libs property and doesn't distinguish between
453 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900454 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900455 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900456 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
457 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900458
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900459 if module.properties.Metalava_enabled == nil {
460 module.properties.Metalava_enabled = proptools.BoolPtr(true)
461 }
462
463 droiddocArgs := ""
464 if Bool(module.properties.Metalava_enabled) == true {
465 droiddocArgs = " --stub-packages " + strings.Join(module.properties.Api_packages, ":") +
466 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, " --hide-package ") +
467 " " + android.JoinWithPrefix(module.properties.Droiddoc_options, " ") +
468 " --hide MissingPermission --hide BroadcastBehavior " +
469 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
470 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
471 } else {
472 droiddocProps.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
473 droiddocArgs = " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
474 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, " -hidePackage ") +
475 " " + android.JoinWithPrefix(module.properties.Droiddoc_options, " ") +
476 " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128 -nodocs"
477 }
478
Jiyong Parkdf130542018-04-27 16:29:21 +0900479 switch apiScope {
480 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900481 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900482 case apiScopeTest:
483 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900484 }
485 props.Args = proptools.StringPtr(droiddocArgs)
486
487 // List of APIs identified from the provided source files are created. They are later
488 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
489 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900490 currentApiFileName := "current.txt"
491 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900492 switch apiScope {
493 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900494 currentApiFileName = "system-" + currentApiFileName
495 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900496 case apiScopeTest:
497 currentApiFileName = "test-" + currentApiFileName
498 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900499 }
500 currentApiFileName = path.Join("api", currentApiFileName)
501 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900502 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900503 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900504 props.Api_filename = proptools.StringPtr(currentApiFileName)
505 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
506
Jiyong Park58c518b2018-05-12 22:29:12 +0900507 // check against the not-yet-release API
508 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
509 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900510
511 // check against the latest released API
512 props.Check_api.Last_released.Api_file = proptools.StringPtr(
513 module.latestApiFilegroupName(apiScope))
514 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
515 module.latestRemovedApiFilegroupName(apiScope))
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900516 if Bool(module.properties.Metalava_enabled) == false {
517 // any change is reported as error
518 props.Check_api.Current.Args = proptools.StringPtr("-error 2 -error 3 -error 4 -error 5 " +
519 "-error 6 -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 " +
520 "-error 14 -error 15 -error 16 -error 17 -error 18 -error 19 -error 20 " +
521 "-error 21 -error 23 -error 24 -error 25 -error 26 -error 27")
Jiyong Park58c518b2018-05-12 22:29:12 +0900522
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900523 // backward incompatible changes are reported as error
524 props.Check_api.Last_released.Args = proptools.StringPtr("-hide 2 -hide 3 -hide 4 -hide 5 " +
525 "-hide 6 -hide 24 -hide 25 -hide 26 -hide 27 " +
526 "-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 " +
527 "-error 15 -error 16 -error 17 -error 18")
528
529 // Include the part of the framework source. This is required for the case when
530 // API class is extending from the framework class. In that case, doclava needs
531 // to know whether the base class is hidden or not. Since that information is
532 // encoded as @hide string in the comment, we need source files for the classes,
533 // not the compiled ones.
534 props.Srcs_lib = proptools.StringPtr("framework")
535 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
536
537 // Add android.annotation package to give access to the framework-defined
538 // annotations such as SystemApi, NonNull, etc.
539 if module.properties.Srcs_lib_whitelist_pkgs != nil {
540 props.Srcs_lib_whitelist_pkgs = module.properties.Srcs_lib_whitelist_pkgs
541 } else {
542 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
543 }
Sundong Ahndd567f92018-07-31 17:19:11 +0900544 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900545
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900546 if Bool(module.properties.Metalava_enabled) == true {
547 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
548 } else {
549 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props, &droiddocProps)
550 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900551}
552
553// Creates the runtime library. This is not directly linkable from other modules.
554func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
555 props := struct {
556 Name *string
557 Srcs []string
558 Libs []string
559 Static_libs []string
560 Soc_specific *bool
561 Device_specific *bool
562 Product_specific *bool
Colin Cross9ae1b922018-06-26 17:59:05 -0700563 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900564 Required []string
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900565 Errorprone struct {
566 Javacflags []string
567 }
Colin Cross43f08db2018-11-12 10:13:39 -0800568 IsSDKLibrary bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900569 }{}
570
571 props.Name = proptools.StringPtr(module.implName())
572 props.Srcs = module.properties.Srcs
573 props.Libs = module.properties.Libs
574 props.Static_libs = module.properties.Static_libs
Colin Cross9ae1b922018-06-26 17:59:05 -0700575 props.Installable = proptools.BoolPtr(true)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900576 // XML file is installed along with the impl lib
577 props.Required = []string{module.xmlFileName()}
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900578 props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
Colin Cross43f08db2018-11-12 10:13:39 -0800579 props.IsSDKLibrary = true
Jiyong Parkc678ad32018-04-10 13:07:10 +0900580
581 if module.SocSpecific() {
582 props.Soc_specific = proptools.BoolPtr(true)
583 } else if module.DeviceSpecific() {
584 props.Device_specific = proptools.BoolPtr(true)
585 } else if module.ProductSpecific() {
586 props.Product_specific = proptools.BoolPtr(true)
587 }
588
Colin Cross43f08db2018-11-12 10:13:39 -0800589 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory),
590 &props,
591 &module.deviceProperties,
592 &module.dexpreoptProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900593}
594
595// Creates the xml file that publicizes the runtime library
596func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
597 template := `
598<?xml version="1.0" encoding="utf-8"?>
599<!-- Copyright (C) 2018 The Android Open Source Project
600
601 Licensed under the Apache License, Version 2.0 (the "License");
602 you may not use this file except in compliance with the License.
603 You may obtain a copy of the License at
604
605 http://www.apache.org/licenses/LICENSE-2.0
606
607 Unless required by applicable law or agreed to in writing, software
608 distributed under the License is distributed on an "AS IS" BASIS,
609 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
610 See the License for the specific language governing permissions and
611 limitations under the License.
612-->
613
614<permissions>
615 <library name="%s" file="%s"/>
616</permissions>
617`
618 // genrule to generate the xml file content from the template above
619 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
620 // in the ninja file. Do we need to have an external tool for this?
621 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
622 genruleProps := struct {
623 Name *string
624 Cmd *string
625 Out []string
626 }{}
627 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
628 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
629 genruleProps.Out = []string{module.xmlFileName()}
630 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
631
632 // creates a prebuilt_etc module to actually place the xml file under
633 // <partition>/etc/permissions
634 etcProps := struct {
635 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900636 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900637 Sub_dir *string
638 Soc_specific *bool
639 Device_specific *bool
640 Product_specific *bool
641 }{}
642 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900643 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900644 etcProps.Sub_dir = proptools.StringPtr("permissions")
645 if module.SocSpecific() {
646 etcProps.Soc_specific = proptools.BoolPtr(true)
647 } else if module.DeviceSpecific() {
648 etcProps.Device_specific = proptools.BoolPtr(true)
649 } else if module.ProductSpecific() {
650 etcProps.Product_specific = proptools.BoolPtr(true)
651 }
652 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
653}
654
655// to satisfy SdkLibraryDependency interface
656func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
657 // This module is just a wrapper for the stubs.
Sundong Ahn57368eb2018-07-06 11:20:23 +0900658 if linkType == javaSystem {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900659 return module.systemApiStubsPath
Sundong Ahn57368eb2018-07-06 11:20:23 +0900660 } else if linkType == javaPlatform {
661 return module.implLibPath
Jiyong Parkc678ad32018-04-10 13:07:10 +0900662 } else {
663 return module.publicApiStubsPath
664 }
665}
666
Sundong Ahn241cd372018-07-13 16:16:44 +0900667// to satisfy SdkLibraryDependency interface
668func (module *sdkLibrary) ImplementationJars(linkType linkType) android.Paths {
669 // This module is just a wrapper for the stubs.
670 if linkType == javaSystem {
671 return module.systemApiStubsImplPath
672 } else if linkType == javaPlatform {
673 return module.implLibImplPath
674 } else {
675 return module.publicApiStubsImplPath
676 }
677}
678
Jiyong Park82484c02018-04-23 21:41:26 +0900679func javaSdkLibraries(config android.Config) *[]string {
680 return config.Once("javaSdkLibraries", func() interface{} {
681 return &[]string{}
682 }).(*[]string)
683}
684
Jiyong Parkc678ad32018-04-10 13:07:10 +0900685// For a java_sdk_library module, create internal modules for stubs, docs,
686// runtime libs and xml file. If requested, the stubs and docs are created twice
687// once for public API level and once for system API level
688func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
689 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100690 if module.properties.Srcs == nil {
691 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
692 }
693 if module.properties.Api_packages == nil {
694 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
695 }
696
Jiyong Parkc678ad32018-04-10 13:07:10 +0900697 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900698 module.createStubsLibrary(mctx, apiScopePublic)
699 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900700
701 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900702 module.createStubsLibrary(mctx, apiScopeSystem)
703 module.createDocs(mctx, apiScopeSystem)
704
705 // for test API stubs
706 module.createStubsLibrary(mctx, apiScopeTest)
707 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900708
709 // for runtime
710 module.createXmlFile(mctx)
711 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900712
713 // record java_sdk_library modules so that they are exported to make
714 javaSdkLibraries := javaSdkLibraries(mctx.Config())
715 javaSdkLibrariesLock.Lock()
716 defer javaSdkLibrariesLock.Unlock()
717 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900718 }
719}
720
721func sdkLibraryFactory() android.Module {
722 module := &sdkLibrary{}
723 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900724 module.AddProperties(&module.deviceProperties)
Colin Cross43f08db2018-11-12 10:13:39 -0800725 module.AddProperties(&module.dexpreoptProperties)
Colin Cross48de9a42018-10-02 13:53:33 -0700726 InitJavaModule(module, android.DeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900727 return module
728}