blob: 69d94d63b9fccff39c4af2e185c22718357185d4 [file] [log] [blame]
Steven Morelandd56e5bb2017-07-18 22:04:16 -07001// Copyright (C) 2017 The Android Open Source Project
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 hidl
16
17import (
18 "strings"
19 "sync"
20
21 "github.com/google/blueprint/proptools"
22
23 "android/soong/android"
24 "android/soong/cc"
25 "android/soong/genrule"
26 "android/soong/java"
27)
28
29var (
30 hidlInterfaceSuffix = "_interface"
31)
32
33func init() {
34 android.RegisterModuleType("hidl_interface", hidlInterfaceFactory)
35}
36
37type hidlInterfaceProperties struct {
38 // Vndk properties for interface library only.
39 cc.VndkProperties
40
Steven Moreland89a9ebb2017-12-04 10:18:00 -080041 // The owner of the module
42 Owner *string
43
Steven Morelandd56e5bb2017-07-18 22:04:16 -070044 // List of .hal files which compose this interface.
45 Srcs []string
46
47 // List of hal interface packages that this library depends on.
48 Interfaces []string
49
50 // Package root for this package, must be a prefix of name
51 Root string
52
53 // List of non-TypeDef types declared in types.hal.
54 Types []string
55
56 // Whether to generate the Java library stubs.
57 // Default: true
58 Gen_java *bool
59
60 // Whether to generate a Java library containing constants
61 // expressed by @export annotations in the hal files.
62 Gen_java_constants bool
Steven Morelandd56e5bb2017-07-18 22:04:16 -070063}
64
65type hidlInterface struct {
66 android.ModuleBase
67
68 properties hidlInterfaceProperties
69}
70
Steven Morelandd56e5bb2017-07-18 22:04:16 -070071func processSources(mctx android.LoadHookContext, srcs []string) ([]string, []string, bool) {
72 var interfaces []string
73 var types []string // hidl-gen only supports types.hal, but don't assume that here
74
75 hasError := false
76
77 for _, v := range srcs {
78 if !strings.HasSuffix(v, ".hal") {
79 mctx.PropertyErrorf("srcs", "Source must be a .hal file: "+v)
80 hasError = true
81 continue
82 }
83
84 name := strings.TrimSuffix(v, ".hal")
85
86 if strings.HasPrefix(name, "I") {
87 baseName := strings.TrimPrefix(name, "I")
88 interfaces = append(interfaces, baseName)
89 } else {
90 types = append(types, name)
91 }
92 }
93
94 return interfaces, types, !hasError
95}
96
97func processDependencies(mctx android.LoadHookContext, interfaces []string) ([]string, []string, bool) {
98 var dependencies []string
99 var javaDependencies []string
100
101 hasError := false
102
103 for _, v := range interfaces {
104 name, err := parseFqName(v)
105 if err != nil {
106 mctx.PropertyErrorf("interfaces", err.Error())
107 hasError = true
108 continue
109 }
110 dependencies = append(dependencies, name.string())
111 javaDependencies = append(javaDependencies, name.javaName())
112 }
113
114 return dependencies, javaDependencies, !hasError
115}
116
117func getRootList(mctx android.LoadHookContext, interfaces []string) ([]string, bool) {
118 var roots []string
119 hasError := false
120
121 for _, i := range interfaces {
122 interfaceObject := lookupInterface(i)
123 if interfaceObject == nil {
124 mctx.PropertyErrorf("interfaces", "Cannot find interface "+i)
125 hasError = true
126 continue
127 }
128 root := interfaceObject.properties.Root
129 rootObject := lookupPackageRoot(root)
130 if rootObject == nil {
Steven Morelande34b9df2017-11-29 14:40:50 -0800131 mctx.PropertyErrorf("interfaces", `Cannot find package root specification for package `+
132 `root '%s' needed for module '%s'. Either this is a mispelling of the package `+
133 `root, or a new hidl_package_root module needs to be added. For example, you can `+
134 `fix this error by adding the following to <some path>/Android.bp:
135
136hidl_package_root {
137 name: "%s",
138 path: "<some path>",
139}
140
141This corresponds to the "-r%s:<some path>" option that would be passed into hidl-gen.`, root, i, root, root)
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700142 hasError = true
143 continue
144 }
145
146 roots = append(roots, root+":"+rootObject.properties.Path)
147 }
148
149 return android.FirstUniqueStrings(roots), !hasError
150}
151
152func removeCoreDependencies(mctx android.LoadHookContext, dependencies []string) ([]string, bool) {
153 var ret []string
154 hasError := false
155
156 for _, i := range dependencies {
Steven Morelandb49d3a72018-07-25 16:40:03 -0700157 if !isCorePackage(i) {
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700158 ret = append(ret, i)
159 }
160 }
161
162 return ret, !hasError
163}
164
165func hidlGenCommand(lang string, roots []string, name *fqName) *string {
Colin Crossa8109602018-07-11 14:51:24 -0700166 cmd := "$(location hidl-gen) -p . -d $(depfile) -o $(genDir)"
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700167 cmd += " -L" + lang
168 cmd += " " + strings.Join(wrap("-r", roots, ""), " ")
169 cmd += " " + name.string()
170 return &cmd
171}
172
173func hidlInterfaceMutator(mctx android.LoadHookContext, i *hidlInterface) {
174 name, err := parseFqName(i.ModuleBase.Name())
175 if err != nil {
176 mctx.PropertyErrorf("name", err.Error())
177 }
178
179 if !name.inPackage(i.properties.Root) {
180 mctx.PropertyErrorf("root", "Root, "+i.properties.Root+", for "+name.string()+" must be a prefix.")
181 }
182
183 interfaces, types, _ := processSources(mctx, i.properties.Srcs)
184
185 if len(interfaces) == 0 && len(types) == 0 {
186 mctx.PropertyErrorf("srcs", "No sources provided.")
187 }
188
189 dependencies, javaDependencies, _ := processDependencies(mctx, i.properties.Interfaces)
Steven Moreland12ff1262017-11-13 13:35:37 -0800190 roots, _ := getRootList(mctx, append(dependencies, name.string()))
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700191 cppDependencies, _ := removeCoreDependencies(mctx, dependencies)
192
193 if mctx.Failed() {
194 return
195 }
196
Steven Morelandb49d3a72018-07-25 16:40:03 -0700197 shouldGenerateLibrary := !isCorePackage(name.string())
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700198 // explicitly true if not specified to give early warning to devs
199 shouldGenerateJava := i.properties.Gen_java == nil || *i.properties.Gen_java
200 shouldGenerateJavaConstants := i.properties.Gen_java_constants
201
202 var libraryIfExists []string
203 if shouldGenerateLibrary {
204 libraryIfExists = []string{name.string()}
205 }
206
207 // TODO(b/69002743): remove filegroups
Pirama Arumuga Nainarf43bb1e2018-04-18 11:34:56 -0700208 mctx.CreateModule(android.ModuleFactoryAdaptor(android.FileGroupFactory), &fileGroupProperties{
Steven Moreland89a9ebb2017-12-04 10:18:00 -0800209 Name: proptools.StringPtr(name.fileGroupName()),
210 Owner: i.properties.Owner,
211 Srcs: i.properties.Srcs,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700212 })
213
214 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800215 Name: proptools.StringPtr(name.sourcesName()),
216 Depfile: proptools.BoolPtr(true),
217 Owner: i.properties.Owner,
218 Tools: []string{"hidl-gen"},
219 Cmd: hidlGenCommand("c++-sources", roots, name),
220 Srcs: i.properties.Srcs,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700221 Out: concat(wrap(name.dir(), interfaces, "All.cpp"),
222 wrap(name.dir(), types, ".cpp")),
223 })
224 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800225 Name: proptools.StringPtr(name.headersName()),
226 Depfile: proptools.BoolPtr(true),
227 Owner: i.properties.Owner,
228 Tools: []string{"hidl-gen"},
229 Cmd: hidlGenCommand("c++-headers", roots, name),
230 Srcs: i.properties.Srcs,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700231 Out: concat(wrap(name.dir()+"I", interfaces, ".h"),
232 wrap(name.dir()+"Bs", interfaces, ".h"),
233 wrap(name.dir()+"BnHw", interfaces, ".h"),
234 wrap(name.dir()+"BpHw", interfaces, ".h"),
235 wrap(name.dir()+"IHw", interfaces, ".h"),
236 wrap(name.dir(), types, ".h"),
237 wrap(name.dir()+"hw", types, ".h")),
238 })
239
240 if shouldGenerateLibrary {
241 mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
Jerry Zhangf2a93962018-05-30 17:16:05 -0700242 Name: proptools.StringPtr(name.string()),
243 Owner: i.properties.Owner,
244 Recovery_available: proptools.BoolPtr(true),
245 Vendor_available: proptools.BoolPtr(true),
246 Double_loadable: proptools.BoolPtr(isDoubleLoadable(name.string())),
247 Defaults: []string{"hidl-module-defaults"},
248 Generated_sources: []string{name.sourcesName()},
249 Generated_headers: []string{name.headersName()},
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700250 Shared_libs: concat(cppDependencies, []string{
251 "libhidlbase",
252 "libhidltransport",
253 "libhwbinder",
254 "liblog",
255 "libutils",
256 "libcutils",
257 }),
258 Export_shared_lib_headers: concat(cppDependencies, []string{
259 "libhidlbase",
260 "libhidltransport",
261 "libhwbinder",
262 "libutils",
263 }),
264 Export_generated_headers: []string{name.headersName()},
265 }, &i.properties.VndkProperties)
266 }
267
268 if shouldGenerateJava {
269 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800270 Name: proptools.StringPtr(name.javaSourcesName()),
271 Depfile: proptools.BoolPtr(true),
272 Owner: i.properties.Owner,
273 Tools: []string{"hidl-gen"},
274 Cmd: hidlGenCommand("java", roots, name),
275 Srcs: i.properties.Srcs,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700276 Out: concat(wrap(name.sanitizedDir()+"I", interfaces, ".java"),
277 wrap(name.sanitizedDir(), i.properties.Types, ".java")),
278 })
Colin Crossf5536c32018-06-26 23:29:10 -0700279 mctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProperties{
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700280 Name: proptools.StringPtr(name.javaName()),
Steven Moreland89a9ebb2017-12-04 10:18:00 -0800281 Owner: i.properties.Owner,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700282 Defaults: []string{"hidl-java-module-defaults"},
283 No_framework_libs: proptools.BoolPtr(true),
Colin Crossf5536c32018-06-26 23:29:10 -0700284 Installable: proptools.BoolPtr(true),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700285 Srcs: []string{":" + name.javaSourcesName()},
Steven Morelandfcfbeaf2018-01-29 19:34:52 -0800286 Static_libs: javaDependencies,
Colin Crossa5050552018-03-29 10:30:03 -0700287
288 // This should ideally be system_current, but android.hidl.base-V1.0-java is used
289 // to build framework, which is used to build system_current. Use core_current
290 // plus hwbinder.stubs, which together form a subset of system_current that does
291 // not depend on framework.
292 Sdk_version: proptools.StringPtr("core_current"),
293 Libs: []string{"hwbinder.stubs"},
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700294 })
295 }
296
297 if shouldGenerateJavaConstants {
298 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800299 Name: proptools.StringPtr(name.javaConstantsSourcesName()),
300 Depfile: proptools.BoolPtr(true),
301 Owner: i.properties.Owner,
302 Tools: []string{"hidl-gen"},
303 Cmd: hidlGenCommand("java-constants", roots, name),
304 Srcs: i.properties.Srcs,
305 Out: []string{name.sanitizedDir() + "Constants.java"},
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700306 })
Colin Crossf5536c32018-06-26 23:29:10 -0700307 mctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProperties{
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700308 Name: proptools.StringPtr(name.javaConstantsName()),
Steven Moreland89a9ebb2017-12-04 10:18:00 -0800309 Owner: i.properties.Owner,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700310 Defaults: []string{"hidl-java-module-defaults"},
311 No_framework_libs: proptools.BoolPtr(true),
312 Srcs: []string{":" + name.javaConstantsSourcesName()},
313 })
314 }
315
316 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800317 Name: proptools.StringPtr(name.adapterHelperSourcesName()),
318 Depfile: proptools.BoolPtr(true),
319 Owner: i.properties.Owner,
320 Tools: []string{"hidl-gen"},
321 Cmd: hidlGenCommand("c++-adapter-sources", roots, name),
322 Srcs: i.properties.Srcs,
323 Out: wrap(name.dir()+"A", concat(interfaces, types), ".cpp"),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700324 })
325 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800326 Name: proptools.StringPtr(name.adapterHelperHeadersName()),
327 Depfile: proptools.BoolPtr(true),
328 Owner: i.properties.Owner,
329 Tools: []string{"hidl-gen"},
330 Cmd: hidlGenCommand("c++-adapter-headers", roots, name),
331 Srcs: i.properties.Srcs,
332 Out: wrap(name.dir()+"A", concat(interfaces, types), ".h"),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700333 })
334
335 mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
336 Name: proptools.StringPtr(name.adapterHelperName()),
Steven Moreland89a9ebb2017-12-04 10:18:00 -0800337 Owner: i.properties.Owner,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700338 Vendor_available: proptools.BoolPtr(true),
339 Defaults: []string{"hidl-module-defaults"},
340 Generated_sources: []string{name.adapterHelperSourcesName()},
341 Generated_headers: []string{name.adapterHelperHeadersName()},
Steven Moreland10d1ec42017-11-29 13:56:28 -0800342 Shared_libs: []string{
Steven Morelandd90bdaa2018-01-03 11:12:43 -0800343 "libbase",
Steven Morelandffa25282017-11-13 14:23:25 -0800344 "libcutils",
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700345 "libhidlbase",
346 "libhidltransport",
Steven Morelandffa25282017-11-13 14:23:25 -0800347 "libhwbinder",
348 "liblog",
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700349 "libutils",
Steven Morelandffa25282017-11-13 14:23:25 -0800350 },
351 Static_libs: concat([]string{
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700352 "libhidladapter",
353 }, wrap("", dependencies, "-adapter-helper"), cppDependencies, libraryIfExists),
Steven Morelandffa25282017-11-13 14:23:25 -0800354 Export_shared_lib_headers: []string{
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700355 "libhidlbase",
356 "libhidltransport",
Steven Morelandffa25282017-11-13 14:23:25 -0800357 },
358 Export_static_lib_headers: concat([]string{
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700359 "libhidladapter",
360 }, wrap("", dependencies, "-adapter-helper"), cppDependencies, libraryIfExists),
361 Export_generated_headers: []string{name.adapterHelperHeadersName()},
Steven Moreland10d1ec42017-11-29 13:56:28 -0800362 Group_static_libs: proptools.BoolPtr(true),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700363 })
364 mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProperties{
Steven Moreland394af5c2018-02-09 14:41:46 -0800365 Name: proptools.StringPtr(name.adapterSourcesName()),
366 Depfile: proptools.BoolPtr(true),
367 Owner: i.properties.Owner,
368 Tools: []string{"hidl-gen"},
369 Cmd: hidlGenCommand("c++-adapter-main", roots, name),
370 Srcs: i.properties.Srcs,
371 Out: []string{"main.cpp"},
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700372 })
373 mctx.CreateModule(android.ModuleFactoryAdaptor(cc.TestFactory), &ccProperties{
374 Name: proptools.StringPtr(name.adapterName()),
Steven Moreland89a9ebb2017-12-04 10:18:00 -0800375 Owner: i.properties.Owner,
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700376 Generated_sources: []string{name.adapterSourcesName()},
Steven Moreland10d1ec42017-11-29 13:56:28 -0800377 Shared_libs: []string{
Steven Morelandd90bdaa2018-01-03 11:12:43 -0800378 "libbase",
Steven Morelandffa25282017-11-13 14:23:25 -0800379 "libcutils",
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700380 "libhidlbase",
381 "libhidltransport",
Steven Morelandffa25282017-11-13 14:23:25 -0800382 "libhwbinder",
383 "liblog",
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700384 "libutils",
Steven Morelandffa25282017-11-13 14:23:25 -0800385 },
386 Static_libs: concat([]string{
387 "libhidladapter",
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700388 name.adapterHelperName(),
Steven Morelandffa25282017-11-13 14:23:25 -0800389 }, wrap("", dependencies, "-adapter-helper"), cppDependencies, libraryIfExists),
390 Group_static_libs: proptools.BoolPtr(true),
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700391 })
392}
393
394func (h *hidlInterface) Name() string {
395 return h.ModuleBase.Name() + hidlInterfaceSuffix
396}
397func (h *hidlInterface) GenerateAndroidBuildActions(ctx android.ModuleContext) {
398}
399func (h *hidlInterface) DepsMutator(ctx android.BottomUpMutatorContext) {
400}
Steven Morelandd56e5bb2017-07-18 22:04:16 -0700401
402var hidlInterfaceMutex sync.Mutex
403var hidlInterfaces []*hidlInterface
404
405func hidlInterfaceFactory() android.Module {
406 i := &hidlInterface{}
407 i.AddProperties(&i.properties)
408 android.InitAndroidModule(i)
409 android.AddLoadHook(i, func(ctx android.LoadHookContext) { hidlInterfaceMutator(ctx, i) })
410
411 hidlInterfaceMutex.Lock()
412 hidlInterfaces = append(hidlInterfaces, i)
413 hidlInterfaceMutex.Unlock()
414
415 return i
416}
417
418func lookupInterface(name string) *hidlInterface {
419 for _, i := range hidlInterfaces {
420 if i.ModuleBase.Name() == name {
421 return i
422 }
423 }
424 return nil
425}
Jiyong Parkd26759f2018-04-09 12:22:18 +0900426
Colin Crossf5536c32018-06-26 23:29:10 -0700427var doubleLoadablePackageNames = []string{
Jiyong Parkd26759f2018-04-09 12:22:18 +0900428 "android.hardware.configstore@",
429 "android.hardware.graphics.allocator@",
430 "android.hardware.graphics.bufferqueue@",
431 "android.hardware.media.omx@",
432 "android.hardware.media@",
433 "android.hardware.neuralnetworks@",
434 "android.hidl.allocator@",
435 "android.hidl.token@",
436}
437
438func isDoubleLoadable(name string) bool {
439 for _, pkgname := range doubleLoadablePackageNames {
440 if strings.HasPrefix(name, pkgname) {
441 return true
442 }
443 }
444 return false
445}
Steven Morelandb49d3a72018-07-25 16:40:03 -0700446
447// packages in libhidltransport
448var coreDependencyPackageNames = []string{
449 "android.hidl.base@",
450 "android.hidl.manager@",
451}
452
453func isCorePackage(name string) bool {
454 for _, pkgname := range coreDependencyPackageNames {
455 if strings.HasPrefix(name, pkgname) {
456 return true
457 }
458 }
459 return false
460}