blob: 64bbb8b61b4d71071e5354a74516ea1b538c0cce [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
Jiyong Park90078382018-05-02 19:30:15 +090071// 2) ensuring that apps have appropriate <uses-library> tag
72// 3) disallowing linking to the runtime shared lib
73// 4) HTML generation
Jiyong Parkc678ad32018-04-10 13:07:10 +090074
75func init() {
76 android.RegisterModuleType("java_sdk_library", sdkLibraryFactory)
77
78 android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
79 ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
80 })
Jiyong Park82484c02018-04-23 21:41:26 +090081
82 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
83 javaSdkLibraries := javaSdkLibraries(ctx.Config())
84 sort.Strings(*javaSdkLibraries)
85 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
86 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090087}
88
89type sdkLibraryProperties struct {
90 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
91 // or .aidl files.
92 Srcs []string `android:"arch_variant"`
93
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +090094 // list of optional source files that are part of API but not part of runtime library.
95 Api_srcs []string `android:"arch_variant"`
96
Jiyong Parkc678ad32018-04-10 13:07:10 +090097 // list of of java libraries that will be in the classpath
98 Libs []string `android:"arch_variant"`
99
100 // list of java libraries that will be compiled into the resulting runtime jar.
101 // These libraries are not compiled into the stubs jar.
102 Static_libs []string `android:"arch_variant"`
103
104 // list of package names that will be documented and publicized as API
105 Api_packages []string
106
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900107 // list of package names that must be hidden from the API
108 Hidden_api_packages []string
109
Jiyong Parkc678ad32018-04-10 13:07:10 +0900110 // TODO: determines whether to create HTML doc or not
111 //Html_doc *bool
112}
113
114type sdkLibrary struct {
115 android.ModuleBase
116 android.DefaultableModuleBase
117
Jiyong Park441a47d2018-05-01 23:33:08 +0900118 properties sdkLibraryProperties
119 deviceProperties CompilerDeviceProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900120
121 publicApiStubsPath android.Paths
122 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900123 testApiStubsPath android.Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +0900124}
125
126func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
127 // Add dependencies to the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900128 ctx.AddDependency(ctx.Module(), publicApiStubsTag, module.stubsName(apiScopePublic))
129 ctx.AddDependency(ctx.Module(), systemApiStubsTag, module.stubsName(apiScopeSystem))
130 ctx.AddDependency(ctx.Module(), testApiStubsTag, module.stubsName(apiScopeTest))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900131}
132
133func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
134 // Record the paths to the header jars of the stubs library.
135 // When this java_sdk_library is dependened from others via "libs" property,
136 // the recorded paths will be returned depending on the link type of the caller.
137 ctx.VisitDirectDeps(func(to android.Module) {
138 otherName := ctx.OtherModuleName(to)
139 tag := ctx.OtherModuleDependencyTag(to)
140
141 if stubs, ok := to.(Dependency); ok {
142 switch tag {
143 case publicApiStubsTag:
144 module.publicApiStubsPath = stubs.HeaderJars()
145 case systemApiStubsTag:
146 module.systemApiStubsPath = stubs.HeaderJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900147 case testApiStubsTag:
148 module.testApiStubsPath = stubs.HeaderJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900149 default:
150 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
151 }
152 }
153 })
154}
155
Jiyong Park82484c02018-04-23 21:41:26 +0900156func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Jiyong Park82484c02018-04-23 21:41:26 +0900157 return android.AndroidMkData{
158 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
Jiyong Park90078382018-05-02 19:30:15 +0900159 // Create a phony module that installs the impl library, for the case when this lib is
160 // in PRODUCT_PACKAGES.
Jiyong Park82484c02018-04-23 21:41:26 +0900161 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
162 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
163 fmt.Fprintln(w, "LOCAL_MODULE :=", name)
164 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
165 fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
Jiyong Park90078382018-05-02 19:30:15 +0900166 // Create dist rules to install the stubs libs to the dist dir
167 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
168 module.publicApiStubsPath.Strings()[0]+
169 ":"+path.Join("apistubs", "public", module.BaseModuleName()+".jar")+")")
170 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
171 module.systemApiStubsPath.Strings()[0]+
172 ":"+path.Join("apistubs", "system", module.BaseModuleName()+".jar")+")")
173 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
174 module.testApiStubsPath.Strings()[0]+
175 ":"+path.Join("apistubs", "test", module.BaseModuleName()+".jar")+")")
Jiyong Park82484c02018-04-23 21:41:26 +0900176 },
177 }
178}
179
Jiyong Parkc678ad32018-04-10 13:07:10 +0900180// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900181func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900182 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900183 switch apiScope {
184 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900185 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900186 case apiScopeTest:
187 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900188 }
189 return stubsName
190}
191
192// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900193func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900194 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900195 switch apiScope {
196 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900197 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900198 case apiScopeTest:
199 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900200 }
201 return docsName
202}
203
204// Module name of the runtime implementation library
205func (module *sdkLibrary) implName() string {
206 return module.BaseModuleName() + sdkImplLibrarySuffix
207}
208
209// File path to the runtime implementation library
210func (module *sdkLibrary) implPath() string {
211 partition := "system"
212 if module.SocSpecific() {
213 partition = "vendor"
214 } else if module.DeviceSpecific() {
215 partition = "odm"
216 } else if module.ProductSpecific() {
217 partition = "product"
218 }
219 return "/" + partition + "/framework/" + module.implName() + ".jar"
220}
221
222// Module name of the XML file for the lib
223func (module *sdkLibrary) xmlFileName() string {
224 return module.BaseModuleName() + sdkXmlFileSuffix
225}
226
227// SDK version that the stubs library is built against. Note that this is always
228// *current. Older stubs library built with a numberd SDK version is created from
229// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900230func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
231 switch apiScope {
232 case apiScopePublic:
233 return "current"
234 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900235 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900236 case apiScopeTest:
237 return "test_current"
238 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900239 return "current"
240 }
241}
242
243// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
244// api file for the current source
245// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900246func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900247 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900248 switch apiScope {
249 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900250 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900251 case apiScopeTest:
252 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900253 }
254 return apiTagName
255}
256
257// returns the path (relative to this module) to the API txt file. Files are located
258// ./<api_dir>/<api_level>.txt where <api_level> is either current, system-current, removed,
259// or system-removed.
Jiyong Parkdf130542018-04-27 16:29:21 +0900260func (module *sdkLibrary) apiFilePath(apiLevel string, apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900261 apiDir := "api"
262 apiFile := apiLevel
Jiyong Parkdf130542018-04-27 16:29:21 +0900263 switch apiScope {
264 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900265 apiFile = "system-" + apiFile
Jiyong Parkdf130542018-04-27 16:29:21 +0900266 case apiScopeTest:
267 apiFile = "test-" + apiFile
Jiyong Parkc678ad32018-04-10 13:07:10 +0900268 }
269 apiFile = apiFile + ".txt"
270
271 return path.Join(apiDir, apiFile)
272}
273
274// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900275func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900276 props := struct {
277 Name *string
278 Srcs []string
279 Sdk_version *string
280 Soc_specific *bool
281 Device_specific *bool
282 Product_specific *bool
283 Product_variables struct {
284 Unbundled_build struct {
285 Enabled *bool
286 }
Jiyong Park82484c02018-04-23 21:41:26 +0900287 Pdk struct {
288 Enabled *bool
289 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900290 }
291 }{}
292
Jiyong Parkdf130542018-04-27 16:29:21 +0900293 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900294 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900295 props.Srcs = []string{":" + module.docsName(apiScope)}
296 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900297 // Unbundled apps will use the prebult one from /prebuilts/sdk
298 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900299 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900300
301 if module.SocSpecific() {
302 props.Soc_specific = proptools.BoolPtr(true)
303 } else if module.DeviceSpecific() {
304 props.Device_specific = proptools.BoolPtr(true)
305 } else if module.ProductSpecific() {
306 props.Product_specific = proptools.BoolPtr(true)
307 }
308
309 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(false)), &props)
310}
311
312// Creates a droiddoc module that creates stubs source files from the given full source
313// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900314func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900315 props := struct {
316 Name *string
317 Srcs []string
318 Custom_template *string
319 Installable *bool
320 Srcs_lib *string
321 Srcs_lib_whitelist_dirs []string
322 Srcs_lib_whitelist_pkgs []string
323 Libs []string
324 Args *string
325 Api_tag_name *string
326 Api_filename *string
327 Removed_api_filename *string
328 }{}
329
Jiyong Parkdf130542018-04-27 16:29:21 +0900330 props.Name = proptools.StringPtr(module.docsName(apiScope))
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900331 props.Srcs = append(props.Srcs, module.properties.Srcs...)
332 props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900333 props.Custom_template = proptools.StringPtr("droiddoc-templates-sdk")
334 props.Installable = proptools.BoolPtr(false)
335 props.Libs = module.properties.Libs
336
337 droiddocArgs := " -hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128" +
338 " -stubpackages " + strings.Join(module.properties.Api_packages, ":") +
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900339 " " + android.JoinWithPrefix(module.properties.Hidden_api_packages, "-hidePackage ") +
Jiyong Parkc678ad32018-04-10 13:07:10 +0900340 " -nodocs"
Jiyong Parkdf130542018-04-27 16:29:21 +0900341 switch apiScope {
342 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900343 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900344 case apiScopeTest:
345 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900346 }
347 props.Args = proptools.StringPtr(droiddocArgs)
348
349 // List of APIs identified from the provided source files are created. They are later
350 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
351 // last-released (a.k.a numbered) list of API.
352 // TODO: If any incompatible change is detected, break the build
353 currentApiFileName := "current.txt"
354 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900355 switch apiScope {
356 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900357 currentApiFileName = "system-" + currentApiFileName
358 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900359 case apiScopeTest:
360 currentApiFileName = "test-" + currentApiFileName
361 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900362 }
363 currentApiFileName = path.Join("api", currentApiFileName)
364 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Parkdf130542018-04-27 16:29:21 +0900365 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900366 // Note: the exact names of these two are not important because they are always
367 // referenced by the make variable $(INTERNAL_PLATFORM_<TAG_NAME>_API_FILE)
368 props.Api_filename = proptools.StringPtr(currentApiFileName)
369 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
370
Jiyong Park82484c02018-04-23 21:41:26 +0900371 // Include the part of the framework source. This is required for the case when
372 // API class is extending from the framework class. In that case, doclava needs
373 // to know whether the base class is hidden or not. Since that information is
374 // encoded as @hide string in the comment, we need source files for the classes,
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900375 // not the compiled ones.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900376 props.Srcs_lib = proptools.StringPtr("framework")
377 props.Srcs_lib_whitelist_dirs = []string{"core/java"}
Jiyong Park82484c02018-04-23 21:41:26 +0900378 // Add android.annotation package to give access to the framework-defined
379 // annotations such as SystemApi, NonNull, etc.
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +0900380 props.Srcs_lib_whitelist_pkgs = []string{"android.annotation"}
Jiyong Park82484c02018-04-23 21:41:26 +0900381 // These libs are required by doclava to parse the framework sources add via
382 // Src_lib and Src_lib_whitelist_* properties just above.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900383 // If we don't add them to the classpath, errors messages are generated by doclava,
384 // though they don't break the build.
Jiyong Park82484c02018-04-23 21:41:26 +0900385 props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900386
387 mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
388}
389
390// Creates the runtime library. This is not directly linkable from other modules.
391func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
392 props := struct {
393 Name *string
394 Srcs []string
395 Libs []string
396 Static_libs []string
397 Soc_specific *bool
398 Device_specific *bool
399 Product_specific *bool
400 Required []string
401 }{}
402
403 props.Name = proptools.StringPtr(module.implName())
404 props.Srcs = module.properties.Srcs
405 props.Libs = module.properties.Libs
406 props.Static_libs = module.properties.Static_libs
407 // XML file is installed along with the impl lib
408 props.Required = []string{module.xmlFileName()}
409
410 if module.SocSpecific() {
411 props.Soc_specific = proptools.BoolPtr(true)
412 } else if module.DeviceSpecific() {
413 props.Device_specific = proptools.BoolPtr(true)
414 } else if module.ProductSpecific() {
415 props.Product_specific = proptools.BoolPtr(true)
416 }
417
Jiyong Park441a47d2018-05-01 23:33:08 +0900418 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory(true)), &props, &module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900419}
420
421// Creates the xml file that publicizes the runtime library
422func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
423 template := `
424<?xml version="1.0" encoding="utf-8"?>
425<!-- Copyright (C) 2018 The Android Open Source Project
426
427 Licensed under the Apache License, Version 2.0 (the "License");
428 you may not use this file except in compliance with the License.
429 You may obtain a copy of the License at
430
431 http://www.apache.org/licenses/LICENSE-2.0
432
433 Unless required by applicable law or agreed to in writing, software
434 distributed under the License is distributed on an "AS IS" BASIS,
435 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
436 See the License for the specific language governing permissions and
437 limitations under the License.
438-->
439
440<permissions>
441 <library name="%s" file="%s"/>
442</permissions>
443`
444 // genrule to generate the xml file content from the template above
445 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
446 // in the ninja file. Do we need to have an external tool for this?
447 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
448 genruleProps := struct {
449 Name *string
450 Cmd *string
451 Out []string
452 }{}
453 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
454 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
455 genruleProps.Out = []string{module.xmlFileName()}
456 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
457
458 // creates a prebuilt_etc module to actually place the xml file under
459 // <partition>/etc/permissions
460 etcProps := struct {
461 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900462 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900463 Sub_dir *string
464 Soc_specific *bool
465 Device_specific *bool
466 Product_specific *bool
467 }{}
468 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900469 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900470 etcProps.Sub_dir = proptools.StringPtr("permissions")
471 if module.SocSpecific() {
472 etcProps.Soc_specific = proptools.BoolPtr(true)
473 } else if module.DeviceSpecific() {
474 etcProps.Device_specific = proptools.BoolPtr(true)
475 } else if module.ProductSpecific() {
476 etcProps.Product_specific = proptools.BoolPtr(true)
477 }
478 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
479}
480
481// to satisfy SdkLibraryDependency interface
482func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
483 // This module is just a wrapper for the stubs.
484 if linkType == javaSystem || linkType == javaPlatform {
485 return module.systemApiStubsPath
486 } else {
487 return module.publicApiStubsPath
488 }
489}
490
Jiyong Park82484c02018-04-23 21:41:26 +0900491func javaSdkLibraries(config android.Config) *[]string {
492 return config.Once("javaSdkLibraries", func() interface{} {
493 return &[]string{}
494 }).(*[]string)
495}
496
Jiyong Parkc678ad32018-04-10 13:07:10 +0900497// For a java_sdk_library module, create internal modules for stubs, docs,
498// runtime libs and xml file. If requested, the stubs and docs are created twice
499// once for public API level and once for system API level
500func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
501 if module, ok := mctx.Module().(*sdkLibrary); ok {
Anton Hansson8959e142018-04-25 11:56:13 +0100502 if module.properties.Srcs == nil {
503 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
504 }
505 if module.properties.Api_packages == nil {
506 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
507 }
508
Jiyong Parkc678ad32018-04-10 13:07:10 +0900509 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900510 module.createStubsLibrary(mctx, apiScopePublic)
511 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900512
513 // for system API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900514 module.createStubsLibrary(mctx, apiScopeSystem)
515 module.createDocs(mctx, apiScopeSystem)
516
517 // for test API stubs
518 module.createStubsLibrary(mctx, apiScopeTest)
519 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900520
521 // for runtime
522 module.createXmlFile(mctx)
523 module.createImplLibrary(mctx)
Jiyong Park82484c02018-04-23 21:41:26 +0900524
525 // record java_sdk_library modules so that they are exported to make
526 javaSdkLibraries := javaSdkLibraries(mctx.Config())
527 javaSdkLibrariesLock.Lock()
528 defer javaSdkLibrariesLock.Unlock()
529 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900530 }
531}
532
533func sdkLibraryFactory() android.Module {
534 module := &sdkLibrary{}
535 module.AddProperties(&module.properties)
Jiyong Park441a47d2018-05-01 23:33:08 +0900536 module.AddProperties(&module.deviceProperties)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900537 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
538 android.InitDefaultableModule(module)
539 return module
540}