blob: 72c5cfc27b0829670398bf2b37e34603dcc4c9ac [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() {
Inseob Kimc0907f12019-02-08 21:00:45 +090077 android.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
Colin Cross79c7c262019-04-17 11:11:46 -070078 android.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory)
Jiyong Parkc678ad32018-04-10 13:07:10 +090079
Jiyong Park82484c02018-04-23 21:41:26 +090080 android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
81 javaSdkLibraries := javaSdkLibraries(ctx.Config())
82 sort.Strings(*javaSdkLibraries)
83 ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
84 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090085}
86
87type sdkLibraryProperties struct {
Jiyong Parkbaaf9dd2018-05-02 01:35:27 +090088 // list of optional source files that are part of API but not part of runtime library.
89 Api_srcs []string `android:"arch_variant"`
90
Sundong Ahnf043cf62018-06-25 16:04:37 +090091 // List of Java libraries that will be in the classpath when building stubs
92 Stub_only_libs []string `android:"arch_variant"`
93
Jiyong Parkc678ad32018-04-10 13:07:10 +090094 // list of package names that will be documented and publicized as API
95 Api_packages []string
96
Jiyong Park5a2c9d72018-05-01 22:25:41 +090097 // list of package names that must be hidden from the API
98 Hidden_api_packages []string
99
Paul Duffin11512472019-02-11 15:55:17 +0000100 // local files that are used within user customized droiddoc options.
101 Droiddoc_option_files []string
102
103 // additional droiddoc options
104 // Available variables for substitution:
105 //
106 // $(location <label>): the path to the droiddoc_option_files with name <label>
Sundong Ahndd567f92018-07-31 17:19:11 +0900107 Droiddoc_options []string
108
Sundong Ahnb952ba02019-01-08 16:32:12 +0900109 // the java library (in classpath) for documentation that provides java srcs and srcjars.
110 Srcs_lib *string
111
112 // the base dirs under srcs_lib will be scanned for java srcs.
113 Srcs_lib_whitelist_dirs []string
114
Sundong Ahndd567f92018-07-31 17:19:11 +0900115 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
116 // Defaults to "android.annotation".
117 Srcs_lib_whitelist_pkgs []string
118
Sundong Ahn054b19a2018-10-19 13:46:09 +0900119 // a list of top-level directories containing files to merge qualifier annotations
120 // (i.e. those intended to be included in the stubs written) from.
121 Merge_annotations_dirs []string
122
123 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
124 Merge_inclusion_annotations_dirs []string
125
126 // If set to true, the path of dist files is apistubs/core. Defaults to false.
127 Core_lib *bool
128
Jiyong Parkc678ad32018-04-10 13:07:10 +0900129 // TODO: determines whether to create HTML doc or not
130 //Html_doc *bool
131}
132
Inseob Kimc0907f12019-02-08 21:00:45 +0900133type SdkLibrary struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900134 Library
Jiyong Parkc678ad32018-04-10 13:07:10 +0900135
Sundong Ahn054b19a2018-10-19 13:46:09 +0900136 sdkLibraryProperties sdkLibraryProperties
Jiyong Parkc678ad32018-04-10 13:07:10 +0900137
138 publicApiStubsPath android.Paths
139 systemApiStubsPath android.Paths
Jiyong Parkdf130542018-04-27 16:29:21 +0900140 testApiStubsPath android.Paths
Sundong Ahn241cd372018-07-13 16:16:44 +0900141
142 publicApiStubsImplPath android.Paths
143 systemApiStubsImplPath android.Paths
144 testApiStubsImplPath android.Paths
Sundong Ahn20e998b2018-07-24 11:19:26 +0900145
146 publicApiFilePath android.Path
147 systemApiFilePath android.Path
148 testApiFilePath android.Path
Jiyong Parkc678ad32018-04-10 13:07:10 +0900149}
150
Inseob Kimc0907f12019-02-08 21:00:45 +0900151var _ Dependency = (*SdkLibrary)(nil)
152var _ SdkLibraryDependency = (*SdkLibrary)(nil)
Colin Cross897d2ed2019-02-11 14:03:51 -0800153
Inseob Kimc0907f12019-02-08 21:00:45 +0900154func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900155 // Add dependencies to the stubs library
Colin Cross42d48b72018-08-29 14:10:52 -0700156 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
Colin Cross42d48b72018-08-29 14:10:52 -0700157 ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900158
159 if !Bool(module.properties.No_standard_libs) {
160 ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
161 ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
162 ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
163 ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
164 }
165
166 module.Library.deps(ctx)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900167}
168
Inseob Kimc0907f12019-02-08 21:00:45 +0900169func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900170 module.Library.GenerateAndroidBuildActions(ctx)
171
Sundong Ahn57368eb2018-07-06 11:20:23 +0900172 // Record the paths to the header jars of the library (stubs and impl).
Jiyong Parkc678ad32018-04-10 13:07:10 +0900173 // When this java_sdk_library is dependened from others via "libs" property,
174 // the recorded paths will be returned depending on the link type of the caller.
175 ctx.VisitDirectDeps(func(to android.Module) {
176 otherName := ctx.OtherModuleName(to)
177 tag := ctx.OtherModuleDependencyTag(to)
178
Sundong Ahn57368eb2018-07-06 11:20:23 +0900179 if lib, ok := to.(Dependency); ok {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900180 switch tag {
181 case publicApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900182 module.publicApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900183 module.publicApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900184 case systemApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900185 module.systemApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900186 module.systemApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkdf130542018-04-27 16:29:21 +0900187 case testApiStubsTag:
Sundong Ahn57368eb2018-07-06 11:20:23 +0900188 module.testApiStubsPath = lib.HeaderJars()
Sundong Ahn241cd372018-07-13 16:16:44 +0900189 module.testApiStubsImplPath = lib.ImplementationJars()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900190 }
191 }
Sundong Ahn20e998b2018-07-24 11:19:26 +0900192 if doc, ok := to.(ApiFilePath); ok {
193 switch tag {
194 case publicApiFileTag:
195 module.publicApiFilePath = doc.ApiFilePath()
196 case systemApiFileTag:
197 module.systemApiFilePath = doc.ApiFilePath()
198 case testApiFileTag:
199 module.testApiFilePath = doc.ApiFilePath()
200 default:
201 ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
202 }
203 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900204 })
205}
206
Inseob Kimc0907f12019-02-08 21:00:45 +0900207func (module *SdkLibrary) AndroidMk() android.AndroidMkData {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900208 data := module.Library.AndroidMk()
209 data.Required = append(data.Required, module.xmlFileName())
210
211 data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
212 android.WriteAndroidMkData(w, data)
213
214 module.Library.AndroidMkHostDex(w, name, data)
215 // Create a phony module that installs the impl library, for the case when this lib is
216 // in PRODUCT_PACKAGES.
217 owner := module.ModuleBase.Owner()
218 if owner == "" {
219 if Bool(module.sdkLibraryProperties.Core_lib) {
220 owner = "core"
221 } else {
Sundong Ahn4fd04bb2018-08-31 18:01:37 +0900222 owner = "android"
223 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900224 }
225 // Create dist rules to install the stubs libs to the dist dir
226 if len(module.publicApiStubsPath) == 1 {
227 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
228 module.publicApiStubsImplPath.Strings()[0]+
229 ":"+path.Join("apistubs", owner, "public",
230 module.BaseModuleName()+".jar")+")")
231 }
232 if len(module.systemApiStubsPath) == 1 {
233 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
234 module.systemApiStubsImplPath.Strings()[0]+
235 ":"+path.Join("apistubs", owner, "system",
236 module.BaseModuleName()+".jar")+")")
237 }
238 if len(module.testApiStubsPath) == 1 {
239 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
240 module.testApiStubsImplPath.Strings()[0]+
241 ":"+path.Join("apistubs", owner, "test",
242 module.BaseModuleName()+".jar")+")")
243 }
244 if module.publicApiFilePath != nil {
245 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
246 module.publicApiFilePath.String()+
247 ":"+path.Join("apistubs", owner, "public", "api",
248 module.BaseModuleName()+".txt")+")")
249 }
250 if module.systemApiFilePath != nil {
251 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
252 module.systemApiFilePath.String()+
253 ":"+path.Join("apistubs", owner, "system", "api",
254 module.BaseModuleName()+".txt")+")")
255 }
256 if module.testApiFilePath != nil {
257 fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
258 module.testApiFilePath.String()+
259 ":"+path.Join("apistubs", owner, "test", "api",
260 module.BaseModuleName()+".txt")+")")
261 }
Jiyong Park82484c02018-04-23 21:41:26 +0900262 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900263 return data
Jiyong Park82484c02018-04-23 21:41:26 +0900264}
265
Jiyong Parkc678ad32018-04-10 13:07:10 +0900266// Module name of the stubs library
Inseob Kimc0907f12019-02-08 21:00:45 +0900267func (module *SdkLibrary) stubsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900268 stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900269 switch apiScope {
270 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900271 stubsName = stubsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900272 case apiScopeTest:
273 stubsName = stubsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900274 }
275 return stubsName
276}
277
278// Module name of the docs
Inseob Kimc0907f12019-02-08 21:00:45 +0900279func (module *SdkLibrary) docsName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900280 docsName := module.BaseModuleName() + sdkDocsSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900281 switch apiScope {
282 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900283 docsName = docsName + sdkSystemApiSuffix
Jiyong Parkdf130542018-04-27 16:29:21 +0900284 case apiScopeTest:
285 docsName = docsName + sdkTestApiSuffix
Jiyong Parkc678ad32018-04-10 13:07:10 +0900286 }
287 return docsName
288}
289
290// Module name of the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900291func (module *SdkLibrary) implName() string {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900292 return module.BaseModuleName()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900293}
294
295// File path to the runtime implementation library
Inseob Kimc0907f12019-02-08 21:00:45 +0900296func (module *SdkLibrary) implPath() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900297 partition := "system"
298 if module.SocSpecific() {
299 partition = "vendor"
300 } else if module.DeviceSpecific() {
301 partition = "odm"
302 } else if module.ProductSpecific() {
303 partition = "product"
304 }
305 return "/" + partition + "/framework/" + module.implName() + ".jar"
306}
307
308// Module name of the XML file for the lib
Inseob Kimc0907f12019-02-08 21:00:45 +0900309func (module *SdkLibrary) xmlFileName() string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900310 return module.BaseModuleName() + sdkXmlFileSuffix
311}
312
313// SDK version that the stubs library is built against. Note that this is always
314// *current. Older stubs library built with a numberd SDK version is created from
315// the prebuilt jar.
Inseob Kimc0907f12019-02-08 21:00:45 +0900316func (module *SdkLibrary) sdkVersion(apiScope apiScope) string {
Jiyong Parkdf130542018-04-27 16:29:21 +0900317 switch apiScope {
318 case apiScopePublic:
319 return "current"
320 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900321 return "system_current"
Jiyong Parkdf130542018-04-27 16:29:21 +0900322 case apiScopeTest:
323 return "test_current"
324 default:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900325 return "current"
326 }
327}
328
329// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
330// api file for the current source
331// TODO: remove this when apicheck is done in soong
Inseob Kimc0907f12019-02-08 21:00:45 +0900332func (module *SdkLibrary) apiTagName(apiScope apiScope) string {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900333 apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
Jiyong Parkdf130542018-04-27 16:29:21 +0900334 switch apiScope {
335 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900336 apiTagName = apiTagName + "_SYSTEM"
Jiyong Parkdf130542018-04-27 16:29:21 +0900337 case apiScopeTest:
338 apiTagName = apiTagName + "_TEST"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900339 }
340 return apiTagName
341}
342
Inseob Kimc0907f12019-02-08 21:00:45 +0900343func (module *SdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
Jiyong Park58c518b2018-05-12 22:29:12 +0900344 name := ":" + module.BaseModuleName() + ".api."
Jiyong Parkdf130542018-04-27 16:29:21 +0900345 switch apiScope {
Jiyong Park58c518b2018-05-12 22:29:12 +0900346 case apiScopePublic:
347 name = name + "public"
Jiyong Parkdf130542018-04-27 16:29:21 +0900348 case apiScopeSystem:
Jiyong Park58c518b2018-05-12 22:29:12 +0900349 name = name + "system"
Jiyong Parkdf130542018-04-27 16:29:21 +0900350 case apiScopeTest:
Jiyong Park58c518b2018-05-12 22:29:12 +0900351 name = name + "test"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900352 }
Jiyong Park58c518b2018-05-12 22:29:12 +0900353 name = name + ".latest"
354 return name
355}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900356
Inseob Kimc0907f12019-02-08 21:00:45 +0900357func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
Jiyong Park58c518b2018-05-12 22:29:12 +0900358 name := ":" + module.BaseModuleName() + "-removed.api."
359 switch apiScope {
360 case apiScopePublic:
361 name = name + "public"
362 case apiScopeSystem:
363 name = name + "system"
364 case apiScopeTest:
365 name = name + "test"
366 }
367 name = name + ".latest"
368 return name
Jiyong Parkc678ad32018-04-10 13:07:10 +0900369}
370
371// Creates a static java library that has API stubs
Colin Crossf8b860a2019-04-16 14:43:28 -0700372func (module *SdkLibrary) createStubsLibrary(mctx android.LoadHookContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900373 props := struct {
374 Name *string
375 Srcs []string
376 Sdk_version *string
Sundong Ahnf043cf62018-06-25 16:04:37 +0900377 Libs []string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900378 Soc_specific *bool
379 Device_specific *bool
380 Product_specific *bool
Sundong Ahndd567f92018-07-31 17:19:11 +0900381 Compile_dex *bool
Sundong Ahn054b19a2018-10-19 13:46:09 +0900382 No_standard_libs *bool
383 System_modules *string
384 Java_version *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900385 Product_variables struct {
386 Unbundled_build struct {
387 Enabled *bool
388 }
Jiyong Park82484c02018-04-23 21:41:26 +0900389 Pdk struct {
390 Enabled *bool
391 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900392 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900393 Openjdk9 struct {
394 Srcs []string
395 Javacflags []string
396 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900397 }{}
398
Jiyong Parkdf130542018-04-27 16:29:21 +0900399 props.Name = proptools.StringPtr(module.stubsName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900400 // sources are generated from the droiddoc
Jiyong Parkdf130542018-04-27 16:29:21 +0900401 props.Srcs = []string{":" + module.docsName(apiScope)}
402 props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900403 props.Libs = module.sdkLibraryProperties.Stub_only_libs
Jiyong Parkc678ad32018-04-10 13:07:10 +0900404 // Unbundled apps will use the prebult one from /prebuilts/sdk
Colin Cross10932872019-04-18 14:27:12 -0700405 if mctx.Config().UnbundledBuildUsePrebuiltSdks() {
Colin Cross2c77ceb2019-01-21 11:56:21 -0800406 props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
407 }
Jiyong Park82484c02018-04-23 21:41:26 +0900408 props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900409 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
410 props.System_modules = module.Library.Module.deviceProperties.System_modules
411 props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
412 props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
413 props.Java_version = module.Library.Module.properties.Java_version
414 if module.Library.Module.deviceProperties.Compile_dex != nil {
415 props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
Sundong Ahndd567f92018-07-31 17:19:11 +0900416 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900417
418 if module.SocSpecific() {
419 props.Soc_specific = proptools.BoolPtr(true)
420 } else if module.DeviceSpecific() {
421 props.Device_specific = proptools.BoolPtr(true)
422 } else if module.ProductSpecific() {
423 props.Product_specific = proptools.BoolPtr(true)
424 }
425
Colin Cross9ae1b922018-06-26 17:59:05 -0700426 mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900427}
428
429// Creates a droiddoc module that creates stubs source files from the given full source
430// files
Colin Crossf8b860a2019-04-16 14:43:28 -0700431func (module *SdkLibrary) createDocs(mctx android.LoadHookContext, apiScope apiScope) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900432 props := struct {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900433 Name *string
434 Srcs []string
435 Installable *bool
436 Srcs_lib *string
437 Srcs_lib_whitelist_dirs []string
438 Srcs_lib_whitelist_pkgs []string
439 Libs []string
Paul Duffin11512472019-02-11 15:55:17 +0000440 Arg_files []string
Sundong Ahn054b19a2018-10-19 13:46:09 +0900441 Args *string
442 Api_tag_name *string
443 Api_filename *string
444 Removed_api_filename *string
445 No_standard_libs *bool
446 Java_version *string
447 Merge_annotations_dirs []string
448 Merge_inclusion_annotations_dirs []string
449 Check_api struct {
Inseob Kim38449af2019-02-28 14:24:05 +0900450 Current ApiToCheck
451 Last_released ApiToCheck
452 Ignore_missing_latest_api *bool
Jiyong Park58c518b2018-05-12 22:29:12 +0900453 }
Sundong Ahn1b92c822018-05-29 11:35:17 +0900454 Aidl struct {
455 Include_dirs []string
456 Local_include_dirs []string
457 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900458 }{}
459
Jiyong Parkdf130542018-04-27 16:29:21 +0900460 props.Name = proptools.StringPtr(module.docsName(apiScope))
Sundong Ahn054b19a2018-10-19 13:46:09 +0900461 props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
462 props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900463 props.Installable = proptools.BoolPtr(false)
Sundong Ahne6f0b052018-06-05 16:46:14 +0900464 // A droiddoc module has only one Libs property and doesn't distinguish between
465 // shared libs and static libs. So we need to add both of these libs to Libs property.
Sundong Ahn054b19a2018-10-19 13:46:09 +0900466 props.Libs = module.Library.Module.properties.Libs
467 props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
468 props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
469 props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
470 props.No_standard_libs = module.Library.Module.properties.No_standard_libs
471 props.Java_version = module.Library.Module.properties.Java_version
Jiyong Parkc678ad32018-04-10 13:07:10 +0900472
Sundong Ahn054b19a2018-10-19 13:46:09 +0900473 props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
474 props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
475
476 droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
477 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
478 " " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900479 " --hide MissingPermission --hide BroadcastBehavior " +
480 "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
481 "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
Sundong Ahnfb2721f2018-09-17 13:23:09 +0900482
Jiyong Parkdf130542018-04-27 16:29:21 +0900483 switch apiScope {
484 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900485 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.SystemApi"
Jiyong Parkdf130542018-04-27 16:29:21 +0900486 case apiScopeTest:
487 droiddocArgs = droiddocArgs + " -showAnnotation android.annotation.TestApi"
Jiyong Parkc678ad32018-04-10 13:07:10 +0900488 }
Paul Duffin11512472019-02-11 15:55:17 +0000489 props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
Jiyong Parkc678ad32018-04-10 13:07:10 +0900490 props.Args = proptools.StringPtr(droiddocArgs)
491
492 // List of APIs identified from the provided source files are created. They are later
493 // compared against to the not-yet-released (a.k.a current) list of APIs and to the
494 // last-released (a.k.a numbered) list of API.
Jiyong Parkc678ad32018-04-10 13:07:10 +0900495 currentApiFileName := "current.txt"
496 removedApiFileName := "removed.txt"
Jiyong Parkdf130542018-04-27 16:29:21 +0900497 switch apiScope {
498 case apiScopeSystem:
Jiyong Parkc678ad32018-04-10 13:07:10 +0900499 currentApiFileName = "system-" + currentApiFileName
500 removedApiFileName = "system-" + removedApiFileName
Jiyong Parkdf130542018-04-27 16:29:21 +0900501 case apiScopeTest:
502 currentApiFileName = "test-" + currentApiFileName
503 removedApiFileName = "test-" + removedApiFileName
Jiyong Parkc678ad32018-04-10 13:07:10 +0900504 }
505 currentApiFileName = path.Join("api", currentApiFileName)
506 removedApiFileName = path.Join("api", removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900507 // TODO(jiyong): remove these three props
Jiyong Parkdf130542018-04-27 16:29:21 +0900508 props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
Jiyong Parkc678ad32018-04-10 13:07:10 +0900509 props.Api_filename = proptools.StringPtr(currentApiFileName)
510 props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
511
Jiyong Park58c518b2018-05-12 22:29:12 +0900512 // check against the not-yet-release API
513 props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
514 props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
Jiyong Park58c518b2018-05-12 22:29:12 +0900515
516 // check against the latest released API
517 props.Check_api.Last_released.Api_file = proptools.StringPtr(
518 module.latestApiFilegroupName(apiScope))
519 props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
520 module.latestRemovedApiFilegroupName(apiScope))
Inseob Kim38449af2019-02-28 14:24:05 +0900521 props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
Sundong Ahn054b19a2018-10-19 13:46:09 +0900522 props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
523 props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
524 props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
Jiyong Park58c518b2018-05-12 22:29:12 +0900525
Sundong Ahn04ef8a32019-01-14 11:36:50 +0900526 mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900527}
528
Jiyong Parkc678ad32018-04-10 13:07:10 +0900529// Creates the xml file that publicizes the runtime library
Colin Crossf8b860a2019-04-16 14:43:28 -0700530func (module *SdkLibrary) createXmlFile(mctx android.LoadHookContext) {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900531 template := `
532<?xml version="1.0" encoding="utf-8"?>
533<!-- Copyright (C) 2018 The Android Open Source Project
534
535 Licensed under the Apache License, Version 2.0 (the "License");
536 you may not use this file except in compliance with the License.
537 You may obtain a copy of the License at
538
539 http://www.apache.org/licenses/LICENSE-2.0
540
541 Unless required by applicable law or agreed to in writing, software
542 distributed under the License is distributed on an "AS IS" BASIS,
543 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
544 See the License for the specific language governing permissions and
545 limitations under the License.
546-->
547
548<permissions>
549 <library name="%s" file="%s"/>
550</permissions>
551`
552 // genrule to generate the xml file content from the template above
553 // TODO: preserve newlines in the generate xml file. Newlines are being squashed
554 // in the ninja file. Do we need to have an external tool for this?
555 xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
556 genruleProps := struct {
557 Name *string
558 Cmd *string
559 Out []string
560 }{}
561 genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
562 genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
563 genruleProps.Out = []string{module.xmlFileName()}
564 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
565
566 // creates a prebuilt_etc module to actually place the xml file under
567 // <partition>/etc/permissions
568 etcProps := struct {
569 Name *string
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900570 Src *string
Jiyong Parkc678ad32018-04-10 13:07:10 +0900571 Sub_dir *string
572 Soc_specific *bool
573 Device_specific *bool
574 Product_specific *bool
575 }{}
576 etcProps.Name = proptools.StringPtr(module.xmlFileName())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900577 etcProps.Src = proptools.StringPtr(":" + module.xmlFileName() + "-gen")
Jiyong Parkc678ad32018-04-10 13:07:10 +0900578 etcProps.Sub_dir = proptools.StringPtr("permissions")
579 if module.SocSpecific() {
580 etcProps.Soc_specific = proptools.BoolPtr(true)
581 } else if module.DeviceSpecific() {
582 etcProps.Device_specific = proptools.BoolPtr(true)
583 } else if module.ProductSpecific() {
584 etcProps.Product_specific = proptools.BoolPtr(true)
585 }
586 mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
587}
588
Inseob Kimc0907f12019-02-08 21:00:45 +0900589func (module *SdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900590 var api, v string
591 if sdkVersion == "" {
592 api = "system"
593 v = "current"
594 } else if strings.Contains(sdkVersion, "_") {
595 t := strings.Split(sdkVersion, "_")
596 api = t[0]
597 v = t[1]
Jiyong Parkc678ad32018-04-10 13:07:10 +0900598 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900599 api = "public"
600 v = sdkVersion
601 }
602 dir := filepath.Join("prebuilts", "sdk", v, api)
603 jar := filepath.Join(dir, module.BaseModuleName()+".jar")
604 jarPath := android.ExistentPathForSource(ctx, jar)
Sundong Ahnae418ac2019-02-28 15:01:28 +0900605 if !jarPath.Valid() {
606 ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", v, jar)
607 return nil
608 }
Sundong Ahn054b19a2018-10-19 13:46:09 +0900609 return android.Paths{jarPath.Path()}
610}
611
612// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900613func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900614 // This module is just a wrapper for the stubs.
Colin Cross10932872019-04-18 14:27:12 -0700615 if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900616 return module.PrebuiltJars(ctx, sdkVersion)
617 } else {
618 if strings.HasPrefix(sdkVersion, "system_") {
619 return module.systemApiStubsPath
620 } else if sdkVersion == "" {
621 return module.Library.HeaderJars()
622 } else {
623 return module.publicApiStubsPath
624 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900625 }
626}
627
Sundong Ahn241cd372018-07-13 16:16:44 +0900628// to satisfy SdkLibraryDependency interface
Inseob Kimc0907f12019-02-08 21:00:45 +0900629func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
Sundong Ahn241cd372018-07-13 16:16:44 +0900630 // This module is just a wrapper for the stubs.
Colin Cross10932872019-04-18 14:27:12 -0700631 if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900632 return module.PrebuiltJars(ctx, sdkVersion)
Sundong Ahn241cd372018-07-13 16:16:44 +0900633 } else {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900634 if strings.HasPrefix(sdkVersion, "system_") {
635 return module.systemApiStubsImplPath
636 } else if sdkVersion == "" {
637 return module.Library.ImplementationJars()
638 } else {
639 return module.publicApiStubsImplPath
640 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900641 }
642}
643
Colin Cross571cccf2019-02-04 11:22:08 -0800644var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
645
Jiyong Park82484c02018-04-23 21:41:26 +0900646func javaSdkLibraries(config android.Config) *[]string {
Colin Cross571cccf2019-02-04 11:22:08 -0800647 return config.Once(javaSdkLibrariesKey, func() interface{} {
Jiyong Park82484c02018-04-23 21:41:26 +0900648 return &[]string{}
649 }).(*[]string)
650}
651
Jiyong Parkc678ad32018-04-10 13:07:10 +0900652// For a java_sdk_library module, create internal modules for stubs, docs,
653// runtime libs and xml file. If requested, the stubs and docs are created twice
654// once for public API level and once for system API level
Colin Crossf8b860a2019-04-16 14:43:28 -0700655func (module *SdkLibrary) CreateInternalModules(mctx android.LoadHookContext) {
Inseob Kim6e93ac92019-03-21 17:43:49 +0900656 if len(module.Library.Module.properties.Srcs) == 0 {
Inseob Kimc0907f12019-02-08 21:00:45 +0900657 mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
658 }
659
Inseob Kim6e93ac92019-03-21 17:43:49 +0900660 if len(module.sdkLibraryProperties.Api_packages) == 0 {
Inseob Kimc0907f12019-02-08 21:00:45 +0900661 mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
662 }
Inseob Kim8098faa2019-03-18 10:19:51 +0900663
664 missing_current_api := false
665
666 for _, scope := range []string{"", "system-", "test-"} {
667 for _, api := range []string{"current.txt", "removed.txt"} {
668 path := path.Join(mctx.ModuleDir(), "api", scope+api)
669 p := android.ExistentPathForSource(mctx, path)
670 if !p.Valid() {
671 mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
672 missing_current_api = true
673 }
674 }
675 }
676
677 if missing_current_api {
678 script := "build/soong/scripts/gen-java-current-api-files.sh"
679 p := android.ExistentPathForSource(mctx, script)
680
681 if !p.Valid() {
682 panic(fmt.Sprintf("script file %s doesn't exist", script))
683 }
684
685 mctx.ModuleErrorf("One or more current api files are missing. "+
686 "You can update them by:\n"+
687 "%s %q && m update-api", script, mctx.ModuleDir())
688 return
689 }
690
Inseob Kimc0907f12019-02-08 21:00:45 +0900691 // for public API stubs
692 module.createStubsLibrary(mctx, apiScopePublic)
693 module.createDocs(mctx, apiScopePublic)
694
695 if !Bool(module.properties.No_standard_libs) {
696 // for system API stubs
697 module.createStubsLibrary(mctx, apiScopeSystem)
698 module.createDocs(mctx, apiScopeSystem)
699
700 // for test API stubs
701 module.createStubsLibrary(mctx, apiScopeTest)
702 module.createDocs(mctx, apiScopeTest)
703
704 // for runtime
705 module.createXmlFile(mctx)
706 }
707
708 // record java_sdk_library modules so that they are exported to make
709 javaSdkLibraries := javaSdkLibraries(mctx.Config())
710 javaSdkLibrariesLock.Lock()
711 defer javaSdkLibrariesLock.Unlock()
712 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
713}
714
715func (module *SdkLibrary) InitSdkLibraryProperties() {
Sundong Ahn054b19a2018-10-19 13:46:09 +0900716 module.AddProperties(
717 &module.sdkLibraryProperties,
718 &module.Library.Module.properties,
719 &module.Library.Module.dexpreoptProperties,
720 &module.Library.Module.deviceProperties,
721 &module.Library.Module.protoProperties,
722 )
723
724 module.Library.Module.properties.Installable = proptools.BoolPtr(true)
725 module.Library.Module.deviceProperties.IsSDKLibrary = true
Inseob Kimc0907f12019-02-08 21:00:45 +0900726}
Sundong Ahn054b19a2018-10-19 13:46:09 +0900727
Inseob Kimc0907f12019-02-08 21:00:45 +0900728func SdkLibraryFactory() android.Module {
729 module := &SdkLibrary{}
730 module.InitSdkLibraryProperties()
Sundong Ahn054b19a2018-10-19 13:46:09 +0900731 InitJavaModule(module, android.HostAndDeviceSupported)
Colin Crossf8b860a2019-04-16 14:43:28 -0700732 android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.CreateInternalModules(ctx) })
Jiyong Parkc678ad32018-04-10 13:07:10 +0900733 return module
734}
Colin Cross79c7c262019-04-17 11:11:46 -0700735
736//
737// SDK library prebuilts
738//
739
740type sdkLibraryImportProperties struct {
741 Jars []string `android:"path"`
742
743 Sdk_version *string
744
745 Installable *bool
746
747 // List of shared java libs that this module has dependencies to
748 Libs []string
749
750 // List of files to remove from the jar file(s)
751 Exclude_files []string
752
753 // List of directories to remove from the jar file(s)
754 Exclude_dirs []string
755}
756
757type sdkLibraryImport struct {
758 android.ModuleBase
759 android.DefaultableModuleBase
760 prebuilt android.Prebuilt
761
762 properties sdkLibraryImportProperties
763
764 stubsPath android.Paths
765}
766
767var _ SdkLibraryDependency = (*sdkLibraryImport)(nil)
768
769func sdkLibraryImportFactory() android.Module {
770 module := &sdkLibraryImport{}
771
772 module.AddProperties(&module.properties)
773
774 android.InitPrebuiltModule(module, &module.properties.Jars)
775 InitJavaModule(module, android.HostAndDeviceSupported)
776
777 android.AddLoadHook(module, func(mctx android.LoadHookContext) { module.createInternalModules(mctx) })
778 return module
779}
780
781func (module *sdkLibraryImport) Prebuilt() *android.Prebuilt {
782 return &module.prebuilt
783}
784
785func (module *sdkLibraryImport) Name() string {
786 return module.prebuilt.Name(module.ModuleBase.Name())
787}
788
789func (module *sdkLibraryImport) createInternalModules(mctx android.LoadHookContext) {
790 // Creates a java import for the jar with ".stubs" suffix
791 props := struct {
792 Name *string
793 Soc_specific *bool
794 Device_specific *bool
795 Product_specific *bool
796 }{}
797
798 props.Name = proptools.StringPtr(module.BaseModuleName() + sdkStubsLibrarySuffix)
799
800 if module.SocSpecific() {
801 props.Soc_specific = proptools.BoolPtr(true)
802 } else if module.DeviceSpecific() {
803 props.Device_specific = proptools.BoolPtr(true)
804 } else if module.ProductSpecific() {
805 props.Product_specific = proptools.BoolPtr(true)
806 }
807
808 mctx.CreateModule(android.ModuleFactoryAdaptor(ImportFactory), &props, &module.properties)
809
810 javaSdkLibraries := javaSdkLibraries(mctx.Config())
811 javaSdkLibrariesLock.Lock()
812 defer javaSdkLibrariesLock.Unlock()
813 *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
814}
815
816func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
817 // Add dependencies to the prebuilt stubs library
818 ctx.AddVariationDependencies(nil, publicApiStubsTag, module.BaseModuleName()+sdkStubsLibrarySuffix)
819}
820
821func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
822 // Record the paths to the prebuilt stubs library.
823 ctx.VisitDirectDeps(func(to android.Module) {
824 tag := ctx.OtherModuleDependencyTag(to)
825
826 switch tag {
827 case publicApiStubsTag:
828 module.stubsPath = to.(Dependency).HeaderJars()
829 }
830 })
831}
832
833// to satisfy SdkLibraryDependency interface
834func (module *sdkLibraryImport) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
835 // This module is just a wrapper for the prebuilt stubs.
836 return module.stubsPath
837}
838
839// to satisfy SdkLibraryDependency interface
840func (module *sdkLibraryImport) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
841 // This module is just a wrapper for the stubs.
842 return module.stubsPath
843}