• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// 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	"fmt"
19	"sort"
20	"strings"
21	"sync"
22
23	"github.com/google/blueprint"
24	"github.com/google/blueprint/proptools"
25
26	"android/soong/android"
27	"android/soong/cc"
28	"android/soong/genrule"
29	"android/soong/java"
30)
31
32var (
33	hidlInterfaceSuffix = "_interface"
34
35	pctx = android.NewPackageContext("android/hidl")
36
37	hidl      = pctx.HostBinToolVariable("hidl", "hidl-gen")
38	vtsc      = pctx.HostBinToolVariable("vtsc", "vtsc")
39	soong_zip = pctx.HostBinToolVariable("soong_zip", "soong_zip")
40
41	hidlRule = pctx.StaticRule("hidlRule", blueprint.RuleParams{
42		Depfile:     "${depfile}",
43		Deps:        blueprint.DepsGCC,
44		Command:     "rm -rf ${genDir} && ${hidl} -R -p . -d ${depfile} -o ${genDir} -L ${language} ${roots} ${fqName}",
45		CommandDeps: []string{"${hidl}"},
46		Description: "HIDL ${language}: ${in} => ${out}",
47	}, "depfile", "fqName", "genDir", "language", "roots")
48
49	hidlSrcJarRule = pctx.StaticRule("hidlSrcJarRule", blueprint.RuleParams{
50		Depfile: "${depfile}",
51		Deps:    blueprint.DepsGCC,
52		Command: "rm -rf ${genDir} && " +
53			"${hidl} -R -p . -d ${depfile} -o ${genDir}/srcs -L ${language} ${roots} ${fqName} && " +
54			"${soong_zip} -o ${genDir}/srcs.srcjar -C ${genDir}/srcs -D ${genDir}/srcs",
55		CommandDeps: []string{"${hidl}", "${soong_zip}"},
56		Description: "HIDL ${language}: ${in} => srcs.srcjar",
57	}, "depfile", "fqName", "genDir", "language", "roots")
58
59	vtsRule = pctx.StaticRule("vtsRule", blueprint.RuleParams{
60		Command:     "rm -rf ${genDir} && ${vtsc} -m${mode} -t${type} ${inputDir}/${packagePath} ${genDir}/${packagePath}",
61		CommandDeps: []string{"${vtsc}"},
62		Description: "VTS ${mode} ${type}: ${in} => ${out}",
63	}, "mode", "type", "inputDir", "genDir", "packagePath")
64)
65
66func init() {
67	android.RegisterModuleType("hidl_interface", hidlInterfaceFactory)
68	android.RegisterMakeVarsProvider(pctx, makeVarsProvider)
69}
70
71type hidlGenProperties struct {
72	Language   string
73	FqName     string
74	Root       string
75	Interfaces []string
76	Inputs     []string
77	Outputs    []string
78}
79
80type hidlGenRule struct {
81	android.ModuleBase
82
83	properties hidlGenProperties
84
85	genOutputDir android.Path
86	genInputs    android.Paths
87	genOutputs   android.WritablePaths
88}
89
90var _ android.SourceFileProducer = (*hidlGenRule)(nil)
91var _ genrule.SourceFileGenerator = (*hidlGenRule)(nil)
92
93func (g *hidlGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
94	g.genOutputDir = android.PathForModuleGen(ctx)
95
96	for _, input := range g.properties.Inputs {
97		g.genInputs = append(g.genInputs, android.PathForModuleSrc(ctx, input))
98	}
99
100	for _, output := range g.properties.Outputs {
101		g.genOutputs = append(g.genOutputs, android.PathForModuleGen(ctx, output))
102	}
103
104	if g.properties.Language == "vts" && isVtsSpecPackage(ctx.ModuleName()) {
105		vtsList := vtsList(ctx.AConfig())
106		vtsListMutex.Lock()
107		*vtsList = append(*vtsList, g.genOutputs.Paths()...)
108		vtsListMutex.Unlock()
109	}
110
111	var fullRootOptions []string
112	var currentPath android.OptionalPath
113	ctx.VisitDirectDeps(func(dep android.Module) {
114		switch t := dep.(type) {
115		case *hidlInterface:
116			fullRootOptions = append(fullRootOptions, t.properties.Full_root_option)
117		case *hidlPackageRoot:
118			if currentPath.Valid() {
119				panic(fmt.Sprintf("Expecting only one path, but found %v %v", currentPath, t.getCurrentPath()))
120			}
121
122			currentPath = t.getCurrentPath()
123		default:
124			panic(fmt.Sprintf("Unrecognized hidlGenProperties dependency: %T", t))
125		}
126	})
127
128	fullRootOptions = android.FirstUniqueStrings(fullRootOptions)
129
130	inputs := g.genInputs
131	if currentPath.Valid() {
132		inputs = append(inputs, currentPath.Path())
133	}
134
135	rule := hidlRule
136	if g.properties.Language == "java" {
137		rule = hidlSrcJarRule
138	}
139
140	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
141		Rule:            rule,
142		Inputs:          inputs,
143		Output:          g.genOutputs[0],
144		ImplicitOutputs: g.genOutputs[1:],
145		Args: map[string]string{
146			"depfile":  g.genOutputs[0].String() + ".d",
147			"genDir":   g.genOutputDir.String(),
148			"fqName":   g.properties.FqName,
149			"language": g.properties.Language,
150			"roots":    strings.Join(fullRootOptions, " "),
151		},
152	})
153}
154
155func (g *hidlGenRule) GeneratedSourceFiles() android.Paths {
156	return g.genOutputs.Paths()
157}
158
159func (g *hidlGenRule) Srcs() android.Paths {
160	return g.genOutputs.Paths()
161}
162
163func (g *hidlGenRule) GeneratedDeps() android.Paths {
164	return g.genOutputs.Paths()
165}
166
167func (g *hidlGenRule) GeneratedHeaderDirs() android.Paths {
168	return android.Paths{g.genOutputDir}
169}
170
171func (g *hidlGenRule) DepsMutator(ctx android.BottomUpMutatorContext) {
172	ctx.AddDependency(ctx.Module(), nil, g.properties.FqName+hidlInterfaceSuffix)
173	ctx.AddDependency(ctx.Module(), nil, wrap("", g.properties.Interfaces, hidlInterfaceSuffix)...)
174	ctx.AddDependency(ctx.Module(), nil, g.properties.Root)
175}
176
177func hidlGenFactory() android.Module {
178	g := &hidlGenRule{}
179	g.AddProperties(&g.properties)
180	android.InitAndroidModule(g)
181	return g
182}
183
184type vtscProperties struct {
185	Mode        string
186	Type        string
187	SpecName    string // e.g. foo-vts.spec
188	Outputs     []string
189	PackagePath string // e.g. android/hardware/foo/1.0/
190}
191
192type vtscRule struct {
193	android.ModuleBase
194
195	properties vtscProperties
196
197	genOutputDir android.Path
198	genInputDir  android.Path
199	genInputs    android.Paths
200	genOutputs   android.WritablePaths
201}
202
203var _ android.SourceFileProducer = (*vtscRule)(nil)
204var _ genrule.SourceFileGenerator = (*vtscRule)(nil)
205
206func (g *vtscRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
207	g.genOutputDir = android.PathForModuleGen(ctx)
208
209	ctx.VisitDirectDeps(func(dep android.Module) {
210		if specs, ok := dep.(*hidlGenRule); ok {
211			g.genInputDir = specs.genOutputDir
212			g.genInputs = specs.genOutputs.Paths()
213		}
214	})
215
216	for _, output := range g.properties.Outputs {
217		g.genOutputs = append(g.genOutputs, android.PathForModuleGen(ctx, output))
218	}
219
220	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
221		Rule:    vtsRule,
222		Inputs:  g.genInputs,
223		Outputs: g.genOutputs,
224		Args: map[string]string{
225			"mode":        g.properties.Mode,
226			"type":        g.properties.Type,
227			"inputDir":    g.genInputDir.String(),
228			"genDir":      g.genOutputDir.String(),
229			"packagePath": g.properties.PackagePath,
230		},
231	})
232}
233
234func (g *vtscRule) GeneratedSourceFiles() android.Paths {
235	return g.genOutputs.Paths()
236}
237
238func (g *vtscRule) Srcs() android.Paths {
239	return g.genOutputs.Paths()
240}
241
242func (g *vtscRule) GeneratedDeps() android.Paths {
243	return g.genOutputs.Paths()
244}
245
246func (g *vtscRule) GeneratedHeaderDirs() android.Paths {
247	return android.Paths{g.genOutputDir}
248}
249
250func (g *vtscRule) DepsMutator(ctx android.BottomUpMutatorContext) {
251	ctx.AddDependency(ctx.Module(), nil, g.properties.SpecName)
252}
253
254func vtscFactory() android.Module {
255	g := &vtscRule{}
256	g.AddProperties(&g.properties)
257	android.InitAndroidModule(g)
258	return g
259}
260
261type hidlInterfaceProperties struct {
262	// Vndk properties for interface library only.
263	cc.VndkProperties
264
265	// List of .hal files which compose this interface.
266	Srcs []string
267
268	// List of hal interface packages that this library depends on.
269	Interfaces []string
270
271	// Package root for this package, must be a prefix of name
272	Root string
273
274	// Unused/deprecated: List of non-TypeDef types declared in types.hal.
275	Types []string
276
277	// Whether to generate the Java library stubs.
278	// Default: true
279	Gen_java *bool
280
281	// Whether to generate a Java library containing constants
282	// expressed by @export annotations in the hal files.
283	Gen_java_constants bool
284
285	// Whether to generate VTS-related testing libraries.
286	Gen_vts *bool
287
288	// example: -randroid.hardware:hardware/interfaces
289	Full_root_option string `blueprint:"mutated"`
290}
291
292// TODO(b/119771576): These properties are shared by all Android modules, and we are specifically
293// calling these out to be copied to every create module. However, if a new property is added, it
294// could break things because this code has no way to know about that.
295type manuallyInheritCommonProperties struct {
296	Enabled          *bool
297	Compile_multilib *string
298	Target           struct {
299		Host struct {
300			Compile_multilib *string
301		}
302		Android struct {
303			Compile_multilib *string
304		}
305	}
306	Proprietary               *bool
307	Owner                     *string
308	Vendor                    *bool
309	Soc_specific              *bool
310	Device_specific           *bool
311	Product_specific          *bool
312	Product_services_specific *bool
313	Recovery                  *bool
314	Init_rc                   []string
315	Vintf_fragments           []string
316	Required                  []string
317	Notice                    *string
318	Dist                      struct {
319		Targets []string
320		Dest    *string
321		Dir     *string
322		Suffix  *string
323	}
324}
325
326type hidlInterface struct {
327	android.ModuleBase
328
329	properties              hidlInterfaceProperties
330	inheritCommonProperties manuallyInheritCommonProperties
331}
332
333func processSources(mctx android.LoadHookContext, srcs []string) ([]string, []string, bool) {
334	var interfaces []string
335	var types []string // hidl-gen only supports types.hal, but don't assume that here
336
337	hasError := false
338
339	for _, v := range srcs {
340		if !strings.HasSuffix(v, ".hal") {
341			mctx.PropertyErrorf("srcs", "Source must be a .hal file: "+v)
342			hasError = true
343			continue
344		}
345
346		name := strings.TrimSuffix(v, ".hal")
347
348		if strings.HasPrefix(name, "I") {
349			baseName := strings.TrimPrefix(name, "I")
350			interfaces = append(interfaces, baseName)
351		} else {
352			types = append(types, name)
353		}
354	}
355
356	return interfaces, types, !hasError
357}
358
359func processDependencies(mctx android.LoadHookContext, interfaces []string) ([]string, []string, bool) {
360	var dependencies []string
361	var javaDependencies []string
362
363	hasError := false
364
365	for _, v := range interfaces {
366		name, err := parseFqName(v)
367		if err != nil {
368			mctx.PropertyErrorf("interfaces", err.Error())
369			hasError = true
370			continue
371		}
372		dependencies = append(dependencies, name.string())
373		javaDependencies = append(javaDependencies, name.javaName())
374	}
375
376	return dependencies, javaDependencies, !hasError
377}
378
379func removeCoreDependencies(mctx android.LoadHookContext, dependencies []string) []string {
380	var ret []string
381
382	for _, i := range dependencies {
383		if !isCorePackage(i) {
384			ret = append(ret, i)
385		}
386	}
387
388	return ret
389}
390
391func hidlInterfaceMutator(mctx android.LoadHookContext, i *hidlInterface) {
392	name, err := parseFqName(i.ModuleBase.Name())
393	if err != nil {
394		mctx.PropertyErrorf("name", err.Error())
395	}
396
397	if !name.inPackage(i.properties.Root) {
398		mctx.PropertyErrorf("root", i.properties.Root+" must be a prefix of  "+name.string()+".")
399	}
400	if lookupPackageRoot(i.properties.Root) == nil {
401		mctx.PropertyErrorf("interfaces", `Cannot find package root specification for package `+
402			`root '%s' needed for module '%s'. Either this is a mispelling of the package `+
403			`root, or a new hidl_package_root module needs to be added. For example, you can `+
404			`fix this error by adding the following to <some path>/Android.bp:
405
406hidl_package_root {
407name: "%s",
408path: "<some path>",
409}
410
411This corresponds to the "-r%s:<some path>" option that would be passed into hidl-gen.`,
412			i.properties.Root, name, i.properties.Root, i.properties.Root)
413	}
414
415	interfaces, types, _ := processSources(mctx, i.properties.Srcs)
416
417	if len(interfaces) == 0 && len(types) == 0 {
418		mctx.PropertyErrorf("srcs", "No sources provided.")
419	}
420
421	dependencies, javaDependencies, _ := processDependencies(mctx, i.properties.Interfaces)
422	cppDependencies := removeCoreDependencies(mctx, dependencies)
423
424	if mctx.Failed() {
425		return
426	}
427
428	shouldGenerateLibrary := !isCorePackage(name.string())
429	// explicitly true if not specified to give early warning to devs
430	shouldGenerateJava := proptools.BoolDefault(i.properties.Gen_java, true)
431	shouldGenerateJavaConstants := i.properties.Gen_java_constants
432	shouldGenerateVts := shouldGenerateLibrary && proptools.BoolDefault(i.properties.Gen_vts, true)
433
434	var libraryIfExists []string
435	if shouldGenerateLibrary {
436		libraryIfExists = []string{name.string()}
437	}
438
439	// TODO(b/69002743): remove filegroups
440	mctx.CreateModule(android.ModuleFactoryAdaptor(android.FileGroupFactory), &fileGroupProperties{
441		Name: proptools.StringPtr(name.fileGroupName()),
442		Srcs: i.properties.Srcs,
443	}, &i.inheritCommonProperties)
444
445	mctx.CreateModule(android.ModuleFactoryAdaptor(hidlGenFactory), &nameProperties{
446		Name: proptools.StringPtr(name.sourcesName()),
447	}, &hidlGenProperties{
448		Language:   "c++-sources",
449		FqName:     name.string(),
450		Root:       i.properties.Root,
451		Interfaces: i.properties.Interfaces,
452		Inputs:     i.properties.Srcs,
453		Outputs:    concat(wrap(name.dir(), interfaces, "All.cpp"), wrap(name.dir(), types, ".cpp")),
454	}, &i.inheritCommonProperties)
455	mctx.CreateModule(android.ModuleFactoryAdaptor(hidlGenFactory), &nameProperties{
456		Name: proptools.StringPtr(name.headersName()),
457	}, &hidlGenProperties{
458		Language:   "c++-headers",
459		FqName:     name.string(),
460		Root:       i.properties.Root,
461		Interfaces: i.properties.Interfaces,
462		Inputs:     i.properties.Srcs,
463		Outputs: concat(wrap(name.dir()+"I", interfaces, ".h"),
464			wrap(name.dir()+"Bs", interfaces, ".h"),
465			wrap(name.dir()+"BnHw", interfaces, ".h"),
466			wrap(name.dir()+"BpHw", interfaces, ".h"),
467			wrap(name.dir()+"IHw", interfaces, ".h"),
468			wrap(name.dir(), types, ".h"),
469			wrap(name.dir()+"hw", types, ".h")),
470	}, &i.inheritCommonProperties)
471
472	if shouldGenerateLibrary {
473		mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
474			Name:               proptools.StringPtr(name.string()),
475			Recovery_available: proptools.BoolPtr(true),
476			Vendor_available:   proptools.BoolPtr(true),
477			Double_loadable:    proptools.BoolPtr(isDoubleLoadable(name.string())),
478			Defaults:           []string{"hidl-module-defaults"},
479			Generated_sources:  []string{name.sourcesName()},
480			Generated_headers:  []string{name.headersName()},
481			Shared_libs: concat(cppDependencies, []string{
482				"libhidlbase",
483				"libhidltransport",
484				"libhwbinder",
485				"liblog",
486				"libutils",
487				"libcutils",
488			}),
489			Export_shared_lib_headers: concat(cppDependencies, []string{
490				"libhidlbase",
491				"libhidltransport",
492				"libhwbinder",
493				"libutils",
494			}),
495			Export_generated_headers: []string{name.headersName()},
496		}, &i.properties.VndkProperties, &i.inheritCommonProperties)
497	}
498
499	if shouldGenerateJava {
500		mctx.CreateModule(android.ModuleFactoryAdaptor(hidlGenFactory), &nameProperties{
501			Name: proptools.StringPtr(name.javaSourcesName()),
502		}, &hidlGenProperties{
503			Language:   "java",
504			FqName:     name.string(),
505			Root:       i.properties.Root,
506			Interfaces: i.properties.Interfaces,
507			Inputs:     i.properties.Srcs,
508			Outputs:    []string{"srcs.srcjar"},
509		}, &i.inheritCommonProperties)
510
511		commonJavaProperties := javaProperties{
512			Defaults:          []string{"hidl-java-module-defaults"},
513			No_framework_libs: proptools.BoolPtr(true),
514			Installable:       proptools.BoolPtr(true),
515			Srcs:              []string{":" + name.javaSourcesName()},
516
517			// This should ideally be system_current, but android.hidl.base-V1.0-java is used
518			// to build framework, which is used to build system_current.  Use core_current
519			// plus hwbinder.stubs, which together form a subset of system_current that does
520			// not depend on framework.
521			Sdk_version: proptools.StringPtr("core_current"),
522			Libs:        []string{"hwbinder.stubs"},
523		}
524
525		mctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProperties{
526			Name:        proptools.StringPtr(name.javaName()),
527			Static_libs: javaDependencies,
528		}, &i.inheritCommonProperties, &commonJavaProperties)
529		mctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProperties{
530			Name: proptools.StringPtr(name.javaSharedName()),
531			Libs: javaDependencies,
532		}, &i.inheritCommonProperties, &commonJavaProperties)
533	}
534
535	if shouldGenerateJavaConstants {
536		mctx.CreateModule(android.ModuleFactoryAdaptor(hidlGenFactory), &nameProperties{
537			Name: proptools.StringPtr(name.javaConstantsSourcesName()),
538		}, &hidlGenProperties{
539			Language:   "java-constants",
540			FqName:     name.string(),
541			Root:       i.properties.Root,
542			Interfaces: i.properties.Interfaces,
543			Inputs:     i.properties.Srcs,
544			Outputs:    []string{name.sanitizedDir() + "Constants.java"},
545		}, &i.inheritCommonProperties)
546		mctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProperties{
547			Name:              proptools.StringPtr(name.javaConstantsName()),
548			Defaults:          []string{"hidl-java-module-defaults"},
549			No_framework_libs: proptools.BoolPtr(true),
550			Srcs:              []string{":" + name.javaConstantsSourcesName()},
551		}, &i.inheritCommonProperties)
552	}
553
554	mctx.CreateModule(android.ModuleFactoryAdaptor(hidlGenFactory), &nameProperties{
555		Name: proptools.StringPtr(name.adapterHelperSourcesName()),
556	}, &hidlGenProperties{
557		Language:   "c++-adapter-sources",
558		FqName:     name.string(),
559		Root:       i.properties.Root,
560		Interfaces: i.properties.Interfaces,
561		Inputs:     i.properties.Srcs,
562		Outputs:    wrap(name.dir()+"A", concat(interfaces, types), ".cpp"),
563	}, &i.inheritCommonProperties)
564	mctx.CreateModule(android.ModuleFactoryAdaptor(hidlGenFactory), &nameProperties{
565		Name: proptools.StringPtr(name.adapterHelperHeadersName()),
566	}, &hidlGenProperties{
567		Language:   "c++-adapter-headers",
568		FqName:     name.string(),
569		Root:       i.properties.Root,
570		Interfaces: i.properties.Interfaces,
571		Inputs:     i.properties.Srcs,
572		Outputs:    wrap(name.dir()+"A", concat(interfaces, types), ".h"),
573	}, &i.inheritCommonProperties)
574
575	mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
576		Name:              proptools.StringPtr(name.adapterHelperName()),
577		Vendor_available:  proptools.BoolPtr(true),
578		Defaults:          []string{"hidl-module-defaults"},
579		Generated_sources: []string{name.adapterHelperSourcesName()},
580		Generated_headers: []string{name.adapterHelperHeadersName()},
581		Shared_libs: []string{
582			"libbase",
583			"libcutils",
584			"libhidlbase",
585			"libhidltransport",
586			"libhwbinder",
587			"liblog",
588			"libutils",
589		},
590		Static_libs: concat([]string{
591			"libhidladapter",
592		}, wrap("", dependencies, "-adapter-helper"), cppDependencies, libraryIfExists),
593		Export_shared_lib_headers: []string{
594			"libhidlbase",
595			"libhidltransport",
596		},
597		Export_static_lib_headers: concat([]string{
598			"libhidladapter",
599		}, wrap("", dependencies, "-adapter-helper"), cppDependencies, libraryIfExists),
600		Export_generated_headers: []string{name.adapterHelperHeadersName()},
601		Group_static_libs:        proptools.BoolPtr(true),
602	}, &i.inheritCommonProperties)
603	mctx.CreateModule(android.ModuleFactoryAdaptor(hidlGenFactory), &nameProperties{
604		Name: proptools.StringPtr(name.adapterSourcesName()),
605	}, &hidlGenProperties{
606		Language:   "c++-adapter-main",
607		FqName:     name.string(),
608		Root:       i.properties.Root,
609		Interfaces: i.properties.Interfaces,
610		Inputs:     i.properties.Srcs,
611		Outputs:    []string{"main.cpp"},
612	}, &i.inheritCommonProperties)
613	mctx.CreateModule(android.ModuleFactoryAdaptor(cc.TestFactory), &ccProperties{
614		Name:              proptools.StringPtr(name.adapterName()),
615		Generated_sources: []string{name.adapterSourcesName()},
616		Shared_libs: []string{
617			"libbase",
618			"libcutils",
619			"libhidlbase",
620			"libhidltransport",
621			"libhwbinder",
622			"liblog",
623			"libutils",
624		},
625		Static_libs: concat([]string{
626			"libhidladapter",
627			name.adapterHelperName(),
628		}, wrap("", dependencies, "-adapter-helper"), cppDependencies, libraryIfExists),
629		Group_static_libs: proptools.BoolPtr(true),
630	}, &i.inheritCommonProperties)
631
632	if shouldGenerateVts {
633		vtsSpecs := concat(wrap(name.dir(), interfaces, ".vts"), wrap(name.dir(), types, ".vts"))
634
635		mctx.CreateModule(android.ModuleFactoryAdaptor(hidlGenFactory), &nameProperties{
636			Name: proptools.StringPtr(name.vtsSpecName()),
637		}, &hidlGenProperties{
638			Language:   "vts",
639			FqName:     name.string(),
640			Root:       i.properties.Root,
641			Interfaces: i.properties.Interfaces,
642			Inputs:     i.properties.Srcs,
643			Outputs:    vtsSpecs,
644		}, &i.inheritCommonProperties)
645
646		mctx.CreateModule(android.ModuleFactoryAdaptor(vtscFactory), &nameProperties{
647			Name: proptools.StringPtr(name.vtsDriverSourcesName()),
648		}, &vtscProperties{
649			Mode:        "DRIVER",
650			Type:        "SOURCE",
651			SpecName:    name.vtsSpecName(),
652			Outputs:     wrap("", vtsSpecs, ".cpp"),
653			PackagePath: name.dir(),
654		}, &i.inheritCommonProperties)
655		mctx.CreateModule(android.ModuleFactoryAdaptor(vtscFactory), &nameProperties{
656			Name: proptools.StringPtr(name.vtsDriverHeadersName()),
657		}, &vtscProperties{
658			Mode:        "DRIVER",
659			Type:        "HEADER",
660			SpecName:    name.vtsSpecName(),
661			Outputs:     wrap("", vtsSpecs, ".h"),
662			PackagePath: name.dir(),
663		}, &i.inheritCommonProperties)
664		mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
665			Name:                      proptools.StringPtr(name.vtsDriverName()),
666			Defaults:                  []string{"VtsHalDriverDefaults"},
667			Generated_sources:         []string{name.vtsDriverSourcesName()},
668			Generated_headers:         []string{name.vtsDriverHeadersName()},
669			Export_generated_headers:  []string{name.vtsDriverHeadersName()},
670			Shared_libs:               wrap("", cppDependencies, "-vts.driver"),
671			Export_shared_lib_headers: wrap("", cppDependencies, "-vts.driver"),
672			Static_libs:               concat(cppDependencies, libraryIfExists),
673
674			// TODO(b/126244142)
675			Cflags: []string{"-Wno-unused-variable"},
676		}, &i.inheritCommonProperties)
677
678		mctx.CreateModule(android.ModuleFactoryAdaptor(vtscFactory), &nameProperties{
679			Name: proptools.StringPtr(name.vtsProfilerSourcesName()),
680		}, &vtscProperties{
681			Mode:        "PROFILER",
682			Type:        "SOURCE",
683			SpecName:    name.vtsSpecName(),
684			Outputs:     wrap("", vtsSpecs, ".cpp"),
685			PackagePath: name.dir(),
686		}, &i.inheritCommonProperties)
687		mctx.CreateModule(android.ModuleFactoryAdaptor(vtscFactory), &nameProperties{
688			Name: proptools.StringPtr(name.vtsProfilerHeadersName()),
689		}, &vtscProperties{
690			Mode:        "PROFILER",
691			Type:        "HEADER",
692			SpecName:    name.vtsSpecName(),
693			Outputs:     wrap("", vtsSpecs, ".h"),
694			PackagePath: name.dir(),
695		}, &i.inheritCommonProperties)
696		mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
697			Name:                      proptools.StringPtr(name.vtsProfilerName()),
698			Defaults:                  []string{"VtsHalProfilerDefaults"},
699			Generated_sources:         []string{name.vtsProfilerSourcesName()},
700			Generated_headers:         []string{name.vtsProfilerHeadersName()},
701			Export_generated_headers:  []string{name.vtsProfilerHeadersName()},
702			Shared_libs:               wrap("", cppDependencies, "-vts.profiler"),
703			Export_shared_lib_headers: wrap("", cppDependencies, "-vts.profiler"),
704			Static_libs:               concat(cppDependencies, libraryIfExists),
705
706			// TODO(b/126244142)
707			Cflags: []string{"-Wno-unused-variable"},
708		}, &i.inheritCommonProperties)
709	}
710}
711
712func (h *hidlInterface) Name() string {
713	return h.ModuleBase.Name() + hidlInterfaceSuffix
714}
715func (h *hidlInterface) GenerateAndroidBuildActions(ctx android.ModuleContext) {
716	visited := false
717	ctx.VisitDirectDeps(func(dep android.Module) {
718		if visited {
719			panic("internal error, multiple dependencies found but only one added")
720		}
721		visited = true
722		h.properties.Full_root_option = dep.(*hidlPackageRoot).getFullPackageRoot()
723	})
724	if !visited {
725		panic("internal error, no dependencies found but dependency added")
726	}
727
728}
729func (h *hidlInterface) DepsMutator(ctx android.BottomUpMutatorContext) {
730	ctx.AddDependency(ctx.Module(), nil, h.properties.Root)
731}
732
733func hidlInterfaceFactory() android.Module {
734	i := &hidlInterface{}
735	i.AddProperties(&i.properties)
736	i.AddProperties(&i.inheritCommonProperties)
737	android.InitAndroidModule(i)
738	android.AddLoadHook(i, func(ctx android.LoadHookContext) { hidlInterfaceMutator(ctx, i) })
739
740	return i
741}
742
743var doubleLoadablePackageNames = []string{
744	"android.frameworks.bufferhub@1.0",
745	"android.hardware.cas@1.0",
746	"android.hardware.cas.native@1.0",
747	"android.hardware.configstore@",
748	"android.hardware.drm@1.0",
749	"android.hardware.drm@1.1",
750	"android.hardware.drm@1.2",
751	"android.hardware.graphics.allocator@",
752	"android.hardware.graphics.bufferqueue@",
753	"android.hardware.media@",
754	"android.hardware.media.omx@",
755	"android.hardware.memtrack@1.0",
756	"android.hardware.neuralnetworks@",
757	"android.hidl.allocator@",
758	"android.hidl.token@",
759	"android.system.suspend@1.0",
760}
761
762func isDoubleLoadable(name string) bool {
763	for _, pkgname := range doubleLoadablePackageNames {
764		if strings.HasPrefix(name, pkgname) {
765			return true
766		}
767	}
768	return false
769}
770
771// packages in libhidltransport
772var coreDependencyPackageNames = []string{
773	"android.hidl.base@",
774	"android.hidl.manager@",
775}
776
777func isCorePackage(name string) bool {
778	for _, pkgname := range coreDependencyPackageNames {
779		if strings.HasPrefix(name, pkgname) {
780			return true
781		}
782	}
783	return false
784}
785
786// TODO(b/126383715): centralize this logic/support filtering in core VTS build
787var coreVtsSpecs = []string{
788	"android.frameworks.",
789	"android.hardware.",
790	"android.hidl.",
791	"android.system.",
792}
793
794func isVtsSpecPackage(name string) bool {
795	for _, pkgname := range coreVtsSpecs {
796		if strings.HasPrefix(name, pkgname) {
797			return true
798		}
799	}
800	return false
801}
802
803var vtsListKey = android.NewOnceKey("vtsList")
804
805func vtsList(config android.Config) *android.Paths {
806	return config.Once(vtsListKey, func() interface{} {
807		return &android.Paths{}
808	}).(*android.Paths)
809}
810
811var vtsListMutex sync.Mutex
812
813func makeVarsProvider(ctx android.MakeVarsContext) {
814	vtsList := vtsList(ctx.Config()).Strings()
815	sort.Strings(vtsList)
816
817	ctx.Strict("VTS_SPEC_FILE_LIST", strings.Join(vtsList, " "))
818}
819