blob: e65af65f4637ad423d56c6becff5485fd3afc09e [file] [log] [blame]
Jiyong Parkc678ad32018-04-10 13:07:10 +09001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
18 "android/soong/android"
19 "android/soong/genrule"
20 "fmt"
Jiyong Park82484c02018-04-23 21:41:26 +090021 "io"
Jiyong Parkc678ad32018-04-10 13:07:10 +090022 "path"
Jiyong Park82484c02018-04-23 21:41:26 +090023 "sort"
Jiyong Parkc678ad32018-04-10 13:07:10 +090024 "strings"
Jiyong Park82484c02018-04-23 21:41:26 +090025 "sync"
Jiyong Parkc678ad32018-04-10 13:07:10 +090026
27 "github.com/google/blueprint"
28 "github.com/google/blueprint/proptools"
29)
30
31var (
32 sdkStubsLibrarySuffix = ".stubs"
33 sdkSystemApiSuffix = ".system"
Jiyong Parkdf130542018-04-27 16:29:21 +090034 sdkTestApiSuffix = ".test"
Jiyong Parkc678ad32018-04-10 13:07:10 +090035 sdkDocsSuffix = ".docs"
36 sdkImplLibrarySuffix = ".impl"
37 sdkXmlFileSuffix = ".xml"
38)
39
40type stubsLibraryDependencyTag struct {
41 blueprint.BaseDependencyTag
42 name string
43}
44
45var (
46 publicApiStubsTag = dependencyTag{name: "public"}
47 systemApiStubsTag = dependencyTag{name: "system"}
Jiyong Parkdf130542018-04-27 16:29:21 +090048 testApiStubsTag = dependencyTag{name: "test"}
Sundong Ahn57368eb2018-07-06 11:20:23 +090049 implLibTag = dependencyTag{name: "platform"}
Jiyong Parkdf130542018-04-27 16:29:21 +090050)
51
52type apiScope int
53
54const (
55 apiScopePublic apiScope = iota
56 apiScopeSystem
57 apiScopeTest
Jiyong Parkc678ad32018-04-10 13:07:10 +090058)
59
Jiyong Park82484c02018-04-23 21:41:26 +090060var (
61 javaSdkLibrariesLock sync.Mutex
62)
63
Jiyong Parkc678ad32018-04-10 13:07:10 +090064// java_sdk_library is to make a Java library that implements optional platform APIs to apps.
65// It is actually a wrapper of several modules: 1) stubs library that clients are linked against
66// to, 2) droiddoc module that internally generates API stubs source files, 3) the real runtime
67// shared library that implements the APIs, and 4) XML file for adding the runtime lib to the
68// classpath at runtime if requested via <uses-library>.
69//
70// TODO: these are big features that are currently missing
Jiyong Park1be96912018-05-28 18:02:19 +090071// 1) disallowing linking to the runtime shared lib
72// 2) 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
Sundong Ahnf043cf62018-06-25 16:04:37 +0900103 // List of Java libraries that will be in the classpath when building stubs
104 Stub_only_libs []string `android:"arch_variant"`
105
Jiyong Parkc678ad32018-04-10 13:07:10 +0900106 // list of package names that will be documented and publicized as API
107 Api_packages []string
108
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900109 // list of package names that must be hidden from the API
110 Hidden_api_packages []string
111
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900112 Errorprone struct {
113 // List of javac flags that should only be used when running errorprone.
114 Javacflags []string
115 }
116
Jiyong Parkc678ad32018-04-10 13:07:10 +0900117 // TODO: determines whether to create HTML doc or not
118 //Html_doc *bool
119}
120
121type sdkLibrary struct {
122 android.ModuleBase
123 android.DefaultableModuleBase
124
Jiyong Park441a47d2018-05-01 23:33:08 +0900125 properties sdkLibraryProperties
126 deviceProperties CompilerDeviceProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900127
128 publicApiStubsPath android.Paths
129 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900130 testApiStubsPath android.Paths
Sundong Ahn57368eb2018-07-06 11:20:23 +0900131 implLibPath android.Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +0900132}
133
134func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
135 // Add dependencies to the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900136 ctx.AddDependency(ctx.Module(), publicApiStubsTag, module.stubsName(apiScopePublic))
137 ctx.AddDependency(ctx.Module(), systemApiStubsTag, module.stubsName(apiScopeSystem))
138 ctx.AddDependency(ctx.Module(), testApiStubsTag, module.stubsName(apiScopeTest))
Sundong Ahn57368eb2018-07-06 11:20:23 +0900139 ctx.AddDependency(ctx.Module(), implLibTag, module.implName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900140}
141
142func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn57368eb2018-07-06 11:20:23 +0900143 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900144 // When this java_sdk_library is dependened from others via "libs" property,
145 // the recorded paths will be returned depending on the link type of the caller.
146 ctx.VisitDirectDeps(func(to android.Module) {
147 otherName := ctx.OtherModuleName(to)
148 tag := ctx.OtherModuleDependencyTag(to)
149
Sundong Ahn57368eb2018-07-06 11:20:23 +0900150 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900151 switch tag {
152 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900153 module.publicApiStubsPath = lib.HeaderJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900154 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900155 module.systemApiStubsPath = lib.HeaderJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900156 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900157 module.testApiStubsPath = lib.HeaderJars()
158 case implLibTag:
159 module.implLibPath = lib.HeaderJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900160 default:
161 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
162 }
163 }
164 })
165}
166
Jiyong Park82484c02018-04-23 21:41:26 +0900167func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900168 return android.AndroidMkData{
169 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900170 // Create a phony module that installs the impl library, for the case when this lib is
171 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900172 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
173 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
174 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
175 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
176 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Jiyong Park90078382018-05-02 19:30:15 +0900177 // Create dist rules to install the stubs libs to the dist dir
Jiyong Parkb674a522018-05-06 07:53:02 +0900178 if len(module.publicApiStubsPath) == 1 {
179 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
180 module.publicApiStubsPath.Strings()[0]+
181 ":"+path.Join("apistubs", "public", module.BaseModuleName()+".jar")+")")
182 }
183 if len(module.systemApiStubsPath) == 1 {
184 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
185 module.systemApiStubsPath.Strings()[0]+
186 ":"+path.Join("apistubs", "system", module.BaseModuleName()+".jar")+")")
187 }
188 if len(module.testApiStubsPath) == 1 {
189 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
190 module.testApiStubsPath.Strings()[0]+
191 ":"+path.Join("apistubs", "test", module.BaseModuleName()+".jar")+")")
192 }
Jiyong Park82484c02018-04-23 21:41:26 +0900193 },
194 }
195}
196
Jiyong Parkc678ad32018-04-10 13:07:10 +0900197// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900198func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900199 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900200 switch apiScope {
201 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900202 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900203 case apiScopeTest:
204 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900205 }
206 return stubsName
207}
208
209// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900210func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900211 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900212 switch apiScope {
213 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900214 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900215 case apiScopeTest:
216 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900217 }
218 return docsName
219}
220
221// Module name of the runtime implementation library
222func (module *sdkLibrary) implName() string {
223 return module.BaseModuleName() + sdkImplLibrarySuffix
224}
225
226// File path to the runtime implementation library
227func (module *sdkLibrary) implPath() string {
228 partition := "system"
229 if module.SocSpecific() {
230 partition = "vendor"
231 } else if module.DeviceSpecific() {
232 partition = "odm"
233 } else if module.ProductSpecific() {
234 partition = "product"
235 }
236 return "/" + partition + "/framework/" + module.implName() + ".jar"
237}
238
239// Module name of the XML file for the lib
240func (module *sdkLibrary) xmlFileName() string {
241 return module.BaseModuleName() + sdkXmlFileSuffix
242}
243
244// SDK version that the stubs library is built against. Note that this is always
245// *current. Older stubs library built with a numberd SDK version is created from
246// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900247func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
248 switch apiScope {
249 case apiScopePublic:
250 return "current"
251 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900252 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900253 case apiScopeTest:
254 return "test_current"
255 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900256 return "current"
257 }
258}
259
260// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
261// api file for the current source
262// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900263func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900264 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900265 switch apiScope {
266 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900267 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900268 case apiScopeTest:
269 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900270 }
271 return apiTagName
272}
273
Jiyong Park58c518b2018-05-12 22:29:12 +0900274func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
275 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900276 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900277 case apiScopePublic:
278 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900279 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900280 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900281 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900282 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900283 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900284 name = name + ".latest"
285 return name
286}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900287
Jiyong Park58c518b2018-05-12 22:29:12 +0900288func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
289 name := ":" + module.BaseModuleName() + "-removed.api."
290 switch apiScope {
291 case apiScopePublic:
292 name = name + "public"
293 case apiScopeSystem:
294 name = name + "system"
295 case apiScopeTest:
296 name = name + "test"
297 }
298 name = name + ".latest"
299 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900300}
301
302// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900303func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900304 props := struct {
305 Name *string
306 Srcs []string
307 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900308 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900309 Soc_specific *bool
310 Device_specific *bool
311 Product_specific *bool
312 Product_variables struct {
313 Unbundled_build struct {
314 Enabled *bool
315 }
Jiyong Park82484c02018-04-23 21:41:26 +0900316 Pdk struct {
317 Enabled *bool
318 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900319 }
320 }{}
321
Jiyong Parkdf130542018-04-27 16:29:21 +0900322 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900323 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900324 props.Srcs = []string{":" + module.docsName(apiScope)}
325 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahnf043cf62018-06-25 16:04:37 +0900326 props.Libs = module.properties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900327 // Unbundled apps will use the prebult one from /prebuilts/sdk
328 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900329 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900330
331 if module.SocSpecific() {
332 props.Soc_specific = proptools.BoolPtr(true)
333 } else if module.DeviceSpecific() {
334 props.Device_specific = proptools.BoolPtr(true)
335 } else if module.ProductSpecific() {
336 props.Product_specific = proptools.BoolPtr(true)
337 }
338
Colin Cross9ae1b922018-06-26 17:59:05 -0700339 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900340}
341
342// Creates a droiddoc module that creates stubs source files from the given full source
343// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900344func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900345 props := struct {
346 Name *string
347 Srcs []string
348 Custom_template *string
349 Installable *bool
350 Srcs_lib *string
351 Srcs_lib_whitelist_dirs []string
352 Srcs_lib_whitelist_pkgs []string
353 Libs []string
354 Args *string
355 Api_tag_name *string
356 Api_filename *string
357 Removed_api_filename *string
Jiyong Park58c518b2018-05-12 22:29:12 +0900358 Check_api struct {
359 Current ApiToCheck
360 Last_released ApiToCheck
361 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900362 Aidl struct {
363 Include_dirs []string
364 Local_include_dirs []string
365 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900366 }{}
367
Jiyong Parkdf130542018-04-27 16:29:21 +0900368 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900369 props.Srcs = append(props.Srcs, module.properties.Srcs...)
370 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900371 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
372 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900373 // A droiddoc module has only one Libs property and doesn't distinguish between
374 // shared libs and static libs. So we need to add both of these libs to Libs property.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900375 props.Libs = module.properties.Libs
Sundong Ahne6f0b052018-06-05 16:46:14 +0900376 props.Libs = append(props.Libs, module.properties.Static_libs...)
Sundong Ahn1b92c822018-05-29 11:35:17 +0900377 props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
378 props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900379
380 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
381 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900382 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Jiyong Parkc678ad32018-04-10 13:07:10 +0900383 " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900384 switch apiScope {
385 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900386 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900387 case apiScopeTest:
388 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900389 }
390 props.Args = proptools.StringPtr(droiddocArgs)
391
392 // List of APIs identified from the provided source files are created. They are later
393 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
394 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900395 currentApiFileName := "current.txt"
396 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900397 switch apiScope {
398 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900399 currentApiFileName = "system-" + currentApiFileName
400 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900401 case apiScopeTest:
402 currentApiFileName = "test-" + currentApiFileName
403 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900404 }
405 currentApiFileName = path.Join("api", currentApiFileName)
406 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900407 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900408 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900409 props.Api_filename = proptools.StringPtr(currentApiFileName)
410 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
411
Jiyong Park58c518b2018-05-12 22:29:12 +0900412 // check against the not-yet-release API
413 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
414 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
415 // any change is reported as error
416 props.Check_api.Current.Args = proptools.StringPtr("-error 2 -error 3 -error 4 -error 5 " +
417 "-error 6 -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 " +
418 "-error 14 -error 15 -error 16 -error 17 -error 18 -error 19 -error 20 " +
419 "-error 21 -error 23 -error 24 -error 25 -error 26 -error 27")
420
421 // check against the latest released API
422 props.Check_api.Last_released.Api_file = proptools.StringPtr(
423 module.latestApiFilegroupName(apiScope))
424 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
425 module.latestRemovedApiFilegroupName(apiScope))
426 // backward incompatible changes are reported as error
427 props.Check_api.Last_released.Args = proptools.StringPtr("-hide 2 -hide 3 -hide 4 -hide 5 " +
428 "-hide 6 -hide 24 -hide 25 -hide 26 -hide 27 " +
429 "-error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 " +
430 "-error 15 -error 16 -error 17 -error 18")
431
Jiyong Park82484c02018-04-23 21:41:26 +0900432 // Include the part of the framework source. This is required for the case when
433 // API class is extending from the framework class. In that case, doclava needs
434 // to know whether the base class is hidden or not. Since that information is
435 // encoded as @hide string in the comment, we need source files for the classes,
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900436 // not the compiled ones.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900437 props.Srcs_lib = proptools.StringPtr("framework")
438 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900439 // Add android.annotation package to give access to the framework-defined
440 // annotations such as SystemApi, NonNull, etc.
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900441 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
Jiyong Park82484c02018-04-23 21:41:26 +0900442 // These libs are required by doclava to parse the framework sources add via
443 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900444 // If we don't add them to the classpath, errors messages are generated by doclava,
445 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900446 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900447
448 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
449}
450
451// Creates the runtime library. This is not directly linkable from other modules.
452func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
453 props := struct {
454 Name *string
455 Srcs []string
456 Libs []string
457 Static_libs []string
458 Soc_specific *bool
459 Device_specific *bool
460 Product_specific *bool
Colin Cross9ae1b922018-06-26 17:59:05 -0700461 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +0900462 Required []string
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900463 Errorprone struct {
464 Javacflags []string
465 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900466 }{}
467
468 props.Name = proptools.StringPtr(module.implName())
469 props.Srcs = module.properties.Srcs
470 props.Libs = module.properties.Libs
471 props.Static_libs = module.properties.Static_libs
Colin Cross9ae1b922018-06-26 17:59:05 -0700472 props.Installable = proptools.BoolPtr(true)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900473 // XML file is installed along with the impl lib
474 props.Required = []string{module.xmlFileName()}
Jiyong Parkb5b709f2018-06-15 10:38:59 +0900475 props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
Jiyong Parkc678ad32018-04-10 13:07:10 +0900476
477 if module.SocSpecific() {
478 props.Soc_specific = proptools.BoolPtr(true)
479 } else if module.DeviceSpecific() {
480 props.Device_specific = proptools.BoolPtr(true)
481 } else if module.ProductSpecific() {
482 props.Product_specific = proptools.BoolPtr(true)
483 }
484
Colin Cross9ae1b922018-06-26 17:59:05 -0700485 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props, &module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900486}
487
488// Creates the xml file that publicizes the runtime library
489func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
490 template := `
491<?xml version="1.0" encoding="utf-8"?>
492<!-- Copyright (C) 2018 The Android Open Source Project
493
494 Licensed under the Apache License, Version 2.0 (the "License");
495 you may not use this file except in compliance with the License.
496 You may obtain a copy of the License at
497
498 http://www.apache.org/licenses/LICENSE-2.0
499
500 Unless required by applicable law or agreed to in writing, software
501 distributed under the License is distributed on an "AS IS" BASIS,
502 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
503 See the License for the specific language governing permissions and
504 limitations under the License.
505-->
506
507<permissions>
508 <library name="%s" file="%s"/>
509</permissions>
510`
511 // genrule to generate the xml file content from the template above
512 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
513 // in the ninja file. Do we need to have an external tool for this?
514 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
515 genruleProps := struct {
516 Name *string
517 Cmd *string
518 Out []string
519 }{}
520 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
521 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
522 genruleProps.Out = []string{module.xmlFileName()}
523 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
524
525 // creates a prebuilt_etc module to actually place the xml file under
526 // <partition>/etc/permissions
527 etcProps := struct {
528 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900529 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900530 Sub_dir *string
531 Soc_specific *bool
532 Device_specific *bool
533 Product_specific *bool
534 }{}
535 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900536 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900537 etcProps.Sub_dir = proptools.StringPtr("permissions")
538 if module.SocSpecific() {
539 etcProps.Soc_specific = proptools.BoolPtr(true)
540 } else if module.DeviceSpecific() {
541 etcProps.Device_specific = proptools.BoolPtr(true)
542 } else if module.ProductSpecific() {
543 etcProps.Product_specific = proptools.BoolPtr(true)
544 }
545 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
546}
547
548// to satisfy SdkLibraryDependency interface
549func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
550 // This module is just a wrapper for the stubs.
Sundong Ahn57368eb2018-07-06 11:20:23 +0900551 if linkType == javaSystem {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900552 return module.systemApiStubsPath
Sundong Ahn57368eb2018-07-06 11:20:23 +0900553 } else if linkType == javaPlatform {
554 return module.implLibPath
Jiyong Parkc678ad32018-04-10 13:07:10 +0900555 } else {
556 return module.publicApiStubsPath
557 }
558}
559
Jiyong Park82484c02018-04-23 21:41:26 +0900560func javaSdkLibraries(config android.Config) *[]string {
561 return config.Once("javaSdkLibraries", func() interface{} {
562 return &[]string{}
563 }).(*[]string)
564}
565
Jiyong Parkc678ad32018-04-10 13:07:10 +0900566// For a java_sdk_library module, create internal modules for stubs, docs,
567// runtime libs and xml file. If requested, the stubs and docs are created twice
568// once for public API level and once for system API level
569func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
570 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100571 if module.properties.Srcs == nil {
572 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
573 }
574 if module.properties.Api_packages == nil {
575 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
576 }
577
Jiyong Parkc678ad32018-04-10 13:07:10 +0900578 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900579 module.createStubsLibrary(mctx, apiScopePublic)
580 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900581
582 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900583 module.createStubsLibrary(mctx, apiScopeSystem)
584 module.createDocs(mctx, apiScopeSystem)
585
586 // for test API stubs
587 module.createStubsLibrary(mctx, apiScopeTest)
588 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900589
590 // for runtime
591 module.createXmlFile(mctx)
592 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900593
594 // record java_sdk_library modules so that they are exported to make
595 javaSdkLibraries := javaSdkLibraries(mctx.Config())
596 javaSdkLibrariesLock.Lock()
597 defer javaSdkLibrariesLock.Unlock()
598 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900599 }
600}
601
602func sdkLibraryFactory() android.Module {
603 module := &sdkLibrary{}
604 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900605 module.AddProperties(&module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900606 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
607 android.InitDefaultableModule(module)
608 return module
609}