blob: 3e6908bde10ccecf80aadecc867ef2df6831d33e [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)")
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900220 owner := module.ModuleBase.Owner()
221 if owner == "" {
222 owner = "android"
223 }
Jiyong Park90078382018-05-02 19:30:15 +0900224 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900225 if len(module.publicApiStubsPath) == 1 {
226 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
227 module.publicApiStubsPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900228 ":"+path.Join("apistubs", owner, "public",
229 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900230 }
231 if len(module.systemApiStubsPath) == 1 {
232 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
233 module.systemApiStubsPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900234 ":"+path.Join("apistubs", owner, "system",
235 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900236 }
237 if len(module.testApiStubsPath) == 1 {
238 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
239 module.testApiStubsPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900240 ":"+path.Join("apistubs", owner, "test",
241 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900242 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900243 if module.publicApiFilePath != nil {
244 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
245 module.publicApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900246 ":"+path.Join("apistubs", owner, "public", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900247 module.BaseModuleName()+".txt")+")")
248 }
249 if module.systemApiFilePath != nil {
250 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
251 module.systemApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900252 ":"+path.Join("apistubs", owner, "system", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900253 module.BaseModuleName()+".txt")+")")
254 }
255 if module.testApiFilePath != nil {
256 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
257 module.testApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900258 ":"+path.Join("apistubs", owner, "test", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900259 module.BaseModuleName()+".txt")+")")
260 }
Jiyong Park82484c02018-04-23 21:41:26 +0900261 },
262 }
263}
264
Jiyong Parkc678ad32018-04-10 13:07:10 +0900265// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900266func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900267 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900268 switch apiScope {
269 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900270 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900271 case apiScopeTest:
272 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900273 }
274 return stubsName
275}
276
277// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900278func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900279 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900280 switch apiScope {
281 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900282 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900283 case apiScopeTest:
284 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900285 }
286 return docsName
287}
288
289// Module name of the runtime implementation library
290func (module *sdkLibrary) implName() string {
291 return module.BaseModuleName() + sdkImplLibrarySuffix
292}
293
294// File path to the runtime implementation library
295func (module *sdkLibrary) implPath() string {
296 partition := "system"
297 if module.SocSpecific() {
298 partition = "vendor"
299 } else if module.DeviceSpecific() {
300 partition = "odm"
301 } else if module.ProductSpecific() {
302 partition = "product"
303 }
304 return "/" + partition + "/framework/" + module.implName() + ".jar"
305}
306
307// Module name of the XML file for the lib
308func (module *sdkLibrary) xmlFileName() string {
309 return module.BaseModuleName() + sdkXmlFileSuffix
310}
311
312// SDK version that the stubs library is built against. Note that this is always
313// *current. Older stubs library built with a numberd SDK version is created from
314// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900315func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
316 switch apiScope {
317 case apiScopePublic:
318 return "current"
319 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900320 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900321 case apiScopeTest:
322 return "test_current"
323 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900324 return "current"
325 }
326}
327
328// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
329// api file for the current source
330// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900331func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900332 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900333 switch apiScope {
334 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900335 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900336 case apiScopeTest:
337 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900338 }
339 return apiTagName
340}
341
Jiyong Park58c518b2018-05-12 22:29:12 +0900342func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
343 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900344 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900345 case apiScopePublic:
346 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900347 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900348 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900349 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900350 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900351 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900352 name = name + ".latest"
353 return name
354}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900355
Jiyong Park58c518b2018-05-12 22:29:12 +0900356func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
357 name := ":" + module.BaseModuleName() + "-removed.api."
358 switch apiScope {
359 case apiScopePublic:
360 name = name + "public"
361 case apiScopeSystem:
362 name = name + "system"
363 case apiScopeTest:
364 name = name + "test"
365 }
366 name = name + ".latest"
367 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900368}
369
370// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900371func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900372 props := struct {
373 Name *string
374 Srcs []string
375 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900376 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900377 Soc_specific *bool
378 Device_specific *bool
379 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900380 Compile_dex *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900381 Product_variables struct {
382 Unbundled_build struct {
383 Enabled *bool
384 }
Jiyong Park82484c02018-04-23 21:41:26 +0900385 Pdk struct {
386 Enabled *bool
387 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900388 }
389 }{}
390
Jiyong Parkdf130542018-04-27 16:29:21 +0900391 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900392 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900393 props.Srcs = []string{":" + module.docsName(apiScope)}
394 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahnf043cf62018-06-25 16:04:37 +0900395 props.Libs = module.properties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900396 // Unbundled apps will use the prebult one from /prebuilts/sdk
397 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900398 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahndd567f92018-07-31 17:19:11 +0900399 if module.properties.Compile_dex != nil {
400 props.Compile_dex = module.properties.Compile_dex
401 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900402
403 if module.SocSpecific() {
404 props.Soc_specific = proptools.BoolPtr(true)
405 } else if module.DeviceSpecific() {
406 props.Device_specific = proptools.BoolPtr(true)
407 } else if module.ProductSpecific() {
408 props.Product_specific = proptools.BoolPtr(true)
409 }
410
Colin Cross9ae1b922018-06-26 17:59:05 -0700411 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900412}
413
414// Creates a droiddoc module that creates stubs source files from the given full source
415// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900416func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900417 props := struct {
418 Name *string
419 Srcs []string
420 Custom_template *string
421 Installable *bool
422 Srcs_lib *string
423 Srcs_lib_whitelist_dirs []string
424 Srcs_lib_whitelist_pkgs []string
425 Libs []string
426 Args *string
427 Api_tag_name *string
428 Api_filename *string
429 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900430 Check_api struct {
431 Current ApiToCheck
432 Last_released ApiToCheck
433 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900434 Aidl struct {
435 Include_dirs []string
436 Local_include_dirs []string
437 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900438 }{}
439
Jiyong Parkdf130542018-04-27 16:29:21 +0900440 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900441 props.Srcs = append(props.Srcs, module.properties.Srcs...)
442 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900443 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
444 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900445 // A droiddoc module has only one Libs property and doesn't distinguish between
446 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900447 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900448 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900449 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
450 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900451
452 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
453 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900454 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Sundong Ahndd567f92018-07-31 17:19:11 +0900455 " " + android.JoinWithPrefix(module.properties.Droiddoc_options, "-") + " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900456 switch apiScope {
457 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900458 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900459 case apiScopeTest:
460 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900461 }
462 props.Args = proptools.StringPtr(droiddocArgs)
463
464 // List of APIs identified from the provided source files are created. They are later
465 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
466 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900467 currentApiFileName := "current.txt"
468 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900469 switch apiScope {
470 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900471 currentApiFileName = "system-" + currentApiFileName
472 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900473 case apiScopeTest:
474 currentApiFileName = "test-" + currentApiFileName
475 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900476 }
477 currentApiFileName = path.Join("api", currentApiFileName)
478 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900479 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900480 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900481 props.Api_filename = proptools.StringPtr(currentApiFileName)
482 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
483
Jiyong Park58c518b2018-05-12 22:29:12 +0900484 // check against the not-yet-release API
485 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
486 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
487 // any change is reported as error
488 props.Check_api.Current.Args = proptools.StringPtr("-error 2 -error 3 -error 4 -error 5 " +
489 "-error 6 -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 " +
490 "-error 14 -error 15 -error 16 -error 17 -error 18 -error 19 -error 20 " +
491 "-error 21 -error 23 -error 24 -error 25 -error 26 -error 27")
492
493 // check against the latest released API
494 props.Check_api.Last_released.Api_file = proptools.StringPtr(
495 module.latestApiFilegroupName(apiScope))
496 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
497 module.latestRemovedApiFilegroupName(apiScope))
498 // backward incompatible changes are reported as error
499 props.Check_api.Last_released.Args = proptools.StringPtr("-hide 2 -hide 3 -hide 4 -hide 5 " +
500 "-hide 6 -hide 24 -hide 25 -hide 26 -hide 27 " +
501 "-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 " +
502 "-error 15 -error 16 -error 17 -error 18")
503
Jiyong Park82484c02018-04-23 21:41:26 +0900504 // Include the part of the framework source. This is required for the case when
505 // API class is extending from the framework class. In that case, doclava needs
506 // to know whether the base class is hidden or not. Since that information is
507 // encoded as @hide string in the comment, we need source files for the classes,
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900508 // not the compiled ones.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900509 props.Srcs_lib = proptools.StringPtr("framework")
510 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900511 // Add android.annotation package to give access to the framework-defined
512 // annotations such as SystemApi, NonNull, etc.
Sundong Ahndd567f92018-07-31 17:19:11 +0900513 if module.properties.Srcs_lib_whitelist_pkgs != nil {
514 props.Srcs_lib_whitelist_pkgs = module.properties.Srcs_lib_whitelist_pkgs
515 } else {
516 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
517 }
Jiyong Park82484c02018-04-23 21:41:26 +0900518 // These libs are required by doclava to parse the framework sources add via
519 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900520 // If we don't add them to the classpath, errors messages are generated by doclava,
521 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900522 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900523
524 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
525}
526
527// Creates the runtime library. This is not directly linkable from other modules.
528func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
529 props := struct {
530 Name *string
531 Srcs []string
532 Libs []string
533 Static_libs []string
534 Soc_specific *bool
535 Device_specific *bool
536 Product_specific *bool
Colin Cross9ae1b922018-06-26 17:59:05 -0700537 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900538 Required []string
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900539 Errorprone struct {
540 Javacflags []string
541 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900542 }{}
543
544 props.Name = proptools.StringPtr(module.implName())
545 props.Srcs = module.properties.Srcs
546 props.Libs = module.properties.Libs
547 props.Static_libs = module.properties.Static_libs
Colin Cross9ae1b922018-06-26 17:59:05 -0700548 props.Installable = proptools.BoolPtr(true)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900549 // XML file is installed along with the impl lib
550 props.Required = []string{module.xmlFileName()}
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900551 props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
Jiyong Parkc678ad32018-04-10 13:07:10 +0900552
553 if module.SocSpecific() {
554 props.Soc_specific = proptools.BoolPtr(true)
555 } else if module.DeviceSpecific() {
556 props.Device_specific = proptools.BoolPtr(true)
557 } else if module.ProductSpecific() {
558 props.Product_specific = proptools.BoolPtr(true)
559 }
560
Colin Cross9ae1b922018-06-26 17:59:05 -0700561 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props, &module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900562}
563
564// Creates the xml file that publicizes the runtime library
565func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
566 template := `
567<?xml version="1.0" encoding="utf-8"?>
568<!-- Copyright (C) 2018 The Android Open Source Project
569
570 Licensed under the Apache License, Version 2.0 (the "License");
571 you may not use this file except in compliance with the License.
572 You may obtain a copy of the License at
573
574 http://www.apache.org/licenses/LICENSE-2.0
575
576 Unless required by applicable law or agreed to in writing, software
577 distributed under the License is distributed on an "AS IS" BASIS,
578 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
579 See the License for the specific language governing permissions and
580 limitations under the License.
581-->
582
583<permissions>
584 <library name="%s" file="%s"/>
585</permissions>
586`
587 // genrule to generate the xml file content from the template above
588 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
589 // in the ninja file. Do we need to have an external tool for this?
590 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
591 genruleProps := struct {
592 Name *string
593 Cmd *string
594 Out []string
595 }{}
596 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
597 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
598 genruleProps.Out = []string{module.xmlFileName()}
599 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
600
601 // creates a prebuilt_etc module to actually place the xml file under
602 // <partition>/etc/permissions
603 etcProps := struct {
604 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900605 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900606 Sub_dir *string
607 Soc_specific *bool
608 Device_specific *bool
609 Product_specific *bool
610 }{}
611 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900612 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900613 etcProps.Sub_dir = proptools.StringPtr("permissions")
614 if module.SocSpecific() {
615 etcProps.Soc_specific = proptools.BoolPtr(true)
616 } else if module.DeviceSpecific() {
617 etcProps.Device_specific = proptools.BoolPtr(true)
618 } else if module.ProductSpecific() {
619 etcProps.Product_specific = proptools.BoolPtr(true)
620 }
621 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
622}
623
624// to satisfy SdkLibraryDependency interface
625func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
626 // This module is just a wrapper for the stubs.
Sundong Ahn57368eb2018-07-06 11:20:23 +0900627 if linkType == javaSystem {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900628 return module.systemApiStubsPath
Sundong Ahn57368eb2018-07-06 11:20:23 +0900629 } else if linkType == javaPlatform {
630 return module.implLibPath
Jiyong Parkc678ad32018-04-10 13:07:10 +0900631 } else {
632 return module.publicApiStubsPath
633 }
634}
635
Sundong Ahn241cd372018-07-13 16:16:44 +0900636// to satisfy SdkLibraryDependency interface
637func (module *sdkLibrary) ImplementationJars(linkType linkType) android.Paths {
638 // This module is just a wrapper for the stubs.
639 if linkType == javaSystem {
640 return module.systemApiStubsImplPath
641 } else if linkType == javaPlatform {
642 return module.implLibImplPath
643 } else {
644 return module.publicApiStubsImplPath
645 }
646}
647
Jiyong Park82484c02018-04-23 21:41:26 +0900648func javaSdkLibraries(config android.Config) *[]string {
649 return config.Once("javaSdkLibraries", func() interface{} {
650 return &[]string{}
651 }).(*[]string)
652}
653
Jiyong Parkc678ad32018-04-10 13:07:10 +0900654// For a java_sdk_library module, create internal modules for stubs, docs,
655// runtime libs and xml file. If requested, the stubs and docs are created twice
656// once for public API level and once for system API level
657func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
658 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100659 if module.properties.Srcs == nil {
660 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
661 }
662 if module.properties.Api_packages == nil {
663 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
664 }
665
Jiyong Parkc678ad32018-04-10 13:07:10 +0900666 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900667 module.createStubsLibrary(mctx, apiScopePublic)
668 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900669
670 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900671 module.createStubsLibrary(mctx, apiScopeSystem)
672 module.createDocs(mctx, apiScopeSystem)
673
674 // for test API stubs
675 module.createStubsLibrary(mctx, apiScopeTest)
676 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900677
678 // for runtime
679 module.createXmlFile(mctx)
680 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900681
682 // record java_sdk_library modules so that they are exported to make
683 javaSdkLibraries := javaSdkLibraries(mctx.Config())
684 javaSdkLibrariesLock.Lock()
685 defer javaSdkLibrariesLock.Unlock()
686 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900687 }
688}
689
690func sdkLibraryFactory() android.Module {
691 module := &sdkLibrary{}
692 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900693 module.AddProperties(&module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900694 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
695 android.InitDefaultableModule(module)
696 return module
697}