blob: 55a959036d8343b408e6aad532600bf94612a347 [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
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900137 // if set to true, create stubs through Metalava instead of Doclava. Javadoc/Doclava is
138 // currently still used for documentation generation, and will be replaced by Dokka soon.
139 // Defaults to true.
140 Metalava_enabled *bool
141
Jiyong Parkc678ad32018-04-10 13:07:10 +0900142 // TODO: determines whether to create HTML doc or not
143 //Html_doc *bool
144}
145
146type sdkLibrary struct {
147 android.ModuleBase
148 android.DefaultableModuleBase
149
Colin Cross43f08db2018-11-12 10:13:39 -0800150 properties sdkLibraryProperties
151 deviceProperties CompilerDeviceProperties
152 dexpreoptProperties DexpreoptProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900153
154 publicApiStubsPath android.Paths
155 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900156 testApiStubsPath android.Paths
Sundong Ahn57368eb2018-07-06 11:20:23 +0900157 implLibPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900158
159 publicApiStubsImplPath android.Paths
160 systemApiStubsImplPath android.Paths
161 testApiStubsImplPath android.Paths
162 implLibImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900163
164 publicApiFilePath android.Path
165 systemApiFilePath android.Path
166 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900167}
168
169func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
170 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700171 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
172 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
173 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
174 ctx.AddVariationDependencies(nil, implLibTag, module.implName())
Sundong Ahn20e998b2018-07-24 11:19:26 +0900175
Colin Cross42d48b72018-08-29 14:10:52 -0700176 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
177 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
178 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900179}
180
181func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn57368eb2018-07-06 11:20:23 +0900182 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900183 // When this java_sdk_library is dependened from others via "libs" property,
184 // the recorded paths will be returned depending on the link type of the caller.
185 ctx.VisitDirectDeps(func(to android.Module) {
186 otherName := ctx.OtherModuleName(to)
187 tag := ctx.OtherModuleDependencyTag(to)
188
Sundong Ahn57368eb2018-07-06 11:20:23 +0900189 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900190 switch tag {
191 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900192 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900193 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900194 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900195 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900196 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900197 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900198 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900199 module.testApiStubsImplPath = lib.ImplementationJars()
Sundong Ahn57368eb2018-07-06 11:20:23 +0900200 case implLibTag:
201 module.implLibPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900202 module.implLibImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900203 default:
204 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
205 }
206 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900207 if doc, ok := to.(ApiFilePath); ok {
208 switch tag {
209 case publicApiFileTag:
210 module.publicApiFilePath = doc.ApiFilePath()
211 case systemApiFileTag:
212 module.systemApiFilePath = doc.ApiFilePath()
213 case testApiFileTag:
214 module.testApiFilePath = doc.ApiFilePath()
215 default:
216 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
217 }
218 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900219 })
220}
221
Jiyong Park82484c02018-04-23 21:41:26 +0900222func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900223 return android.AndroidMkData{
224 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900225 // Create a phony module that installs the impl library, for the case when this lib is
226 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900227 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
228 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
229 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
230 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
231 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900232 owner := module.ModuleBase.Owner()
233 if owner == "" {
234 owner = "android"
235 }
Jiyong Park90078382018-05-02 19:30:15 +0900236 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900237 if len(module.publicApiStubsPath) == 1 {
238 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
Colin Crossac502722018-11-21 20:33:56 -0800239 module.publicApiStubsImplPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900240 ":"+path.Join("apistubs", owner, "public",
241 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900242 }
243 if len(module.systemApiStubsPath) == 1 {
244 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
Colin Crossac502722018-11-21 20:33:56 -0800245 module.systemApiStubsImplPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900246 ":"+path.Join("apistubs", owner, "system",
247 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900248 }
249 if len(module.testApiStubsPath) == 1 {
250 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
Colin Crossac502722018-11-21 20:33:56 -0800251 module.testApiStubsImplPath.Strings()[0]+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900252 ":"+path.Join("apistubs", owner, "test",
253 module.BaseModuleName()+".jar")+")")
Jiyong Parkb674a522018-05-06 07:53:02 +0900254 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900255 if module.publicApiFilePath != nil {
256 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
257 module.publicApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900258 ":"+path.Join("apistubs", owner, "public", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900259 module.BaseModuleName()+".txt")+")")
260 }
261 if module.systemApiFilePath != nil {
262 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
263 module.systemApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900264 ":"+path.Join("apistubs", owner, "system", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900265 module.BaseModuleName()+".txt")+")")
266 }
267 if module.testApiFilePath != nil {
268 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
269 module.testApiFilePath.String()+
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900270 ":"+path.Join("apistubs", owner, "test", "api",
Sundong Ahn20e998b2018-07-24 11:19:26 +0900271 module.BaseModuleName()+".txt")+")")
272 }
Jiyong Park82484c02018-04-23 21:41:26 +0900273 },
274 }
275}
276
Jiyong Parkc678ad32018-04-10 13:07:10 +0900277// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900278func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900279 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900280 switch apiScope {
281 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900282 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900283 case apiScopeTest:
284 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900285 }
286 return stubsName
287}
288
289// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900290func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900291 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900292 switch apiScope {
293 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900294 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900295 case apiScopeTest:
296 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900297 }
298 return docsName
299}
300
301// Module name of the runtime implementation library
302func (module *sdkLibrary) implName() string {
303 return module.BaseModuleName() + sdkImplLibrarySuffix
304}
305
306// File path to the runtime implementation library
307func (module *sdkLibrary) implPath() string {
308 partition := "system"
309 if module.SocSpecific() {
310 partition = "vendor"
311 } else if module.DeviceSpecific() {
312 partition = "odm"
313 } else if module.ProductSpecific() {
314 partition = "product"
315 }
316 return "/" + partition + "/framework/" + module.implName() + ".jar"
317}
318
319// Module name of the XML file for the lib
320func (module *sdkLibrary) xmlFileName() string {
321 return module.BaseModuleName() + sdkXmlFileSuffix
322}
323
324// SDK version that the stubs library is built against. Note that this is always
325// *current. Older stubs library built with a numberd SDK version is created from
326// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900327func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
328 switch apiScope {
329 case apiScopePublic:
330 return "current"
331 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900332 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900333 case apiScopeTest:
334 return "test_current"
335 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900336 return "current"
337 }
338}
339
340// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
341// api file for the current source
342// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900343func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900344 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900345 switch apiScope {
346 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900347 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900348 case apiScopeTest:
349 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900350 }
351 return apiTagName
352}
353
Jiyong Park58c518b2018-05-12 22:29:12 +0900354func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
355 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900356 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900357 case apiScopePublic:
358 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900359 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900360 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900361 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900362 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900363 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900364 name = name + ".latest"
365 return name
366}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900367
Jiyong Park58c518b2018-05-12 22:29:12 +0900368func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
369 name := ":" + module.BaseModuleName() + "-removed.api."
370 switch apiScope {
371 case apiScopePublic:
372 name = name + "public"
373 case apiScopeSystem:
374 name = name + "system"
375 case apiScopeTest:
376 name = name + "test"
377 }
378 name = name + ".latest"
379 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900380}
381
382// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900383func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900384 props := struct {
385 Name *string
386 Srcs []string
387 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900388 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900389 Soc_specific *bool
390 Device_specific *bool
391 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900392 Compile_dex *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900393 Product_variables struct {
394 Unbundled_build struct {
395 Enabled *bool
396 }
Jiyong Park82484c02018-04-23 21:41:26 +0900397 Pdk struct {
398 Enabled *bool
399 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900400 }
401 }{}
402
Jiyong Parkdf130542018-04-27 16:29:21 +0900403 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900404 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900405 props.Srcs = []string{":" + module.docsName(apiScope)}
406 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahnf043cf62018-06-25 16:04:37 +0900407 props.Libs = module.properties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900408 // Unbundled apps will use the prebult one from /prebuilts/sdk
409 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900410 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahndd567f92018-07-31 17:19:11 +0900411 if module.properties.Compile_dex != nil {
412 props.Compile_dex = module.properties.Compile_dex
413 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900414
415 if module.SocSpecific() {
416 props.Soc_specific = proptools.BoolPtr(true)
417 } else if module.DeviceSpecific() {
418 props.Device_specific = proptools.BoolPtr(true)
419 } else if module.ProductSpecific() {
420 props.Product_specific = proptools.BoolPtr(true)
421 }
422
Colin Cross9ae1b922018-06-26 17:59:05 -0700423 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900424}
425
426// Creates a droiddoc module that creates stubs source files from the given full source
427// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900428func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900429 props := struct {
430 Name *string
431 Srcs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900432 Installable *bool
433 Srcs_lib *string
434 Srcs_lib_whitelist_dirs []string
435 Srcs_lib_whitelist_pkgs []string
436 Libs []string
437 Args *string
438 Api_tag_name *string
439 Api_filename *string
440 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900441 Check_api struct {
442 Current ApiToCheck
443 Last_released ApiToCheck
444 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900445 Aidl struct {
446 Include_dirs []string
447 Local_include_dirs []string
448 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900449 }{}
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900450 droiddocProps := struct {
451 Custom_template *string
452 }{}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900453
Jiyong Parkdf130542018-04-27 16:29:21 +0900454 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900455 props.Srcs = append(props.Srcs, module.properties.Srcs...)
456 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900457 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900458 // A droiddoc module has only one Libs property and doesn't distinguish between
459 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900460 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900461 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900462 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
463 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900464
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900465 if module.properties.Metalava_enabled == nil {
466 module.properties.Metalava_enabled = proptools.BoolPtr(true)
467 }
468
469 droiddocArgs := ""
470 if Bool(module.properties.Metalava_enabled) == true {
471 droiddocArgs = " --stub-packages " + strings.Join(module.properties.Api_packages, ":") +
472 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, " --hide-package ") +
473 " " + android.JoinWithPrefix(module.properties.Droiddoc_options, " ") +
474 " --hide MissingPermission --hide BroadcastBehavior " +
475 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
476 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
477 } else {
478 droiddocProps.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
479 droiddocArgs = " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
480 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, " -hidePackage ") +
481 " " + android.JoinWithPrefix(module.properties.Droiddoc_options, " ") +
482 " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128 -nodocs"
483 }
484
Jiyong Parkdf130542018-04-27 16:29:21 +0900485 switch apiScope {
486 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900487 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900488 case apiScopeTest:
489 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900490 }
491 props.Args = proptools.StringPtr(droiddocArgs)
492
493 // List of APIs identified from the provided source files are created. They are later
494 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
495 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900496 currentApiFileName := "current.txt"
497 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900498 switch apiScope {
499 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900500 currentApiFileName = "system-" + currentApiFileName
501 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900502 case apiScopeTest:
503 currentApiFileName = "test-" + currentApiFileName
504 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900505 }
506 currentApiFileName = path.Join("api", currentApiFileName)
507 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900508 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900509 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900510 props.Api_filename = proptools.StringPtr(currentApiFileName)
511 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
512
Jiyong Park58c518b2018-05-12 22:29:12 +0900513 // check against the not-yet-release API
514 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
515 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900516
517 // check against the latest released API
518 props.Check_api.Last_released.Api_file = proptools.StringPtr(
519 module.latestApiFilegroupName(apiScope))
520 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
521 module.latestRemovedApiFilegroupName(apiScope))
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900522 if Bool(module.properties.Metalava_enabled) == false {
523 // any change is reported as error
524 props.Check_api.Current.Args = proptools.StringPtr("-error 2 -error 3 -error 4 -error 5 " +
525 "-error 6 -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 " +
526 "-error 14 -error 15 -error 16 -error 17 -error 18 -error 19 -error 20 " +
527 "-error 21 -error 23 -error 24 -error 25 -error 26 -error 27")
Jiyong Park58c518b2018-05-12 22:29:12 +0900528
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900529 // backward incompatible changes are reported as error
530 props.Check_api.Last_released.Args = proptools.StringPtr("-hide 2 -hide 3 -hide 4 -hide 5 " +
531 "-hide 6 -hide 24 -hide 25 -hide 26 -hide 27 " +
532 "-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 " +
533 "-error 15 -error 16 -error 17 -error 18")
534
535 // Include the part of the framework source. This is required for the case when
536 // API class is extending from the framework class. In that case, doclava needs
537 // to know whether the base class is hidden or not. Since that information is
538 // encoded as @hide string in the comment, we need source files for the classes,
539 // not the compiled ones.
540 props.Srcs_lib = proptools.StringPtr("framework")
541 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
542
543 // Add android.annotation package to give access to the framework-defined
544 // annotations such as SystemApi, NonNull, etc.
545 if module.properties.Srcs_lib_whitelist_pkgs != nil {
546 props.Srcs_lib_whitelist_pkgs = module.properties.Srcs_lib_whitelist_pkgs
547 } else {
548 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
549 }
Sundong Ahnb952ba02019-01-08 16:32:12 +0900550 } else {
551 props.Srcs_lib = module.properties.Srcs_lib
552 props.Srcs_lib_whitelist_dirs = module.properties.Srcs_lib_whitelist_dirs
553 props.Srcs_lib_whitelist_pkgs = module.properties.Srcs_lib_whitelist_pkgs
Sundong Ahndd567f92018-07-31 17:19:11 +0900554 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900555
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900556 if Bool(module.properties.Metalava_enabled) == true {
557 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
558 } else {
559 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props, &droiddocProps)
560 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900561}
562
563// Creates the runtime library. This is not directly linkable from other modules.
564func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
565 props := struct {
566 Name *string
567 Srcs []string
568 Libs []string
569 Static_libs []string
570 Soc_specific *bool
571 Device_specific *bool
572 Product_specific *bool
Colin Cross9ae1b922018-06-26 17:59:05 -0700573 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900574 Required []string
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900575 Errorprone struct {
576 Javacflags []string
577 }
Colin Cross43f08db2018-11-12 10:13:39 -0800578 IsSDKLibrary bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900579 }{}
580
581 props.Name = proptools.StringPtr(module.implName())
582 props.Srcs = module.properties.Srcs
583 props.Libs = module.properties.Libs
584 props.Static_libs = module.properties.Static_libs
Colin Cross9ae1b922018-06-26 17:59:05 -0700585 props.Installable = proptools.BoolPtr(true)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900586 // XML file is installed along with the impl lib
587 props.Required = []string{module.xmlFileName()}
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900588 props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
Colin Cross43f08db2018-11-12 10:13:39 -0800589 props.IsSDKLibrary = true
Jiyong Parkc678ad32018-04-10 13:07:10 +0900590
591 if module.SocSpecific() {
592 props.Soc_specific = proptools.BoolPtr(true)
593 } else if module.DeviceSpecific() {
594 props.Device_specific = proptools.BoolPtr(true)
595 } else if module.ProductSpecific() {
596 props.Product_specific = proptools.BoolPtr(true)
597 }
598
Colin Cross43f08db2018-11-12 10:13:39 -0800599 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory),
600 &props,
601 &module.deviceProperties,
602 &module.dexpreoptProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900603}
604
605// Creates the xml file that publicizes the runtime library
606func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
607 template := `
608<?xml version="1.0" encoding="utf-8"?>
609<!-- Copyright (C) 2018 The Android Open Source Project
610
611 Licensed under the Apache License, Version 2.0 (the "License");
612 you may not use this file except in compliance with the License.
613 You may obtain a copy of the License at
614
615 http://www.apache.org/licenses/LICENSE-2.0
616
617 Unless required by applicable law or agreed to in writing, software
618 distributed under the License is distributed on an "AS IS" BASIS,
619 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
620 See the License for the specific language governing permissions and
621 limitations under the License.
622-->
623
624<permissions>
625 <library name="%s" file="%s"/>
626</permissions>
627`
628 // genrule to generate the xml file content from the template above
629 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
630 // in the ninja file. Do we need to have an external tool for this?
631 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
632 genruleProps := struct {
633 Name *string
634 Cmd *string
635 Out []string
636 }{}
637 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
638 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
639 genruleProps.Out = []string{module.xmlFileName()}
640 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
641
642 // creates a prebuilt_etc module to actually place the xml file under
643 // <partition>/etc/permissions
644 etcProps := struct {
645 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900646 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900647 Sub_dir *string
648 Soc_specific *bool
649 Device_specific *bool
650 Product_specific *bool
651 }{}
652 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900653 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900654 etcProps.Sub_dir = proptools.StringPtr("permissions")
655 if module.SocSpecific() {
656 etcProps.Soc_specific = proptools.BoolPtr(true)
657 } else if module.DeviceSpecific() {
658 etcProps.Device_specific = proptools.BoolPtr(true)
659 } else if module.ProductSpecific() {
660 etcProps.Product_specific = proptools.BoolPtr(true)
661 }
662 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
663}
664
665// to satisfy SdkLibraryDependency interface
666func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
667 // This module is just a wrapper for the stubs.
Sundong Ahn57368eb2018-07-06 11:20:23 +0900668 if linkType == javaSystem {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900669 return module.systemApiStubsPath
Sundong Ahn57368eb2018-07-06 11:20:23 +0900670 } else if linkType == javaPlatform {
671 return module.implLibPath
Jiyong Parkc678ad32018-04-10 13:07:10 +0900672 } else {
673 return module.publicApiStubsPath
674 }
675}
676
Sundong Ahn241cd372018-07-13 16:16:44 +0900677// to satisfy SdkLibraryDependency interface
678func (module *sdkLibrary) ImplementationJars(linkType linkType) android.Paths {
679 // This module is just a wrapper for the stubs.
680 if linkType == javaSystem {
681 return module.systemApiStubsImplPath
682 } else if linkType == javaPlatform {
683 return module.implLibImplPath
684 } else {
685 return module.publicApiStubsImplPath
686 }
687}
688
Jiyong Park82484c02018-04-23 21:41:26 +0900689func javaSdkLibraries(config android.Config) *[]string {
690 return config.Once("javaSdkLibraries", func() interface{} {
691 return &[]string{}
692 }).(*[]string)
693}
694
Jiyong Parkc678ad32018-04-10 13:07:10 +0900695// For a java_sdk_library module, create internal modules for stubs, docs,
696// runtime libs and xml file. If requested, the stubs and docs are created twice
697// once for public API level and once for system API level
698func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
699 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100700 if module.properties.Srcs == nil {
701 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
702 }
703 if module.properties.Api_packages == nil {
704 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
705 }
706
Jiyong Parkc678ad32018-04-10 13:07:10 +0900707 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900708 module.createStubsLibrary(mctx, apiScopePublic)
709 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900710
711 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900712 module.createStubsLibrary(mctx, apiScopeSystem)
713 module.createDocs(mctx, apiScopeSystem)
714
715 // for test API stubs
716 module.createStubsLibrary(mctx, apiScopeTest)
717 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900718
719 // for runtime
720 module.createXmlFile(mctx)
721 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900722
723 // record java_sdk_library modules so that they are exported to make
724 javaSdkLibraries := javaSdkLibraries(mctx.Config())
725 javaSdkLibrariesLock.Lock()
726 defer javaSdkLibrariesLock.Unlock()
727 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900728 }
729}
730
731func sdkLibraryFactory() android.Module {
732 module := &sdkLibrary{}
733 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900734 module.AddProperties(&module.deviceProperties)
Colin Cross43f08db2018-11-12 10:13:39 -0800735 module.AddProperties(&module.dexpreoptProperties)
Colin Cross48de9a42018-10-02 13:53:33 -0700736 InitJavaModule(module, android.DeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900737 return module
738}