blob: 974131cf9043c34dcad77551cfb43bc1981eade0 [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 Parkc678ad32018-04-10 13:07:10 +0900165 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700166 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
Colin Cross42d48b72018-08-29 14:10:52 -0700167 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900168
169 if !Bool(module.properties.No_standard_libs) {
170 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
171 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
172 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
173 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
174 }
175
176 module.Library.deps(ctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900177}
178
Inseob Kimc0907f12019-02-08 21:00:45 +0900179func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900180 module.Library.GenerateAndroidBuildActions(ctx)
181
Sundong Ahn57368eb2018-07-06 11:20:23 +0900182 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900183 // When this java_sdk_library is dependened from others via "libs" property,
184 // the recorded paths will be returned depending on the link type of the caller.
185 ctx.VisitDirectDeps(func(to android.Module) {
186 otherName := ctx.OtherModuleName(to)
187 tag := ctx.OtherModuleDependencyTag(to)
188
Sundong Ahn57368eb2018-07-06 11:20:23 +0900189 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900190 switch tag {
191 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900192 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900193 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900194 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900195 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900196 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900197 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900198 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900199 module.testApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900200 }
201 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900202 if doc, ok := to.(ApiFilePath); ok {
203 switch tag {
204 case publicApiFileTag:
205 module.publicApiFilePath = doc.ApiFilePath()
206 case systemApiFileTag:
207 module.systemApiFilePath = doc.ApiFilePath()
208 case testApiFileTag:
209 module.testApiFilePath = doc.ApiFilePath()
210 default:
211 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
212 }
213 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900214 })
215}
216
Inseob Kimc0907f12019-02-08 21:00:45 +0900217func (module *SdkLibrary) AndroidMk() android.AndroidMkData {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900218 data := module.Library.AndroidMk()
219 data.Required = append(data.Required, module.xmlFileName())
220
221 data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
222 android.WriteAndroidMkData(w, data)
223
224 module.Library.AndroidMkHostDex(w, name, data)
Sundong Ahna4a385f2019-05-13 15:02:50 +0900225 if !Bool(module.sdkLibraryProperties.No_dist) {
226 // Create a phony module that installs the impl library, for the case when this lib is
227 // in PRODUCT_PACKAGES.
228 owner := module.ModuleBase.Owner()
229 if owner == "" {
230 if Bool(module.sdkLibraryProperties.Core_lib) {
231 owner = "core"
232 } else {
233 owner = "android"
234 }
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900235 }
Sundong Ahna4a385f2019-05-13 15:02:50 +0900236 // Create dist rules to install the stubs libs to the dist dir
237 if len(module.publicApiStubsPath) == 1 {
238 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
239 module.publicApiStubsImplPath.Strings()[0]+
240 ":"+path.Join("apistubs", owner, "public",
241 module.BaseModuleName()+".jar")+")")
242 }
243 if len(module.systemApiStubsPath) == 1 {
244 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
245 module.systemApiStubsImplPath.Strings()[0]+
246 ":"+path.Join("apistubs", owner, "system",
247 module.BaseModuleName()+".jar")+")")
248 }
249 if len(module.testApiStubsPath) == 1 {
250 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
251 module.testApiStubsImplPath.Strings()[0]+
252 ":"+path.Join("apistubs", owner, "test",
253 module.BaseModuleName()+".jar")+")")
254 }
255 if module.publicApiFilePath != nil {
256 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
257 module.publicApiFilePath.String()+
258 ":"+path.Join("apistubs", owner, "public", "api",
259 module.BaseModuleName()+".txt")+")")
260 }
261 if module.systemApiFilePath != nil {
262 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
263 module.systemApiFilePath.String()+
264 ":"+path.Join("apistubs", owner, "system", "api",
265 module.BaseModuleName()+".txt")+")")
266 }
267 if module.testApiFilePath != nil {
268 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
269 module.testApiFilePath.String()+
270 ":"+path.Join("apistubs", owner, "test", "api",
271 module.BaseModuleName()+".txt")+")")
272 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900273 }
Jiyong Park82484c02018-04-23 21:41:26 +0900274 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900275 return data
Jiyong Park82484c02018-04-23 21:41:26 +0900276}
277
Jiyong Parkc678ad32018-04-10 13:07:10 +0900278// Module name of the stubs library
Inseob Kimc0907f12019-02-08 21:00:45 +0900279func (module *SdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900280 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900281 switch apiScope {
282 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900283 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900284 case apiScopeTest:
285 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900286 }
287 return stubsName
288}
289
290// Module name of the docs
Inseob Kimc0907f12019-02-08 21:00:45 +0900291func (module *SdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900292 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900293 switch apiScope {
294 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900295 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900296 case apiScopeTest:
297 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900298 }
299 return docsName
300}
301
302// Module name of the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900303func (module *SdkLibrary) implName() string {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900304 return module.BaseModuleName()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900305}
306
307// File path to the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900308func (module *SdkLibrary) implPath() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900309 partition := "system"
310 if module.SocSpecific() {
311 partition = "vendor"
312 } else if module.DeviceSpecific() {
313 partition = "odm"
314 } else if module.ProductSpecific() {
315 partition = "product"
316 }
317 return "/" + partition + "/framework/" + module.implName() + ".jar"
318}
319
320// Module name of the XML file for the lib
Inseob Kimc0907f12019-02-08 21:00:45 +0900321func (module *SdkLibrary) xmlFileName() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900322 return module.BaseModuleName() + sdkXmlFileSuffix
323}
324
325// SDK version that the stubs library is built against. Note that this is always
326// *current. Older stubs library built with a numberd SDK version is created from
327// the prebuilt jar.
Inseob Kimc0907f12019-02-08 21:00:45 +0900328func (module *SdkLibrary) sdkVersion(apiScope apiScope) string {
Jiyong Parkdf130542018-04-27 16:29:21 +0900329 switch apiScope {
330 case apiScopePublic:
331 return "current"
332 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900333 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900334 case apiScopeTest:
335 return "test_current"
336 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900337 return "current"
338 }
339}
340
341// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
342// api file for the current source
343// TODO: remove this when apicheck is done in soong
Inseob Kimc0907f12019-02-08 21:00:45 +0900344func (module *SdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900345 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900346 switch apiScope {
347 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900348 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900349 case apiScopeTest:
350 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900351 }
352 return apiTagName
353}
354
Inseob Kimc0907f12019-02-08 21:00:45 +0900355func (module *SdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
Jiyong Park58c518b2018-05-12 22:29:12 +0900356 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900357 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900358 case apiScopePublic:
359 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900360 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900361 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900362 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900363 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900364 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900365 name = name + ".latest"
366 return name
367}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900368
Inseob Kimc0907f12019-02-08 21:00:45 +0900369func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
Jiyong Park58c518b2018-05-12 22:29:12 +0900370 name := ":" + module.BaseModuleName() + "-removed.api."
371 switch apiScope {
372 case apiScopePublic:
373 name = name + "public"
374 case apiScopeSystem:
375 name = name + "system"
376 case apiScopeTest:
377 name = name + "test"
378 }
379 name = name + ".latest"
380 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900381}
382
383// Creates a static java library that has API stubs
Inseob Kimc0907f12019-02-08 21:00:45 +0900384func (module *SdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900385 props := struct {
386 Name *string
387 Srcs []string
388 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900389 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900390 Soc_specific *bool
391 Device_specific *bool
392 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900393 Compile_dex *bool
Sundong Ahn054b19a2018-10-19 13:46:09 +0900394 No_standard_libs *bool
395 System_modules *string
396 Java_version *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900397 Product_variables struct {
398 Unbundled_build struct {
399 Enabled *bool
400 }
Jiyong Park82484c02018-04-23 21:41:26 +0900401 Pdk struct {
402 Enabled *bool
403 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900404 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900405 Openjdk9 struct {
406 Srcs []string
407 Javacflags []string
408 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900409 }{}
410
Jiyong Parkdf130542018-04-27 16:29:21 +0900411 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900412 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900413 props.Srcs = []string{":" + module.docsName(apiScope)}
414 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900415 props.Libs = module.sdkLibraryProperties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900416 // Unbundled apps will use the prebult one from /prebuilts/sdk
Colin Cross5c877912019-04-18 14:27:12 -0700417 if mctx.Config().UnbundledBuildUsePrebuiltSdks() {
Colin Cross2c77ceb2019-01-21 11:56:21 -0800418 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
419 }
Jiyong Park82484c02018-04-23 21:41:26 +0900420 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900421 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
422 props.System_modules = module.Library.Module.deviceProperties.System_modules
423 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
424 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
425 props.Java_version = module.Library.Module.properties.Java_version
426 if module.Library.Module.deviceProperties.Compile_dex != nil {
427 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900428 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900429
430 if module.SocSpecific() {
431 props.Soc_specific = proptools.BoolPtr(true)
432 } else if module.DeviceSpecific() {
433 props.Device_specific = proptools.BoolPtr(true)
434 } else if module.ProductSpecific() {
435 props.Product_specific = proptools.BoolPtr(true)
436 }
437
Colin Cross9ae1b922018-06-26 17:59:05 -0700438 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900439}
440
441// Creates a droiddoc module that creates stubs source files from the given full source
442// files
Inseob Kimc0907f12019-02-08 21:00:45 +0900443func (module *SdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900444 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900445 Name *string
446 Srcs []string
447 Installable *bool
448 Srcs_lib *string
449 Srcs_lib_whitelist_dirs []string
450 Srcs_lib_whitelist_pkgs []string
451 Libs []string
Paul Duffin11512472019-02-11 15:55:17 +0000452 Arg_files []string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900453 Args *string
454 Api_tag_name *string
455 Api_filename *string
456 Removed_api_filename *string
457 No_standard_libs *bool
458 Java_version *string
459 Merge_annotations_dirs []string
460 Merge_inclusion_annotations_dirs []string
461 Check_api struct {
Inseob Kim38449af2019-02-28 14:24:05 +0900462 Current ApiToCheck
463 Last_released ApiToCheck
464 Ignore_missing_latest_api *bool
Jiyong Park58c518b2018-05-12 22:29:12 +0900465 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900466 Aidl struct {
467 Include_dirs []string
468 Local_include_dirs []string
469 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900470 }{}
471
Jiyong Parkdf130542018-04-27 16:29:21 +0900472 props.Name = proptools.StringPtr(module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900473 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
474 props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900475 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900476 // A droiddoc module has only one Libs property and doesn't distinguish between
477 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900478 props.Libs = module.Library.Module.properties.Libs
479 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
480 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
481 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
482 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
483 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900484
Sundong Ahn054b19a2018-10-19 13:46:09 +0900485 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
486 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
487
488 droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
489 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
490 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900491 " --hide MissingPermission --hide BroadcastBehavior " +
492 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
493 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900494
Jiyong Parkdf130542018-04-27 16:29:21 +0900495 switch apiScope {
496 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900497 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900498 case apiScopeTest:
499 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900500 }
Paul Duffin11512472019-02-11 15:55:17 +0000501 props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
Jiyong Parkc678ad32018-04-10 13:07:10 +0900502 props.Args = proptools.StringPtr(droiddocArgs)
503
504 // List of APIs identified from the provided source files are created. They are later
505 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
506 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900507 currentApiFileName := "current.txt"
508 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900509 switch apiScope {
510 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900511 currentApiFileName = "system-" + currentApiFileName
512 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900513 case apiScopeTest:
514 currentApiFileName = "test-" + currentApiFileName
515 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900516 }
517 currentApiFileName = path.Join("api", currentApiFileName)
518 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900519 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900520 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900521 props.Api_filename = proptools.StringPtr(currentApiFileName)
522 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
523
Jiyong Park58c518b2018-05-12 22:29:12 +0900524 // check against the not-yet-release API
525 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
526 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900527
528 // check against the latest released API
529 props.Check_api.Last_released.Api_file = proptools.StringPtr(
530 module.latestApiFilegroupName(apiScope))
531 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
532 module.latestRemovedApiFilegroupName(apiScope))
Inseob Kim38449af2019-02-28 14:24:05 +0900533 props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900534 props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
535 props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
536 props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900537
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900538 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900539}
540
Jiyong Parkc678ad32018-04-10 13:07:10 +0900541// Creates the xml file that publicizes the runtime library
Inseob Kimc0907f12019-02-08 21:00:45 +0900542func (module *SdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900543 template := `
544<?xml version="1.0" encoding="utf-8"?>
545<!-- Copyright (C) 2018 The Android Open Source Project
546
547 Licensed under the Apache License, Version 2.0 (the "License");
548 you may not use this file except in compliance with the License.
549 You may obtain a copy of the License at
550
551 http://www.apache.org/licenses/LICENSE-2.0
552
553 Unless required by applicable law or agreed to in writing, software
554 distributed under the License is distributed on an "AS IS" BASIS,
555 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
556 See the License for the specific language governing permissions and
557 limitations under the License.
558-->
559
560<permissions>
561 <library name="%s" file="%s"/>
562</permissions>
563`
564 // genrule to generate the xml file content from the template above
565 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
566 // in the ninja file. Do we need to have an external tool for this?
567 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
568 genruleProps := struct {
569 Name *string
570 Cmd *string
571 Out []string
572 }{}
573 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
574 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
575 genruleProps.Out = []string{module.xmlFileName()}
576 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
577
578 // creates a prebuilt_etc module to actually place the xml file under
579 // <partition>/etc/permissions
580 etcProps := struct {
581 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900582 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900583 Sub_dir *string
584 Soc_specific *bool
585 Device_specific *bool
586 Product_specific *bool
587 }{}
588 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900589 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900590 etcProps.Sub_dir = proptools.StringPtr("permissions")
591 if module.SocSpecific() {
592 etcProps.Soc_specific = proptools.BoolPtr(true)
593 } else if module.DeviceSpecific() {
594 etcProps.Device_specific = proptools.BoolPtr(true)
595 } else if module.ProductSpecific() {
596 etcProps.Product_specific = proptools.BoolPtr(true)
597 }
598 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
599}
600
Inseob Kimc0907f12019-02-08 21:00:45 +0900601func (module *SdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900602 var api, v string
603 if sdkVersion == "" {
604 api = "system"
605 v = "current"
606 } else if strings.Contains(sdkVersion, "_") {
607 t := strings.Split(sdkVersion, "_")
608 api = t[0]
609 v = t[1]
Jiyong Parkc678ad32018-04-10 13:07:10 +0900610 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900611 api = "public"
612 v = sdkVersion
613 }
614 dir := filepath.Join("prebuilts", "sdk", v, api)
615 jar := filepath.Join(dir, module.BaseModuleName()+".jar")
616 jarPath := android.ExistentPathForSource(ctx, jar)
Sundong Ahnae418ac2019-02-28 15:01:28 +0900617 if !jarPath.Valid() {
618 ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", v, jar)
619 return nil
620 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900621 return android.Paths{jarPath.Path()}
622}
623
624// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900625func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900626 // This module is just a wrapper for the stubs.
Colin Cross5c877912019-04-18 14:27:12 -0700627 if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900628 return module.PrebuiltJars(ctx, sdkVersion)
629 } else {
630 if strings.HasPrefix(sdkVersion, "system_") {
631 return module.systemApiStubsPath
632 } else if sdkVersion == "" {
633 return module.Library.HeaderJars()
634 } else {
635 return module.publicApiStubsPath
636 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900637 }
638}
639
Sundong Ahn241cd372018-07-13 16:16:44 +0900640// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900641func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn241cd372018-07-13 16:16:44 +0900642 // This module is just a wrapper for the stubs.
Colin Cross5c877912019-04-18 14:27:12 -0700643 if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900644 return module.PrebuiltJars(ctx, sdkVersion)
Sundong Ahn241cd372018-07-13 16:16:44 +0900645 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900646 if strings.HasPrefix(sdkVersion, "system_") {
647 return module.systemApiStubsImplPath
648 } else if sdkVersion == "" {
649 return module.Library.ImplementationJars()
650 } else {
651 return module.publicApiStubsImplPath
652 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900653 }
654}
655
Sundong Ahna4a385f2019-05-13 15:02:50 +0900656func (module *SdkLibrary) SetNoDist() {
657 module.sdkLibraryProperties.No_dist = proptools.BoolPtr(true)
658}
659
Colin Cross571cccf2019-02-04 11:22:08 -0800660var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
661
Jiyong Park82484c02018-04-23 21:41:26 +0900662func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -0800663 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +0900664 return &[]string{}
665 }).(*[]string)
666}
667
Jiyong Parkc678ad32018-04-10 13:07:10 +0900668// For a java_sdk_library module, create internal modules for stubs, docs,
669// runtime libs and xml file. If requested, the stubs and docs are created twice
670// once for public API level and once for system API level
Inseob Kimc0907f12019-02-08 21:00:45 +0900671func SdkLibraryMutator(mctx android.TopDownMutatorContext) {
672 if module, ok := mctx.Module().(*SdkLibrary); ok {
673 module.createInternalModules(mctx)
674 } else if module, ok := mctx.Module().(syspropLibraryInterface); ok {
675 module.SyspropJavaModule().createInternalModules(mctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900676 }
677}
678
Inseob Kimc0907f12019-02-08 21:00:45 +0900679func (module *SdkLibrary) createInternalModules(mctx android.TopDownMutatorContext) {
Inseob Kim6e93ac92019-03-21 17:43:49 +0900680 if len(module.Library.Module.properties.Srcs) == 0 {
Inseob Kimc0907f12019-02-08 21:00:45 +0900681 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
682 }
683
Inseob Kim6e93ac92019-03-21 17:43:49 +0900684 if len(module.sdkLibraryProperties.Api_packages) == 0 {
Inseob Kimc0907f12019-02-08 21:00:45 +0900685 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
686 }
Inseob Kim8098faa2019-03-18 10:19:51 +0900687
688 missing_current_api := false
689
690 for _, scope := range []string{"", "system-", "test-"} {
691 for _, api := range []string{"current.txt", "removed.txt"} {
692 path := path.Join(mctx.ModuleDir(), "api", scope+api)
693 p := android.ExistentPathForSource(mctx, path)
694 if !p.Valid() {
695 mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
696 missing_current_api = true
697 }
698 }
699 }
700
701 if missing_current_api {
702 script := "build/soong/scripts/gen-java-current-api-files.sh"
703 p := android.ExistentPathForSource(mctx, script)
704
705 if !p.Valid() {
706 panic(fmt.Sprintf("script file %s doesn't exist", script))
707 }
708
709 mctx.ModuleErrorf("One or more current api files are missing. "+
710 "You can update them by:\n"+
711 "%s %q && m update-api", script, mctx.ModuleDir())
712 return
713 }
714
Inseob Kimc0907f12019-02-08 21:00:45 +0900715 // for public API stubs
716 module.createStubsLibrary(mctx, apiScopePublic)
717 module.createDocs(mctx, apiScopePublic)
718
719 if !Bool(module.properties.No_standard_libs) {
720 // for system API stubs
721 module.createStubsLibrary(mctx, apiScopeSystem)
722 module.createDocs(mctx, apiScopeSystem)
723
724 // for test API stubs
725 module.createStubsLibrary(mctx, apiScopeTest)
726 module.createDocs(mctx, apiScopeTest)
727
728 // for runtime
729 module.createXmlFile(mctx)
730 }
731
732 // record java_sdk_library modules so that they are exported to make
733 javaSdkLibraries := javaSdkLibraries(mctx.Config())
734 javaSdkLibrariesLock.Lock()
735 defer javaSdkLibrariesLock.Unlock()
736 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
737}
738
739func (module *SdkLibrary) InitSdkLibraryProperties() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900740 module.AddProperties(
741 &module.sdkLibraryProperties,
742 &module.Library.Module.properties,
743 &module.Library.Module.dexpreoptProperties,
744 &module.Library.Module.deviceProperties,
745 &module.Library.Module.protoProperties,
746 )
747
748 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
749 module.Library.Module.deviceProperties.IsSDKLibrary = true
Inseob Kimc0907f12019-02-08 21:00:45 +0900750}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900751
Inseob Kimc0907f12019-02-08 21:00:45 +0900752func SdkLibraryFactory() android.Module {
753 module := &SdkLibrary{}
754 module.InitSdkLibraryProperties()
Sundong Ahn054b19a2018-10-19 13:46:09 +0900755 InitJavaModule(module, android.HostAndDeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900756 return module
757}