blob: 3623e7cd0298090611f8f79f02eef1c98b979a30 [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
Paul Duffin11512472019-02-11 15:55:17 +0000103 // local files that are used within user customized droiddoc options.
104 Droiddoc_option_files []string
105
106 // additional droiddoc options
107 // Available variables for substitution:
108 //
109 // $(location <label>): the path to the droiddoc_option_files with name <label>
Sundong Ahndd567f92018-07-31 17:19:11 +0900110 Droiddoc_options []string
111
Sundong Ahnb952ba02019-01-08 16:32:12 +0900112 // the java library (in classpath) for documentation that provides java srcs and srcjars.
113 Srcs_lib *string
114
115 // the base dirs under srcs_lib will be scanned for java srcs.
116 Srcs_lib_whitelist_dirs []string
117
Sundong Ahndd567f92018-07-31 17:19:11 +0900118 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
119 // Defaults to "android.annotation".
120 Srcs_lib_whitelist_pkgs []string
121
Sundong Ahn054b19a2018-10-19 13:46:09 +0900122 // a list of top-level directories containing files to merge qualifier annotations
123 // (i.e. those intended to be included in the stubs written) from.
124 Merge_annotations_dirs []string
125
126 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
127 Merge_inclusion_annotations_dirs []string
128
129 // If set to true, the path of dist files is apistubs/core. Defaults to false.
130 Core_lib *bool
131
Jiyong Parkc678ad32018-04-10 13:07:10 +0900132 // TODO: determines whether to create HTML doc or not
133 //Html_doc *bool
134}
135
136type sdkLibrary struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900137 Library
Jiyong Parkc678ad32018-04-10 13:07:10 +0900138
Sundong Ahn054b19a2018-10-19 13:46:09 +0900139 sdkLibraryProperties sdkLibraryProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900140
141 publicApiStubsPath android.Paths
142 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900143 testApiStubsPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900144
145 publicApiStubsImplPath android.Paths
146 systemApiStubsImplPath android.Paths
147 testApiStubsImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900148
149 publicApiFilePath android.Path
150 systemApiFilePath android.Path
151 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900152}
153
Colin Cross897d2ed2019-02-11 14:03:51 -0800154var _ Dependency = (*sdkLibrary)(nil)
155var _ SdkLibraryDependency = (*sdkLibrary)(nil)
156
Jiyong Parkc678ad32018-04-10 13:07:10 +0900157func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
158 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700159 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
Colin Cross42d48b72018-08-29 14:10:52 -0700160 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900161
162 if !Bool(module.properties.No_standard_libs) {
163 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
164 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
165 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
166 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
167 }
168
169 module.Library.deps(ctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900170}
171
172func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900173 module.Library.GenerateAndroidBuildActions(ctx)
174
Sundong Ahn57368eb2018-07-06 11:20:23 +0900175 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900176 // When this java_sdk_library is dependened from others via "libs" property,
177 // the recorded paths will be returned depending on the link type of the caller.
178 ctx.VisitDirectDeps(func(to android.Module) {
179 otherName := ctx.OtherModuleName(to)
180 tag := ctx.OtherModuleDependencyTag(to)
181
Sundong Ahn57368eb2018-07-06 11:20:23 +0900182 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900183 switch tag {
184 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900185 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900186 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900187 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900188 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900189 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900190 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900191 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900192 module.testApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900193 }
194 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900195 if doc, ok := to.(ApiFilePath); ok {
196 switch tag {
197 case publicApiFileTag:
198 module.publicApiFilePath = doc.ApiFilePath()
199 case systemApiFileTag:
200 module.systemApiFilePath = doc.ApiFilePath()
201 case testApiFileTag:
202 module.testApiFilePath = doc.ApiFilePath()
203 default:
204 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
205 }
206 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900207 })
208}
209
Jiyong Park82484c02018-04-23 21:41:26 +0900210func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900211 data := module.Library.AndroidMk()
212 data.Required = append(data.Required, module.xmlFileName())
213
214 data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
215 android.WriteAndroidMkData(w, data)
216
217 module.Library.AndroidMkHostDex(w, name, data)
218 // Create a phony module that installs the impl library, for the case when this lib is
219 // in PRODUCT_PACKAGES.
220 owner := module.ModuleBase.Owner()
221 if owner == "" {
222 if Bool(module.sdkLibraryProperties.Core_lib) {
223 owner = "core"
224 } else {
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900225 owner = "android"
226 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900227 }
228 // Create dist rules to install the stubs libs to the dist dir
229 if len(module.publicApiStubsPath) == 1 {
230 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
231 module.publicApiStubsImplPath.Strings()[0]+
232 ":"+path.Join("apistubs", owner, "public",
233 module.BaseModuleName()+".jar")+")")
234 }
235 if len(module.systemApiStubsPath) == 1 {
236 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
237 module.systemApiStubsImplPath.Strings()[0]+
238 ":"+path.Join("apistubs", owner, "system",
239 module.BaseModuleName()+".jar")+")")
240 }
241 if len(module.testApiStubsPath) == 1 {
242 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
243 module.testApiStubsImplPath.Strings()[0]+
244 ":"+path.Join("apistubs", owner, "test",
245 module.BaseModuleName()+".jar")+")")
246 }
247 if module.publicApiFilePath != nil {
248 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
249 module.publicApiFilePath.String()+
250 ":"+path.Join("apistubs", owner, "public", "api",
251 module.BaseModuleName()+".txt")+")")
252 }
253 if module.systemApiFilePath != nil {
254 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
255 module.systemApiFilePath.String()+
256 ":"+path.Join("apistubs", owner, "system", "api",
257 module.BaseModuleName()+".txt")+")")
258 }
259 if module.testApiFilePath != nil {
260 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
261 module.testApiFilePath.String()+
262 ":"+path.Join("apistubs", owner, "test", "api",
263 module.BaseModuleName()+".txt")+")")
264 }
Jiyong Park82484c02018-04-23 21:41:26 +0900265 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900266 return data
Jiyong Park82484c02018-04-23 21:41:26 +0900267}
268
Jiyong Parkc678ad32018-04-10 13:07:10 +0900269// Module name of the stubs library
Jiyong Parkdf130542018-04-27 16:29:21 +0900270func (module *sdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900271 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900272 switch apiScope {
273 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900274 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900275 case apiScopeTest:
276 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900277 }
278 return stubsName
279}
280
281// Module name of the docs
Jiyong Parkdf130542018-04-27 16:29:21 +0900282func (module *sdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900283 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900284 switch apiScope {
285 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900286 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900287 case apiScopeTest:
288 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900289 }
290 return docsName
291}
292
293// Module name of the runtime implementation library
294func (module *sdkLibrary) implName() string {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900295 return module.BaseModuleName()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900296}
297
298// File path to the runtime implementation library
299func (module *sdkLibrary) implPath() string {
300 partition := "system"
301 if module.SocSpecific() {
302 partition = "vendor"
303 } else if module.DeviceSpecific() {
304 partition = "odm"
305 } else if module.ProductSpecific() {
306 partition = "product"
307 }
308 return "/" + partition + "/framework/" + module.implName() + ".jar"
309}
310
311// Module name of the XML file for the lib
312func (module *sdkLibrary) xmlFileName() string {
313 return module.BaseModuleName() + sdkXmlFileSuffix
314}
315
316// SDK version that the stubs library is built against. Note that this is always
317// *current. Older stubs library built with a numberd SDK version is created from
318// the prebuilt jar.
Jiyong Parkdf130542018-04-27 16:29:21 +0900319func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
320 switch apiScope {
321 case apiScopePublic:
322 return "current"
323 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900324 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900325 case apiScopeTest:
326 return "test_current"
327 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900328 return "current"
329 }
330}
331
332// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
333// api file for the current source
334// TODO: remove this when apicheck is done in soong
Jiyong Parkdf130542018-04-27 16:29:21 +0900335func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900336 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900337 switch apiScope {
338 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900339 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900340 case apiScopeTest:
341 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900342 }
343 return apiTagName
344}
345
Jiyong Park58c518b2018-05-12 22:29:12 +0900346func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
347 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900348 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900349 case apiScopePublic:
350 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900351 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900352 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900353 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900354 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900355 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900356 name = name + ".latest"
357 return name
358}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900359
Jiyong Park58c518b2018-05-12 22:29:12 +0900360func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
361 name := ":" + module.BaseModuleName() + "-removed.api."
362 switch apiScope {
363 case apiScopePublic:
364 name = name + "public"
365 case apiScopeSystem:
366 name = name + "system"
367 case apiScopeTest:
368 name = name + "test"
369 }
370 name = name + ".latest"
371 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900372}
373
374// Creates a static java library that has API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900375func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900376 props := struct {
377 Name *string
378 Srcs []string
379 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900380 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900381 Soc_specific *bool
382 Device_specific *bool
383 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900384 Compile_dex *bool
Sundong Ahn054b19a2018-10-19 13:46:09 +0900385 No_standard_libs *bool
386 System_modules *string
387 Java_version *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900388 Product_variables struct {
389 Unbundled_build struct {
390 Enabled *bool
391 }
Jiyong Park82484c02018-04-23 21:41:26 +0900392 Pdk struct {
393 Enabled *bool
394 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900395 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900396 Openjdk9 struct {
397 Srcs []string
398 Javacflags []string
399 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900400 }{}
401
Jiyong Parkdf130542018-04-27 16:29:21 +0900402 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900403 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900404 props.Srcs = []string{":" + module.docsName(apiScope)}
405 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900406 props.Libs = module.sdkLibraryProperties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900407 // Unbundled apps will use the prebult one from /prebuilts/sdk
Colin Cross2c77ceb2019-01-21 11:56:21 -0800408 if mctx.Config().UnbundledBuildPrebuiltSdks() {
409 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
410 }
Jiyong Park82484c02018-04-23 21:41:26 +0900411 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900412 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
413 props.System_modules = module.Library.Module.deviceProperties.System_modules
414 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
415 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
416 props.Java_version = module.Library.Module.properties.Java_version
417 if module.Library.Module.deviceProperties.Compile_dex != nil {
418 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900419 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900420
421 if module.SocSpecific() {
422 props.Soc_specific = proptools.BoolPtr(true)
423 } else if module.DeviceSpecific() {
424 props.Device_specific = proptools.BoolPtr(true)
425 } else if module.ProductSpecific() {
426 props.Product_specific = proptools.BoolPtr(true)
427 }
428
Colin Cross9ae1b922018-06-26 17:59:05 -0700429 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900430}
431
432// Creates a droiddoc module that creates stubs source files from the given full source
433// files
Jiyong Parkdf130542018-04-27 16:29:21 +0900434func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900435 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900436 Name *string
437 Srcs []string
438 Installable *bool
439 Srcs_lib *string
440 Srcs_lib_whitelist_dirs []string
441 Srcs_lib_whitelist_pkgs []string
442 Libs []string
Paul Duffin11512472019-02-11 15:55:17 +0000443 Arg_files []string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900444 Args *string
445 Api_tag_name *string
446 Api_filename *string
447 Removed_api_filename *string
448 No_standard_libs *bool
449 Java_version *string
450 Merge_annotations_dirs []string
451 Merge_inclusion_annotations_dirs []string
452 Check_api struct {
Jiyong Park58c518b2018-05-12 22:29:12 +0900453 Current ApiToCheck
454 Last_released ApiToCheck
455 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900456 Aidl struct {
457 Include_dirs []string
458 Local_include_dirs []string
459 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900460 }{}
461
Jiyong Parkdf130542018-04-27 16:29:21 +0900462 props.Name = proptools.StringPtr(module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900463 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
464 props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900465 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900466 // A droiddoc module has only one Libs property and doesn't distinguish between
467 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900468 props.Libs = module.Library.Module.properties.Libs
469 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
470 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
471 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
472 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
473 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900474
Sundong Ahn054b19a2018-10-19 13:46:09 +0900475 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
476 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
477
478 droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
479 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
480 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900481 " --hide MissingPermission --hide BroadcastBehavior " +
482 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
483 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900484
Jiyong Parkdf130542018-04-27 16:29:21 +0900485 switch apiScope {
486 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900487 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900488 case apiScopeTest:
489 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900490 }
Paul Duffin11512472019-02-11 15:55:17 +0000491 props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
Jiyong Parkc678ad32018-04-10 13:07:10 +0900492 props.Args = proptools.StringPtr(droiddocArgs)
493
494 // List of APIs identified from the provided source files are created. They are later
495 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
496 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900497 currentApiFileName := "current.txt"
498 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900499 switch apiScope {
500 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900501 currentApiFileName = "system-" + currentApiFileName
502 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900503 case apiScopeTest:
504 currentApiFileName = "test-" + currentApiFileName
505 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900506 }
507 currentApiFileName = path.Join("api", currentApiFileName)
508 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900509 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900510 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900511 props.Api_filename = proptools.StringPtr(currentApiFileName)
512 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
513
Jiyong Park58c518b2018-05-12 22:29:12 +0900514 // check against the not-yet-release API
515 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
516 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900517
518 // check against the latest released API
519 props.Check_api.Last_released.Api_file = proptools.StringPtr(
520 module.latestApiFilegroupName(apiScope))
521 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
522 module.latestRemovedApiFilegroupName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900523 props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
524 props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
525 props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900526
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900527 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900528}
529
Jiyong Parkc678ad32018-04-10 13:07:10 +0900530// Creates the xml file that publicizes the runtime library
531func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
532 template := `
533<?xml version="1.0" encoding="utf-8"?>
534<!-- Copyright (C) 2018 The Android Open Source Project
535
536 Licensed under the Apache License, Version 2.0 (the "License");
537 you may not use this file except in compliance with the License.
538 You may obtain a copy of the License at
539
540 http://www.apache.org/licenses/LICENSE-2.0
541
542 Unless required by applicable law or agreed to in writing, software
543 distributed under the License is distributed on an "AS IS" BASIS,
544 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
545 See the License for the specific language governing permissions and
546 limitations under the License.
547-->
548
549<permissions>
550 <library name="%s" file="%s"/>
551</permissions>
552`
553 // genrule to generate the xml file content from the template above
554 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
555 // in the ninja file. Do we need to have an external tool for this?
556 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
557 genruleProps := struct {
558 Name *string
559 Cmd *string
560 Out []string
561 }{}
562 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
563 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
564 genruleProps.Out = []string{module.xmlFileName()}
565 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
566
567 // creates a prebuilt_etc module to actually place the xml file under
568 // <partition>/etc/permissions
569 etcProps := struct {
570 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900571 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900572 Sub_dir *string
573 Soc_specific *bool
574 Device_specific *bool
575 Product_specific *bool
576 }{}
577 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900578 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900579 etcProps.Sub_dir = proptools.StringPtr("permissions")
580 if module.SocSpecific() {
581 etcProps.Soc_specific = proptools.BoolPtr(true)
582 } else if module.DeviceSpecific() {
583 etcProps.Device_specific = proptools.BoolPtr(true)
584 } else if module.ProductSpecific() {
585 etcProps.Product_specific = proptools.BoolPtr(true)
586 }
587 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
588}
589
Sundong Ahn054b19a2018-10-19 13:46:09 +0900590func (module *sdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
591 var api, v string
592 if sdkVersion == "" {
593 api = "system"
594 v = "current"
595 } else if strings.Contains(sdkVersion, "_") {
596 t := strings.Split(sdkVersion, "_")
597 api = t[0]
598 v = t[1]
Jiyong Parkc678ad32018-04-10 13:07:10 +0900599 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900600 api = "public"
601 v = sdkVersion
602 }
603 dir := filepath.Join("prebuilts", "sdk", v, api)
604 jar := filepath.Join(dir, module.BaseModuleName()+".jar")
605 jarPath := android.ExistentPathForSource(ctx, jar)
606 return android.Paths{jarPath.Path()}
607}
608
609// to satisfy SdkLibraryDependency interface
Colin Cross897d2ed2019-02-11 14:03:51 -0800610func (module *sdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900611 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800612 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900613 return module.PrebuiltJars(ctx, sdkVersion)
614 } else {
615 if strings.HasPrefix(sdkVersion, "system_") {
616 return module.systemApiStubsPath
617 } else if sdkVersion == "" {
618 return module.Library.HeaderJars()
619 } else {
620 return module.publicApiStubsPath
621 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900622 }
623}
624
Sundong Ahn241cd372018-07-13 16:16:44 +0900625// to satisfy SdkLibraryDependency interface
Colin Cross897d2ed2019-02-11 14:03:51 -0800626func (module *sdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn241cd372018-07-13 16:16:44 +0900627 // This module is just a wrapper for the stubs.
Colin Cross2c77ceb2019-01-21 11:56:21 -0800628 if ctx.Config().UnbundledBuildPrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900629 return module.PrebuiltJars(ctx, sdkVersion)
Sundong Ahn241cd372018-07-13 16:16:44 +0900630 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900631 if strings.HasPrefix(sdkVersion, "system_") {
632 return module.systemApiStubsImplPath
633 } else if sdkVersion == "" {
634 return module.Library.ImplementationJars()
635 } else {
636 return module.publicApiStubsImplPath
637 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900638 }
639}
640
Colin Cross571cccf2019-02-04 11:22:08 -0800641var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
642
Jiyong Park82484c02018-04-23 21:41:26 +0900643func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -0800644 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +0900645 return &[]string{}
646 }).(*[]string)
647}
648
Jiyong Parkc678ad32018-04-10 13:07:10 +0900649// For a java_sdk_library module, create internal modules for stubs, docs,
650// runtime libs and xml file. If requested, the stubs and docs are created twice
651// once for public API level and once for system API level
652func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
653 if module, ok := mctx.Module().(*sdkLibrary); ok {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900654 if module.Library.Module.properties.Srcs == nil {
Anton Hansson8959e142018-04-25 11:56:13 +0100655 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
656 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900657
658 if module.sdkLibraryProperties.Api_packages == nil {
Anton Hansson8959e142018-04-25 11:56:13 +0100659 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
660 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900661 // for public API stubs
Jiyong Parkdf130542018-04-27 16:29:21 +0900662 module.createStubsLibrary(mctx, apiScopePublic)
663 module.createDocs(mctx, apiScopePublic)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900664
Sundong Ahn054b19a2018-10-19 13:46:09 +0900665 if !Bool(module.properties.No_standard_libs) {
666 // for system API stubs
667 module.createStubsLibrary(mctx, apiScopeSystem)
668 module.createDocs(mctx, apiScopeSystem)
Jiyong Parkdf130542018-04-27 16:29:21 +0900669
Sundong Ahn054b19a2018-10-19 13:46:09 +0900670 // for test API stubs
671 module.createStubsLibrary(mctx, apiScopeTest)
672 module.createDocs(mctx, apiScopeTest)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900673
Sundong Ahn054b19a2018-10-19 13:46:09 +0900674 // for runtime
675 module.createXmlFile(mctx)
676 }
Jiyong Park82484c02018-04-23 21:41:26 +0900677
678 // record java_sdk_library modules so that they are exported to make
679 javaSdkLibraries := javaSdkLibraries(mctx.Config())
680 javaSdkLibrariesLock.Lock()
681 defer javaSdkLibrariesLock.Unlock()
682 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900683 }
684}
685
686func sdkLibraryFactory() android.Module {
687 module := &sdkLibrary{}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900688 module.AddProperties(
689 &module.sdkLibraryProperties,
690 &module.Library.Module.properties,
691 &module.Library.Module.dexpreoptProperties,
692 &module.Library.Module.deviceProperties,
693 &module.Library.Module.protoProperties,
694 )
695
696 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
697 module.Library.Module.deviceProperties.IsSDKLibrary = true
698
699 InitJavaModule(module, android.HostAndDeviceSupported)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900700 return module
701}