blob: abd2dc2c2bfa07feeac6de3f12ae94bd64466a25 [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 Parkc678ad32018-04-10 13:07:10 +0900109 // TODO: determines whether to create HTML doc or not
110 //Html_doc *bool
111}
112
113type sdkLibrary struct {
114 android.ModuleBase
115 android.DefaultableModuleBase
116
Jiyong Park441a47d2018-05-01 23:33:08 +0900117 properties sdkLibraryProperties
118 deviceProperties CompilerDeviceProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900119
120 publicApiStubsPath android.Paths
121 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900122 testApiStubsPath android.Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +0900123}
124
125func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
126 // Add dependencies to the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900127 ctx.AddDependency(ctx.Module(), publicApiStubsTag, module.stubsName(apiScopePublic))
128 ctx.AddDependency(ctx.Module(), systemApiStubsTag, module.stubsName(apiScopeSystem))
129 ctx.AddDependency(ctx.Module(), testApiStubsTag, module.stubsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900130}
131
132func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
133 // Record the paths to the header jars of the stubs library.
134 // When this java_sdk_library is dependened from others via "libs" property,
135 // the recorded paths will be returned depending on the link type of the caller.
136 ctx.VisitDirectDeps(func(to android.Module) {
137 otherName := ctx.OtherModuleName(to)
138 tag := ctx.OtherModuleDependencyTag(to)
139
140 if stubs, ok := to.(Dependency); ok {
141 switch tag {
142 case publicApiStubsTag:
143 module.publicApiStubsPath = stubs.HeaderJars()
144 case systemApiStubsTag:
145 module.systemApiStubsPath = stubs.HeaderJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900146 case testApiStubsTag:
147 module.testApiStubsPath = stubs.HeaderJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900148 default:
149 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
150 }
151 }
152 })
153}
154
Jiyong Park82484c02018-04-23 21:41:26 +0900155func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900156 return android.AndroidMkData{
157 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900158 // Create a phony module that installs the impl library, for the case when this lib is
159 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900160 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
161 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
162 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
163 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
164 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Jiyong Park90078382018-05-02 19:30:15 +0900165 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900166 if len(module.publicApiStubsPath) == 1 {
167 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
168 module.publicApiStubsPath.Strings()[0]+
169 ":"+path.Join("apistubs", "public", module.BaseModuleName()+".jar")+")")
170 }
171 if len(module.systemApiStubsPath) == 1 {
172 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
173 module.systemApiStubsPath.Strings()[0]+
174 ":"+path.Join("apistubs", "system", module.BaseModuleName()+".jar")+")")
175 }
176 if len(module.testApiStubsPath) == 1 {
177 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
178 module.testApiStubsPath.Strings()[0]+
179 ":"+path.Join("apistubs", "test", module.BaseModuleName()+".jar")+")")
180 }
Jiyong Park82484c02018-04-23 21:41:26 +0900181 },
182 }
183}
184
Jiyong Parkc678ad32018-04-10 13:07:10 +0900185// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900186func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900187 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900188 switch apiScope {
189 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900190 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900191 case apiScopeTest:
192 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900193 }
194 return stubsName
195}
196
197// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900198func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900199 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900200 switch apiScope {
201 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900202 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900203 case apiScopeTest:
204 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900205 }
206 return docsName
207}
208
209// Module name of the runtime implementation library
210func (module *sdkLibrary) implName() string {
211 return module.BaseModuleName() + sdkImplLibrarySuffix
212}
213
214// File path to the runtime implementation library
215func (module *sdkLibrary) implPath() string {
216 partition := "system"
217 if module.SocSpecific() {
218 partition = "vendor"
219 } else if module.DeviceSpecific() {
220 partition = "odm"
221 } else if module.ProductSpecific() {
222 partition = "product"
223 }
224 return "/" + partition + "/framework/" + module.implName() + ".jar"
225}
226
227// Module name of the XML file for the lib
228func (module *sdkLibrary) xmlFileName() string {
229 return module.BaseModuleName() + sdkXmlFileSuffix
230}
231
232// SDK version that the stubs library is built against. Note that this is always
233// *current. Older stubs library built with a numberd SDK version is created from
234// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900235func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
236 switch apiScope {
237 case apiScopePublic:
238 return "current"
239 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900240 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900241 case apiScopeTest:
242 return "test_current"
243 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900244 return "current"
245 }
246}
247
248// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
249// api file for the current source
250// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900251func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900252 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900253 switch apiScope {
254 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900255 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900256 case apiScopeTest:
257 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900258 }
259 return apiTagName
260}
261
Jiyong Park58c518b2018-05-12 22:29:12 +0900262func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
263 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900264 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900265 case apiScopePublic:
266 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900267 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900268 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900269 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900270 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900271 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900272 name = name + ".latest"
273 return name
274}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900275
Jiyong Park58c518b2018-05-12 22:29:12 +0900276func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
277 name := ":" + module.BaseModuleName() + "-removed.api."
278 switch apiScope {
279 case apiScopePublic:
280 name = name + "public"
281 case apiScopeSystem:
282 name = name + "system"
283 case apiScopeTest:
284 name = name + "test"
285 }
286 name = name + ".latest"
287 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900288}
289
290// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900291func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900292 props := struct {
293 Name *string
294 Srcs []string
295 Sdk_version *string
296 Soc_specific *bool
297 Device_specific *bool
298 Product_specific *bool
299 Product_variables struct {
300 Unbundled_build struct {
301 Enabled *bool
302 }
Jiyong Park82484c02018-04-23 21:41:26 +0900303 Pdk struct {
304 Enabled *bool
305 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900306 }
307 }{}
308
Jiyong Parkdf130542018-04-27 16:29:21 +0900309 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900310 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900311 props.Srcs = []string{":" + module.docsName(apiScope)}
312 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900313 // Unbundled apps will use the prebult one from /prebuilts/sdk
314 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900315 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900316
317 if module.SocSpecific() {
318 props.Soc_specific = proptools.BoolPtr(true)
319 } else if module.DeviceSpecific() {
320 props.Device_specific = proptools.BoolPtr(true)
321 } else if module.ProductSpecific() {
322 props.Product_specific = proptools.BoolPtr(true)
323 }
324
325 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(false)), &props)
326}
327
328// Creates a droiddoc module that creates stubs source files from the given full source
329// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900330func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900331 props := struct {
332 Name *string
333 Srcs []string
334 Custom_template *string
335 Installable *bool
336 Srcs_lib *string
337 Srcs_lib_whitelist_dirs []string
338 Srcs_lib_whitelist_pkgs []string
339 Libs []string
340 Args *string
341 Api_tag_name *string
342 Api_filename *string
343 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900344 Check_api struct {
345 Current ApiToCheck
346 Last_released ApiToCheck
347 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900348 Aidl struct {
349 Include_dirs []string
350 Local_include_dirs []string
351 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900352 }{}
353
Jiyong Parkdf130542018-04-27 16:29:21 +0900354 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900355 props.Srcs = append(props.Srcs, module.properties.Srcs...)
356 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900357 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
358 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900359 // A droiddoc module has only one Libs property and doesn't distinguish between
360 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900361 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900362 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900363 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
364 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900365
366 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
367 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900368 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Jiyong Parkc678ad32018-04-10 13:07:10 +0900369 " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900370 switch apiScope {
371 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900372 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900373 case apiScopeTest:
374 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900375 }
376 props.Args = proptools.StringPtr(droiddocArgs)
377
378 // List of APIs identified from the provided source files are created. They are later
379 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
380 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900381 currentApiFileName := "current.txt"
382 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900383 switch apiScope {
384 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900385 currentApiFileName = "system-" + currentApiFileName
386 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900387 case apiScopeTest:
388 currentApiFileName = "test-" + currentApiFileName
389 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900390 }
391 currentApiFileName = path.Join("api", currentApiFileName)
392 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900393 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900394 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900395 props.Api_filename = proptools.StringPtr(currentApiFileName)
396 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
397
Jiyong Park58c518b2018-05-12 22:29:12 +0900398 // check against the not-yet-release API
399 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
400 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
401 // any change is reported as error
402 props.Check_api.Current.Args = proptools.StringPtr("-error 2 -error 3 -error 4 -error 5 " +
403 "-error 6 -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 " +
404 "-error 14 -error 15 -error 16 -error 17 -error 18 -error 19 -error 20 " +
405 "-error 21 -error 23 -error 24 -error 25 -error 26 -error 27")
406
407 // check against the latest released API
408 props.Check_api.Last_released.Api_file = proptools.StringPtr(
409 module.latestApiFilegroupName(apiScope))
410 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
411 module.latestRemovedApiFilegroupName(apiScope))
412 // backward incompatible changes are reported as error
413 props.Check_api.Last_released.Args = proptools.StringPtr("-hide 2 -hide 3 -hide 4 -hide 5 " +
414 "-hide 6 -hide 24 -hide 25 -hide 26 -hide 27 " +
415 "-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 " +
416 "-error 15 -error 16 -error 17 -error 18")
417
Jiyong Park82484c02018-04-23 21:41:26 +0900418 // Include the part of the framework source. This is required for the case when
419 // API class is extending from the framework class. In that case, doclava needs
420 // to know whether the base class is hidden or not. Since that information is
421 // encoded as @hide string in the comment, we need source files for the classes,
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900422 // not the compiled ones.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900423 props.Srcs_lib = proptools.StringPtr("framework")
424 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900425 // Add android.annotation package to give access to the framework-defined
426 // annotations such as SystemApi, NonNull, etc.
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900427 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
Jiyong Park82484c02018-04-23 21:41:26 +0900428 // These libs are required by doclava to parse the framework sources add via
429 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900430 // If we don't add them to the classpath, errors messages are generated by doclava,
431 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900432 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900433
434 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
435}
436
437// Creates the runtime library. This is not directly linkable from other modules.
438func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
439 props := struct {
440 Name *string
441 Srcs []string
442 Libs []string
443 Static_libs []string
444 Soc_specific *bool
445 Device_specific *bool
446 Product_specific *bool
447 Required []string
448 }{}
449
450 props.Name = proptools.StringPtr(module.implName())
451 props.Srcs = module.properties.Srcs
452 props.Libs = module.properties.Libs
453 props.Static_libs = module.properties.Static_libs
454 // XML file is installed along with the impl lib
455 props.Required = []string{module.xmlFileName()}
456
457 if module.SocSpecific() {
458 props.Soc_specific = proptools.BoolPtr(true)
459 } else if module.DeviceSpecific() {
460 props.Device_specific = proptools.BoolPtr(true)
461 } else if module.ProductSpecific() {
462 props.Product_specific = proptools.BoolPtr(true)
463 }
464
Jiyong Park441a47d2018-05-01 23:33:08 +0900465 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(true)), &props, &module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900466}
467
468// Creates the xml file that publicizes the runtime library
469func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
470 template := `
471<?xml version="1.0" encoding="utf-8"?>
472<!-- Copyright (C) 2018 The Android Open Source Project
473
474 Licensed under the Apache License, Version 2.0 (the "License");
475 you may not use this file except in compliance with the License.
476 You may obtain a copy of the License at
477
478 http://www.apache.org/licenses/LICENSE-2.0
479
480 Unless required by applicable law or agreed to in writing, software
481 distributed under the License is distributed on an "AS IS" BASIS,
482 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
483 See the License for the specific language governing permissions and
484 limitations under the License.
485-->
486
487<permissions>
488 <library name="%s" file="%s"/>
489</permissions>
490`
491 // genrule to generate the xml file content from the template above
492 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
493 // in the ninja file. Do we need to have an external tool for this?
494 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
495 genruleProps := struct {
496 Name *string
497 Cmd *string
498 Out []string
499 }{}
500 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
501 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
502 genruleProps.Out = []string{module.xmlFileName()}
503 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
504
505 // creates a prebuilt_etc module to actually place the xml file under
506 // <partition>/etc/permissions
507 etcProps := struct {
508 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900509 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900510 Sub_dir *string
511 Soc_specific *bool
512 Device_specific *bool
513 Product_specific *bool
514 }{}
515 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900516 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900517 etcProps.Sub_dir = proptools.StringPtr("permissions")
518 if module.SocSpecific() {
519 etcProps.Soc_specific = proptools.BoolPtr(true)
520 } else if module.DeviceSpecific() {
521 etcProps.Device_specific = proptools.BoolPtr(true)
522 } else if module.ProductSpecific() {
523 etcProps.Product_specific = proptools.BoolPtr(true)
524 }
525 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
526}
527
528// to satisfy SdkLibraryDependency interface
529func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
530 // This module is just a wrapper for the stubs.
531 if linkType == javaSystem || linkType == javaPlatform {
532 return module.systemApiStubsPath
533 } else {
534 return module.publicApiStubsPath
535 }
536}
537
Jiyong Park82484c02018-04-23 21:41:26 +0900538func javaSdkLibraries(config android.Config) *[]string {
539 return config.Once("javaSdkLibraries", func() interface{} {
540 return &[]string{}
541 }).(*[]string)
542}
543
Jiyong Parkc678ad32018-04-10 13:07:10 +0900544// For a java_sdk_library module, create internal modules for stubs, docs,
545// runtime libs and xml file. If requested, the stubs and docs are created twice
546// once for public API level and once for system API level
547func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
548 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100549 if module.properties.Srcs == nil {
550 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
551 }
552 if module.properties.Api_packages == nil {
553 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
554 }
555
Jiyong Parkc678ad32018-04-10 13:07:10 +0900556 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900557 module.createStubsLibrary(mctx, apiScopePublic)
558 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900559
560 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900561 module.createStubsLibrary(mctx, apiScopeSystem)
562 module.createDocs(mctx, apiScopeSystem)
563
564 // for test API stubs
565 module.createStubsLibrary(mctx, apiScopeTest)
566 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900567
568 // for runtime
569 module.createXmlFile(mctx)
570 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900571
572 // record java_sdk_library modules so that they are exported to make
573 javaSdkLibraries := javaSdkLibraries(mctx.Config())
574 javaSdkLibrariesLock.Lock()
575 defer javaSdkLibrariesLock.Unlock()
576 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900577 }
578}
579
580func sdkLibraryFactory() android.Module {
581 module := &sdkLibrary{}
582 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900583 module.AddProperties(&module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900584 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
585 android.InitDefaultableModule(module)
586 return module
587}