blob: aee528f4fcf7e35073562816d3ad6a2bb4e68fc9 [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"}
49)
50
51type apiScope int
52
53const (
54 apiScopePublic apiScope = iota
55 apiScopeSystem
56 apiScopeTest
Jiyong Parkc678ad32018-04-10 13:07:10 +090057)
58
Jiyong Park82484c02018-04-23 21:41:26 +090059var (
60 javaSdkLibrariesLock sync.Mutex
61)
62
Jiyong Parkc678ad32018-04-10 13:07:10 +090063// java_sdk_library is to make a Java library that implements optional platform APIs to apps.
64// It is actually a wrapper of several modules: 1) stubs library that clients are linked against
65// to, 2) droiddoc module that internally generates API stubs source files, 3) the real runtime
66// shared library that implements the APIs, and 4) XML file for adding the runtime lib to the
67// classpath at runtime if requested via <uses-library>.
68//
69// TODO: these are big features that are currently missing
Jiyong Park58c518b2018-05-12 22:29:12 +090070// 1) ensuring that apps have appropriate <uses-library> tag
71// 2) disallowing linking to the runtime shared lib
72// 3) HTML generation
Jiyong Parkc678ad32018-04-10 13:07:10 +090073
74func init() {
75 android.RegisterModuleType("java_sdk_library", sdkLibraryFactory)
76
77 android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
78 ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
79 })
Jiyong Park82484c02018-04-23 21:41:26 +090080
81 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
82 javaSdkLibraries := javaSdkLibraries(ctx.Config())
83 sort.Strings(*javaSdkLibraries)
84 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
85 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090086}
87
88type sdkLibraryProperties struct {
89 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
90 // or .aidl files.
91 Srcs []string `android:"arch_variant"`
92
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +090093 // list of optional source files that are part of API but not part of runtime library.
94 Api_srcs []string `android:"arch_variant"`
95
Jiyong Parkc678ad32018-04-10 13:07:10 +090096 // list of of java libraries that will be in the classpath
97 Libs []string `android:"arch_variant"`
98
99 // list of java libraries that will be compiled into the resulting runtime jar.
100 // These libraries are not compiled into the stubs jar.
101 Static_libs []string `android:"arch_variant"`
102
103 // list of package names that will be documented and publicized as API
104 Api_packages []string
105
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900106 // list of package names that must be hidden from the API
107 Hidden_api_packages []string
108
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900109 Errorprone struct {
110 // List of javac flags that should only be used when running errorprone.
111 Javacflags []string
112 }
113
Jiyong Parkc678ad32018-04-10 13:07:10 +0900114 // TODO: determines whether to create HTML doc or not
115 //Html_doc *bool
116}
117
118type sdkLibrary struct {
119 android.ModuleBase
120 android.DefaultableModuleBase
121
Jiyong Park441a47d2018-05-01 23:33:08 +0900122 properties sdkLibraryProperties
123 deviceProperties CompilerDeviceProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900124
125 publicApiStubsPath android.Paths
126 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900127 testApiStubsPath android.Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +0900128}
129
130func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
131 // Add dependencies to the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900132 ctx.AddDependency(ctx.Module(), publicApiStubsTag, module.stubsName(apiScopePublic))
133 ctx.AddDependency(ctx.Module(), systemApiStubsTag, module.stubsName(apiScopeSystem))
134 ctx.AddDependency(ctx.Module(), testApiStubsTag, module.stubsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900135}
136
137func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
138 // Record the paths to the header jars of the stubs library.
139 // When this java_sdk_library is dependened from others via "libs" property,
140 // the recorded paths will be returned depending on the link type of the caller.
141 ctx.VisitDirectDeps(func(to android.Module) {
142 otherName := ctx.OtherModuleName(to)
143 tag := ctx.OtherModuleDependencyTag(to)
144
145 if stubs, ok := to.(Dependency); ok {
146 switch tag {
147 case publicApiStubsTag:
148 module.publicApiStubsPath = stubs.HeaderJars()
149 case systemApiStubsTag:
150 module.systemApiStubsPath = stubs.HeaderJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900151 case testApiStubsTag:
152 module.testApiStubsPath = stubs.HeaderJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900153 default:
154 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
155 }
156 }
157 })
158}
159
Jiyong Park82484c02018-04-23 21:41:26 +0900160func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900161 return android.AndroidMkData{
162 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900163 // Create a phony module that installs the impl library, for the case when this lib is
164 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900165 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
166 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
167 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
168 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
169 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Jiyong Park90078382018-05-02 19:30:15 +0900170 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900171 if len(module.publicApiStubsPath) == 1 {
172 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
173 module.publicApiStubsPath.Strings()[0]+
174 ":"+path.Join("apistubs", "public", module.BaseModuleName()+".jar")+")")
175 }
176 if len(module.systemApiStubsPath) == 1 {
177 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
178 module.systemApiStubsPath.Strings()[0]+
179 ":"+path.Join("apistubs", "system", module.BaseModuleName()+".jar")+")")
180 }
181 if len(module.testApiStubsPath) == 1 {
182 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
183 module.testApiStubsPath.Strings()[0]+
184 ":"+path.Join("apistubs", "test", module.BaseModuleName()+".jar")+")")
185 }
Jiyong Park82484c02018-04-23 21:41:26 +0900186 },
187 }
188}
189
Jiyong Parkc678ad32018-04-10 13:07:10 +0900190// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900191func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900192 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900193 switch apiScope {
194 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900195 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900196 case apiScopeTest:
197 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900198 }
199 return stubsName
200}
201
202// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900203func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900204 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900205 switch apiScope {
206 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900207 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900208 case apiScopeTest:
209 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900210 }
211 return docsName
212}
213
214// Module name of the runtime implementation library
215func (module *sdkLibrary) implName() string {
216 return module.BaseModuleName() + sdkImplLibrarySuffix
217}
218
219// File path to the runtime implementation library
220func (module *sdkLibrary) implPath() string {
221 partition := "system"
222 if module.SocSpecific() {
223 partition = "vendor"
224 } else if module.DeviceSpecific() {
225 partition = "odm"
226 } else if module.ProductSpecific() {
227 partition = "product"
228 }
229 return "/" + partition + "/framework/" + module.implName() + ".jar"
230}
231
232// Module name of the XML file for the lib
233func (module *sdkLibrary) xmlFileName() string {
234 return module.BaseModuleName() + sdkXmlFileSuffix
235}
236
237// SDK version that the stubs library is built against. Note that this is always
238// *current. Older stubs library built with a numberd SDK version is created from
239// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900240func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
241 switch apiScope {
242 case apiScopePublic:
243 return "current"
244 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900245 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900246 case apiScopeTest:
247 return "test_current"
248 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900249 return "current"
250 }
251}
252
253// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
254// api file for the current source
255// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900256func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900257 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900258 switch apiScope {
259 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900260 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900261 case apiScopeTest:
262 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900263 }
264 return apiTagName
265}
266
Jiyong Park58c518b2018-05-12 22:29:12 +0900267func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
268 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900269 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900270 case apiScopePublic:
271 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900272 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900273 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900274 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900275 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900276 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900277 name = name + ".latest"
278 return name
279}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900280
Jiyong Park58c518b2018-05-12 22:29:12 +0900281func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
282 name := ":" + module.BaseModuleName() + "-removed.api."
283 switch apiScope {
284 case apiScopePublic:
285 name = name + "public"
286 case apiScopeSystem:
287 name = name + "system"
288 case apiScopeTest:
289 name = name + "test"
290 }
291 name = name + ".latest"
292 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900293}
294
295// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900296func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900297 props := struct {
298 Name *string
299 Srcs []string
300 Sdk_version *string
301 Soc_specific *bool
302 Device_specific *bool
303 Product_specific *bool
304 Product_variables struct {
305 Unbundled_build struct {
306 Enabled *bool
307 }
Jiyong Park82484c02018-04-23 21:41:26 +0900308 Pdk struct {
309 Enabled *bool
310 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900311 }
312 }{}
313
Jiyong Parkdf130542018-04-27 16:29:21 +0900314 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900315 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900316 props.Srcs = []string{":" + module.docsName(apiScope)}
317 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900318 // Unbundled apps will use the prebult one from /prebuilts/sdk
319 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900320 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900321
322 if module.SocSpecific() {
323 props.Soc_specific = proptools.BoolPtr(true)
324 } else if module.DeviceSpecific() {
325 props.Device_specific = proptools.BoolPtr(true)
326 } else if module.ProductSpecific() {
327 props.Product_specific = proptools.BoolPtr(true)
328 }
329
330 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(false)), &props)
331}
332
333// Creates a droiddoc module that creates stubs source files from the given full source
334// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900335func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900336 props := struct {
337 Name *string
338 Srcs []string
339 Custom_template *string
340 Installable *bool
341 Srcs_lib *string
342 Srcs_lib_whitelist_dirs []string
343 Srcs_lib_whitelist_pkgs []string
344 Libs []string
345 Args *string
346 Api_tag_name *string
347 Api_filename *string
348 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900349 Check_api struct {
350 Current ApiToCheck
351 Last_released ApiToCheck
352 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900353 Aidl struct {
354 Include_dirs []string
355 Local_include_dirs []string
356 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900357 }{}
358
Jiyong Parkdf130542018-04-27 16:29:21 +0900359 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900360 props.Srcs = append(props.Srcs, module.properties.Srcs...)
361 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900362 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
363 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900364 // A droiddoc module has only one Libs property and doesn't distinguish between
365 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900366 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900367 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900368 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
369 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900370
371 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
372 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900373 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Jiyong Parkc678ad32018-04-10 13:07:10 +0900374 " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900375 switch apiScope {
376 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900377 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900378 case apiScopeTest:
379 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900380 }
381 props.Args = proptools.StringPtr(droiddocArgs)
382
383 // List of APIs identified from the provided source files are created. They are later
384 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
385 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900386 currentApiFileName := "current.txt"
387 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900388 switch apiScope {
389 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900390 currentApiFileName = "system-" + currentApiFileName
391 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900392 case apiScopeTest:
393 currentApiFileName = "test-" + currentApiFileName
394 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900395 }
396 currentApiFileName = path.Join("api", currentApiFileName)
397 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900398 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900399 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900400 props.Api_filename = proptools.StringPtr(currentApiFileName)
401 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
402
Jiyong Park58c518b2018-05-12 22:29:12 +0900403 // check against the not-yet-release API
404 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
405 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
406 // any change is reported as error
407 props.Check_api.Current.Args = proptools.StringPtr("-error 2 -error 3 -error 4 -error 5 " +
408 "-error 6 -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 " +
409 "-error 14 -error 15 -error 16 -error 17 -error 18 -error 19 -error 20 " +
410 "-error 21 -error 23 -error 24 -error 25 -error 26 -error 27")
411
412 // check against the latest released API
413 props.Check_api.Last_released.Api_file = proptools.StringPtr(
414 module.latestApiFilegroupName(apiScope))
415 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
416 module.latestRemovedApiFilegroupName(apiScope))
417 // backward incompatible changes are reported as error
418 props.Check_api.Last_released.Args = proptools.StringPtr("-hide 2 -hide 3 -hide 4 -hide 5 " +
419 "-hide 6 -hide 24 -hide 25 -hide 26 -hide 27 " +
420 "-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 " +
421 "-error 15 -error 16 -error 17 -error 18")
422
Jiyong Park82484c02018-04-23 21:41:26 +0900423 // Include the part of the framework source. This is required for the case when
424 // API class is extending from the framework class. In that case, doclava needs
425 // to know whether the base class is hidden or not. Since that information is
426 // encoded as @hide string in the comment, we need source files for the classes,
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900427 // not the compiled ones.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900428 props.Srcs_lib = proptools.StringPtr("framework")
429 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900430 // Add android.annotation package to give access to the framework-defined
431 // annotations such as SystemApi, NonNull, etc.
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900432 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
Jiyong Park82484c02018-04-23 21:41:26 +0900433 // These libs are required by doclava to parse the framework sources add via
434 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900435 // If we don't add them to the classpath, errors messages are generated by doclava,
436 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900437 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900438
439 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
440}
441
442// Creates the runtime library. This is not directly linkable from other modules.
443func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
444 props := struct {
445 Name *string
446 Srcs []string
447 Libs []string
448 Static_libs []string
449 Soc_specific *bool
450 Device_specific *bool
451 Product_specific *bool
452 Required []string
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900453 Errorprone struct {
454 Javacflags []string
455 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900456 }{}
457
458 props.Name = proptools.StringPtr(module.implName())
459 props.Srcs = module.properties.Srcs
460 props.Libs = module.properties.Libs
461 props.Static_libs = module.properties.Static_libs
462 // XML file is installed along with the impl lib
463 props.Required = []string{module.xmlFileName()}
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900464 props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
Jiyong Parkc678ad32018-04-10 13:07:10 +0900465
466 if module.SocSpecific() {
467 props.Soc_specific = proptools.BoolPtr(true)
468 } else if module.DeviceSpecific() {
469 props.Device_specific = proptools.BoolPtr(true)
470 } else if module.ProductSpecific() {
471 props.Product_specific = proptools.BoolPtr(true)
472 }
473
Jiyong Park441a47d2018-05-01 23:33:08 +0900474 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(true)), &props, &module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900475}
476
477// Creates the xml file that publicizes the runtime library
478func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
479 template := `
480<?xml version="1.0" encoding="utf-8"?>
481<!-- Copyright (C) 2018 The Android Open Source Project
482
483 Licensed under the Apache License, Version 2.0 (the "License");
484 you may not use this file except in compliance with the License.
485 You may obtain a copy of the License at
486
487 http://www.apache.org/licenses/LICENSE-2.0
488
489 Unless required by applicable law or agreed to in writing, software
490 distributed under the License is distributed on an "AS IS" BASIS,
491 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
492 See the License for the specific language governing permissions and
493 limitations under the License.
494-->
495
496<permissions>
497 <library name="%s" file="%s"/>
498</permissions>
499`
500 // genrule to generate the xml file content from the template above
501 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
502 // in the ninja file. Do we need to have an external tool for this?
503 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
504 genruleProps := struct {
505 Name *string
506 Cmd *string
507 Out []string
508 }{}
509 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
510 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
511 genruleProps.Out = []string{module.xmlFileName()}
512 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
513
514 // creates a prebuilt_etc module to actually place the xml file under
515 // <partition>/etc/permissions
516 etcProps := struct {
517 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900518 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900519 Sub_dir *string
520 Soc_specific *bool
521 Device_specific *bool
522 Product_specific *bool
523 }{}
524 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900525 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900526 etcProps.Sub_dir = proptools.StringPtr("permissions")
527 if module.SocSpecific() {
528 etcProps.Soc_specific = proptools.BoolPtr(true)
529 } else if module.DeviceSpecific() {
530 etcProps.Device_specific = proptools.BoolPtr(true)
531 } else if module.ProductSpecific() {
532 etcProps.Product_specific = proptools.BoolPtr(true)
533 }
534 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
535}
536
537// to satisfy SdkLibraryDependency interface
538func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
539 // This module is just a wrapper for the stubs.
540 if linkType == javaSystem || linkType == javaPlatform {
541 return module.systemApiStubsPath
542 } else {
543 return module.publicApiStubsPath
544 }
545}
546
Jiyong Park82484c02018-04-23 21:41:26 +0900547func javaSdkLibraries(config android.Config) *[]string {
548 return config.Once("javaSdkLibraries", func() interface{} {
549 return &[]string{}
550 }).(*[]string)
551}
552
Jiyong Parkc678ad32018-04-10 13:07:10 +0900553// For a java_sdk_library module, create internal modules for stubs, docs,
554// runtime libs and xml file. If requested, the stubs and docs are created twice
555// once for public API level and once for system API level
556func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
557 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100558 if module.properties.Srcs == nil {
559 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
560 }
561 if module.properties.Api_packages == nil {
562 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
563 }
564
Jiyong Parkc678ad32018-04-10 13:07:10 +0900565 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900566 module.createStubsLibrary(mctx, apiScopePublic)
567 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900568
569 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900570 module.createStubsLibrary(mctx, apiScopeSystem)
571 module.createDocs(mctx, apiScopeSystem)
572
573 // for test API stubs
574 module.createStubsLibrary(mctx, apiScopeTest)
575 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900576
577 // for runtime
578 module.createXmlFile(mctx)
579 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900580
581 // record java_sdk_library modules so that they are exported to make
582 javaSdkLibraries := javaSdkLibraries(mctx.Config())
583 javaSdkLibrariesLock.Lock()
584 defer javaSdkLibrariesLock.Unlock()
585 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900586 }
587}
588
589func sdkLibraryFactory() android.Module {
590 module := &sdkLibrary{}
591 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900592 module.AddProperties(&module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900593 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
594 android.InitDefaultableModule(module)
595 return module
596}