blob: 941e665949ff29632a530d3ca1f5d490a63c75ea [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
Sundong Ahnb952ba02019-01-08 16:32:12 +0900127 // the java library (in classpath) for documentation that provides java srcs and srcjars.
128 Srcs_lib *string
129
130 // the base dirs under srcs_lib will be scanned for java srcs.
131 Srcs_lib_whitelist_dirs []string
132
Sundong Ahndd567f92018-07-31 17:19:11 +0900133 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
134 // Defaults to "android.annotation".
135 Srcs_lib_whitelist_pkgs []string
136
Jiyong Parkc678ad32018-04-10 13:07:10 +0900137 // TODO: determines whether to create HTML doc or not
138 //Html_doc *bool
139}
140
141type sdkLibrary struct {
142 android.ModuleBase
143 android.DefaultableModuleBase
144
Colin Cross43f08db2018-11-12 10:13:39 -0800145 properties sdkLibraryProperties
146 deviceProperties CompilerDeviceProperties
147 dexpreoptProperties DexpreoptProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900148
149 publicApiStubsPath android.Paths
150 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900151 testApiStubsPath android.Paths
Sundong Ahn57368eb2018-07-06 11:20:23 +0900152 implLibPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900153
154 publicApiStubsImplPath android.Paths
155 systemApiStubsImplPath android.Paths
156 testApiStubsImplPath android.Paths
157 implLibImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900158
159 publicApiFilePath android.Path
160 systemApiFilePath android.Path
161 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900162}
163
164func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
165 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700166 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
167 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
168 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
169 ctx.AddVariationDependencies(nil, implLibTag, module.implName())
Sundong Ahn20e998b2018-07-24 11:19:26 +0900170
Colin Cross42d48b72018-08-29 14:10:52 -0700171 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
172 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
173 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900174}
175
176func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn57368eb2018-07-06 11:20:23 +0900177 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900178 // When this java_sdk_library is dependened from others via "libs" property,
179 // the recorded paths will be returned depending on the link type of the caller.
180 ctx.VisitDirectDeps(func(to android.Module) {
181 otherName := ctx.OtherModuleName(to)
182 tag := ctx.OtherModuleDependencyTag(to)
183
Sundong Ahn57368eb2018-07-06 11:20:23 +0900184 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900185 switch tag {
186 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900187 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900188 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900189 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900190 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900191 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900192 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900193 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900194 module.testApiStubsImplPath = lib.ImplementationJars()
Sundong Ahn57368eb2018-07-06 11:20:23 +0900195 case implLibTag:
196 module.implLibPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900197 module.implLibImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900198 default:
199 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
200 }
201 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900202 if doc, ok := to.(ApiFilePath); ok {
203 switch tag {
204 case publicApiFileTag:
205 module.publicApiFilePath = doc.ApiFilePath()
206 case systemApiFileTag:
207 module.systemApiFilePath = doc.ApiFilePath()
208 case testApiFileTag:
209 module.testApiFilePath = doc.ApiFilePath()
210 default:
211 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
212 }
213 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900214 })
215}
216
Jiyong Park82484c02018-04-23 21:41:26 +0900217func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900218 return android.AndroidMkData{
219 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900220 // Create a phony module that installs the impl library, for the case when this lib is
221 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900222 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
223 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
224 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
225 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
226 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900227 owner := module.ModuleBase.Owner()
228 if owner == "" {
229 owner = "android"
230 }
Jiyong Park90078382018-05-02 19:30:15 +0900231 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900232 if len(module.publicApiStubsPath) == 1 {
233 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
Colin Crossac502722018-11-21 20:33:56 -0800234 module.publicApiStubsImplPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900235 ":"+path.Join("apistubs", owner, "public",
236 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900237 }
238 if len(module.systemApiStubsPath) == 1 {
239 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
Colin Crossac502722018-11-21 20:33:56 -0800240 module.systemApiStubsImplPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900241 ":"+path.Join("apistubs", owner, "system",
242 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900243 }
244 if len(module.testApiStubsPath) == 1 {
245 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
Colin Crossac502722018-11-21 20:33:56 -0800246 module.testApiStubsImplPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900247 ":"+path.Join("apistubs", owner, "test",
248 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900249 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900250 if module.publicApiFilePath != nil {
251 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
252 module.publicApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900253 ":"+path.Join("apistubs", owner, "public", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900254 module.BaseModuleName()+".txt")+")")
255 }
256 if module.systemApiFilePath != nil {
257 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
258 module.systemApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900259 ":"+path.Join("apistubs", owner, "system", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900260 module.BaseModuleName()+".txt")+")")
261 }
262 if module.testApiFilePath != nil {
263 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
264 module.testApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900265 ":"+path.Join("apistubs", owner, "test", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900266 module.BaseModuleName()+".txt")+")")
267 }
Jiyong Park82484c02018-04-23 21:41:26 +0900268 },
269 }
270}
271
Jiyong Parkc678ad32018-04-10 13:07:10 +0900272// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900273func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900274 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900275 switch apiScope {
276 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900277 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900278 case apiScopeTest:
279 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900280 }
281 return stubsName
282}
283
284// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900285func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900286 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900287 switch apiScope {
288 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900289 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900290 case apiScopeTest:
291 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900292 }
293 return docsName
294}
295
296// Module name of the runtime implementation library
297func (module *sdkLibrary) implName() string {
298 return module.BaseModuleName() + sdkImplLibrarySuffix
299}
300
301// File path to the runtime implementation library
302func (module *sdkLibrary) implPath() string {
303 partition := "system"
304 if module.SocSpecific() {
305 partition = "vendor"
306 } else if module.DeviceSpecific() {
307 partition = "odm"
308 } else if module.ProductSpecific() {
309 partition = "product"
310 }
311 return "/" + partition + "/framework/" + module.implName() + ".jar"
312}
313
314// Module name of the XML file for the lib
315func (module *sdkLibrary) xmlFileName() string {
316 return module.BaseModuleName() + sdkXmlFileSuffix
317}
318
319// SDK version that the stubs library is built against. Note that this is always
320// *current. Older stubs library built with a numberd SDK version is created from
321// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900322func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
323 switch apiScope {
324 case apiScopePublic:
325 return "current"
326 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900327 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900328 case apiScopeTest:
329 return "test_current"
330 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900331 return "current"
332 }
333}
334
335// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
336// api file for the current source
337// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900338func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900339 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900340 switch apiScope {
341 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900342 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900343 case apiScopeTest:
344 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900345 }
346 return apiTagName
347}
348
Jiyong Park58c518b2018-05-12 22:29:12 +0900349func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
350 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900351 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900352 case apiScopePublic:
353 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900354 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900355 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900356 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900357 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900358 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900359 name = name + ".latest"
360 return name
361}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900362
Jiyong Park58c518b2018-05-12 22:29:12 +0900363func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
364 name := ":" + module.BaseModuleName() + "-removed.api."
365 switch apiScope {
366 case apiScopePublic:
367 name = name + "public"
368 case apiScopeSystem:
369 name = name + "system"
370 case apiScopeTest:
371 name = name + "test"
372 }
373 name = name + ".latest"
374 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900375}
376
377// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900378func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900379 props := struct {
380 Name *string
381 Srcs []string
382 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900383 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900384 Soc_specific *bool
385 Device_specific *bool
386 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900387 Compile_dex *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900388 Product_variables struct {
389 Unbundled_build struct {
390 Enabled *bool
391 }
Jiyong Park82484c02018-04-23 21:41:26 +0900392 Pdk struct {
393 Enabled *bool
394 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900395 }
396 }{}
397
Jiyong Parkdf130542018-04-27 16:29:21 +0900398 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900399 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900400 props.Srcs = []string{":" + module.docsName(apiScope)}
401 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahnf043cf62018-06-25 16:04:37 +0900402 props.Libs = module.properties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900403 // Unbundled apps will use the prebult one from /prebuilts/sdk
404 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900405 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahndd567f92018-07-31 17:19:11 +0900406 if module.properties.Compile_dex != nil {
407 props.Compile_dex = module.properties.Compile_dex
408 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900409
410 if module.SocSpecific() {
411 props.Soc_specific = proptools.BoolPtr(true)
412 } else if module.DeviceSpecific() {
413 props.Device_specific = proptools.BoolPtr(true)
414 } else if module.ProductSpecific() {
415 props.Product_specific = proptools.BoolPtr(true)
416 }
417
Colin Cross9ae1b922018-06-26 17:59:05 -0700418 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900419}
420
421// Creates a droiddoc module that creates stubs source files from the given full source
422// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900423func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900424 props := struct {
425 Name *string
426 Srcs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900427 Installable *bool
428 Srcs_lib *string
429 Srcs_lib_whitelist_dirs []string
430 Srcs_lib_whitelist_pkgs []string
431 Libs []string
432 Args *string
433 Api_tag_name *string
434 Api_filename *string
435 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900436 Check_api struct {
437 Current ApiToCheck
438 Last_released ApiToCheck
439 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900440 Aidl struct {
441 Include_dirs []string
442 Local_include_dirs []string
443 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900444 }{}
445
Jiyong Parkdf130542018-04-27 16:29:21 +0900446 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900447 props.Srcs = append(props.Srcs, module.properties.Srcs...)
448 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900449 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900450 // A droiddoc module has only one Libs property and doesn't distinguish between
451 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900452 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900453 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900454 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
455 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900456
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900457 droiddocArgs := " --stub-packages " + strings.Join(module.properties.Api_packages, ":") +
458 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, " --hide-package ") +
459 " " + android.JoinWithPrefix(module.properties.Droiddoc_options, " ") +
460 " --hide MissingPermission --hide BroadcastBehavior " +
461 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
462 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900463
Jiyong Parkdf130542018-04-27 16:29:21 +0900464 switch apiScope {
465 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900466 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900467 case apiScopeTest:
468 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900469 }
470 props.Args = proptools.StringPtr(droiddocArgs)
471
472 // List of APIs identified from the provided source files are created. They are later
473 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
474 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900475 currentApiFileName := "current.txt"
476 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900477 switch apiScope {
478 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900479 currentApiFileName = "system-" + currentApiFileName
480 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900481 case apiScopeTest:
482 currentApiFileName = "test-" + currentApiFileName
483 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900484 }
485 currentApiFileName = path.Join("api", currentApiFileName)
486 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900487 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900488 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900489 props.Api_filename = proptools.StringPtr(currentApiFileName)
490 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
491
Jiyong Park58c518b2018-05-12 22:29:12 +0900492 // check against the not-yet-release API
493 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
494 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900495
496 // check against the latest released API
497 props.Check_api.Last_released.Api_file = proptools.StringPtr(
498 module.latestApiFilegroupName(apiScope))
499 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
500 module.latestRemovedApiFilegroupName(apiScope))
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900501 props.Srcs_lib = module.properties.Srcs_lib
502 props.Srcs_lib_whitelist_dirs = module.properties.Srcs_lib_whitelist_dirs
503 props.Srcs_lib_whitelist_pkgs = module.properties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900504
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900505 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900506}
507
508// Creates the runtime library. This is not directly linkable from other modules.
509func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
510 props := struct {
511 Name *string
512 Srcs []string
513 Libs []string
514 Static_libs []string
515 Soc_specific *bool
516 Device_specific *bool
517 Product_specific *bool
Colin Cross9ae1b922018-06-26 17:59:05 -0700518 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900519 Required []string
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900520 Errorprone struct {
521 Javacflags []string
522 }
Colin Cross43f08db2018-11-12 10:13:39 -0800523 IsSDKLibrary bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900524 }{}
525
526 props.Name = proptools.StringPtr(module.implName())
527 props.Srcs = module.properties.Srcs
528 props.Libs = module.properties.Libs
529 props.Static_libs = module.properties.Static_libs
Colin Cross9ae1b922018-06-26 17:59:05 -0700530 props.Installable = proptools.BoolPtr(true)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900531 // XML file is installed along with the impl lib
532 props.Required = []string{module.xmlFileName()}
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900533 props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
Colin Cross43f08db2018-11-12 10:13:39 -0800534 props.IsSDKLibrary = true
Jiyong Parkc678ad32018-04-10 13:07:10 +0900535
536 if module.SocSpecific() {
537 props.Soc_specific = proptools.BoolPtr(true)
538 } else if module.DeviceSpecific() {
539 props.Device_specific = proptools.BoolPtr(true)
540 } else if module.ProductSpecific() {
541 props.Product_specific = proptools.BoolPtr(true)
542 }
543
Colin Cross43f08db2018-11-12 10:13:39 -0800544 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory),
545 &props,
546 &module.deviceProperties,
547 &module.dexpreoptProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900548}
549
550// Creates the xml file that publicizes the runtime library
551func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
552 template := `
553<?xml version="1.0" encoding="utf-8"?>
554<!-- Copyright (C) 2018 The Android Open Source Project
555
556 Licensed under the Apache License, Version 2.0 (the "License");
557 you may not use this file except in compliance with the License.
558 You may obtain a copy of the License at
559
560 http://www.apache.org/licenses/LICENSE-2.0
561
562 Unless required by applicable law or agreed to in writing, software
563 distributed under the License is distributed on an "AS IS" BASIS,
564 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
565 See the License for the specific language governing permissions and
566 limitations under the License.
567-->
568
569<permissions>
570 <library name="%s" file="%s"/>
571</permissions>
572`
573 // genrule to generate the xml file content from the template above
574 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
575 // in the ninja file. Do we need to have an external tool for this?
576 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
577 genruleProps := struct {
578 Name *string
579 Cmd *string
580 Out []string
581 }{}
582 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
583 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
584 genruleProps.Out = []string{module.xmlFileName()}
585 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
586
587 // creates a prebuilt_etc module to actually place the xml file under
588 // <partition>/etc/permissions
589 etcProps := struct {
590 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900591 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900592 Sub_dir *string
593 Soc_specific *bool
594 Device_specific *bool
595 Product_specific *bool
596 }{}
597 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900598 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900599 etcProps.Sub_dir = proptools.StringPtr("permissions")
600 if module.SocSpecific() {
601 etcProps.Soc_specific = proptools.BoolPtr(true)
602 } else if module.DeviceSpecific() {
603 etcProps.Device_specific = proptools.BoolPtr(true)
604 } else if module.ProductSpecific() {
605 etcProps.Product_specific = proptools.BoolPtr(true)
606 }
607 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
608}
609
610// to satisfy SdkLibraryDependency interface
611func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
612 // This module is just a wrapper for the stubs.
Sundong Ahn57368eb2018-07-06 11:20:23 +0900613 if linkType == javaSystem {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900614 return module.systemApiStubsPath
Sundong Ahn57368eb2018-07-06 11:20:23 +0900615 } else if linkType == javaPlatform {
616 return module.implLibPath
Jiyong Parkc678ad32018-04-10 13:07:10 +0900617 } else {
618 return module.publicApiStubsPath
619 }
620}
621
Sundong Ahn241cd372018-07-13 16:16:44 +0900622// to satisfy SdkLibraryDependency interface
623func (module *sdkLibrary) ImplementationJars(linkType linkType) android.Paths {
624 // This module is just a wrapper for the stubs.
625 if linkType == javaSystem {
626 return module.systemApiStubsImplPath
627 } else if linkType == javaPlatform {
628 return module.implLibImplPath
629 } else {
630 return module.publicApiStubsImplPath
631 }
632}
633
Jiyong Park82484c02018-04-23 21:41:26 +0900634func javaSdkLibraries(config android.Config) *[]string {
635 return config.Once("javaSdkLibraries", func() interface{} {
636 return &[]string{}
637 }).(*[]string)
638}
639
Jiyong Parkc678ad32018-04-10 13:07:10 +0900640// For a java_sdk_library module, create internal modules for stubs, docs,
641// runtime libs and xml file. If requested, the stubs and docs are created twice
642// once for public API level and once for system API level
643func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
644 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100645 if module.properties.Srcs == nil {
646 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
647 }
648 if module.properties.Api_packages == nil {
649 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
650 }
651
Jiyong Parkc678ad32018-04-10 13:07:10 +0900652 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900653 module.createStubsLibrary(mctx, apiScopePublic)
654 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900655
656 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900657 module.createStubsLibrary(mctx, apiScopeSystem)
658 module.createDocs(mctx, apiScopeSystem)
659
660 // for test API stubs
661 module.createStubsLibrary(mctx, apiScopeTest)
662 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900663
664 // for runtime
665 module.createXmlFile(mctx)
666 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900667
668 // record java_sdk_library modules so that they are exported to make
669 javaSdkLibraries := javaSdkLibraries(mctx.Config())
670 javaSdkLibrariesLock.Lock()
671 defer javaSdkLibrariesLock.Unlock()
672 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900673 }
674}
675
676func sdkLibraryFactory() android.Module {
677 module := &sdkLibrary{}
678 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900679 module.AddProperties(&module.deviceProperties)
Colin Cross43f08db2018-11-12 10:13:39 -0800680 module.AddProperties(&module.dexpreoptProperties)
Colin Cross48de9a42018-10-02 13:53:33 -0700681 InitJavaModule(module, android.DeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900682 return module
683}