blob: d33149b1b825d28f5d733036d303fdc09206707c [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
148func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
149 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700150 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
Colin Cross42d48b72018-08-29 14:10:52 -0700151 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900152
153 if !Bool(module.properties.No_standard_libs) {
154 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
155 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
156 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
157 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
158 }
159
160 module.Library.deps(ctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900161}
162
163func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900164 module.Library.GenerateAndroidBuildActions(ctx)
165
Sundong Ahn57368eb2018-07-06 11:20:23 +0900166 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900167 // When this java_sdk_library is dependened from others via "libs" property,
168 // the recorded paths will be returned depending on the link type of the caller.
169 ctx.VisitDirectDeps(func(to android.Module) {
170 otherName := ctx.OtherModuleName(to)
171 tag := ctx.OtherModuleDependencyTag(to)
172
Sundong Ahn57368eb2018-07-06 11:20:23 +0900173 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900174 switch tag {
175 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900176 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900177 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900178 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900179 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900180 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900181 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900182 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900183 module.testApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900184 }
185 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900186 if doc, ok := to.(ApiFilePath); ok {
187 switch tag {
188 case publicApiFileTag:
189 module.publicApiFilePath = doc.ApiFilePath()
190 case systemApiFileTag:
191 module.systemApiFilePath = doc.ApiFilePath()
192 case testApiFileTag:
193 module.testApiFilePath = doc.ApiFilePath()
194 default:
195 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
196 }
197 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900198 })
199}
200
Jiyong Park82484c02018-04-23 21:41:26 +0900201func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900202 data := module.Library.AndroidMk()
203 data.Required = append(data.Required, module.xmlFileName())
204
205 data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
206 android.WriteAndroidMkData(w, data)
207
208 module.Library.AndroidMkHostDex(w, name, data)
209 // Create a phony module that installs the impl library, for the case when this lib is
210 // in PRODUCT_PACKAGES.
211 owner := module.ModuleBase.Owner()
212 if owner == "" {
213 if Bool(module.sdkLibraryProperties.Core_lib) {
214 owner = "core"
215 } else {
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900216 owner = "android"
217 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900218 }
219 // Create dist rules to install the stubs libs to the dist dir
220 if len(module.publicApiStubsPath) == 1 {
221 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
222 module.publicApiStubsImplPath.Strings()[0]+
223 ":"+path.Join("apistubs", owner, "public",
224 module.BaseModuleName()+".jar")+")")
225 }
226 if len(module.systemApiStubsPath) == 1 {
227 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
228 module.systemApiStubsImplPath.Strings()[0]+
229 ":"+path.Join("apistubs", owner, "system",
230 module.BaseModuleName()+".jar")+")")
231 }
232 if len(module.testApiStubsPath) == 1 {
233 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
234 module.testApiStubsImplPath.Strings()[0]+
235 ":"+path.Join("apistubs", owner, "test",
236 module.BaseModuleName()+".jar")+")")
237 }
238 if module.publicApiFilePath != nil {
239 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
240 module.publicApiFilePath.String()+
241 ":"+path.Join("apistubs", owner, "public", "api",
242 module.BaseModuleName()+".txt")+")")
243 }
244 if module.systemApiFilePath != nil {
245 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
246 module.systemApiFilePath.String()+
247 ":"+path.Join("apistubs", owner, "system", "api",
248 module.BaseModuleName()+".txt")+")")
249 }
250 if module.testApiFilePath != nil {
251 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
252 module.testApiFilePath.String()+
253 ":"+path.Join("apistubs", owner, "test", "api",
254 module.BaseModuleName()+".txt")+")")
255 }
Jiyong Park82484c02018-04-23 21:41:26 +0900256 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900257 return data
Jiyong Park82484c02018-04-23 21:41:26 +0900258}
259
Jiyong Parkc678ad32018-04-10 13:07:10 +0900260// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900261func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900262 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900263 switch apiScope {
264 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900265 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900266 case apiScopeTest:
267 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900268 }
269 return stubsName
270}
271
272// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900273func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900274 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900275 switch apiScope {
276 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900277 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900278 case apiScopeTest:
279 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900280 }
281 return docsName
282}
283
284// Module name of the runtime implementation library
285func (module *sdkLibrary) implName() string {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900286 return module.BaseModuleName()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900287}
288
289// File path to the runtime implementation library
290func (module *sdkLibrary) implPath() string {
291 partition := "system"
292 if module.SocSpecific() {
293 partition = "vendor"
294 } else if module.DeviceSpecific() {
295 partition = "odm"
296 } else if module.ProductSpecific() {
297 partition = "product"
298 }
299 return "/" + partition + "/framework/" + module.implName() + ".jar"
300}
301
302// Module name of the XML file for the lib
303func (module *sdkLibrary) xmlFileName() string {
304 return module.BaseModuleName() + sdkXmlFileSuffix
305}
306
307// SDK version that the stubs library is built against. Note that this is always
308// *current. Older stubs library built with a numberd SDK version is created from
309// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900310func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
311 switch apiScope {
312 case apiScopePublic:
313 return "current"
314 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900315 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900316 case apiScopeTest:
317 return "test_current"
318 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900319 return "current"
320 }
321}
322
323// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
324// api file for the current source
325// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900326func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900327 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900328 switch apiScope {
329 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900330 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900331 case apiScopeTest:
332 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900333 }
334 return apiTagName
335}
336
Jiyong Park58c518b2018-05-12 22:29:12 +0900337func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
338 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900339 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900340 case apiScopePublic:
341 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900342 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900343 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900344 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900345 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900346 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900347 name = name + ".latest"
348 return name
349}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900350
Jiyong Park58c518b2018-05-12 22:29:12 +0900351func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
352 name := ":" + module.BaseModuleName() + "-removed.api."
353 switch apiScope {
354 case apiScopePublic:
355 name = name + "public"
356 case apiScopeSystem:
357 name = name + "system"
358 case apiScopeTest:
359 name = name + "test"
360 }
361 name = name + ".latest"
362 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900363}
364
365// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900366func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900367 props := struct {
368 Name *string
369 Srcs []string
370 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900371 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900372 Soc_specific *bool
373 Device_specific *bool
374 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900375 Compile_dex *bool
Sundong Ahn054b19a2018-10-19 13:46:09 +0900376 No_standard_libs *bool
377 System_modules *string
378 Java_version *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900379 Product_variables struct {
380 Unbundled_build struct {
381 Enabled *bool
382 }
Jiyong Park82484c02018-04-23 21:41:26 +0900383 Pdk struct {
384 Enabled *bool
385 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900386 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900387 Openjdk9 struct {
388 Srcs []string
389 Javacflags []string
390 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900391 }{}
392
Jiyong Parkdf130542018-04-27 16:29:21 +0900393 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900394 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900395 props.Srcs = []string{":" + module.docsName(apiScope)}
396 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900397 props.Libs = module.sdkLibraryProperties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900398 // Unbundled apps will use the prebult one from /prebuilts/sdk
399 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
Jiyong Park82484c02018-04-23 21:41:26 +0900400 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900401 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
402 props.System_modules = module.Library.Module.deviceProperties.System_modules
403 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
404 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
405 props.Java_version = module.Library.Module.properties.Java_version
406 if module.Library.Module.deviceProperties.Compile_dex != nil {
407 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900408 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900409
410 if module.SocSpecific() {
411 props.Soc_specific = proptools.BoolPtr(true)
412 } else if module.DeviceSpecific() {
413 props.Device_specific = proptools.BoolPtr(true)
414 } else if module.ProductSpecific() {
415 props.Product_specific = proptools.BoolPtr(true)
416 }
417
Colin Cross9ae1b922018-06-26 17:59:05 -0700418 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900419}
420
421// Creates a droiddoc module that creates stubs source files from the given full source
422// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900423func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900424 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900425 Name *string
426 Srcs []string
427 Installable *bool
428 Srcs_lib *string
429 Srcs_lib_whitelist_dirs []string
430 Srcs_lib_whitelist_pkgs []string
431 Libs []string
432 Args *string
433 Api_tag_name *string
434 Api_filename *string
435 Removed_api_filename *string
436 No_standard_libs *bool
437 Java_version *string
438 Merge_annotations_dirs []string
439 Merge_inclusion_annotations_dirs []string
440 Check_api struct {
Jiyong Park58c518b2018-05-12 22:29:12 +0900441 Current ApiToCheck
442 Last_released ApiToCheck
443 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900444 Aidl struct {
445 Include_dirs []string
446 Local_include_dirs []string
447 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900448 }{}
449
Jiyong Parkdf130542018-04-27 16:29:21 +0900450 props.Name = proptools.StringPtr(module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900451 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
452 props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900453 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900454 // A droiddoc module has only one Libs property and doesn't distinguish between
455 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900456 props.Libs = module.Library.Module.properties.Libs
457 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
458 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
459 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
460 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
461 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900462
Sundong Ahn054b19a2018-10-19 13:46:09 +0900463 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
464 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
465
466 droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
467 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
468 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900469 " --hide MissingPermission --hide BroadcastBehavior " +
470 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
471 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900472
Jiyong Parkdf130542018-04-27 16:29:21 +0900473 switch apiScope {
474 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900475 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900476 case apiScopeTest:
477 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900478 }
479 props.Args = proptools.StringPtr(droiddocArgs)
480
481 // List of APIs identified from the provided source files are created. They are later
482 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
483 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900484 currentApiFileName := "current.txt"
485 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900486 switch apiScope {
487 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900488 currentApiFileName = "system-" + currentApiFileName
489 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900490 case apiScopeTest:
491 currentApiFileName = "test-" + currentApiFileName
492 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900493 }
494 currentApiFileName = path.Join("api", currentApiFileName)
495 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900496 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900497 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900498 props.Api_filename = proptools.StringPtr(currentApiFileName)
499 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
500
Jiyong Park58c518b2018-05-12 22:29:12 +0900501 // check against the not-yet-release API
502 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
503 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900504
505 // check against the latest released API
506 props.Check_api.Last_released.Api_file = proptools.StringPtr(
507 module.latestApiFilegroupName(apiScope))
508 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
509 module.latestRemovedApiFilegroupName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900510 props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
511 props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
512 props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900513
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900514 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900515}
516
Jiyong Parkc678ad32018-04-10 13:07:10 +0900517// Creates the xml file that publicizes the runtime library
518func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
519 template := `
520<?xml version="1.0" encoding="utf-8"?>
521<!-- Copyright (C) 2018 The Android Open Source Project
522
523 Licensed under the Apache License, Version 2.0 (the "License");
524 you may not use this file except in compliance with the License.
525 You may obtain a copy of the License at
526
527 http://www.apache.org/licenses/LICENSE-2.0
528
529 Unless required by applicable law or agreed to in writing, software
530 distributed under the License is distributed on an "AS IS" BASIS,
531 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
532 See the License for the specific language governing permissions and
533 limitations under the License.
534-->
535
536<permissions>
537 <library name="%s" file="%s"/>
538</permissions>
539`
540 // genrule to generate the xml file content from the template above
541 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
542 // in the ninja file. Do we need to have an external tool for this?
543 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
544 genruleProps := struct {
545 Name *string
546 Cmd *string
547 Out []string
548 }{}
549 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
550 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
551 genruleProps.Out = []string{module.xmlFileName()}
552 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
553
554 // creates a prebuilt_etc module to actually place the xml file under
555 // <partition>/etc/permissions
556 etcProps := struct {
557 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900558 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900559 Sub_dir *string
560 Soc_specific *bool
561 Device_specific *bool
562 Product_specific *bool
563 }{}
564 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900565 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900566 etcProps.Sub_dir = proptools.StringPtr("permissions")
567 if module.SocSpecific() {
568 etcProps.Soc_specific = proptools.BoolPtr(true)
569 } else if module.DeviceSpecific() {
570 etcProps.Device_specific = proptools.BoolPtr(true)
571 } else if module.ProductSpecific() {
572 etcProps.Product_specific = proptools.BoolPtr(true)
573 }
574 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
575}
576
Sundong Ahn054b19a2018-10-19 13:46:09 +0900577func (module *sdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
578 var api, v string
579 if sdkVersion == "" {
580 api = "system"
581 v = "current"
582 } else if strings.Contains(sdkVersion, "_") {
583 t := strings.Split(sdkVersion, "_")
584 api = t[0]
585 v = t[1]
Jiyong Parkc678ad32018-04-10 13:07:10 +0900586 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900587 api = "public"
588 v = sdkVersion
589 }
590 dir := filepath.Join("prebuilts", "sdk", v, api)
591 jar := filepath.Join(dir, module.BaseModuleName()+".jar")
592 jarPath := android.ExistentPathForSource(ctx, jar)
593 return android.Paths{jarPath.Path()}
594}
595
596// to satisfy SdkLibraryDependency interface
597func (module *sdkLibrary) HeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
598 // This module is just a wrapper for the stubs.
599 if ctx.Config().UnbundledBuild() {
600 return module.PrebuiltJars(ctx, sdkVersion)
601 } else {
602 if strings.HasPrefix(sdkVersion, "system_") {
603 return module.systemApiStubsPath
604 } else if sdkVersion == "" {
605 return module.Library.HeaderJars()
606 } else {
607 return module.publicApiStubsPath
608 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900609 }
610}
611
Sundong Ahn241cd372018-07-13 16:16:44 +0900612// to satisfy SdkLibraryDependency interface
Sundong Ahn054b19a2018-10-19 13:46:09 +0900613func (module *sdkLibrary) ImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn241cd372018-07-13 16:16:44 +0900614 // This module is just a wrapper for the stubs.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900615 if ctx.Config().UnbundledBuild() {
616 return module.PrebuiltJars(ctx, sdkVersion)
Sundong Ahn241cd372018-07-13 16:16:44 +0900617 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900618 if strings.HasPrefix(sdkVersion, "system_") {
619 return module.systemApiStubsImplPath
620 } else if sdkVersion == "" {
621 return module.Library.ImplementationJars()
622 } else {
623 return module.publicApiStubsImplPath
624 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900625 }
626}
627
Jiyong Park82484c02018-04-23 21:41:26 +0900628func javaSdkLibraries(config android.Config) *[]string {
629 return config.Once("javaSdkLibraries", func() interface{} {
630 return &[]string{}
631 }).(*[]string)
632}
633
Jiyong Parkc678ad32018-04-10 13:07:10 +0900634// For a java_sdk_library module, create internal modules for stubs, docs,
635// runtime libs and xml file. If requested, the stubs and docs are created twice
636// once for public API level and once for system API level
637func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
638 if module, ok := mctx.Module().(*sdkLibrary); ok {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900639 if module.Library.Module.properties.Srcs == nil {
Anton Hansson8959e142018-04-25 11:56:13 +0100640 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
641 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900642
643 if module.sdkLibraryProperties.Api_packages == nil {
Anton Hansson8959e142018-04-25 11:56:13 +0100644 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
645 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900646 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900647 module.createStubsLibrary(mctx, apiScopePublic)
648 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900649
Sundong Ahn054b19a2018-10-19 13:46:09 +0900650 if !Bool(module.properties.No_standard_libs) {
651 // for system API stubs
652 module.createStubsLibrary(mctx, apiScopeSystem)
653 module.createDocs(mctx, apiScopeSystem)
Jiyong Parkdf130542018-04-27 16:29:21 +0900654
Sundong Ahn054b19a2018-10-19 13:46:09 +0900655 // for test API stubs
656 module.createStubsLibrary(mctx, apiScopeTest)
657 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900658
Sundong Ahn054b19a2018-10-19 13:46:09 +0900659 // for runtime
660 module.createXmlFile(mctx)
661 }
Jiyong Park82484c02018-04-23 21:41:26 +0900662
663 // record java_sdk_library modules so that they are exported to make
664 javaSdkLibraries := javaSdkLibraries(mctx.Config())
665 javaSdkLibrariesLock.Lock()
666 defer javaSdkLibrariesLock.Unlock()
667 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900668 }
669}
670
671func sdkLibraryFactory() android.Module {
672 module := &sdkLibrary{}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900673 module.AddProperties(
674 &module.sdkLibraryProperties,
675 &module.Library.Module.properties,
676 &module.Library.Module.dexpreoptProperties,
677 &module.Library.Module.deviceProperties,
678 &module.Library.Module.protoProperties,
679 )
680
681 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
682 module.Library.Module.deviceProperties.IsSDKLibrary = true
683
684 InitJavaModule(module, android.HostAndDeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900685 return module
686}