blob: 956edce423ee2688d915e607036cf0e091d29bd9 [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
70// 1) check for API consistency
71// 2) install stubs libs as the dist artifacts
72// 3) ensuring that apps have appropriate <uses-library> tag
73// 4) disallowing linking to the runtime shared lib
74// 5) HTML generation
75
76func init() {
77 android.RegisterModuleType("java_sdk_library", sdkLibraryFactory)
78
79 android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
80 ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
81 })
Jiyong Park82484c02018-04-23 21:41:26 +090082
83 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
84 javaSdkLibraries := javaSdkLibraries(ctx.Config())
85 sort.Strings(*javaSdkLibraries)
86 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
87 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090088}
89
90type sdkLibraryProperties struct {
91 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
92 // or .aidl files.
93 Srcs []string `android:"arch_variant"`
94
95 // 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 Parkc678ad32018-04-10 13:07:10 +0900108 // TODO: determines whether to create HTML doc or not
109 //Html_doc *bool
110}
111
112type sdkLibrary struct {
113 android.ModuleBase
114 android.DefaultableModuleBase
115
116 properties sdkLibraryProperties
117
118 publicApiStubsPath android.Paths
119 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900120 testApiStubsPath android.Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +0900121}
122
123func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
124 // Add dependencies to the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900125 ctx.AddDependency(ctx.Module(), publicApiStubsTag, module.stubsName(apiScopePublic))
126 ctx.AddDependency(ctx.Module(), systemApiStubsTag, module.stubsName(apiScopeSystem))
127 ctx.AddDependency(ctx.Module(), testApiStubsTag, module.stubsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900128}
129
130func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
131 // Record the paths to the header jars of the stubs library.
132 // When this java_sdk_library is dependened from others via "libs" property,
133 // the recorded paths will be returned depending on the link type of the caller.
134 ctx.VisitDirectDeps(func(to android.Module) {
135 otherName := ctx.OtherModuleName(to)
136 tag := ctx.OtherModuleDependencyTag(to)
137
138 if stubs, ok := to.(Dependency); ok {
139 switch tag {
140 case publicApiStubsTag:
141 module.publicApiStubsPath = stubs.HeaderJars()
142 case systemApiStubsTag:
143 module.systemApiStubsPath = stubs.HeaderJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900144 case testApiStubsTag:
145 module.testApiStubsPath = stubs.HeaderJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900146 default:
147 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
148 }
149 }
150 })
151}
152
Jiyong Park82484c02018-04-23 21:41:26 +0900153func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
154 // Create a phony module that installs the impl library, for the case when this lib is
155 // in PRODUCT_PACKAGES.
156 return android.AndroidMkData{
157 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
158 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
159 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
160 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
161 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
162 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
163 },
164 }
165}
166
Jiyong Parkc678ad32018-04-10 13:07:10 +0900167// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900168func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900169 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900170 switch apiScope {
171 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900172 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900173 case apiScopeTest:
174 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900175 }
176 return stubsName
177}
178
179// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900180func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900181 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900182 switch apiScope {
183 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900184 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900185 case apiScopeTest:
186 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900187 }
188 return docsName
189}
190
191// Module name of the runtime implementation library
192func (module *sdkLibrary) implName() string {
193 return module.BaseModuleName() + sdkImplLibrarySuffix
194}
195
196// File path to the runtime implementation library
197func (module *sdkLibrary) implPath() string {
198 partition := "system"
199 if module.SocSpecific() {
200 partition = "vendor"
201 } else if module.DeviceSpecific() {
202 partition = "odm"
203 } else if module.ProductSpecific() {
204 partition = "product"
205 }
206 return "/" + partition + "/framework/" + module.implName() + ".jar"
207}
208
209// Module name of the XML file for the lib
210func (module *sdkLibrary) xmlFileName() string {
211 return module.BaseModuleName() + sdkXmlFileSuffix
212}
213
214// SDK version that the stubs library is built against. Note that this is always
215// *current. Older stubs library built with a numberd SDK version is created from
216// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900217func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
218 switch apiScope {
219 case apiScopePublic:
220 return "current"
221 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900222 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900223 case apiScopeTest:
224 return "test_current"
225 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900226 return "current"
227 }
228}
229
230// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
231// api file for the current source
232// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900233func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900234 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900235 switch apiScope {
236 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900237 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900238 case apiScopeTest:
239 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900240 }
241 return apiTagName
242}
243
244// returns the path (relative to this module) to the API txt file. Files are located
245// ./<api_dir>/<api_level>.txt where <api_level> is either current, system-current, removed,
246// or system-removed.
Jiyong Parkdf130542018-04-27 16:29:21 +0900247func (module *sdkLibrary) apiFilePath(apiLevel string, apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900248 apiDir := "api"
249 apiFile := apiLevel
Jiyong Parkdf130542018-04-27 16:29:21 +0900250 switch apiScope {
251 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900252 apiFile = "system-" + apiFile
Jiyong Parkdf130542018-04-27 16:29:21 +0900253 case apiScopeTest:
254 apiFile = "test-" + apiFile
Jiyong Parkc678ad32018-04-10 13:07:10 +0900255 }
256 apiFile = apiFile + ".txt"
257
258 return path.Join(apiDir, apiFile)
259}
260
261// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900262func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900263 props := struct {
264 Name *string
265 Srcs []string
266 Sdk_version *string
267 Soc_specific *bool
268 Device_specific *bool
269 Product_specific *bool
270 Product_variables struct {
271 Unbundled_build struct {
272 Enabled *bool
273 }
Jiyong Park82484c02018-04-23 21:41:26 +0900274 Pdk struct {
275 Enabled *bool
276 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900277 }
278 }{}
279
Jiyong Parkdf130542018-04-27 16:29:21 +0900280 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900281 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900282 props.Srcs = []string{":" + module.docsName(apiScope)}
283 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900284 // Unbundled apps will use the prebult one from /prebuilts/sdk
285 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900286 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900287
288 if module.SocSpecific() {
289 props.Soc_specific = proptools.BoolPtr(true)
290 } else if module.DeviceSpecific() {
291 props.Device_specific = proptools.BoolPtr(true)
292 } else if module.ProductSpecific() {
293 props.Product_specific = proptools.BoolPtr(true)
294 }
295
296 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(false)), &props)
297}
298
299// Creates a droiddoc module that creates stubs source files from the given full source
300// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900301func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900302 props := struct {
303 Name *string
304 Srcs []string
305 Custom_template *string
306 Installable *bool
307 Srcs_lib *string
308 Srcs_lib_whitelist_dirs []string
309 Srcs_lib_whitelist_pkgs []string
310 Libs []string
311 Args *string
312 Api_tag_name *string
313 Api_filename *string
314 Removed_api_filename *string
315 }{}
316
Jiyong Parkdf130542018-04-27 16:29:21 +0900317 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900318 props.Srcs = module.properties.Srcs
319 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
320 props.Installable = proptools.BoolPtr(false)
321 props.Libs = module.properties.Libs
322
323 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
324 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900325 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Jiyong Parkc678ad32018-04-10 13:07:10 +0900326 " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900327 switch apiScope {
328 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900329 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900330 case apiScopeTest:
331 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900332 }
333 props.Args = proptools.StringPtr(droiddocArgs)
334
335 // List of APIs identified from the provided source files are created. They are later
336 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
337 // last-released (a.k.a numbered) list of API.
338 // TODO: If any incompatible change is detected, break the build
339 currentApiFileName := "current.txt"
340 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900341 switch apiScope {
342 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900343 currentApiFileName = "system-" + currentApiFileName
344 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900345 case apiScopeTest:
346 currentApiFileName = "test-" + currentApiFileName
347 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900348 }
349 currentApiFileName = path.Join("api", currentApiFileName)
350 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Parkdf130542018-04-27 16:29:21 +0900351 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900352 // Note: the exact names of these two are not important because they are always
353 // referenced by the make variable $(INTERNAL_PLATFORM_<TAG_NAME>_API_FILE)
354 props.Api_filename = proptools.StringPtr(currentApiFileName)
355 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
356
Jiyong Park82484c02018-04-23 21:41:26 +0900357 // Include the part of the framework source. This is required for the case when
358 // API class is extending from the framework class. In that case, doclava needs
359 // to know whether the base class is hidden or not. Since that information is
360 // encoded as @hide string in the comment, we need source files for the classes,
361 // not the compiled ones. Also there are rare cases where part of SDK library is
362 // implemented in the framework (e.g. org.apache.http.legacy). In that case,
363 // we need framework source to make API stubs, though the sources are not
364 // required to build the runtime library.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900365 props.Srcs_lib = proptools.StringPtr("framework")
366 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900367 props.Srcs_lib_whitelist_pkgs = module.properties.Api_packages
368 // Add android.annotation package to give access to the framework-defined
369 // annotations such as SystemApi, NonNull, etc.
370 props.Srcs_lib_whitelist_pkgs = append(props.Srcs_lib_whitelist_pkgs, "android.annotation")
371 // These libs are required by doclava to parse the framework sources add via
372 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900373 // If we don't add them to the classpath, errors messages are generated by doclava,
374 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900375 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900376
377 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
378}
379
380// Creates the runtime library. This is not directly linkable from other modules.
381func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
382 props := struct {
383 Name *string
384 Srcs []string
385 Libs []string
386 Static_libs []string
387 Soc_specific *bool
388 Device_specific *bool
389 Product_specific *bool
390 Required []string
391 }{}
392
393 props.Name = proptools.StringPtr(module.implName())
394 props.Srcs = module.properties.Srcs
395 props.Libs = module.properties.Libs
396 props.Static_libs = module.properties.Static_libs
397 // XML file is installed along with the impl lib
398 props.Required = []string{module.xmlFileName()}
399
400 if module.SocSpecific() {
401 props.Soc_specific = proptools.BoolPtr(true)
402 } else if module.DeviceSpecific() {
403 props.Device_specific = proptools.BoolPtr(true)
404 } else if module.ProductSpecific() {
405 props.Product_specific = proptools.BoolPtr(true)
406 }
407
408 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(true)), &props)
409}
410
411// Creates the xml file that publicizes the runtime library
412func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
413 template := `
414<?xml version="1.0" encoding="utf-8"?>
415<!-- Copyright (C) 2018 The Android Open Source Project
416
417 Licensed under the Apache License, Version 2.0 (the "License");
418 you may not use this file except in compliance with the License.
419 You may obtain a copy of the License at
420
421 http://www.apache.org/licenses/LICENSE-2.0
422
423 Unless required by applicable law or agreed to in writing, software
424 distributed under the License is distributed on an "AS IS" BASIS,
425 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
426 See the License for the specific language governing permissions and
427 limitations under the License.
428-->
429
430<permissions>
431 <library name="%s" file="%s"/>
432</permissions>
433`
434 // genrule to generate the xml file content from the template above
435 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
436 // in the ninja file. Do we need to have an external tool for this?
437 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
438 genruleProps := struct {
439 Name *string
440 Cmd *string
441 Out []string
442 }{}
443 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
444 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
445 genruleProps.Out = []string{module.xmlFileName()}
446 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
447
448 // creates a prebuilt_etc module to actually place the xml file under
449 // <partition>/etc/permissions
450 etcProps := struct {
451 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900452 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900453 Sub_dir *string
454 Soc_specific *bool
455 Device_specific *bool
456 Product_specific *bool
457 }{}
458 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900459 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900460 etcProps.Sub_dir = proptools.StringPtr("permissions")
461 if module.SocSpecific() {
462 etcProps.Soc_specific = proptools.BoolPtr(true)
463 } else if module.DeviceSpecific() {
464 etcProps.Device_specific = proptools.BoolPtr(true)
465 } else if module.ProductSpecific() {
466 etcProps.Product_specific = proptools.BoolPtr(true)
467 }
468 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
469}
470
471// to satisfy SdkLibraryDependency interface
472func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
473 // This module is just a wrapper for the stubs.
474 if linkType == javaSystem || linkType == javaPlatform {
475 return module.systemApiStubsPath
476 } else {
477 return module.publicApiStubsPath
478 }
479}
480
Jiyong Park82484c02018-04-23 21:41:26 +0900481func javaSdkLibraries(config android.Config) *[]string {
482 return config.Once("javaSdkLibraries", func() interface{} {
483 return &[]string{}
484 }).(*[]string)
485}
486
Jiyong Parkc678ad32018-04-10 13:07:10 +0900487// For a java_sdk_library module, create internal modules for stubs, docs,
488// runtime libs and xml file. If requested, the stubs and docs are created twice
489// once for public API level and once for system API level
490func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
491 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100492 if module.properties.Srcs == nil {
493 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
494 }
495 if module.properties.Api_packages == nil {
496 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
497 }
498
Jiyong Parkc678ad32018-04-10 13:07:10 +0900499 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900500 module.createStubsLibrary(mctx, apiScopePublic)
501 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900502
503 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900504 module.createStubsLibrary(mctx, apiScopeSystem)
505 module.createDocs(mctx, apiScopeSystem)
506
507 // for test API stubs
508 module.createStubsLibrary(mctx, apiScopeTest)
509 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900510
511 // for runtime
512 module.createXmlFile(mctx)
513 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900514
515 // record java_sdk_library modules so that they are exported to make
516 javaSdkLibraries := javaSdkLibraries(mctx.Config())
517 javaSdkLibrariesLock.Lock()
518 defer javaSdkLibrariesLock.Unlock()
519 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900520 }
521}
522
523func sdkLibraryFactory() android.Module {
524 module := &sdkLibrary{}
525 module.AddProperties(&module.properties)
526 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
527 android.InitDefaultableModule(module)
528 return module
529}