blob: e4cfd417e3a55d5cb43553bcfabbe009de45c8c1 [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
Sundong Ahnf043cf62018-06-25 16:04:37 +0900102 // List of Java libraries that will be in the classpath when building stubs
103 Stub_only_libs []string `android:"arch_variant"`
104
Jiyong Parkc678ad32018-04-10 13:07:10 +0900105 // list of package names that will be documented and publicized as API
106 Api_packages []string
107
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900108 // list of package names that must be hidden from the API
109 Hidden_api_packages []string
110
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900111 Errorprone struct {
112 // List of javac flags that should only be used when running errorprone.
113 Javacflags []string
114 }
115
Jiyong Parkc678ad32018-04-10 13:07:10 +0900116 // TODO: determines whether to create HTML doc or not
117 //Html_doc *bool
118}
119
120type sdkLibrary struct {
121 android.ModuleBase
122 android.DefaultableModuleBase
123
Jiyong Park441a47d2018-05-01 23:33:08 +0900124 properties sdkLibraryProperties
125 deviceProperties CompilerDeviceProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900126
127 publicApiStubsPath android.Paths
128 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900129 testApiStubsPath android.Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +0900130}
131
132func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
133 // Add dependencies to the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900134 ctx.AddDependency(ctx.Module(), publicApiStubsTag, module.stubsName(apiScopePublic))
135 ctx.AddDependency(ctx.Module(), systemApiStubsTag, module.stubsName(apiScopeSystem))
136 ctx.AddDependency(ctx.Module(), testApiStubsTag, module.stubsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900137}
138
139func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
140 // Record the paths to the header jars of the stubs library.
141 // When this java_sdk_library is dependened from others via "libs" property,
142 // the recorded paths will be returned depending on the link type of the caller.
143 ctx.VisitDirectDeps(func(to android.Module) {
144 otherName := ctx.OtherModuleName(to)
145 tag := ctx.OtherModuleDependencyTag(to)
146
147 if stubs, ok := to.(Dependency); ok {
148 switch tag {
149 case publicApiStubsTag:
150 module.publicApiStubsPath = stubs.HeaderJars()
151 case systemApiStubsTag:
152 module.systemApiStubsPath = stubs.HeaderJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900153 case testApiStubsTag:
154 module.testApiStubsPath = stubs.HeaderJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900155 default:
156 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
157 }
158 }
159 })
160}
161
Jiyong Park82484c02018-04-23 21:41:26 +0900162func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900163 return android.AndroidMkData{
164 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900165 // Create a phony module that installs the impl library, for the case when this lib is
166 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900167 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
168 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
169 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
170 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
171 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Jiyong Park90078382018-05-02 19:30:15 +0900172 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900173 if len(module.publicApiStubsPath) == 1 {
174 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
175 module.publicApiStubsPath.Strings()[0]+
176 ":"+path.Join("apistubs", "public", module.BaseModuleName()+".jar")+")")
177 }
178 if len(module.systemApiStubsPath) == 1 {
179 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
180 module.systemApiStubsPath.Strings()[0]+
181 ":"+path.Join("apistubs", "system", module.BaseModuleName()+".jar")+")")
182 }
183 if len(module.testApiStubsPath) == 1 {
184 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
185 module.testApiStubsPath.Strings()[0]+
186 ":"+path.Join("apistubs", "test", module.BaseModuleName()+".jar")+")")
187 }
Jiyong Park82484c02018-04-23 21:41:26 +0900188 },
189 }
190}
191
Jiyong Parkc678ad32018-04-10 13:07:10 +0900192// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900193func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900194 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900195 switch apiScope {
196 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900197 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900198 case apiScopeTest:
199 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900200 }
201 return stubsName
202}
203
204// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900205func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900206 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900207 switch apiScope {
208 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900209 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900210 case apiScopeTest:
211 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900212 }
213 return docsName
214}
215
216// Module name of the runtime implementation library
217func (module *sdkLibrary) implName() string {
218 return module.BaseModuleName() + sdkImplLibrarySuffix
219}
220
221// File path to the runtime implementation library
222func (module *sdkLibrary) implPath() string {
223 partition := "system"
224 if module.SocSpecific() {
225 partition = "vendor"
226 } else if module.DeviceSpecific() {
227 partition = "odm"
228 } else if module.ProductSpecific() {
229 partition = "product"
230 }
231 return "/" + partition + "/framework/" + module.implName() + ".jar"
232}
233
234// Module name of the XML file for the lib
235func (module *sdkLibrary) xmlFileName() string {
236 return module.BaseModuleName() + sdkXmlFileSuffix
237}
238
239// SDK version that the stubs library is built against. Note that this is always
240// *current. Older stubs library built with a numberd SDK version is created from
241// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900242func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
243 switch apiScope {
244 case apiScopePublic:
245 return "current"
246 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900247 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900248 case apiScopeTest:
249 return "test_current"
250 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900251 return "current"
252 }
253}
254
255// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
256// api file for the current source
257// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900258func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900259 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900260 switch apiScope {
261 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900262 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900263 case apiScopeTest:
264 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900265 }
266 return apiTagName
267}
268
Jiyong Park58c518b2018-05-12 22:29:12 +0900269func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
270 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900271 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900272 case apiScopePublic:
273 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900274 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900275 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900276 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900277 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900278 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900279 name = name + ".latest"
280 return name
281}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900282
Jiyong Park58c518b2018-05-12 22:29:12 +0900283func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
284 name := ":" + module.BaseModuleName() + "-removed.api."
285 switch apiScope {
286 case apiScopePublic:
287 name = name + "public"
288 case apiScopeSystem:
289 name = name + "system"
290 case apiScopeTest:
291 name = name + "test"
292 }
293 name = name + ".latest"
294 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900295}
296
297// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900298func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900299 props := struct {
300 Name *string
301 Srcs []string
302 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900303 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900304 Soc_specific *bool
305 Device_specific *bool
306 Product_specific *bool
307 Product_variables struct {
308 Unbundled_build struct {
309 Enabled *bool
310 }
Jiyong Park82484c02018-04-23 21:41:26 +0900311 Pdk struct {
312 Enabled *bool
313 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900314 }
315 }{}
316
Jiyong Parkdf130542018-04-27 16:29:21 +0900317 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900318 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900319 props.Srcs = []string{":" + module.docsName(apiScope)}
320 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahnf043cf62018-06-25 16:04:37 +0900321 props.Libs = module.properties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900322 // Unbundled apps will use the prebult one from /prebuilts/sdk
323 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900324 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900325
326 if module.SocSpecific() {
327 props.Soc_specific = proptools.BoolPtr(true)
328 } else if module.DeviceSpecific() {
329 props.Device_specific = proptools.BoolPtr(true)
330 } else if module.ProductSpecific() {
331 props.Product_specific = proptools.BoolPtr(true)
332 }
333
Colin Cross9ae1b922018-06-26 17:59:05 -0700334 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900335}
336
337// Creates a droiddoc module that creates stubs source files from the given full source
338// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900339func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900340 props := struct {
341 Name *string
342 Srcs []string
343 Custom_template *string
344 Installable *bool
345 Srcs_lib *string
346 Srcs_lib_whitelist_dirs []string
347 Srcs_lib_whitelist_pkgs []string
348 Libs []string
349 Args *string
350 Api_tag_name *string
351 Api_filename *string
352 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900353 Check_api struct {
354 Current ApiToCheck
355 Last_released ApiToCheck
356 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900357 Aidl struct {
358 Include_dirs []string
359 Local_include_dirs []string
360 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900361 }{}
362
Jiyong Parkdf130542018-04-27 16:29:21 +0900363 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900364 props.Srcs = append(props.Srcs, module.properties.Srcs...)
365 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900366 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
367 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900368 // A droiddoc module has only one Libs property and doesn't distinguish between
369 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900370 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900371 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900372 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
373 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900374
375 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
376 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900377 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Jiyong Parkc678ad32018-04-10 13:07:10 +0900378 " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900379 switch apiScope {
380 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900381 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900382 case apiScopeTest:
383 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900384 }
385 props.Args = proptools.StringPtr(droiddocArgs)
386
387 // List of APIs identified from the provided source files are created. They are later
388 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
389 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900390 currentApiFileName := "current.txt"
391 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900392 switch apiScope {
393 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900394 currentApiFileName = "system-" + currentApiFileName
395 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900396 case apiScopeTest:
397 currentApiFileName = "test-" + currentApiFileName
398 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900399 }
400 currentApiFileName = path.Join("api", currentApiFileName)
401 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900402 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900403 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900404 props.Api_filename = proptools.StringPtr(currentApiFileName)
405 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
406
Jiyong Park58c518b2018-05-12 22:29:12 +0900407 // check against the not-yet-release API
408 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
409 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
410 // any change is reported as error
411 props.Check_api.Current.Args = proptools.StringPtr("-error 2 -error 3 -error 4 -error 5 " +
412 "-error 6 -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 " +
413 "-error 14 -error 15 -error 16 -error 17 -error 18 -error 19 -error 20 " +
414 "-error 21 -error 23 -error 24 -error 25 -error 26 -error 27")
415
416 // check against the latest released API
417 props.Check_api.Last_released.Api_file = proptools.StringPtr(
418 module.latestApiFilegroupName(apiScope))
419 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
420 module.latestRemovedApiFilegroupName(apiScope))
421 // backward incompatible changes are reported as error
422 props.Check_api.Last_released.Args = proptools.StringPtr("-hide 2 -hide 3 -hide 4 -hide 5 " +
423 "-hide 6 -hide 24 -hide 25 -hide 26 -hide 27 " +
424 "-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 " +
425 "-error 15 -error 16 -error 17 -error 18")
426
Jiyong Park82484c02018-04-23 21:41:26 +0900427 // Include the part of the framework source. This is required for the case when
428 // API class is extending from the framework class. In that case, doclava needs
429 // to know whether the base class is hidden or not. Since that information is
430 // encoded as @hide string in the comment, we need source files for the classes,
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900431 // not the compiled ones.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900432 props.Srcs_lib = proptools.StringPtr("framework")
433 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900434 // Add android.annotation package to give access to the framework-defined
435 // annotations such as SystemApi, NonNull, etc.
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900436 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
Jiyong Park82484c02018-04-23 21:41:26 +0900437 // These libs are required by doclava to parse the framework sources add via
438 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900439 // If we don't add them to the classpath, errors messages are generated by doclava,
440 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900441 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900442
443 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
444}
445
446// Creates the runtime library. This is not directly linkable from other modules.
447func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
448 props := struct {
449 Name *string
450 Srcs []string
451 Libs []string
452 Static_libs []string
453 Soc_specific *bool
454 Device_specific *bool
455 Product_specific *bool
Colin Cross9ae1b922018-06-26 17:59:05 -0700456 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900457 Required []string
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900458 Errorprone struct {
459 Javacflags []string
460 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900461 }{}
462
463 props.Name = proptools.StringPtr(module.implName())
464 props.Srcs = module.properties.Srcs
465 props.Libs = module.properties.Libs
466 props.Static_libs = module.properties.Static_libs
Colin Cross9ae1b922018-06-26 17:59:05 -0700467 props.Installable = proptools.BoolPtr(true)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900468 // XML file is installed along with the impl lib
469 props.Required = []string{module.xmlFileName()}
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900470 props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
Jiyong Parkc678ad32018-04-10 13:07:10 +0900471
472 if module.SocSpecific() {
473 props.Soc_specific = proptools.BoolPtr(true)
474 } else if module.DeviceSpecific() {
475 props.Device_specific = proptools.BoolPtr(true)
476 } else if module.ProductSpecific() {
477 props.Product_specific = proptools.BoolPtr(true)
478 }
479
Colin Cross9ae1b922018-06-26 17:59:05 -0700480 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props, &module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900481}
482
483// Creates the xml file that publicizes the runtime library
484func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
485 template := `
486<?xml version="1.0" encoding="utf-8"?>
487<!-- Copyright (C) 2018 The Android Open Source Project
488
489 Licensed under the Apache License, Version 2.0 (the "License");
490 you may not use this file except in compliance with the License.
491 You may obtain a copy of the License at
492
493 http://www.apache.org/licenses/LICENSE-2.0
494
495 Unless required by applicable law or agreed to in writing, software
496 distributed under the License is distributed on an "AS IS" BASIS,
497 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
498 See the License for the specific language governing permissions and
499 limitations under the License.
500-->
501
502<permissions>
503 <library name="%s" file="%s"/>
504</permissions>
505`
506 // genrule to generate the xml file content from the template above
507 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
508 // in the ninja file. Do we need to have an external tool for this?
509 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
510 genruleProps := struct {
511 Name *string
512 Cmd *string
513 Out []string
514 }{}
515 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
516 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
517 genruleProps.Out = []string{module.xmlFileName()}
518 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
519
520 // creates a prebuilt_etc module to actually place the xml file under
521 // <partition>/etc/permissions
522 etcProps := struct {
523 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900524 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900525 Sub_dir *string
526 Soc_specific *bool
527 Device_specific *bool
528 Product_specific *bool
529 }{}
530 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900531 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900532 etcProps.Sub_dir = proptools.StringPtr("permissions")
533 if module.SocSpecific() {
534 etcProps.Soc_specific = proptools.BoolPtr(true)
535 } else if module.DeviceSpecific() {
536 etcProps.Device_specific = proptools.BoolPtr(true)
537 } else if module.ProductSpecific() {
538 etcProps.Product_specific = proptools.BoolPtr(true)
539 }
540 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
541}
542
543// to satisfy SdkLibraryDependency interface
544func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
545 // This module is just a wrapper for the stubs.
546 if linkType == javaSystem || linkType == javaPlatform {
547 return module.systemApiStubsPath
548 } else {
549 return module.publicApiStubsPath
550 }
551}
552
Jiyong Park82484c02018-04-23 21:41:26 +0900553func javaSdkLibraries(config android.Config) *[]string {
554 return config.Once("javaSdkLibraries", func() interface{} {
555 return &[]string{}
556 }).(*[]string)
557}
558
Jiyong Parkc678ad32018-04-10 13:07:10 +0900559// For a java_sdk_library module, create internal modules for stubs, docs,
560// runtime libs and xml file. If requested, the stubs and docs are created twice
561// once for public API level and once for system API level
562func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
563 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100564 if module.properties.Srcs == nil {
565 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
566 }
567 if module.properties.Api_packages == nil {
568 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
569 }
570
Jiyong Parkc678ad32018-04-10 13:07:10 +0900571 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900572 module.createStubsLibrary(mctx, apiScopePublic)
573 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900574
575 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900576 module.createStubsLibrary(mctx, apiScopeSystem)
577 module.createDocs(mctx, apiScopeSystem)
578
579 // for test API stubs
580 module.createStubsLibrary(mctx, apiScopeTest)
581 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900582
583 // for runtime
584 module.createXmlFile(mctx)
585 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900586
587 // record java_sdk_library modules so that they are exported to make
588 javaSdkLibraries := javaSdkLibraries(mctx.Config())
589 javaSdkLibrariesLock.Lock()
590 defer javaSdkLibrariesLock.Unlock()
591 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900592 }
593}
594
595func sdkLibraryFactory() android.Module {
596 module := &sdkLibrary{}
597 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900598 module.AddProperties(&module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900599 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
600 android.InitDefaultableModule(module)
601 return module
602}