blob: 84be4dda9b4acc8adbd0b927e01e7409f57766d9 [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"
Sundong Ahn054b19a2018-10-19 13:46:09 +090023 "path/filepath"
Jiyong Park82484c02018-04-23 21:41:26 +090024 "sort"
Jiyong Parkc678ad32018-04-10 13:07:10 +090025 "strings"
Jiyong Park82484c02018-04-23 21:41:26 +090026 "sync"
Jiyong Parkc678ad32018-04-10 13:07:10 +090027
28 "github.com/google/blueprint"
29 "github.com/google/blueprint/proptools"
30)
31
32var (
33 sdkStubsLibrarySuffix = ".stubs"
34 sdkSystemApiSuffix = ".system"
Jiyong Parkdf130542018-04-27 16:29:21 +090035 sdkTestApiSuffix = ".test"
Jiyong Parkc678ad32018-04-10 13:07:10 +090036 sdkDocsSuffix = ".docs"
Jiyong Parkc678ad32018-04-10 13:07:10 +090037 sdkXmlFileSuffix = ".xml"
38)
39
40type stubsLibraryDependencyTag struct {
41 blueprint.BaseDependencyTag
42 name string
43}
44
Inseob Kimc0907f12019-02-08 21:00:45 +090045type syspropLibraryInterface interface {
46 SyspropJavaModule() *SdkLibrary
47}
48
Jiyong Parkc678ad32018-04-10 13:07:10 +090049var (
50 publicApiStubsTag = dependencyTag{name: "public"}
51 systemApiStubsTag = dependencyTag{name: "system"}
Jiyong Parkdf130542018-04-27 16:29:21 +090052 testApiStubsTag = dependencyTag{name: "test"}
Sundong Ahn20e998b2018-07-24 11:19:26 +090053 publicApiFileTag = dependencyTag{name: "publicApi"}
54 systemApiFileTag = dependencyTag{name: "systemApi"}
55 testApiFileTag = dependencyTag{name: "testApi"}
Jiyong Parkdf130542018-04-27 16:29:21 +090056)
57
58type apiScope int
59
60const (
61 apiScopePublic apiScope = iota
62 apiScopeSystem
63 apiScopeTest
Jiyong Parkc678ad32018-04-10 13:07:10 +090064)
65
Jiyong Park82484c02018-04-23 21:41:26 +090066var (
67 javaSdkLibrariesLock sync.Mutex
68)
69
Jiyong Parkc678ad32018-04-10 13:07:10 +090070// java_sdk_library is to make a Java library that implements optional platform APIs to apps.
71// It is actually a wrapper of several modules: 1) stubs library that clients are linked against
72// to, 2) droiddoc module that internally generates API stubs source files, 3) the real runtime
73// shared library that implements the APIs, and 4) XML file for adding the runtime lib to the
74// classpath at runtime if requested via <uses-library>.
75//
76// TODO: these are big features that are currently missing
Jiyong Park1be96912018-05-28 18:02:19 +090077// 1) disallowing linking to the runtime shared lib
78// 2) HTML generation
Jiyong Parkc678ad32018-04-10 13:07:10 +090079
80func init() {
Inseob Kimc0907f12019-02-08 21:00:45 +090081 android.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
Jiyong Parkc678ad32018-04-10 13:07:10 +090082
83 android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
Inseob Kimc0907f12019-02-08 21:00:45 +090084 ctx.TopDown("java_sdk_library", SdkLibraryMutator).Parallel()
Jiyong Parkc678ad32018-04-10 13:07:10 +090085 })
Jiyong Park82484c02018-04-23 21:41:26 +090086
87 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
88 javaSdkLibraries := javaSdkLibraries(ctx.Config())
89 sort.Strings(*javaSdkLibraries)
90 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
91 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090092}
93
94type sdkLibraryProperties struct {
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
Sundong Ahnf043cf62018-06-25 16:04:37 +090098 // List of Java libraries that will be in the classpath when building stubs
99 Stub_only_libs []string `android:"arch_variant"`
100
Jiyong Parkc678ad32018-04-10 13:07:10 +0900101 // list of package names that will be documented and publicized as API
102 Api_packages []string
103
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900104 // list of package names that must be hidden from the API
105 Hidden_api_packages []string
106
Paul Duffin11512472019-02-11 15:55:17 +0000107 // local files that are used within user customized droiddoc options.
108 Droiddoc_option_files []string
109
110 // additional droiddoc options
111 // Available variables for substitution:
112 //
113 // $(location <label>): the path to the droiddoc_option_files with name <label>
Sundong Ahndd567f92018-07-31 17:19:11 +0900114 Droiddoc_options []string
115
Sundong Ahnb952ba02019-01-08 16:32:12 +0900116 // the java library (in classpath) for documentation that provides java srcs and srcjars.
117 Srcs_lib *string
118
119 // the base dirs under srcs_lib will be scanned for java srcs.
120 Srcs_lib_whitelist_dirs []string
121
Sundong Ahndd567f92018-07-31 17:19:11 +0900122 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
123 // Defaults to "android.annotation".
124 Srcs_lib_whitelist_pkgs []string
125
Sundong Ahn054b19a2018-10-19 13:46:09 +0900126 // a list of top-level directories containing files to merge qualifier annotations
127 // (i.e. those intended to be included in the stubs written) from.
128 Merge_annotations_dirs []string
129
130 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
131 Merge_inclusion_annotations_dirs []string
132
133 // If set to true, the path of dist files is apistubs/core. Defaults to false.
134 Core_lib *bool
135
Sundong Ahna4a385f2019-05-13 15:02:50 +0900136 // don't create dist rules.
137 No_dist *bool `blueprint:"mutated"`
138
Jiyong Parkc678ad32018-04-10 13:07:10 +0900139 // TODO: determines whether to create HTML doc or not
140 //Html_doc *bool
141}
142
Inseob Kimc0907f12019-02-08 21:00:45 +0900143type SdkLibrary struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900144 Library
Jiyong Parkc678ad32018-04-10 13:07:10 +0900145
Sundong Ahn054b19a2018-10-19 13:46:09 +0900146 sdkLibraryProperties sdkLibraryProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900147
148 publicApiStubsPath android.Paths
149 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900150 testApiStubsPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900151
152 publicApiStubsImplPath android.Paths
153 systemApiStubsImplPath android.Paths
154 testApiStubsImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900155
156 publicApiFilePath android.Path
157 systemApiFilePath android.Path
158 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900159}
160
Inseob Kimc0907f12019-02-08 21:00:45 +0900161var _ Dependency = (*SdkLibrary)(nil)
162var _ SdkLibraryDependency = (*SdkLibrary)(nil)
Colin Cross897d2ed2019-02-11 14:03:51 -0800163
Inseob Kimc0907f12019-02-08 21:00:45 +0900164func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkb8650ff2019-07-15 15:31:16 +0900165 useBuiltStubs := !ctx.Config().UnbundledBuildUsePrebuiltSdks()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900166 // Add dependencies to the stubs library
Jiyong Parkb8650ff2019-07-15 15:31:16 +0900167 if useBuiltStubs {
168 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
169 }
Colin Cross42d48b72018-08-29 14:10:52 -0700170 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900171
172 if !Bool(module.properties.No_standard_libs) {
Jiyong Parkb8650ff2019-07-15 15:31:16 +0900173 if useBuiltStubs {
174 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
175 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
176 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900177 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
178 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900179 }
180
181 module.Library.deps(ctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900182}
183
Inseob Kimc0907f12019-02-08 21:00:45 +0900184func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900185 module.Library.GenerateAndroidBuildActions(ctx)
186
Sundong Ahn57368eb2018-07-06 11:20:23 +0900187 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900188 // When this java_sdk_library is dependened from others via "libs" property,
189 // the recorded paths will be returned depending on the link type of the caller.
190 ctx.VisitDirectDeps(func(to android.Module) {
191 otherName := ctx.OtherModuleName(to)
192 tag := ctx.OtherModuleDependencyTag(to)
193
Sundong Ahn57368eb2018-07-06 11:20:23 +0900194 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900195 switch tag {
196 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900197 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900198 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900199 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900200 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900201 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900202 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900203 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900204 module.testApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900205 }
206 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900207 if doc, ok := to.(ApiFilePath); ok {
208 switch tag {
209 case publicApiFileTag:
210 module.publicApiFilePath = doc.ApiFilePath()
211 case systemApiFileTag:
212 module.systemApiFilePath = doc.ApiFilePath()
213 case testApiFileTag:
214 module.testApiFilePath = doc.ApiFilePath()
215 default:
216 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
217 }
218 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900219 })
220}
221
Inseob Kimc0907f12019-02-08 21:00:45 +0900222func (module *SdkLibrary) AndroidMk() android.AndroidMkData {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900223 data := module.Library.AndroidMk()
224 data.Required = append(data.Required, module.xmlFileName())
225
226 data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
227 android.WriteAndroidMkData(w, data)
228
229 module.Library.AndroidMkHostDex(w, name, data)
Sundong Ahna4a385f2019-05-13 15:02:50 +0900230 if !Bool(module.sdkLibraryProperties.No_dist) {
231 // Create a phony module that installs the impl library, for the case when this lib is
232 // in PRODUCT_PACKAGES.
233 owner := module.ModuleBase.Owner()
234 if owner == "" {
235 if Bool(module.sdkLibraryProperties.Core_lib) {
236 owner = "core"
237 } else {
238 owner = "android"
239 }
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900240 }
Sundong Ahna4a385f2019-05-13 15:02:50 +0900241 // Create dist rules to install the stubs libs to the dist dir
242 if len(module.publicApiStubsPath) == 1 {
243 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
244 module.publicApiStubsImplPath.Strings()[0]+
245 ":"+path.Join("apistubs", owner, "public",
246 module.BaseModuleName()+".jar")+")")
247 }
248 if len(module.systemApiStubsPath) == 1 {
249 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
250 module.systemApiStubsImplPath.Strings()[0]+
251 ":"+path.Join("apistubs", owner, "system",
252 module.BaseModuleName()+".jar")+")")
253 }
254 if len(module.testApiStubsPath) == 1 {
255 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
256 module.testApiStubsImplPath.Strings()[0]+
257 ":"+path.Join("apistubs", owner, "test",
258 module.BaseModuleName()+".jar")+")")
259 }
260 if module.publicApiFilePath != nil {
261 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
262 module.publicApiFilePath.String()+
263 ":"+path.Join("apistubs", owner, "public", "api",
264 module.BaseModuleName()+".txt")+")")
265 }
266 if module.systemApiFilePath != nil {
267 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
268 module.systemApiFilePath.String()+
269 ":"+path.Join("apistubs", owner, "system", "api",
270 module.BaseModuleName()+".txt")+")")
271 }
272 if module.testApiFilePath != nil {
273 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
274 module.testApiFilePath.String()+
275 ":"+path.Join("apistubs", owner, "test", "api",
276 module.BaseModuleName()+".txt")+")")
277 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900278 }
Jiyong Park82484c02018-04-23 21:41:26 +0900279 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900280 return data
Jiyong Park82484c02018-04-23 21:41:26 +0900281}
282
Jiyong Parkc678ad32018-04-10 13:07:10 +0900283// Module name of the stubs library
Inseob Kimc0907f12019-02-08 21:00:45 +0900284func (module *SdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900285 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900286 switch apiScope {
287 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900288 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900289 case apiScopeTest:
290 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900291 }
292 return stubsName
293}
294
295// Module name of the docs
Inseob Kimc0907f12019-02-08 21:00:45 +0900296func (module *SdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900297 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900298 switch apiScope {
299 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900300 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900301 case apiScopeTest:
302 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900303 }
304 return docsName
305}
306
307// Module name of the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900308func (module *SdkLibrary) implName() string {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900309 return module.BaseModuleName()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900310}
311
312// File path to the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900313func (module *SdkLibrary) implPath() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900314 partition := "system"
315 if module.SocSpecific() {
316 partition = "vendor"
317 } else if module.DeviceSpecific() {
318 partition = "odm"
319 } else if module.ProductSpecific() {
320 partition = "product"
321 }
322 return "/" + partition + "/framework/" + module.implName() + ".jar"
323}
324
325// Module name of the XML file for the lib
Inseob Kimc0907f12019-02-08 21:00:45 +0900326func (module *SdkLibrary) xmlFileName() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900327 return module.BaseModuleName() + sdkXmlFileSuffix
328}
329
330// SDK version that the stubs library is built against. Note that this is always
331// *current. Older stubs library built with a numberd SDK version is created from
332// the prebuilt jar.
Inseob Kimc0907f12019-02-08 21:00:45 +0900333func (module *SdkLibrary) sdkVersion(apiScope apiScope) string {
Jiyong Parkdf130542018-04-27 16:29:21 +0900334 switch apiScope {
335 case apiScopePublic:
336 return "current"
337 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900338 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900339 case apiScopeTest:
340 return "test_current"
341 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900342 return "current"
343 }
344}
345
346// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
347// api file for the current source
348// TODO: remove this when apicheck is done in soong
Inseob Kimc0907f12019-02-08 21:00:45 +0900349func (module *SdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900350 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900351 switch apiScope {
352 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900353 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900354 case apiScopeTest:
355 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900356 }
357 return apiTagName
358}
359
Inseob Kimc0907f12019-02-08 21:00:45 +0900360func (module *SdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
Jiyong Park58c518b2018-05-12 22:29:12 +0900361 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900362 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900363 case apiScopePublic:
364 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900365 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900366 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900367 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900368 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900369 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900370 name = name + ".latest"
371 return name
372}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900373
Inseob Kimc0907f12019-02-08 21:00:45 +0900374func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
Jiyong Park58c518b2018-05-12 22:29:12 +0900375 name := ":" + module.BaseModuleName() + "-removed.api."
376 switch apiScope {
377 case apiScopePublic:
378 name = name + "public"
379 case apiScopeSystem:
380 name = name + "system"
381 case apiScopeTest:
382 name = name + "test"
383 }
384 name = name + ".latest"
385 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900386}
387
388// Creates a static java library that has API stubs
Inseob Kimc0907f12019-02-08 21:00:45 +0900389func (module *SdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900390 props := struct {
391 Name *string
392 Srcs []string
393 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900394 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900395 Soc_specific *bool
396 Device_specific *bool
397 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900398 Compile_dex *bool
Sundong Ahn054b19a2018-10-19 13:46:09 +0900399 No_standard_libs *bool
400 System_modules *string
401 Java_version *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900402 Product_variables struct {
403 Unbundled_build struct {
404 Enabled *bool
405 }
Jiyong Park82484c02018-04-23 21:41:26 +0900406 Pdk struct {
407 Enabled *bool
408 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900409 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900410 Openjdk9 struct {
411 Srcs []string
412 Javacflags []string
413 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900414 }{}
415
Jiyong Parkdf130542018-04-27 16:29:21 +0900416 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900417 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900418 props.Srcs = []string{":" + module.docsName(apiScope)}
419 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900420 props.Libs = module.sdkLibraryProperties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900421 // Unbundled apps will use the prebult one from /prebuilts/sdk
Colin Cross5c877912019-04-18 14:27:12 -0700422 if mctx.Config().UnbundledBuildUsePrebuiltSdks() {
Colin Cross2c77ceb2019-01-21 11:56:21 -0800423 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
424 }
Jiyong Park82484c02018-04-23 21:41:26 +0900425 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900426 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
427 props.System_modules = module.Library.Module.deviceProperties.System_modules
428 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
429 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
430 props.Java_version = module.Library.Module.properties.Java_version
431 if module.Library.Module.deviceProperties.Compile_dex != nil {
432 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900433 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900434
435 if module.SocSpecific() {
436 props.Soc_specific = proptools.BoolPtr(true)
437 } else if module.DeviceSpecific() {
438 props.Device_specific = proptools.BoolPtr(true)
439 } else if module.ProductSpecific() {
440 props.Product_specific = proptools.BoolPtr(true)
441 }
442
Colin Cross9ae1b922018-06-26 17:59:05 -0700443 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900444}
445
446// Creates a droiddoc module that creates stubs source files from the given full source
447// files
Inseob Kimc0907f12019-02-08 21:00:45 +0900448func (module *SdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900449 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900450 Name *string
451 Srcs []string
452 Installable *bool
453 Srcs_lib *string
454 Srcs_lib_whitelist_dirs []string
455 Srcs_lib_whitelist_pkgs []string
456 Libs []string
Paul Duffin11512472019-02-11 15:55:17 +0000457 Arg_files []string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900458 Args *string
459 Api_tag_name *string
460 Api_filename *string
461 Removed_api_filename *string
462 No_standard_libs *bool
463 Java_version *string
464 Merge_annotations_dirs []string
465 Merge_inclusion_annotations_dirs []string
466 Check_api struct {
Inseob Kim38449af2019-02-28 14:24:05 +0900467 Current ApiToCheck
468 Last_released ApiToCheck
469 Ignore_missing_latest_api *bool
Jiyong Park58c518b2018-05-12 22:29:12 +0900470 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900471 Aidl struct {
472 Include_dirs []string
473 Local_include_dirs []string
474 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900475 }{}
476
Jiyong Parkdf130542018-04-27 16:29:21 +0900477 props.Name = proptools.StringPtr(module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900478 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
479 props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900480 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900481 // A droiddoc module has only one Libs property and doesn't distinguish between
482 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900483 props.Libs = module.Library.Module.properties.Libs
484 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
485 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
486 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
487 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
488 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900489
Sundong Ahn054b19a2018-10-19 13:46:09 +0900490 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
491 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
492
493 droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
494 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
495 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900496 " --hide MissingPermission --hide BroadcastBehavior " +
497 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
498 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900499
Jiyong Parkdf130542018-04-27 16:29:21 +0900500 switch apiScope {
501 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900502 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900503 case apiScopeTest:
504 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900505 }
Paul Duffin11512472019-02-11 15:55:17 +0000506 props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
Jiyong Parkc678ad32018-04-10 13:07:10 +0900507 props.Args = proptools.StringPtr(droiddocArgs)
508
509 // List of APIs identified from the provided source files are created. They are later
510 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
511 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900512 currentApiFileName := "current.txt"
513 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900514 switch apiScope {
515 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900516 currentApiFileName = "system-" + currentApiFileName
517 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900518 case apiScopeTest:
519 currentApiFileName = "test-" + currentApiFileName
520 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900521 }
522 currentApiFileName = path.Join("api", currentApiFileName)
523 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900524 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900525 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900526 props.Api_filename = proptools.StringPtr(currentApiFileName)
527 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
528
Jiyong Park58c518b2018-05-12 22:29:12 +0900529 // check against the not-yet-release API
530 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
531 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900532
533 // check against the latest released API
534 props.Check_api.Last_released.Api_file = proptools.StringPtr(
535 module.latestApiFilegroupName(apiScope))
536 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
537 module.latestRemovedApiFilegroupName(apiScope))
Inseob Kim38449af2019-02-28 14:24:05 +0900538 props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900539 props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
540 props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
541 props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900542
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900543 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900544}
545
Jiyong Parkc678ad32018-04-10 13:07:10 +0900546// Creates the xml file that publicizes the runtime library
Inseob Kimc0907f12019-02-08 21:00:45 +0900547func (module *SdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900548 template := `
549<?xml version="1.0" encoding="utf-8"?>
550<!-- Copyright (C) 2018 The Android Open Source Project
551
552 Licensed under the Apache License, Version 2.0 (the "License");
553 you may not use this file except in compliance with the License.
554 You may obtain a copy of the License at
555
556 http://www.apache.org/licenses/LICENSE-2.0
557
558 Unless required by applicable law or agreed to in writing, software
559 distributed under the License is distributed on an "AS IS" BASIS,
560 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
561 See the License for the specific language governing permissions and
562 limitations under the License.
563-->
564
565<permissions>
566 <library name="%s" file="%s"/>
567</permissions>
568`
569 // genrule to generate the xml file content from the template above
570 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
571 // in the ninja file. Do we need to have an external tool for this?
572 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
573 genruleProps := struct {
574 Name *string
575 Cmd *string
576 Out []string
577 }{}
578 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
579 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
580 genruleProps.Out = []string{module.xmlFileName()}
581 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
582
583 // creates a prebuilt_etc module to actually place the xml file under
584 // <partition>/etc/permissions
585 etcProps := struct {
586 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900587 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900588 Sub_dir *string
589 Soc_specific *bool
590 Device_specific *bool
591 Product_specific *bool
592 }{}
593 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900594 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900595 etcProps.Sub_dir = proptools.StringPtr("permissions")
596 if module.SocSpecific() {
597 etcProps.Soc_specific = proptools.BoolPtr(true)
598 } else if module.DeviceSpecific() {
599 etcProps.Device_specific = proptools.BoolPtr(true)
600 } else if module.ProductSpecific() {
601 etcProps.Product_specific = proptools.BoolPtr(true)
602 }
603 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
604}
605
Inseob Kimc0907f12019-02-08 21:00:45 +0900606func (module *SdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900607 var api, v string
608 if sdkVersion == "" {
609 api = "system"
610 v = "current"
611 } else if strings.Contains(sdkVersion, "_") {
612 t := strings.Split(sdkVersion, "_")
613 api = t[0]
614 v = t[1]
Jiyong Parkc678ad32018-04-10 13:07:10 +0900615 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900616 api = "public"
617 v = sdkVersion
618 }
619 dir := filepath.Join("prebuilts", "sdk", v, api)
620 jar := filepath.Join(dir, module.BaseModuleName()+".jar")
621 jarPath := android.ExistentPathForSource(ctx, jar)
Sundong Ahnae418ac2019-02-28 15:01:28 +0900622 if !jarPath.Valid() {
623 ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", v, jar)
624 return nil
625 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900626 return android.Paths{jarPath.Path()}
627}
628
629// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900630func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900631 // This module is just a wrapper for the stubs.
Colin Cross5c877912019-04-18 14:27:12 -0700632 if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900633 return module.PrebuiltJars(ctx, sdkVersion)
634 } else {
635 if strings.HasPrefix(sdkVersion, "system_") {
636 return module.systemApiStubsPath
637 } else if sdkVersion == "" {
638 return module.Library.HeaderJars()
639 } else {
640 return module.publicApiStubsPath
641 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900642 }
643}
644
Sundong Ahn241cd372018-07-13 16:16:44 +0900645// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900646func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn241cd372018-07-13 16:16:44 +0900647 // This module is just a wrapper for the stubs.
Colin Cross5c877912019-04-18 14:27:12 -0700648 if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900649 return module.PrebuiltJars(ctx, sdkVersion)
Sundong Ahn241cd372018-07-13 16:16:44 +0900650 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900651 if strings.HasPrefix(sdkVersion, "system_") {
652 return module.systemApiStubsImplPath
653 } else if sdkVersion == "" {
654 return module.Library.ImplementationJars()
655 } else {
656 return module.publicApiStubsImplPath
657 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900658 }
659}
660
Sundong Ahna4a385f2019-05-13 15:02:50 +0900661func (module *SdkLibrary) SetNoDist() {
662 module.sdkLibraryProperties.No_dist = proptools.BoolPtr(true)
663}
664
Colin Cross571cccf2019-02-04 11:22:08 -0800665var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
666
Jiyong Park82484c02018-04-23 21:41:26 +0900667func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -0800668 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +0900669 return &[]string{}
670 }).(*[]string)
671}
672
Jiyong Parkc678ad32018-04-10 13:07:10 +0900673// For a java_sdk_library module, create internal modules for stubs, docs,
674// runtime libs and xml file. If requested, the stubs and docs are created twice
675// once for public API level and once for system API level
Inseob Kimc0907f12019-02-08 21:00:45 +0900676func SdkLibraryMutator(mctx android.TopDownMutatorContext) {
677 if module, ok := mctx.Module().(*SdkLibrary); ok {
678 module.createInternalModules(mctx)
679 } else if module, ok := mctx.Module().(syspropLibraryInterface); ok {
680 module.SyspropJavaModule().createInternalModules(mctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900681 }
682}
683
Inseob Kimc0907f12019-02-08 21:00:45 +0900684func (module *SdkLibrary) createInternalModules(mctx android.TopDownMutatorContext) {
Inseob Kim6e93ac92019-03-21 17:43:49 +0900685 if len(module.Library.Module.properties.Srcs) == 0 {
Inseob Kimc0907f12019-02-08 21:00:45 +0900686 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
687 }
688
Inseob Kim6e93ac92019-03-21 17:43:49 +0900689 if len(module.sdkLibraryProperties.Api_packages) == 0 {
Inseob Kimc0907f12019-02-08 21:00:45 +0900690 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
691 }
Inseob Kim8098faa2019-03-18 10:19:51 +0900692
693 missing_current_api := false
694
695 for _, scope := range []string{"", "system-", "test-"} {
696 for _, api := range []string{"current.txt", "removed.txt"} {
697 path := path.Join(mctx.ModuleDir(), "api", scope+api)
698 p := android.ExistentPathForSource(mctx, path)
699 if !p.Valid() {
700 mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
701 missing_current_api = true
702 }
703 }
704 }
705
706 if missing_current_api {
707 script := "build/soong/scripts/gen-java-current-api-files.sh"
708 p := android.ExistentPathForSource(mctx, script)
709
710 if !p.Valid() {
711 panic(fmt.Sprintf("script file %s doesn't exist", script))
712 }
713
714 mctx.ModuleErrorf("One or more current api files are missing. "+
715 "You can update them by:\n"+
716 "%s %q && m update-api", script, mctx.ModuleDir())
717 return
718 }
719
Inseob Kimc0907f12019-02-08 21:00:45 +0900720 // for public API stubs
721 module.createStubsLibrary(mctx, apiScopePublic)
722 module.createDocs(mctx, apiScopePublic)
723
724 if !Bool(module.properties.No_standard_libs) {
725 // for system API stubs
726 module.createStubsLibrary(mctx, apiScopeSystem)
727 module.createDocs(mctx, apiScopeSystem)
728
729 // for test API stubs
730 module.createStubsLibrary(mctx, apiScopeTest)
731 module.createDocs(mctx, apiScopeTest)
732
733 // for runtime
734 module.createXmlFile(mctx)
735 }
736
737 // record java_sdk_library modules so that they are exported to make
738 javaSdkLibraries := javaSdkLibraries(mctx.Config())
739 javaSdkLibrariesLock.Lock()
740 defer javaSdkLibrariesLock.Unlock()
741 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
742}
743
744func (module *SdkLibrary) InitSdkLibraryProperties() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900745 module.AddProperties(
746 &module.sdkLibraryProperties,
747 &module.Library.Module.properties,
748 &module.Library.Module.dexpreoptProperties,
749 &module.Library.Module.deviceProperties,
750 &module.Library.Module.protoProperties,
751 )
752
753 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
754 module.Library.Module.deviceProperties.IsSDKLibrary = true
Inseob Kimc0907f12019-02-08 21:00:45 +0900755}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900756
Inseob Kimc0907f12019-02-08 21:00:45 +0900757func SdkLibraryFactory() android.Module {
758 module := &SdkLibrary{}
759 module.InitSdkLibraryProperties()
Sundong Ahn054b19a2018-10-19 13:46:09 +0900760 InitJavaModule(module, android.HostAndDeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900761 return module
762}