blob: 55da533cd2d17814ca2055c693d2c4618fae3ffc [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 Park1be96912018-05-28 18:02:19 +090070// 1) disallowing linking to the runtime shared lib
71// 2) HTML generation
Jiyong Parkc678ad32018-04-10 13:07:10 +090072
73func init() {
74 android.RegisterModuleType("java_sdk_library", sdkLibraryFactory)
75
76 android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
77 ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
78 })
Jiyong Park82484c02018-04-23 21:41:26 +090079
80 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
81 javaSdkLibraries := javaSdkLibraries(ctx.Config())
82 sort.Strings(*javaSdkLibraries)
83 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
84 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090085}
86
87type sdkLibraryProperties struct {
88 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
89 // or .aidl files.
90 Srcs []string `android:"arch_variant"`
91
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +090092 // list of optional source files that are part of API but not part of runtime library.
93 Api_srcs []string `android:"arch_variant"`
94
Jiyong Parkc678ad32018-04-10 13:07:10 +090095 // list of of java libraries that will be in the classpath
96 Libs []string `android:"arch_variant"`
97
98 // list of java libraries that will be compiled into the resulting runtime jar.
99 // These libraries are not compiled into the stubs jar.
100 Static_libs []string `android:"arch_variant"`
101
102 // list of package names that will be documented and publicized as API
103 Api_packages []string
104
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900105 // list of package names that must be hidden from the API
106 Hidden_api_packages []string
107
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900108 Errorprone struct {
109 // List of javac flags that should only be used when running errorprone.
110 Javacflags []string
111 }
112
Jiyong Parkc678ad32018-04-10 13:07:10 +0900113 // TODO: determines whether to create HTML doc or not
114 //Html_doc *bool
115}
116
117type sdkLibrary struct {
118 android.ModuleBase
119 android.DefaultableModuleBase
120
Jiyong Park441a47d2018-05-01 23:33:08 +0900121 properties sdkLibraryProperties
122 deviceProperties CompilerDeviceProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900123
124 publicApiStubsPath android.Paths
125 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900126 testApiStubsPath android.Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +0900127}
128
129func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
130 // Add dependencies to the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900131 ctx.AddDependency(ctx.Module(), publicApiStubsTag, module.stubsName(apiScopePublic))
132 ctx.AddDependency(ctx.Module(), systemApiStubsTag, module.stubsName(apiScopeSystem))
133 ctx.AddDependency(ctx.Module(), testApiStubsTag, module.stubsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900134}
135
136func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
137 // Record the paths to the header jars of the stubs library.
138 // When this java_sdk_library is dependened from others via "libs" property,
139 // the recorded paths will be returned depending on the link type of the caller.
140 ctx.VisitDirectDeps(func(to android.Module) {
141 otherName := ctx.OtherModuleName(to)
142 tag := ctx.OtherModuleDependencyTag(to)
143
144 if stubs, ok := to.(Dependency); ok {
145 switch tag {
146 case publicApiStubsTag:
147 module.publicApiStubsPath = stubs.HeaderJars()
148 case systemApiStubsTag:
149 module.systemApiStubsPath = stubs.HeaderJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900150 case testApiStubsTag:
151 module.testApiStubsPath = stubs.HeaderJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900152 default:
153 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
154 }
155 }
156 })
157}
158
Jiyong Park82484c02018-04-23 21:41:26 +0900159func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900160 return android.AndroidMkData{
161 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900162 // Create a phony module that installs the impl library, for the case when this lib is
163 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900164 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
165 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
166 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
167 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
168 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Jiyong Park90078382018-05-02 19:30:15 +0900169 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900170 if len(module.publicApiStubsPath) == 1 {
171 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
172 module.publicApiStubsPath.Strings()[0]+
173 ":"+path.Join("apistubs", "public", module.BaseModuleName()+".jar")+")")
174 }
175 if len(module.systemApiStubsPath) == 1 {
176 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
177 module.systemApiStubsPath.Strings()[0]+
178 ":"+path.Join("apistubs", "system", module.BaseModuleName()+".jar")+")")
179 }
180 if len(module.testApiStubsPath) == 1 {
181 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
182 module.testApiStubsPath.Strings()[0]+
183 ":"+path.Join("apistubs", "test", module.BaseModuleName()+".jar")+")")
184 }
Jiyong Park82484c02018-04-23 21:41:26 +0900185 },
186 }
187}
188
Jiyong Parkc678ad32018-04-10 13:07:10 +0900189// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900190func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900191 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900192 switch apiScope {
193 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900194 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900195 case apiScopeTest:
196 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900197 }
198 return stubsName
199}
200
201// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900202func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900203 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900204 switch apiScope {
205 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900206 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900207 case apiScopeTest:
208 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900209 }
210 return docsName
211}
212
213// Module name of the runtime implementation library
214func (module *sdkLibrary) implName() string {
215 return module.BaseModuleName() + sdkImplLibrarySuffix
216}
217
218// File path to the runtime implementation library
219func (module *sdkLibrary) implPath() string {
220 partition := "system"
221 if module.SocSpecific() {
222 partition = "vendor"
223 } else if module.DeviceSpecific() {
224 partition = "odm"
225 } else if module.ProductSpecific() {
226 partition = "product"
227 }
228 return "/" + partition + "/framework/" + module.implName() + ".jar"
229}
230
231// Module name of the XML file for the lib
232func (module *sdkLibrary) xmlFileName() string {
233 return module.BaseModuleName() + sdkXmlFileSuffix
234}
235
236// SDK version that the stubs library is built against. Note that this is always
237// *current. Older stubs library built with a numberd SDK version is created from
238// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900239func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
240 switch apiScope {
241 case apiScopePublic:
242 return "current"
243 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900244 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900245 case apiScopeTest:
246 return "test_current"
247 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900248 return "current"
249 }
250}
251
252// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
253// api file for the current source
254// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900255func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900256 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900257 switch apiScope {
258 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900259 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900260 case apiScopeTest:
261 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900262 }
263 return apiTagName
264}
265
Jiyong Park58c518b2018-05-12 22:29:12 +0900266func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
267 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900268 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900269 case apiScopePublic:
270 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900271 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900272 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900273 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900274 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900275 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900276 name = name + ".latest"
277 return name
278}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900279
Jiyong Park58c518b2018-05-12 22:29:12 +0900280func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
281 name := ":" + module.BaseModuleName() + "-removed.api."
282 switch apiScope {
283 case apiScopePublic:
284 name = name + "public"
285 case apiScopeSystem:
286 name = name + "system"
287 case apiScopeTest:
288 name = name + "test"
289 }
290 name = name + ".latest"
291 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900292}
293
294// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900295func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900296 props := struct {
297 Name *string
298 Srcs []string
299 Sdk_version *string
300 Soc_specific *bool
301 Device_specific *bool
302 Product_specific *bool
303 Product_variables struct {
304 Unbundled_build struct {
305 Enabled *bool
306 }
Jiyong Park82484c02018-04-23 21:41:26 +0900307 Pdk struct {
308 Enabled *bool
309 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900310 }
311 }{}
312
Jiyong Parkdf130542018-04-27 16:29:21 +0900313 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900314 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900315 props.Srcs = []string{":" + module.docsName(apiScope)}
316 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900317 // Unbundled apps will use the prebult one from /prebuilts/sdk
318 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900319 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900320
321 if module.SocSpecific() {
322 props.Soc_specific = proptools.BoolPtr(true)
323 } else if module.DeviceSpecific() {
324 props.Device_specific = proptools.BoolPtr(true)
325 } else if module.ProductSpecific() {
326 props.Product_specific = proptools.BoolPtr(true)
327 }
328
329 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(false)), &props)
330}
331
332// Creates a droiddoc module that creates stubs source files from the given full source
333// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900334func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900335 props := struct {
336 Name *string
337 Srcs []string
338 Custom_template *string
339 Installable *bool
340 Srcs_lib *string
341 Srcs_lib_whitelist_dirs []string
342 Srcs_lib_whitelist_pkgs []string
343 Libs []string
344 Args *string
345 Api_tag_name *string
346 Api_filename *string
347 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900348 Check_api struct {
349 Current ApiToCheck
350 Last_released ApiToCheck
351 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900352 Aidl struct {
353 Include_dirs []string
354 Local_include_dirs []string
355 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900356 }{}
357
Jiyong Parkdf130542018-04-27 16:29:21 +0900358 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900359 props.Srcs = append(props.Srcs, module.properties.Srcs...)
360 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900361 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
362 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900363 // A droiddoc module has only one Libs property and doesn't distinguish between
364 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900365 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900366 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900367 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
368 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900369
370 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
371 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900372 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Jiyong Parkc678ad32018-04-10 13:07:10 +0900373 " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900374 switch apiScope {
375 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900376 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900377 case apiScopeTest:
378 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900379 }
380 props.Args = proptools.StringPtr(droiddocArgs)
381
382 // List of APIs identified from the provided source files are created. They are later
383 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
384 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900385 currentApiFileName := "current.txt"
386 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900387 switch apiScope {
388 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900389 currentApiFileName = "system-" + currentApiFileName
390 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900391 case apiScopeTest:
392 currentApiFileName = "test-" + currentApiFileName
393 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900394 }
395 currentApiFileName = path.Join("api", currentApiFileName)
396 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900397 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900398 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900399 props.Api_filename = proptools.StringPtr(currentApiFileName)
400 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
401
Jiyong Park58c518b2018-05-12 22:29:12 +0900402 // check against the not-yet-release API
403 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
404 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
405 // any change is reported as error
406 props.Check_api.Current.Args = proptools.StringPtr("-error 2 -error 3 -error 4 -error 5 " +
407 "-error 6 -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 " +
408 "-error 14 -error 15 -error 16 -error 17 -error 18 -error 19 -error 20 " +
409 "-error 21 -error 23 -error 24 -error 25 -error 26 -error 27")
410
411 // check against the latest released API
412 props.Check_api.Last_released.Api_file = proptools.StringPtr(
413 module.latestApiFilegroupName(apiScope))
414 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
415 module.latestRemovedApiFilegroupName(apiScope))
416 // backward incompatible changes are reported as error
417 props.Check_api.Last_released.Args = proptools.StringPtr("-hide 2 -hide 3 -hide 4 -hide 5 " +
418 "-hide 6 -hide 24 -hide 25 -hide 26 -hide 27 " +
419 "-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 " +
420 "-error 15 -error 16 -error 17 -error 18")
421
Jiyong Park82484c02018-04-23 21:41:26 +0900422 // Include the part of the framework source. This is required for the case when
423 // API class is extending from the framework class. In that case, doclava needs
424 // to know whether the base class is hidden or not. Since that information is
425 // encoded as @hide string in the comment, we need source files for the classes,
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900426 // not the compiled ones.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900427 props.Srcs_lib = proptools.StringPtr("framework")
428 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900429 // Add android.annotation package to give access to the framework-defined
430 // annotations such as SystemApi, NonNull, etc.
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900431 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
Jiyong Park82484c02018-04-23 21:41:26 +0900432 // These libs are required by doclava to parse the framework sources add via
433 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900434 // If we don't add them to the classpath, errors messages are generated by doclava,
435 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900436 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900437
438 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
439}
440
441// Creates the runtime library. This is not directly linkable from other modules.
442func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
443 props := struct {
444 Name *string
445 Srcs []string
446 Libs []string
447 Static_libs []string
448 Soc_specific *bool
449 Device_specific *bool
450 Product_specific *bool
451 Required []string
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900452 Errorprone struct {
453 Javacflags []string
454 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900455 }{}
456
457 props.Name = proptools.StringPtr(module.implName())
458 props.Srcs = module.properties.Srcs
459 props.Libs = module.properties.Libs
460 props.Static_libs = module.properties.Static_libs
461 // XML file is installed along with the impl lib
462 props.Required = []string{module.xmlFileName()}
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900463 props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
Jiyong Parkc678ad32018-04-10 13:07:10 +0900464
465 if module.SocSpecific() {
466 props.Soc_specific = proptools.BoolPtr(true)
467 } else if module.DeviceSpecific() {
468 props.Device_specific = proptools.BoolPtr(true)
469 } else if module.ProductSpecific() {
470 props.Product_specific = proptools.BoolPtr(true)
471 }
472
Jiyong Park441a47d2018-05-01 23:33:08 +0900473 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(true)), &props, &module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900474}
475
476// Creates the xml file that publicizes the runtime library
477func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
478 template := `
479<?xml version="1.0" encoding="utf-8"?>
480<!-- Copyright (C) 2018 The Android Open Source Project
481
482 Licensed under the Apache License, Version 2.0 (the "License");
483 you may not use this file except in compliance with the License.
484 You may obtain a copy of the License at
485
486 http://www.apache.org/licenses/LICENSE-2.0
487
488 Unless required by applicable law or agreed to in writing, software
489 distributed under the License is distributed on an "AS IS" BASIS,
490 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
491 See the License for the specific language governing permissions and
492 limitations under the License.
493-->
494
495<permissions>
496 <library name="%s" file="%s"/>
497</permissions>
498`
499 // genrule to generate the xml file content from the template above
500 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
501 // in the ninja file. Do we need to have an external tool for this?
502 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
503 genruleProps := struct {
504 Name *string
505 Cmd *string
506 Out []string
507 }{}
508 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
509 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
510 genruleProps.Out = []string{module.xmlFileName()}
511 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
512
513 // creates a prebuilt_etc module to actually place the xml file under
514 // <partition>/etc/permissions
515 etcProps := struct {
516 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900517 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900518 Sub_dir *string
519 Soc_specific *bool
520 Device_specific *bool
521 Product_specific *bool
522 }{}
523 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900524 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900525 etcProps.Sub_dir = proptools.StringPtr("permissions")
526 if module.SocSpecific() {
527 etcProps.Soc_specific = proptools.BoolPtr(true)
528 } else if module.DeviceSpecific() {
529 etcProps.Device_specific = proptools.BoolPtr(true)
530 } else if module.ProductSpecific() {
531 etcProps.Product_specific = proptools.BoolPtr(true)
532 }
533 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
534}
535
536// to satisfy SdkLibraryDependency interface
537func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
538 // This module is just a wrapper for the stubs.
539 if linkType == javaSystem || linkType == javaPlatform {
540 return module.systemApiStubsPath
541 } else {
542 return module.publicApiStubsPath
543 }
544}
545
Jiyong Park82484c02018-04-23 21:41:26 +0900546func javaSdkLibraries(config android.Config) *[]string {
547 return config.Once("javaSdkLibraries", func() interface{} {
548 return &[]string{}
549 }).(*[]string)
550}
551
Jiyong Parkc678ad32018-04-10 13:07:10 +0900552// For a java_sdk_library module, create internal modules for stubs, docs,
553// runtime libs and xml file. If requested, the stubs and docs are created twice
554// once for public API level and once for system API level
555func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
556 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100557 if module.properties.Srcs == nil {
558 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
559 }
560 if module.properties.Api_packages == nil {
561 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
562 }
563
Jiyong Parkc678ad32018-04-10 13:07:10 +0900564 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900565 module.createStubsLibrary(mctx, apiScopePublic)
566 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900567
568 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900569 module.createStubsLibrary(mctx, apiScopeSystem)
570 module.createDocs(mctx, apiScopeSystem)
571
572 // for test API stubs
573 module.createStubsLibrary(mctx, apiScopeTest)
574 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900575
576 // for runtime
577 module.createXmlFile(mctx)
578 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900579
580 // record java_sdk_library modules so that they are exported to make
581 javaSdkLibraries := javaSdkLibraries(mctx.Config())
582 javaSdkLibrariesLock.Lock()
583 defer javaSdkLibrariesLock.Unlock()
584 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900585 }
586}
587
588func sdkLibraryFactory() android.Module {
589 module := &sdkLibrary{}
590 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900591 module.AddProperties(&module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900592 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
593 android.InitDefaultableModule(module)
594 return module
595}