blob: 85ce533c0af7a114c069534ad107c1ebde7a1694 [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
45var (
46 publicApiStubsTag = dependencyTag{name: "public"}
47 systemApiStubsTag = dependencyTag{name: "system"}
Jiyong Parkdf130542018-04-27 16:29:21 +090048 testApiStubsTag = dependencyTag{name: "test"}
Sundong Ahn20e998b2018-07-24 11:19:26 +090049 publicApiFileTag = dependencyTag{name: "publicApi"}
50 systemApiFileTag = dependencyTag{name: "systemApi"}
51 testApiFileTag = dependencyTag{name: "testApi"}
Jiyong Parkdf130542018-04-27 16:29:21 +090052)
53
54type apiScope int
55
56const (
57 apiScopePublic apiScope = iota
58 apiScopeSystem
59 apiScopeTest
Jiyong Parkc678ad32018-04-10 13:07:10 +090060)
61
Jiyong Park82484c02018-04-23 21:41:26 +090062var (
63 javaSdkLibrariesLock sync.Mutex
64)
65
Jiyong Parkc678ad32018-04-10 13:07:10 +090066// java_sdk_library is to make a Java library that implements optional platform APIs to apps.
67// It is actually a wrapper of several modules: 1) stubs library that clients are linked against
68// to, 2) droiddoc module that internally generates API stubs source files, 3) the real runtime
69// shared library that implements the APIs, and 4) XML file for adding the runtime lib to the
70// classpath at runtime if requested via <uses-library>.
71//
72// TODO: these are big features that are currently missing
Jiyong Park1be96912018-05-28 18:02:19 +090073// 1) disallowing linking to the runtime shared lib
74// 2) HTML generation
Jiyong Parkc678ad32018-04-10 13:07:10 +090075
76func init() {
77 android.RegisterModuleType("java_sdk_library", sdkLibraryFactory)
78
79 android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
80 ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
81 })
Jiyong Park82484c02018-04-23 21:41:26 +090082
83 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
84 javaSdkLibraries := javaSdkLibraries(ctx.Config())
85 sort.Strings(*javaSdkLibraries)
86 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
87 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090088}
89
90type sdkLibraryProperties struct {
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +090091 // list of optional source files that are part of API but not part of runtime library.
92 Api_srcs []string `android:"arch_variant"`
93
Sundong Ahnf043cf62018-06-25 16:04:37 +090094 // List of Java libraries that will be in the classpath when building stubs
95 Stub_only_libs []string `android:"arch_variant"`
96
Jiyong Parkc678ad32018-04-10 13:07:10 +090097 // list of package names that will be documented and publicized as API
98 Api_packages []string
99
Jiyong Park5a2c9d72018-05-01 22:25:41 +0900100 // list of package names that must be hidden from the API
101 Hidden_api_packages []string
102
Sundong Ahndd567f92018-07-31 17:19:11 +0900103 // Additional droiddoc options
104 Droiddoc_options []string
105
Sundong Ahnb952ba02019-01-08 16:32:12 +0900106 // the java library (in classpath) for documentation that provides java srcs and srcjars.
107 Srcs_lib *string
108
109 // the base dirs under srcs_lib will be scanned for java srcs.
110 Srcs_lib_whitelist_dirs []string
111
Sundong Ahndd567f92018-07-31 17:19:11 +0900112 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
113 // Defaults to "android.annotation".
114 Srcs_lib_whitelist_pkgs []string
115
Sundong Ahn054b19a2018-10-19 13:46:09 +0900116 // a list of top-level directories containing files to merge qualifier annotations
117 // (i.e. those intended to be included in the stubs written) from.
118 Merge_annotations_dirs []string
119
120 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
121 Merge_inclusion_annotations_dirs []string
122
123 // If set to true, the path of dist files is apistubs/core. Defaults to false.
124 Core_lib *bool
125
Jiyong Parkc678ad32018-04-10 13:07:10 +0900126 // TODO: determines whether to create HTML doc or not
127 //Html_doc *bool
128}
129
130type sdkLibrary struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900131 Library
Jiyong Parkc678ad32018-04-10 13:07:10 +0900132
Sundong Ahn054b19a2018-10-19 13:46:09 +0900133 sdkLibraryProperties sdkLibraryProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900134
135 publicApiStubsPath android.Paths
136 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900137 testApiStubsPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900138
139 publicApiStubsImplPath android.Paths
140 systemApiStubsImplPath android.Paths
141 testApiStubsImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900142
143 publicApiFilePath android.Path
144 systemApiFilePath android.Path
145 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900146}
147
Colin Cross897d2ed2019-02-11 14:03:51 -0800148var _ Dependency = (*sdkLibrary)(nil)
149var _ SdkLibraryDependency = (*sdkLibrary)(nil)
150
Jiyong Parkc678ad32018-04-10 13:07:10 +0900151func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
152 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700153 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
Colin Cross42d48b72018-08-29 14:10:52 -0700154 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900155
156 if !Bool(module.properties.No_standard_libs) {
157 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
158 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
159 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
160 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
161 }
162
163 module.Library.deps(ctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900164}
165
166func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900167 module.Library.GenerateAndroidBuildActions(ctx)
168
Sundong Ahn57368eb2018-07-06 11:20:23 +0900169 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900170 // When this java_sdk_library is dependened from others via "libs" property,
171 // the recorded paths will be returned depending on the link type of the caller.
172 ctx.VisitDirectDeps(func(to android.Module) {
173 otherName := ctx.OtherModuleName(to)
174 tag := ctx.OtherModuleDependencyTag(to)
175
Sundong Ahn57368eb2018-07-06 11:20:23 +0900176 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900177 switch tag {
178 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900179 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900180 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900181 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900182 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900183 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900184 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900185 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900186 module.testApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900187 }
188 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900189 if doc, ok := to.(ApiFilePath); ok {
190 switch tag {
191 case publicApiFileTag:
192 module.publicApiFilePath = doc.ApiFilePath()
193 case systemApiFileTag:
194 module.systemApiFilePath = doc.ApiFilePath()
195 case testApiFileTag:
196 module.testApiFilePath = doc.ApiFilePath()
197 default:
198 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
199 }
200 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900201 })
202}
203
Jiyong Park82484c02018-04-23 21:41:26 +0900204func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900205 data := module.Library.AndroidMk()
206 data.Required = append(data.Required, module.xmlFileName())
207
208 data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
209 android.WriteAndroidMkData(w, data)
210
211 module.Library.AndroidMkHostDex(w, name, data)
212 // Create a phony module that installs the impl library, for the case when this lib is
213 // in PRODUCT_PACKAGES.
214 owner := module.ModuleBase.Owner()
215 if owner == "" {
216 if Bool(module.sdkLibraryProperties.Core_lib) {
217 owner = "core"
218 } else {
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900219 owner = "android"
220 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900221 }
222 // Create dist rules to install the stubs libs to the dist dir
223 if len(module.publicApiStubsPath) == 1 {
224 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
225 module.publicApiStubsImplPath.Strings()[0]+
226 ":"+path.Join("apistubs", owner, "public",
227 module.BaseModuleName()+".jar")+")")
228 }
229 if len(module.systemApiStubsPath) == 1 {
230 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
231 module.systemApiStubsImplPath.Strings()[0]+
232 ":"+path.Join("apistubs", owner, "system",
233 module.BaseModuleName()+".jar")+")")
234 }
235 if len(module.testApiStubsPath) == 1 {
236 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
237 module.testApiStubsImplPath.Strings()[0]+
238 ":"+path.Join("apistubs", owner, "test",
239 module.BaseModuleName()+".jar")+")")
240 }
241 if module.publicApiFilePath != nil {
242 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
243 module.publicApiFilePath.String()+
244 ":"+path.Join("apistubs", owner, "public", "api",
245 module.BaseModuleName()+".txt")+")")
246 }
247 if module.systemApiFilePath != nil {
248 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
249 module.systemApiFilePath.String()+
250 ":"+path.Join("apistubs", owner, "system", "api",
251 module.BaseModuleName()+".txt")+")")
252 }
253 if module.testApiFilePath != nil {
254 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
255 module.testApiFilePath.String()+
256 ":"+path.Join("apistubs", owner, "test", "api",
257 module.BaseModuleName()+".txt")+")")
258 }
Jiyong Park82484c02018-04-23 21:41:26 +0900259 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900260 return data
Jiyong Park82484c02018-04-23 21:41:26 +0900261}
262
Jiyong Parkc678ad32018-04-10 13:07:10 +0900263// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900264func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900265 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900266 switch apiScope {
267 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900268 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900269 case apiScopeTest:
270 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900271 }
272 return stubsName
273}
274
275// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900276func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900277 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900278 switch apiScope {
279 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900280 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900281 case apiScopeTest:
282 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900283 }
284 return docsName
285}
286
287// Module name of the runtime implementation library
288func (module *sdkLibrary) implName() string {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900289 return module.BaseModuleName()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900290}
291
292// File path to the runtime implementation library
293func (module *sdkLibrary) implPath() string {
294 partition := "system"
295 if module.SocSpecific() {
296 partition = "vendor"
297 } else if module.DeviceSpecific() {
298 partition = "odm"
299 } else if module.ProductSpecific() {
300 partition = "product"
301 }
302 return "/" + partition + "/framework/" + module.implName() + ".jar"
303}
304
305// Module name of the XML file for the lib
306func (module *sdkLibrary) xmlFileName() string {
307 return module.BaseModuleName() + sdkXmlFileSuffix
308}
309
310// SDK version that the stubs library is built against. Note that this is always
311// *current. Older stubs library built with a numberd SDK version is created from
312// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900313func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
314 switch apiScope {
315 case apiScopePublic:
316 return "current"
317 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900318 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900319 case apiScopeTest:
320 return "test_current"
321 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900322 return "current"
323 }
324}
325
326// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
327// api file for the current source
328// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900329func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900330 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900331 switch apiScope {
332 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900333 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900334 case apiScopeTest:
335 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900336 }
337 return apiTagName
338}
339
Jiyong Park58c518b2018-05-12 22:29:12 +0900340func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
341 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900342 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900343 case apiScopePublic:
344 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900345 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900346 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900347 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900348 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900349 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900350 name = name + ".latest"
351 return name
352}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900353
Jiyong Park58c518b2018-05-12 22:29:12 +0900354func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
355 name := ":" + module.BaseModuleName() + "-removed.api."
356 switch apiScope {
357 case apiScopePublic:
358 name = name + "public"
359 case apiScopeSystem:
360 name = name + "system"
361 case apiScopeTest:
362 name = name + "test"
363 }
364 name = name + ".latest"
365 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900366}
367
368// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900369func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900370 props := struct {
371 Name *string
372 Srcs []string
373 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900374 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900375 Soc_specific *bool
376 Device_specific *bool
377 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900378 Compile_dex *bool
Sundong Ahn054b19a2018-10-19 13:46:09 +0900379 No_standard_libs *bool
380 System_modules *string
381 Java_version *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900382 Product_variables struct {
383 Unbundled_build struct {
384 Enabled *bool
385 }
Jiyong Park82484c02018-04-23 21:41:26 +0900386 Pdk struct {
387 Enabled *bool
388 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900389 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900390 Openjdk9 struct {
391 Srcs []string
392 Javacflags []string
393 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900394 }{}
395
Jiyong Parkdf130542018-04-27 16:29:21 +0900396 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900397 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900398 props.Srcs = []string{":" + module.docsName(apiScope)}
399 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900400 props.Libs = module.sdkLibraryProperties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900401 // Unbundled apps will use the prebult one from /prebuilts/sdk
Colin Cross2c77ceb2019-01-21 11:56:21 -0800402 if mctx.Config().UnbundledBuildPrebuiltSdks() {
403 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
404 }
Jiyong Park82484c02018-04-23 21:41:26 +0900405 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900406 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
407 props.System_modules = module.Library.Module.deviceProperties.System_modules
408 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
409 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
410 props.Java_version = module.Library.Module.properties.Java_version
411 if module.Library.Module.deviceProperties.Compile_dex != nil {
412 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900413 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900414
415 if module.SocSpecific() {
416 props.Soc_specific = proptools.BoolPtr(true)
417 } else if module.DeviceSpecific() {
418 props.Device_specific = proptools.BoolPtr(true)
419 } else if module.ProductSpecific() {
420 props.Product_specific = proptools.BoolPtr(true)
421 }
422
Colin Cross9ae1b922018-06-26 17:59:05 -0700423 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900424}
425
426// Creates a droiddoc module that creates stubs source files from the given full source
427// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900428func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900429 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900430 Name *string
431 Srcs []string
432 Installable *bool
433 Srcs_lib *string
434 Srcs_lib_whitelist_dirs []string
435 Srcs_lib_whitelist_pkgs []string
436 Libs []string
437 Args *string
438 Api_tag_name *string
439 Api_filename *string
440 Removed_api_filename *string
441 No_standard_libs *bool
442 Java_version *string
443 Merge_annotations_dirs []string
444 Merge_inclusion_annotations_dirs []string
445 Check_api struct {
Jiyong Park58c518b2018-05-12 22:29:12 +0900446 Current ApiToCheck
447 Last_released ApiToCheck
448 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900449 Aidl struct {
450 Include_dirs []string
451 Local_include_dirs []string
452 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900453 }{}
454
Jiyong Parkdf130542018-04-27 16:29:21 +0900455 props.Name = proptools.StringPtr(module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900456 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
457 props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900458 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900459 // A droiddoc module has only one Libs property and doesn't distinguish between
460 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900461 props.Libs = module.Library.Module.properties.Libs
462 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
463 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
464 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
465 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
466 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900467
Sundong Ahn054b19a2018-10-19 13:46:09 +0900468 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
469 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
470
471 droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
472 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
473 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900474 " --hide MissingPermission --hide BroadcastBehavior " +
475 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
476 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900477
Jiyong Parkdf130542018-04-27 16:29:21 +0900478 switch apiScope {
479 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900480 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900481 case apiScopeTest:
482 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900483 }
484 props.Args = proptools.StringPtr(droiddocArgs)
485
486 // List of APIs identified from the provided source files are created. They are later
487 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
488 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900489 currentApiFileName := "current.txt"
490 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900491 switch apiScope {
492 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900493 currentApiFileName = "system-" + currentApiFileName
494 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900495 case apiScopeTest:
496 currentApiFileName = "test-" + currentApiFileName
497 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900498 }
499 currentApiFileName = path.Join("api", currentApiFileName)
500 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900501 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900502 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900503 props.Api_filename = proptools.StringPtr(currentApiFileName)
504 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
505
Jiyong Park58c518b2018-05-12 22:29:12 +0900506 // check against the not-yet-release API
507 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
508 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900509
510 // check against the latest released API
511 props.Check_api.Last_released.Api_file = proptools.StringPtr(
512 module.latestApiFilegroupName(apiScope))
513 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
514 module.latestRemovedApiFilegroupName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900515 props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
516 props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
517 props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900518
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900519 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900520}
521
Jiyong Parkc678ad32018-04-10 13:07:10 +0900522// Creates the xml file that publicizes the runtime library
523func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
524 template := `
525<?xml version="1.0" encoding="utf-8"?>
526<!-- Copyright (C) 2018 The Android Open Source Project
527
528 Licensed under the Apache License, Version 2.0 (the "License");
529 you may not use this file except in compliance with the License.
530 You may obtain a copy of the License at
531
532 http://www.apache.org/licenses/LICENSE-2.0
533
534 Unless required by applicable law or agreed to in writing, software
535 distributed under the License is distributed on an "AS IS" BASIS,
536 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
537 See the License for the specific language governing permissions and
538 limitations under the License.
539-->
540
541<permissions>
542 <library name="%s" file="%s"/>
543</permissions>
544`
545 // genrule to generate the xml file content from the template above
546 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
547 // in the ninja file. Do we need to have an external tool for this?
548 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
549 genruleProps := struct {
550 Name *string
551 Cmd *string
552 Out []string
553 }{}
554 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
555 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
556 genruleProps.Out = []string{module.xmlFileName()}
557 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
558
559 // creates a prebuilt_etc module to actually place the xml file under
560 // <partition>/etc/permissions
561 etcProps := struct {
562 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900563 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900564 Sub_dir *string
565 Soc_specific *bool
566 Device_specific *bool
567 Product_specific *bool
568 }{}
569 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900570 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900571 etcProps.Sub_dir = proptools.StringPtr("permissions")
572 if module.SocSpecific() {
573 etcProps.Soc_specific = proptools.BoolPtr(true)
574 } else if module.DeviceSpecific() {
575 etcProps.Device_specific = proptools.BoolPtr(true)
576 } else if module.ProductSpecific() {
577 etcProps.Product_specific = proptools.BoolPtr(true)
578 }
579 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
580}
581
Sundong Ahn054b19a2018-10-19 13:46:09 +0900582func (module *sdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
583 var api, v string
584 if sdkVersion == "" {
585 api = "system"
586 v = "current"
587 } else if strings.Contains(sdkVersion, "_") {
588 t := strings.Split(sdkVersion, "_")
589 api = t[0]
590 v = t[1]
Jiyong Parkc678ad32018-04-10 13:07:10 +0900591 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900592 api = "public"
593 v = sdkVersion
594 }
595 dir := filepath.Join("prebuilts", "sdk", v, api)
596 jar := filepath.Join(dir, module.BaseModuleName()+".jar")
597 jarPath := android.ExistentPathForSource(ctx, jar)
598 return android.Paths{jarPath.Path()}
599}
600
601// to satisfy SdkLibraryDependency interface
Colin Cross897d2ed2019-02-11 14:03:51 -0800602func (module *sdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900603 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800604 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900605 return module.PrebuiltJars(ctx, sdkVersion)
606 } else {
607 if strings.HasPrefix(sdkVersion, "system_") {
608 return module.systemApiStubsPath
609 } else if sdkVersion == "" {
610 return module.Library.HeaderJars()
611 } else {
612 return module.publicApiStubsPath
613 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900614 }
615}
616
Sundong Ahn241cd372018-07-13 16:16:44 +0900617// to satisfy SdkLibraryDependency interface
Colin Cross897d2ed2019-02-11 14:03:51 -0800618func (module *sdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn241cd372018-07-13 16:16:44 +0900619 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800620 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900621 return module.PrebuiltJars(ctx, sdkVersion)
Sundong Ahn241cd372018-07-13 16:16:44 +0900622 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900623 if strings.HasPrefix(sdkVersion, "system_") {
624 return module.systemApiStubsImplPath
625 } else if sdkVersion == "" {
626 return module.Library.ImplementationJars()
627 } else {
628 return module.publicApiStubsImplPath
629 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900630 }
631}
632
Colin Cross571cccf2019-02-04 11:22:08 -0800633var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
634
Jiyong Park82484c02018-04-23 21:41:26 +0900635func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -0800636 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +0900637 return &[]string{}
638 }).(*[]string)
639}
640
Jiyong Parkc678ad32018-04-10 13:07:10 +0900641// For a java_sdk_library module, create internal modules for stubs, docs,
642// runtime libs and xml file. If requested, the stubs and docs are created twice
643// once for public API level and once for system API level
644func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
645 if module, ok := mctx.Module().(*sdkLibrary); ok {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900646 if module.Library.Module.properties.Srcs == nil {
Anton Hansson8959e142018-04-25 11:56:13 +0100647 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
648 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900649
650 if module.sdkLibraryProperties.Api_packages == nil {
Anton Hansson8959e142018-04-25 11:56:13 +0100651 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
652 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900653 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900654 module.createStubsLibrary(mctx, apiScopePublic)
655 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900656
Sundong Ahn054b19a2018-10-19 13:46:09 +0900657 if !Bool(module.properties.No_standard_libs) {
658 // for system API stubs
659 module.createStubsLibrary(mctx, apiScopeSystem)
660 module.createDocs(mctx, apiScopeSystem)
Jiyong Parkdf130542018-04-27 16:29:21 +0900661
Sundong Ahn054b19a2018-10-19 13:46:09 +0900662 // for test API stubs
663 module.createStubsLibrary(mctx, apiScopeTest)
664 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900665
Sundong Ahn054b19a2018-10-19 13:46:09 +0900666 // for runtime
667 module.createXmlFile(mctx)
668 }
Jiyong Park82484c02018-04-23 21:41:26 +0900669
670 // record java_sdk_library modules so that they are exported to make
671 javaSdkLibraries := javaSdkLibraries(mctx.Config())
672 javaSdkLibrariesLock.Lock()
673 defer javaSdkLibrariesLock.Unlock()
674 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900675 }
676}
677
678func sdkLibraryFactory() android.Module {
679 module := &sdkLibrary{}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900680 module.AddProperties(
681 &module.sdkLibraryProperties,
682 &module.Library.Module.properties,
683 &module.Library.Module.dexpreoptProperties,
684 &module.Library.Module.deviceProperties,
685 &module.Library.Module.protoProperties,
686 )
687
688 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
689 module.Library.Module.deviceProperties.IsSDKLibrary = true
690
691 InitJavaModule(module, android.HostAndDeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900692 return module
693}