blob: 1b0fe75e018a316f73df63d553cf55082e13cb86 [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
Colin Cross2c77ceb2019-01-21 11:56:21 -0800399 if mctx.Config().UnbundledBuildPrebuiltSdks() {
400 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
401 }
Jiyong Park82484c02018-04-23 21:41:26 +0900402 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900403 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
404 props.System_modules = module.Library.Module.deviceProperties.System_modules
405 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
406 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
407 props.Java_version = module.Library.Module.properties.Java_version
408 if module.Library.Module.deviceProperties.Compile_dex != nil {
409 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900410 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900411
412 if module.SocSpecific() {
413 props.Soc_specific = proptools.BoolPtr(true)
414 } else if module.DeviceSpecific() {
415 props.Device_specific = proptools.BoolPtr(true)
416 } else if module.ProductSpecific() {
417 props.Product_specific = proptools.BoolPtr(true)
418 }
419
Colin Cross9ae1b922018-06-26 17:59:05 -0700420 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900421}
422
423// Creates a droiddoc module that creates stubs source files from the given full source
424// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900425func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900426 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900427 Name *string
428 Srcs []string
429 Installable *bool
430 Srcs_lib *string
431 Srcs_lib_whitelist_dirs []string
432 Srcs_lib_whitelist_pkgs []string
433 Libs []string
434 Args *string
435 Api_tag_name *string
436 Api_filename *string
437 Removed_api_filename *string
438 No_standard_libs *bool
439 Java_version *string
440 Merge_annotations_dirs []string
441 Merge_inclusion_annotations_dirs []string
442 Check_api struct {
Jiyong Park58c518b2018-05-12 22:29:12 +0900443 Current ApiToCheck
444 Last_released ApiToCheck
445 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900446 Aidl struct {
447 Include_dirs []string
448 Local_include_dirs []string
449 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900450 }{}
451
Jiyong Parkdf130542018-04-27 16:29:21 +0900452 props.Name = proptools.StringPtr(module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900453 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
454 props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900455 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900456 // A droiddoc module has only one Libs property and doesn't distinguish between
457 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900458 props.Libs = module.Library.Module.properties.Libs
459 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
460 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
461 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
462 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
463 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900464
Sundong Ahn054b19a2018-10-19 13:46:09 +0900465 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
466 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
467
468 droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
469 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
470 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900471 " --hide MissingPermission --hide BroadcastBehavior " +
472 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
473 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900474
Jiyong Parkdf130542018-04-27 16:29:21 +0900475 switch apiScope {
476 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900477 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900478 case apiScopeTest:
479 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900480 }
481 props.Args = proptools.StringPtr(droiddocArgs)
482
483 // List of APIs identified from the provided source files are created. They are later
484 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
485 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900486 currentApiFileName := "current.txt"
487 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900488 switch apiScope {
489 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900490 currentApiFileName = "system-" + currentApiFileName
491 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900492 case apiScopeTest:
493 currentApiFileName = "test-" + currentApiFileName
494 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900495 }
496 currentApiFileName = path.Join("api", currentApiFileName)
497 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900498 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900499 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900500 props.Api_filename = proptools.StringPtr(currentApiFileName)
501 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
502
Jiyong Park58c518b2018-05-12 22:29:12 +0900503 // check against the not-yet-release API
504 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
505 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900506
507 // check against the latest released API
508 props.Check_api.Last_released.Api_file = proptools.StringPtr(
509 module.latestApiFilegroupName(apiScope))
510 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
511 module.latestRemovedApiFilegroupName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900512 props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
513 props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
514 props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900515
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900516 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900517}
518
Jiyong Parkc678ad32018-04-10 13:07:10 +0900519// Creates the xml file that publicizes the runtime library
520func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
521 template := `
522<?xml version="1.0" encoding="utf-8"?>
523<!-- Copyright (C) 2018 The Android Open Source Project
524
525 Licensed under the Apache License, Version 2.0 (the "License");
526 you may not use this file except in compliance with the License.
527 You may obtain a copy of the License at
528
529 http://www.apache.org/licenses/LICENSE-2.0
530
531 Unless required by applicable law or agreed to in writing, software
532 distributed under the License is distributed on an "AS IS" BASIS,
533 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
534 See the License for the specific language governing permissions and
535 limitations under the License.
536-->
537
538<permissions>
539 <library name="%s" file="%s"/>
540</permissions>
541`
542 // genrule to generate the xml file content from the template above
543 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
544 // in the ninja file. Do we need to have an external tool for this?
545 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
546 genruleProps := struct {
547 Name *string
548 Cmd *string
549 Out []string
550 }{}
551 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
552 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
553 genruleProps.Out = []string{module.xmlFileName()}
554 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
555
556 // creates a prebuilt_etc module to actually place the xml file under
557 // <partition>/etc/permissions
558 etcProps := struct {
559 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900560 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900561 Sub_dir *string
562 Soc_specific *bool
563 Device_specific *bool
564 Product_specific *bool
565 }{}
566 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900567 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900568 etcProps.Sub_dir = proptools.StringPtr("permissions")
569 if module.SocSpecific() {
570 etcProps.Soc_specific = proptools.BoolPtr(true)
571 } else if module.DeviceSpecific() {
572 etcProps.Device_specific = proptools.BoolPtr(true)
573 } else if module.ProductSpecific() {
574 etcProps.Product_specific = proptools.BoolPtr(true)
575 }
576 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
577}
578
Sundong Ahn054b19a2018-10-19 13:46:09 +0900579func (module *sdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
580 var api, v string
581 if sdkVersion == "" {
582 api = "system"
583 v = "current"
584 } else if strings.Contains(sdkVersion, "_") {
585 t := strings.Split(sdkVersion, "_")
586 api = t[0]
587 v = t[1]
Jiyong Parkc678ad32018-04-10 13:07:10 +0900588 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900589 api = "public"
590 v = sdkVersion
591 }
592 dir := filepath.Join("prebuilts", "sdk", v, api)
593 jar := filepath.Join(dir, module.BaseModuleName()+".jar")
594 jarPath := android.ExistentPathForSource(ctx, jar)
595 return android.Paths{jarPath.Path()}
596}
597
598// to satisfy SdkLibraryDependency interface
599func (module *sdkLibrary) HeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
600 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800601 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900602 return module.PrebuiltJars(ctx, sdkVersion)
603 } else {
604 if strings.HasPrefix(sdkVersion, "system_") {
605 return module.systemApiStubsPath
606 } else if sdkVersion == "" {
607 return module.Library.HeaderJars()
608 } else {
609 return module.publicApiStubsPath
610 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900611 }
612}
613
Sundong Ahn241cd372018-07-13 16:16:44 +0900614// to satisfy SdkLibraryDependency interface
Sundong Ahn054b19a2018-10-19 13:46:09 +0900615func (module *sdkLibrary) ImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn241cd372018-07-13 16:16:44 +0900616 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800617 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900618 return module.PrebuiltJars(ctx, sdkVersion)
Sundong Ahn241cd372018-07-13 16:16:44 +0900619 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900620 if strings.HasPrefix(sdkVersion, "system_") {
621 return module.systemApiStubsImplPath
622 } else if sdkVersion == "" {
623 return module.Library.ImplementationJars()
624 } else {
625 return module.publicApiStubsImplPath
626 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900627 }
628}
629
Colin Cross571cccf2019-02-04 11:22:08 -0800630var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
631
Jiyong Park82484c02018-04-23 21:41:26 +0900632func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -0800633 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +0900634 return &[]string{}
635 }).(*[]string)
636}
637
Jiyong Parkc678ad32018-04-10 13:07:10 +0900638// For a java_sdk_library module, create internal modules for stubs, docs,
639// runtime libs and xml file. If requested, the stubs and docs are created twice
640// once for public API level and once for system API level
641func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
642 if module, ok := mctx.Module().(*sdkLibrary); ok {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900643 if module.Library.Module.properties.Srcs == nil {
Anton Hansson8959e142018-04-25 11:56:13 +0100644 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
645 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900646
647 if module.sdkLibraryProperties.Api_packages == nil {
Anton Hansson8959e142018-04-25 11:56:13 +0100648 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
649 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900650 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900651 module.createStubsLibrary(mctx, apiScopePublic)
652 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900653
Sundong Ahn054b19a2018-10-19 13:46:09 +0900654 if !Bool(module.properties.No_standard_libs) {
655 // for system API stubs
656 module.createStubsLibrary(mctx, apiScopeSystem)
657 module.createDocs(mctx, apiScopeSystem)
Jiyong Parkdf130542018-04-27 16:29:21 +0900658
Sundong Ahn054b19a2018-10-19 13:46:09 +0900659 // for test API stubs
660 module.createStubsLibrary(mctx, apiScopeTest)
661 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900662
Sundong Ahn054b19a2018-10-19 13:46:09 +0900663 // for runtime
664 module.createXmlFile(mctx)
665 }
Jiyong Park82484c02018-04-23 21:41:26 +0900666
667 // record java_sdk_library modules so that they are exported to make
668 javaSdkLibraries := javaSdkLibraries(mctx.Config())
669 javaSdkLibrariesLock.Lock()
670 defer javaSdkLibrariesLock.Unlock()
671 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900672 }
673}
674
675func sdkLibraryFactory() android.Module {
676 module := &sdkLibrary{}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900677 module.AddProperties(
678 &module.sdkLibraryProperties,
679 &module.Library.Module.properties,
680 &module.Library.Module.dexpreoptProperties,
681 &module.Library.Module.deviceProperties,
682 &module.Library.Module.protoProperties,
683 )
684
685 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
686 module.Library.Module.deviceProperties.IsSDKLibrary = true
687
688 InitJavaModule(module, android.HostAndDeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900689 return module
690}