blob: 703401cf1229a66b0e3640726bb9fb5b1e1bf097 [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
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +090095 // list of optional source files that are part of API but not part of runtime library.
96 Api_srcs []string `android:"arch_variant"`
97
Jiyong Parkc678ad32018-04-10 13:07:10 +090098 // list of of java libraries that will be in the classpath
99 Libs []string `android:"arch_variant"`
100
101 // list of java libraries that will be compiled into the resulting runtime jar.
102 // These libraries are not compiled into the stubs jar.
103 Static_libs []string `android:"arch_variant"`
104
105 // 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 Parkc678ad32018-04-10 13:07:10 +0900111 // TODO: determines whether to create HTML doc or not
112 //Html_doc *bool
113}
114
115type sdkLibrary struct {
116 android.ModuleBase
117 android.DefaultableModuleBase
118
Jiyong Park441a47d2018-05-01 23:33:08 +0900119 properties sdkLibraryProperties
120 deviceProperties CompilerDeviceProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900121
122 publicApiStubsPath android.Paths
123 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900124 testApiStubsPath android.Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +0900125}
126
127func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
128 // Add dependencies to the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900129 ctx.AddDependency(ctx.Module(), publicApiStubsTag, module.stubsName(apiScopePublic))
130 ctx.AddDependency(ctx.Module(), systemApiStubsTag, module.stubsName(apiScopeSystem))
131 ctx.AddDependency(ctx.Module(), testApiStubsTag, module.stubsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900132}
133
134func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
135 // Record the paths to the header jars of the stubs library.
136 // When this java_sdk_library is dependened from others via "libs" property,
137 // the recorded paths will be returned depending on the link type of the caller.
138 ctx.VisitDirectDeps(func(to android.Module) {
139 otherName := ctx.OtherModuleName(to)
140 tag := ctx.OtherModuleDependencyTag(to)
141
142 if stubs, ok := to.(Dependency); ok {
143 switch tag {
144 case publicApiStubsTag:
145 module.publicApiStubsPath = stubs.HeaderJars()
146 case systemApiStubsTag:
147 module.systemApiStubsPath = stubs.HeaderJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900148 case testApiStubsTag:
149 module.testApiStubsPath = stubs.HeaderJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900150 default:
151 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
152 }
153 }
154 })
155}
156
Jiyong Park82484c02018-04-23 21:41:26 +0900157func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
158 // Create a phony module that installs the impl library, for the case when this lib is
159 // in PRODUCT_PACKAGES.
160 return android.AndroidMkData{
161 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
162 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
163 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
164 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
165 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
166 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
167 },
168 }
169}
170
Jiyong Parkc678ad32018-04-10 13:07:10 +0900171// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900172func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900173 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900174 switch apiScope {
175 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900176 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900177 case apiScopeTest:
178 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900179 }
180 return stubsName
181}
182
183// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900184func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900185 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900186 switch apiScope {
187 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900188 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900189 case apiScopeTest:
190 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900191 }
192 return docsName
193}
194
195// Module name of the runtime implementation library
196func (module *sdkLibrary) implName() string {
197 return module.BaseModuleName() + sdkImplLibrarySuffix
198}
199
200// File path to the runtime implementation library
201func (module *sdkLibrary) implPath() string {
202 partition := "system"
203 if module.SocSpecific() {
204 partition = "vendor"
205 } else if module.DeviceSpecific() {
206 partition = "odm"
207 } else if module.ProductSpecific() {
208 partition = "product"
209 }
210 return "/" + partition + "/framework/" + module.implName() + ".jar"
211}
212
213// Module name of the XML file for the lib
214func (module *sdkLibrary) xmlFileName() string {
215 return module.BaseModuleName() + sdkXmlFileSuffix
216}
217
218// SDK version that the stubs library is built against. Note that this is always
219// *current. Older stubs library built with a numberd SDK version is created from
220// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900221func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
222 switch apiScope {
223 case apiScopePublic:
224 return "current"
225 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900226 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900227 case apiScopeTest:
228 return "test_current"
229 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900230 return "current"
231 }
232}
233
234// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
235// api file for the current source
236// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900237func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900238 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900239 switch apiScope {
240 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900241 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900242 case apiScopeTest:
243 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900244 }
245 return apiTagName
246}
247
248// returns the path (relative to this module) to the API txt file. Files are located
249// ./<api_dir>/<api_level>.txt where <api_level> is either current, system-current, removed,
250// or system-removed.
Jiyong Parkdf130542018-04-27 16:29:21 +0900251func (module *sdkLibrary) apiFilePath(apiLevel string, apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900252 apiDir := "api"
253 apiFile := apiLevel
Jiyong Parkdf130542018-04-27 16:29:21 +0900254 switch apiScope {
255 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900256 apiFile = "system-" + apiFile
Jiyong Parkdf130542018-04-27 16:29:21 +0900257 case apiScopeTest:
258 apiFile = "test-" + apiFile
Jiyong Parkc678ad32018-04-10 13:07:10 +0900259 }
260 apiFile = apiFile + ".txt"
261
262 return path.Join(apiDir, apiFile)
263}
264
265// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900266func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900267 props := struct {
268 Name *string
269 Srcs []string
270 Sdk_version *string
271 Soc_specific *bool
272 Device_specific *bool
273 Product_specific *bool
274 Product_variables struct {
275 Unbundled_build struct {
276 Enabled *bool
277 }
Jiyong Park82484c02018-04-23 21:41:26 +0900278 Pdk struct {
279 Enabled *bool
280 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900281 }
282 }{}
283
Jiyong Parkdf130542018-04-27 16:29:21 +0900284 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900285 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900286 props.Srcs = []string{":" + module.docsName(apiScope)}
287 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900288 // Unbundled apps will use the prebult one from /prebuilts/sdk
289 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900290 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900291
292 if module.SocSpecific() {
293 props.Soc_specific = proptools.BoolPtr(true)
294 } else if module.DeviceSpecific() {
295 props.Device_specific = proptools.BoolPtr(true)
296 } else if module.ProductSpecific() {
297 props.Product_specific = proptools.BoolPtr(true)
298 }
299
300 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(false)), &props)
301}
302
303// Creates a droiddoc module that creates stubs source files from the given full source
304// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900305func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900306 props := struct {
307 Name *string
308 Srcs []string
309 Custom_template *string
310 Installable *bool
311 Srcs_lib *string
312 Srcs_lib_whitelist_dirs []string
313 Srcs_lib_whitelist_pkgs []string
314 Libs []string
315 Args *string
316 Api_tag_name *string
317 Api_filename *string
318 Removed_api_filename *string
319 }{}
320
Jiyong Parkdf130542018-04-27 16:29:21 +0900321 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900322 props.Srcs = append(props.Srcs, module.properties.Srcs...)
323 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900324 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
325 props.Installable = proptools.BoolPtr(false)
326 props.Libs = module.properties.Libs
327
328 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
329 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900330 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Jiyong Parkc678ad32018-04-10 13:07:10 +0900331 " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900332 switch apiScope {
333 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900334 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900335 case apiScopeTest:
336 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900337 }
338 props.Args = proptools.StringPtr(droiddocArgs)
339
340 // List of APIs identified from the provided source files are created. They are later
341 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
342 // last-released (a.k.a numbered) list of API.
343 // TODO: If any incompatible change is detected, break the build
344 currentApiFileName := "current.txt"
345 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900346 switch apiScope {
347 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900348 currentApiFileName = "system-" + currentApiFileName
349 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900350 case apiScopeTest:
351 currentApiFileName = "test-" + currentApiFileName
352 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900353 }
354 currentApiFileName = path.Join("api", currentApiFileName)
355 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Parkdf130542018-04-27 16:29:21 +0900356 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900357 // Note: the exact names of these two are not important because they are always
358 // referenced by the make variable $(INTERNAL_PLATFORM_<TAG_NAME>_API_FILE)
359 props.Api_filename = proptools.StringPtr(currentApiFileName)
360 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
361
Jiyong Park82484c02018-04-23 21:41:26 +0900362 // Include the part of the framework source. This is required for the case when
363 // API class is extending from the framework class. In that case, doclava needs
364 // to know whether the base class is hidden or not. Since that information is
365 // encoded as @hide string in the comment, we need source files for the classes,
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900366 // not the compiled ones.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900367 props.Srcs_lib = proptools.StringPtr("framework")
368 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900369 // Add android.annotation package to give access to the framework-defined
370 // annotations such as SystemApi, NonNull, etc.
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900371 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
Jiyong Park82484c02018-04-23 21:41:26 +0900372 // These libs are required by doclava to parse the framework sources add via
373 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900374 // If we don't add them to the classpath, errors messages are generated by doclava,
375 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900376 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900377
378 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
379}
380
381// Creates the runtime library. This is not directly linkable from other modules.
382func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
383 props := struct {
384 Name *string
385 Srcs []string
386 Libs []string
387 Static_libs []string
388 Soc_specific *bool
389 Device_specific *bool
390 Product_specific *bool
391 Required []string
392 }{}
393
394 props.Name = proptools.StringPtr(module.implName())
395 props.Srcs = module.properties.Srcs
396 props.Libs = module.properties.Libs
397 props.Static_libs = module.properties.Static_libs
398 // XML file is installed along with the impl lib
399 props.Required = []string{module.xmlFileName()}
400
401 if module.SocSpecific() {
402 props.Soc_specific = proptools.BoolPtr(true)
403 } else if module.DeviceSpecific() {
404 props.Device_specific = proptools.BoolPtr(true)
405 } else if module.ProductSpecific() {
406 props.Product_specific = proptools.BoolPtr(true)
407 }
408
Jiyong Park441a47d2018-05-01 23:33:08 +0900409 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(true)), &props, &module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900410}
411
412// Creates the xml file that publicizes the runtime library
413func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
414 template := `
415<?xml version="1.0" encoding="utf-8"?>
416<!-- Copyright (C) 2018 The Android Open Source Project
417
418 Licensed under the Apache License, Version 2.0 (the "License");
419 you may not use this file except in compliance with the License.
420 You may obtain a copy of the License at
421
422 http://www.apache.org/licenses/LICENSE-2.0
423
424 Unless required by applicable law or agreed to in writing, software
425 distributed under the License is distributed on an "AS IS" BASIS,
426 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
427 See the License for the specific language governing permissions and
428 limitations under the License.
429-->
430
431<permissions>
432 <library name="%s" file="%s"/>
433</permissions>
434`
435 // genrule to generate the xml file content from the template above
436 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
437 // in the ninja file. Do we need to have an external tool for this?
438 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
439 genruleProps := struct {
440 Name *string
441 Cmd *string
442 Out []string
443 }{}
444 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
445 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
446 genruleProps.Out = []string{module.xmlFileName()}
447 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
448
449 // creates a prebuilt_etc module to actually place the xml file under
450 // <partition>/etc/permissions
451 etcProps := struct {
452 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900453 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900454 Sub_dir *string
455 Soc_specific *bool
456 Device_specific *bool
457 Product_specific *bool
458 }{}
459 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900460 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900461 etcProps.Sub_dir = proptools.StringPtr("permissions")
462 if module.SocSpecific() {
463 etcProps.Soc_specific = proptools.BoolPtr(true)
464 } else if module.DeviceSpecific() {
465 etcProps.Device_specific = proptools.BoolPtr(true)
466 } else if module.ProductSpecific() {
467 etcProps.Product_specific = proptools.BoolPtr(true)
468 }
469 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
470}
471
472// to satisfy SdkLibraryDependency interface
473func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
474 // This module is just a wrapper for the stubs.
475 if linkType == javaSystem || linkType == javaPlatform {
476 return module.systemApiStubsPath
477 } else {
478 return module.publicApiStubsPath
479 }
480}
481
Jiyong Park82484c02018-04-23 21:41:26 +0900482func javaSdkLibraries(config android.Config) *[]string {
483 return config.Once("javaSdkLibraries", func() interface{} {
484 return &[]string{}
485 }).(*[]string)
486}
487
Jiyong Parkc678ad32018-04-10 13:07:10 +0900488// For a java_sdk_library module, create internal modules for stubs, docs,
489// runtime libs and xml file. If requested, the stubs and docs are created twice
490// once for public API level and once for system API level
491func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
492 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100493 if module.properties.Srcs == nil {
494 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
495 }
496 if module.properties.Api_packages == nil {
497 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
498 }
499
Jiyong Parkc678ad32018-04-10 13:07:10 +0900500 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900501 module.createStubsLibrary(mctx, apiScopePublic)
502 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900503
504 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900505 module.createStubsLibrary(mctx, apiScopeSystem)
506 module.createDocs(mctx, apiScopeSystem)
507
508 // for test API stubs
509 module.createStubsLibrary(mctx, apiScopeTest)
510 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900511
512 // for runtime
513 module.createXmlFile(mctx)
514 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900515
516 // record java_sdk_library modules so that they are exported to make
517 javaSdkLibraries := javaSdkLibraries(mctx.Config())
518 javaSdkLibrariesLock.Lock()
519 defer javaSdkLibrariesLock.Unlock()
520 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900521 }
522}
523
524func sdkLibraryFactory() android.Module {
525 module := &sdkLibrary{}
526 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900527 module.AddProperties(&module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900528 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
529 android.InitDefaultableModule(module)
530 return module
531}