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	"strings"
20
21	"github.com/google/blueprint"
22	"github.com/google/blueprint/proptools"
23
24	"android/soong/android"
25	"android/soong/cc"
26	"android/soong/genrule"
27	"android/soong/java"
28)
29
30var (
31	hidlInterfaceSuffix       = "_interface"
32	hidlMetadataSingletonName = "hidl_metadata_json"
33
34	pctx = android.NewPackageContext("android/hidl")
35
36	hidl             = pctx.HostBinToolVariable("hidl", "hidl-gen")
37	hidlLint         = pctx.HostBinToolVariable("lint", "hidl-lint")
38	soong_zip        = pctx.HostBinToolVariable("soong_zip", "soong_zip")
39	intermediatesDir = pctx.IntermediatesPathVariable("intermediatesDir", "")
40
41	hidlRule = pctx.StaticRule("hidlRule", blueprint.RuleParams{
42		Depfile:     "${out}.d",
43		Deps:        blueprint.DepsGCC,
44		Command:     "rm -rf ${genDir} && ${hidl} -R -p . -d ${out}.d -o ${genDir} -L ${language} ${options} ${fqName}",
45		CommandDeps: []string{"${hidl}"},
46		Description: "HIDL ${language}: ${in} => ${out}",
47	}, "fqName", "genDir", "language", "options")
48
49	hidlSrcJarRule = pctx.StaticRule("hidlSrcJarRule", blueprint.RuleParams{
50		Depfile: "${out}.d",
51		Deps:    blueprint.DepsGCC,
52		Command: "rm -rf ${genDir} && " +
53			"${hidl} -R -p . -d ${out}.d -o ${genDir}/srcs -L ${language} ${options} ${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	}, "fqName", "genDir", "language", "options")
58
59	lintRule = pctx.StaticRule("lintRule", blueprint.RuleParams{
60		Command:     "rm -f ${output} && touch ${output} && ${lint} -j -e -R -p . ${options} ${fqName} > ${output}",
61		CommandDeps: []string{"${lint}"},
62		Description: "hidl-lint ${fqName}: ${out}",
63	}, "output", "options", "fqName")
64
65	zipLintRule = pctx.StaticRule("zipLintRule", blueprint.RuleParams{
66		Rspfile:        "$out.rsp",
67		RspfileContent: "$files",
68		Command:        "rm -f ${output} && ${soong_zip} -o ${output} -C ${intermediatesDir} -l ${out}.rsp",
69		CommandDeps:    []string{"${soong_zip}"},
70		Description:    "Zipping hidl-lints into ${output}",
71	}, "output", "files")
72
73	inheritanceHierarchyRule = pctx.StaticRule("inheritanceHierarchyRule", blueprint.RuleParams{
74		Command:     "rm -f ${out} && ${hidl} -L inheritance-hierarchy ${options} ${fqInterface} > ${out}",
75		CommandDeps: []string{"${hidl}"},
76		Description: "HIDL inheritance hierarchy: ${fqInterface} => ${out}",
77	}, "options", "fqInterface")
78
79	joinJsonObjectsToArrayRule = pctx.StaticRule("joinJsonObjectsToArrayRule", blueprint.RuleParams{
80		Rspfile:        "$out.rsp",
81		RspfileContent: "$files",
82		Command: "rm -rf ${out} && " +
83			// Start the output array with an opening bracket.
84			"echo '[' >> ${out} && " +
85			// Add prebuilt declarations
86			"echo \"${extras}\" >> ${out} && " +
87			// Append each input file and a comma to the output.
88			"for file in $$(cat ${out}.rsp); do " +
89			"cat $$file >> ${out}; echo ',' >> ${out}; " +
90			"done && " +
91			// Remove the last comma, replacing it with the closing bracket.
92			"sed -i '$$d' ${out} && echo ']' >> ${out}",
93		Description: "Joining JSON objects into array ${out}",
94	}, "extras", "files")
95)
96
97func init() {
98	android.RegisterModuleType("prebuilt_hidl_interfaces", prebuiltHidlInterfaceFactory)
99	android.RegisterModuleType("hidl_interface", HidlInterfaceFactory)
100	android.RegisterParallelSingletonType("all_hidl_lints", allHidlLintsFactory)
101	android.RegisterModuleType("hidl_interfaces_metadata", hidlInterfacesMetadataSingletonFactory)
102	pctx.Import("android/soong/android")
103}
104
105func hidlInterfacesMetadataSingletonFactory() android.Module {
106	i := &hidlInterfacesMetadataSingleton{}
107	android.InitAndroidModule(i)
108	return i
109}
110
111type hidlInterfacesMetadataSingleton struct {
112	android.ModuleBase
113}
114
115func (m *hidlInterfacesMetadataSingleton) GenerateAndroidBuildActions(ctx android.ModuleContext) {
116	if m.Name() != hidlMetadataSingletonName {
117		ctx.PropertyErrorf("name", "must be %s", hidlMetadataSingletonName)
118		return
119	}
120
121	var inheritanceHierarchyOutputs android.Paths
122	additionalInterfaces := []string{}
123	ctx.VisitDirectDeps(func(m android.Module) {
124		if !m.ExportedToMake() {
125			return
126		}
127		if t, ok := m.(*hidlGenRule); ok {
128			if t.properties.Language == "inheritance-hierarchy" {
129				inheritanceHierarchyOutputs = append(inheritanceHierarchyOutputs, t.genOutputs.Paths()...)
130			}
131		} else if t, ok := m.(*prebuiltHidlInterface); ok {
132			additionalInterfaces = append(additionalInterfaces, t.properties.Interfaces...)
133		}
134	})
135
136	inheritanceHierarchyPath := android.PathForIntermediates(ctx, "hidl_inheritance_hierarchy.json")
137
138	ctx.Build(pctx, android.BuildParams{
139		Rule:   joinJsonObjectsToArrayRule,
140		Inputs: inheritanceHierarchyOutputs,
141		Output: inheritanceHierarchyPath,
142		Args: map[string]string{
143			"extras": strings.Join(wrap("{\\\"interface\\\":\\\"", additionalInterfaces, "\\\"},"), " "),
144			"files":  strings.Join(inheritanceHierarchyOutputs.Strings(), " "),
145		},
146	})
147
148	ctx.SetOutputFiles(android.Paths{inheritanceHierarchyPath}, "")
149}
150
151func allHidlLintsFactory() android.Singleton {
152	return &allHidlLintsSingleton{}
153}
154
155type allHidlLintsSingleton struct {
156	outPath android.OutputPath
157}
158
159func (m *allHidlLintsSingleton) GenerateBuildActions(ctx android.SingletonContext) {
160	var hidlLintOutputs android.Paths
161	ctx.VisitAllModules(func(m android.Module) {
162		if t, ok := m.(*hidlGenRule); ok {
163			if t.properties.Language == "lint" {
164				if len(t.genOutputs) == 1 {
165					hidlLintOutputs = append(hidlLintOutputs, t.genOutputs[0])
166				} else {
167					panic("-hidl-lint target was not configured correctly")
168				}
169			}
170		}
171	})
172
173	outPath := android.PathForIntermediates(ctx, "hidl-lint.zip")
174	m.outPath = outPath
175
176	ctx.Build(pctx, android.BuildParams{
177		Rule:   zipLintRule,
178		Inputs: hidlLintOutputs,
179		Output: outPath,
180		Args: map[string]string{
181			"output": outPath.String(),
182			"files":  strings.Join(hidlLintOutputs.Strings(), " "),
183		},
184	})
185}
186
187func (m *allHidlLintsSingleton) MakeVars(ctx android.MakeVarsContext) {
188	ctx.Strict("ALL_HIDL_LINTS_ZIP", m.outPath.String())
189	ctx.DistForGoal("dist_files", m.outPath)
190}
191
192type hidlGenProperties struct {
193	Language       string
194	FqName         string
195	Root           string
196	Interfaces     []string
197	Inputs         []string
198	Outputs        []string
199	Apex_available []string
200}
201
202type hidlGenRule struct {
203	android.ModuleBase
204
205	properties hidlGenProperties
206
207	genOutputDir android.Path
208	genInputs    android.Paths
209	genOutputs   android.WritablePaths
210}
211
212var _ android.SourceFileProducer = (*hidlGenRule)(nil)
213var _ genrule.SourceFileGenerator = (*hidlGenRule)(nil)
214
215func (g *hidlGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
216	g.genOutputDir = android.PathForModuleGen(ctx)
217
218	for _, input := range g.properties.Inputs {
219		g.genInputs = append(g.genInputs, android.PathForModuleSrc(ctx, input))
220	}
221
222	var interfaces []string
223	for _, src := range g.properties.Inputs {
224		if strings.HasSuffix(src, ".hal") && strings.HasPrefix(src, "I") {
225			interfaces = append(interfaces, strings.TrimSuffix(src, ".hal"))
226		}
227	}
228
229	switch g.properties.Language {
230	case "lint":
231		g.genOutputs = append(g.genOutputs, android.PathForModuleGen(ctx, "lint.json"))
232	case "inheritance-hierarchy":
233		for _, intf := range interfaces {
234			g.genOutputs = append(g.genOutputs, android.PathForModuleGen(ctx, intf+"_inheritance_hierarchy.json"))
235		}
236	default:
237		for _, output := range g.properties.Outputs {
238			g.genOutputs = append(g.genOutputs, android.PathForModuleGen(ctx, output))
239		}
240	}
241
242	var extraOptions []string // including roots
243	var currentPath android.OptionalPath
244	ctx.VisitDirectDeps(func(dep android.Module) {
245		switch t := dep.(type) {
246		case *hidlInterface:
247			extraOptions = append(extraOptions, t.properties.Full_root_option)
248		case *hidlPackageRoot:
249			if currentPath.Valid() {
250				panic(fmt.Sprintf("Expecting only one path, but found %v %v", currentPath, t.getCurrentPath()))
251			}
252
253			currentPath = t.getCurrentPath()
254
255			if t.requireFrozen() {
256				extraOptions = append(extraOptions, "-F")
257			}
258		}
259	})
260
261	extraOptions = android.FirstUniqueStrings(extraOptions)
262
263	inputs := g.genInputs
264	if currentPath.Valid() {
265		inputs = append(inputs, currentPath.Path())
266	}
267
268	rule := hidlRule
269	if g.properties.Language == "java" {
270		rule = hidlSrcJarRule
271	}
272
273	if g.properties.Language == "lint" {
274		ctx.Build(pctx, android.BuildParams{
275			Rule:   lintRule,
276			Inputs: inputs,
277			Output: g.genOutputs[0],
278			Args: map[string]string{
279				"output":  g.genOutputs[0].String(),
280				"fqName":  g.properties.FqName,
281				"options": strings.Join(extraOptions, " "),
282			},
283		})
284
285		return
286	}
287
288	if g.properties.Language == "inheritance-hierarchy" {
289		for i, intf := range interfaces {
290			ctx.Build(pctx, android.BuildParams{
291				Rule:   inheritanceHierarchyRule,
292				Inputs: inputs,
293				Output: g.genOutputs[i],
294				Args: map[string]string{
295					"fqInterface": g.properties.FqName + "::" + intf,
296					"options":     strings.Join(extraOptions, " "),
297				},
298			})
299		}
300
301		return
302	}
303
304	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
305		Rule:            rule,
306		Inputs:          inputs,
307		Output:          g.genOutputs[0],
308		ImplicitOutputs: g.genOutputs[1:],
309		Args: map[string]string{
310			"genDir":   g.genOutputDir.String(),
311			"fqName":   g.properties.FqName,
312			"language": g.properties.Language,
313			"options":  strings.Join(extraOptions, " "),
314		},
315	})
316}
317
318func (g *hidlGenRule) GeneratedSourceFiles() android.Paths {
319	return g.genOutputs.Paths()
320}
321
322func (g *hidlGenRule) Srcs() android.Paths {
323	return g.genOutputs.Paths()
324}
325
326func (g *hidlGenRule) GeneratedDeps() android.Paths {
327	return g.genOutputs.Paths()
328}
329
330func (g *hidlGenRule) GeneratedHeaderDirs() android.Paths {
331	return android.Paths{g.genOutputDir}
332}
333
334func (g *hidlGenRule) DepsMutator(ctx android.BottomUpMutatorContext) {
335	ctx.AddDependency(ctx.Module(), nil, g.properties.FqName+hidlInterfaceSuffix)
336	ctx.AddDependency(ctx.Module(), nil, wrap("", g.properties.Interfaces, hidlInterfaceSuffix)...)
337	ctx.AddDependency(ctx.Module(), nil, g.properties.Root)
338
339	ctx.AddReverseDependency(ctx.Module(), nil, hidlMetadataSingletonName)
340}
341
342func hidlGenFactory() android.Module {
343	g := &hidlGenRule{}
344	g.AddProperties(&g.properties)
345	android.InitAndroidModule(g)
346	return g
347}
348
349type prebuiltHidlInterfaceProperties struct {
350	// List of interfaces to consider valid, e.g. "vendor.foo.bar@1.0::IFoo" for typo checking
351	// between init.rc, VINTF, and elsewhere. Note that inheritance properties will not be
352	// checked for these (but would be checked in a branch where the actual hidl_interface
353	// exists).
354	Interfaces []string
355}
356
357type prebuiltHidlInterface struct {
358	android.ModuleBase
359
360	properties prebuiltHidlInterfaceProperties
361}
362
363func (p *prebuiltHidlInterface) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
364
365func (p *prebuiltHidlInterface) DepsMutator(ctx android.BottomUpMutatorContext) {
366	ctx.AddReverseDependency(ctx.Module(), nil, hidlMetadataSingletonName)
367}
368
369func prebuiltHidlInterfaceFactory() android.Module {
370	i := &prebuiltHidlInterface{}
371	i.AddProperties(&i.properties)
372	android.InitAndroidModule(i)
373	return i
374}
375
376type hidlInterfaceProperties struct {
377	// List of .hal files which compose this interface.
378	Srcs []string
379
380	// List of hal interface packages that this library depends on.
381	Interfaces []string
382
383	// Package root for this package, must be a prefix of name
384	Root string
385
386	// Unused/deprecated: List of non-TypeDef types declared in types.hal.
387	Types []string
388
389	// Whether to generate the Java library stubs.
390	// Default: true
391	Gen_java *bool
392
393	// Whether to generate a Java library containing constants
394	// expressed by @export annotations in the hal files.
395	Gen_java_constants bool
396
397	// Whether to generate VTS-related testing libraries.
398	Gen_vts *bool
399
400	// example: -randroid.hardware:hardware/interfaces
401	Full_root_option string `blueprint:"mutated"`
402
403	// List of APEX modules this interface can be used in.
404	//
405	// WARNING: HIDL is not fully supported in APEX since VINTF currently doesn't
406	// read files from APEXes (b/130058564).
407	//
408	// "//apex_available:anyapex" is a pseudo APEX name that matches to any APEX.
409	// "//apex_available:platform" refers to non-APEX partitions like "system.img"
410	//
411	// Note, this only applies to C++ libs, Java libs, and Java constant libs. It
412	// does  not apply to VTS targets targets/fuzzers since these components
413	// should not be shipped on device.
414	Apex_available []string
415
416	// Installs the vendor variant of the module to the /odm partition instead of
417	// the /vendor partition.
418	Odm_available *bool
419}
420
421type hidlInterface struct {
422	android.ModuleBase
423
424	properties hidlInterfaceProperties
425}
426
427func processSources(mctx android.LoadHookContext, srcs []string) ([]string, []string, bool) {
428	var interfaces []string
429	var types []string // hidl-gen only supports types.hal, but don't assume that here
430
431	hasError := false
432
433	for _, v := range srcs {
434		if !strings.HasSuffix(v, ".hal") {
435			mctx.PropertyErrorf("srcs", "Source must be a .hal file: "+v)
436			hasError = true
437			continue
438		}
439
440		name := strings.TrimSuffix(v, ".hal")
441
442		if strings.HasPrefix(name, "I") {
443			baseName := strings.TrimPrefix(name, "I")
444			interfaces = append(interfaces, baseName)
445		} else {
446			types = append(types, name)
447		}
448	}
449
450	return interfaces, types, !hasError
451}
452
453func processDependencies(mctx android.LoadHookContext, interfaces []string) ([]string, []string, bool) {
454	var dependencies []string
455	var javaDependencies []string
456
457	hasError := false
458
459	for _, v := range interfaces {
460		name, err := parseFqName(v)
461		if err != nil {
462			mctx.PropertyErrorf("interfaces", err.Error())
463			hasError = true
464			continue
465		}
466		dependencies = append(dependencies, name.string())
467		javaDependencies = append(javaDependencies, name.javaName())
468	}
469
470	return dependencies, javaDependencies, !hasError
471}
472
473func removeCoreDependencies(mctx android.LoadHookContext, dependencies []string) []string {
474	var ret []string
475
476	for _, i := range dependencies {
477		if !isCorePackage(i) {
478			ret = append(ret, i)
479		}
480	}
481
482	return ret
483}
484
485func hidlInterfaceMutator(mctx android.LoadHookContext, i *hidlInterface) {
486	if !canInterfaceExist(i.ModuleBase.Name()) {
487		mctx.PropertyErrorf("name", "No more HIDL interfaces can be added to Android. Please use AIDL.")
488		return
489	}
490
491	name, err := parseFqName(i.ModuleBase.Name())
492	if err != nil {
493		mctx.PropertyErrorf("name", err.Error())
494	}
495
496	if !name.inPackage(i.properties.Root) {
497		mctx.PropertyErrorf("root", i.properties.Root+" must be a prefix of  "+name.string()+".")
498	}
499	if lookupPackageRoot(i.properties.Root) == nil {
500		mctx.PropertyErrorf("interfaces", `Cannot find package root specification for package `+
501			`root '%s' needed for module '%s'. Either this is a mispelling of the package `+
502			`root, or a new hidl_package_root module needs to be added. For example, you can `+
503			`fix this error by adding the following to <some path>/Android.bp:
504
505hidl_package_root {
506name: "%s",
507// if you want to require <some path>/current.txt for interface versioning
508use_current: true,
509}
510
511This corresponds to the "-r%s:<some path>" option that would be passed into hidl-gen.`,
512			i.properties.Root, name, i.properties.Root, i.properties.Root)
513	}
514
515	interfaces, types, _ := processSources(mctx, i.properties.Srcs)
516
517	if len(interfaces) == 0 && len(types) == 0 {
518		mctx.PropertyErrorf("srcs", "No sources provided.")
519	}
520
521	dependencies, javaDependencies, _ := processDependencies(mctx, i.properties.Interfaces)
522	cppDependencies := removeCoreDependencies(mctx, dependencies)
523
524	if mctx.Failed() {
525		return
526	}
527
528	shouldGenerateLibrary := !isCorePackage(name.string())
529	// explicitly true if not specified to give early warning to devs
530	shouldGenerateJava := proptools.BoolDefault(i.properties.Gen_java, true)
531	shouldGenerateJavaConstants := i.properties.Gen_java_constants
532
533	var productAvailable *bool
534	if !mctx.ProductSpecific() {
535		productAvailable = proptools.BoolPtr(true)
536	}
537
538	var vendorAvailable *bool
539	if !proptools.Bool(i.properties.Odm_available) {
540		vendorAvailable = proptools.BoolPtr(true)
541	}
542
543	// TODO(b/69002743): remove filegroups
544	mctx.CreateModule(android.FileGroupFactory, &fileGroupProperties{
545		Name: proptools.StringPtr(name.fileGroupName()),
546		Srcs: i.properties.Srcs,
547	})
548
549	mctx.CreateModule(hidlGenFactory, &nameProperties{
550		Name: proptools.StringPtr(name.sourcesName()),
551	}, &hidlGenProperties{
552		Language:   "c++-sources",
553		FqName:     name.string(),
554		Root:       i.properties.Root,
555		Interfaces: i.properties.Interfaces,
556		Inputs:     i.properties.Srcs,
557		Outputs:    concat(wrap(name.dir(), interfaces, "All.cpp"), wrap(name.dir(), types, ".cpp")),
558	})
559
560	mctx.CreateModule(hidlGenFactory, &nameProperties{
561		Name: proptools.StringPtr(name.headersName()),
562	}, &hidlGenProperties{
563		Language:   "c++-headers",
564		FqName:     name.string(),
565		Root:       i.properties.Root,
566		Interfaces: i.properties.Interfaces,
567		Inputs:     i.properties.Srcs,
568		Outputs: concat(wrap(name.dir()+"I", interfaces, ".h"),
569			wrap(name.dir()+"Bs", interfaces, ".h"),
570			wrap(name.dir()+"BnHw", interfaces, ".h"),
571			wrap(name.dir()+"BpHw", interfaces, ".h"),
572			wrap(name.dir()+"IHw", interfaces, ".h"),
573			wrap(name.dir(), types, ".h"),
574			wrap(name.dir()+"hw", types, ".h")),
575	})
576
577	if shouldGenerateLibrary {
578		mctx.CreateModule(cc.LibraryFactory, &ccProperties{
579			Name:               proptools.StringPtr(name.string()),
580			Host_supported:     proptools.BoolPtr(true),
581			Recovery_available: proptools.BoolPtr(true),
582			Vendor_available:   vendorAvailable,
583			Odm_available:      i.properties.Odm_available,
584			Product_available:  productAvailable,
585			Double_loadable:    proptools.BoolPtr(isDoubleLoadable(name.string())),
586			Defaults:           []string{"hidl-module-defaults"},
587			Generated_sources:  []string{name.sourcesName()},
588			Generated_headers:  []string{name.headersName()},
589			Shared_libs: concat(cppDependencies, []string{
590				"libhidlbase",
591				"liblog",
592				"libutils",
593				"libcutils",
594			}),
595			Export_shared_lib_headers: concat(cppDependencies, []string{
596				"libhidlbase",
597				"libutils",
598			}),
599			Export_generated_headers: []string{name.headersName()},
600			Apex_available:           i.properties.Apex_available,
601			Min_sdk_version:          getMinSdkVersion(name.string()),
602		})
603	}
604
605	if shouldGenerateJava {
606		mctx.CreateModule(hidlGenFactory, &nameProperties{
607			Name: proptools.StringPtr(name.javaSourcesName()),
608		}, &hidlGenProperties{
609			Language:   "java",
610			FqName:     name.string(),
611			Root:       i.properties.Root,
612			Interfaces: i.properties.Interfaces,
613			Inputs:     i.properties.Srcs,
614			Outputs:    []string{"srcs.srcjar"},
615		})
616
617		commonJavaProperties := javaProperties{
618			Defaults:    []string{"hidl-java-module-defaults"},
619			Installable: proptools.BoolPtr(true),
620			Srcs:        []string{":" + name.javaSourcesName()},
621
622			// This should ideally be system_current, but android.hidl.base-V1.0-java is used
623			// to build framework, which is used to build system_current.  Use core_current
624			// plus hwbinder.stubs, which together form a subset of system_current that does
625			// not depend on framework.
626			Sdk_version:     proptools.StringPtr("core_current"),
627			Libs:            []string{"hwbinder.stubs"},
628			Apex_available:  i.properties.Apex_available,
629			Min_sdk_version: getMinSdkVersion(name.string()),
630		}
631
632		mctx.CreateModule(java.LibraryFactory, &javaProperties{
633			Name:        proptools.StringPtr(name.javaName()),
634			Static_libs: javaDependencies,
635		}, &commonJavaProperties)
636		mctx.CreateModule(java.LibraryFactory, &javaProperties{
637			Name: proptools.StringPtr(name.javaSharedName()),
638			Libs: javaDependencies,
639		}, &commonJavaProperties)
640	}
641
642	if shouldGenerateJavaConstants {
643		mctx.CreateModule(hidlGenFactory, &nameProperties{
644			Name: proptools.StringPtr(name.javaConstantsSourcesName()),
645		}, &hidlGenProperties{
646			Language:   "java-constants",
647			FqName:     name.string(),
648			Root:       i.properties.Root,
649			Interfaces: i.properties.Interfaces,
650			Inputs:     i.properties.Srcs,
651			Outputs:    []string{name.sanitizedDir() + "Constants.java"},
652		})
653		mctx.CreateModule(java.LibraryFactory, &javaProperties{
654			Name:            proptools.StringPtr(name.javaConstantsName()),
655			Defaults:        []string{"hidl-java-module-defaults"},
656			Sdk_version:     proptools.StringPtr("core_current"),
657			Srcs:            []string{":" + name.javaConstantsSourcesName()},
658			Apex_available:  i.properties.Apex_available,
659			Min_sdk_version: getMinSdkVersion(name.string()),
660		})
661	}
662
663	mctx.CreateModule(hidlGenFactory, &nameProperties{
664		Name: proptools.StringPtr(name.lintName()),
665	}, &hidlGenProperties{
666		Language:   "lint",
667		FqName:     name.string(),
668		Root:       i.properties.Root,
669		Interfaces: i.properties.Interfaces,
670		Inputs:     i.properties.Srcs,
671	})
672
673	mctx.CreateModule(hidlGenFactory, &nameProperties{
674		Name: proptools.StringPtr(name.inheritanceHierarchyName()),
675	}, &hidlGenProperties{
676		Language:   "inheritance-hierarchy",
677		FqName:     name.string(),
678		Root:       i.properties.Root,
679		Interfaces: i.properties.Interfaces,
680		Inputs:     i.properties.Srcs,
681	})
682}
683
684func (h *hidlInterface) Name() string {
685	return h.ModuleBase.Name() + hidlInterfaceSuffix
686}
687func (h *hidlInterface) GenerateAndroidBuildActions(ctx android.ModuleContext) {
688	visited := false
689	ctx.VisitDirectDeps(func(dep android.Module) {
690		if r, ok := dep.(*hidlPackageRoot); ok {
691			if visited {
692				panic("internal error, multiple dependencies found but only one added")
693			}
694			visited = true
695			h.properties.Full_root_option = r.getFullPackageRoot()
696		}
697	})
698	if !visited {
699		panic("internal error, no dependencies found but dependency added")
700	}
701
702}
703func (h *hidlInterface) DepsMutator(ctx android.BottomUpMutatorContext) {
704	ctx.AddDependency(ctx.Module(), nil, h.properties.Root)
705}
706
707func HidlInterfaceFactory() android.Module {
708	i := &hidlInterface{}
709	i.AddProperties(&i.properties)
710	android.InitAndroidModule(i)
711	android.AddLoadHook(i, func(ctx android.LoadHookContext) { hidlInterfaceMutator(ctx, i) })
712
713	return i
714}
715
716var minSdkVersion = map[string]string{
717	"android.hardware.audio.common@5.0":            "30",
718	"android.hardware.audio.common@6.0":            "31",
719	"android.hardware.automotive.audiocontrol@1.0": "31",
720	"android.hardware.automotive.audiocontrol@2.0": "31",
721	"android.hardware.automotive.vehicle@2.0":      "31",
722	"android.hardware.bluetooth.a2dp@1.0":          "30",
723	"android.hardware.bluetooth.audio@2.0":         "30",
724	"android.hardware.bluetooth.audio@2.1":         "30",
725	"android.hardware.bluetooth.audio@2.2":         "30",
726	"android.hardware.bluetooth@1.0":               "30",
727	"android.hardware.bluetooth@1.1":               "30",
728	"android.hardware.health@1.0":                  "31",
729	"android.hardware.health@2.0":                  "31",
730	"android.hardware.neuralnetworks@1.0":          "30",
731	"android.hardware.neuralnetworks@1.1":          "30",
732	"android.hardware.neuralnetworks@1.2":          "30",
733	"android.hardware.neuralnetworks@1.3":          "30",
734	"android.hardware.wifi@1.0":                    "30",
735	"android.hardware.wifi@1.1":                    "30",
736	"android.hardware.wifi@1.2":                    "30",
737	"android.hardware.wifi@1.3":                    "30",
738	"android.hardware.wifi@1.4":                    "30",
739	"android.hardware.wifi@1.5":                    "30",
740	"android.hardware.wifi@1.6":                    "30",
741	"android.hardware.wifi.hostapd@1.0":            "30",
742	"android.hardware.wifi.hostapd@1.1":            "30",
743	"android.hardware.wifi.hostapd@1.2":            "30",
744	"android.hardware.wifi.hostapd@1.3":            "30",
745	"android.hardware.wifi.supplicant@1.0":         "30",
746	"android.hardware.wifi.supplicant@1.1":         "30",
747	"android.hardware.wifi.supplicant@1.2":         "30",
748	"android.hardware.wifi.supplicant@1.3":         "30",
749	"android.hardware.wifi.supplicant@1.4":         "30",
750	"android.hidl.manager@1.0":                     "30",
751	"android.hidl.manager@1.1":                     "30",
752	"android.hidl.manager@1.2":                     "30",
753}
754
755func getMinSdkVersion(name string) *string {
756	if ver, ok := minSdkVersion[name]; ok {
757		return proptools.StringPtr(ver)
758	}
759	// legacy, as used
760	if name == "android.hardware.tetheroffload.config@1.0" ||
761		name == "android.hardware.tetheroffload.control@1.0" ||
762		name == "android.hardware.tetheroffload.control@1.1" ||
763		name == "android.hardware.radio@1.0" ||
764		name == "android.hidl.base@1.0" {
765
766		return nil
767	}
768	return proptools.StringPtr("29")
769}
770
771var doubleLoadablePackageNames = []string{
772	"android.frameworks.bufferhub@1.0",
773	"android.hardware.cas@1.0",
774	"android.hardware.cas.native@1.0",
775	"android.hardware.configstore@",
776	"android.hardware.drm@",
777	"android.hardware.graphics.allocator@",
778	"android.hardware.graphics.bufferqueue@",
779	"android.hardware.graphics.common@",
780	"android.hardware.graphics.mapper@",
781	"android.hardware.media@",
782	"android.hardware.media.bufferpool@",
783	"android.hardware.media.c2@",
784	"android.hardware.media.omx@",
785	"android.hardware.memtrack@1.0",
786	"android.hardware.neuralnetworks@",
787	"android.hidl.allocator@",
788	"android.hidl.memory@",
789	"android.hidl.memory.token@",
790	"android.hidl.safe_union@",
791	"android.hidl.token@",
792	"android.hardware.renderscript@",
793	"android.system.suspend@1.0",
794}
795
796func isDoubleLoadable(name string) bool {
797	for _, pkgname := range doubleLoadablePackageNames {
798		if strings.HasPrefix(name, pkgname) {
799			return true
800		}
801	}
802	return false
803}
804
805// packages in libhidlbase
806var coreDependencyPackageNames = []string{
807	"android.hidl.base@",
808	"android.hidl.manager@",
809}
810
811func isCorePackage(name string) bool {
812	for _, pkgname := range coreDependencyPackageNames {
813		if strings.HasPrefix(name, pkgname) {
814			return true
815		}
816	}
817	return false
818}
819
820var fuzzerPackageNameBlacklist = []string{
821	"android.hardware.keymaster@", // to avoid deleteAllKeys()
822	// Same-process HALs are always opened in the same process as their client.
823	// So stability guarantees don't apply to them, e.g. it's OK to crash on
824	// NULL input from client. Disable corresponding fuzzers as they create too
825	// much noise.
826	"android.hardware.graphics.mapper@",
827	"android.hardware.renderscript@",
828	"android.hidl.memory@",
829}
830
831func isFuzzerEnabled(name string) bool {
832	// TODO(151338797): re-enable fuzzers
833	return false
834}
835
836func canInterfaceExist(name string) bool {
837	if strings.HasPrefix(name, "android.") {
838		return allAospHidlInterfaces[name]
839	}
840
841	return true
842}
843
844var allAospHidlInterfaces = map[string]bool{
845	"android.frameworks.automotive.display@1.0":    true,
846	"android.frameworks.bufferhub@1.0":             true,
847	"android.frameworks.cameraservice.common@2.0":  true,
848	"android.frameworks.cameraservice.device@2.0":  true,
849	"android.frameworks.cameraservice.device@2.1":  true,
850	"android.frameworks.cameraservice.service@2.0": true,
851	"android.frameworks.cameraservice.service@2.1": true,
852	"android.frameworks.cameraservice.service@2.2": true,
853	"android.frameworks.displayservice@1.0":        true,
854	"android.frameworks.schedulerservice@1.0":      true,
855	"android.frameworks.sensorservice@1.0":         true,
856	"android.frameworks.stats@1.0":                 true,
857	"android.frameworks.vr.composer@1.0":           true,
858	"android.frameworks.vr.composer@2.0":           true,
859	"android.hardware.atrace@1.0":                  true,
860	"android.hardware.audio@2.0":                   true,
861	"android.hardware.audio@4.0":                   true,
862	"android.hardware.audio@5.0":                   true,
863	"android.hardware.audio@6.0":                   true,
864	"android.hardware.audio@7.0":                   true,
865	"android.hardware.audio@7.1":                   true,
866	"android.hardware.audio.common@2.0":            true,
867	"android.hardware.audio.common@4.0":            true,
868	"android.hardware.audio.common@5.0":            true,
869	"android.hardware.audio.common@6.0":            true,
870	"android.hardware.audio.common@7.0":            true,
871	"android.hardware.audio.effect@2.0":            true,
872	"android.hardware.audio.effect@4.0":            true,
873	"android.hardware.audio.effect@5.0":            true,
874	"android.hardware.audio.effect@6.0":            true,
875	"android.hardware.audio.effect@7.0":            true,
876	"android.hardware.authsecret@1.0":              true,
877	"android.hardware.automotive.audiocontrol@1.0": true,
878	"android.hardware.automotive.audiocontrol@2.0": true,
879	"android.hardware.automotive.can@1.0":          true,
880	"android.hardware.automotive.evs@1.0":          true,
881	"android.hardware.automotive.evs@1.1":          true,
882	"android.hardware.automotive.sv@1.0":           true,
883	"android.hardware.automotive.vehicle@2.0":      true,
884	"android.hardware.biometrics.face@1.0":         true,
885	"android.hardware.biometrics.fingerprint@2.1":  true,
886	"android.hardware.biometrics.fingerprint@2.2":  true,
887	"android.hardware.biometrics.fingerprint@2.3":  true,
888	"android.hardware.bluetooth@1.0":               true,
889	"android.hardware.bluetooth@1.1":               true,
890	"android.hardware.bluetooth.a2dp@1.0":          true,
891	"android.hardware.bluetooth.audio@2.0":         true,
892	"android.hardware.bluetooth.audio@2.1":         true,
893	"android.hardware.bluetooth.audio@2.2":         true,
894	"android.hardware.boot@1.0":                    true,
895	"android.hardware.boot@1.1":                    true,
896	"android.hardware.boot@1.2":                    true,
897	"android.hardware.broadcastradio@1.0":          true,
898	"android.hardware.broadcastradio@1.1":          true,
899	"android.hardware.broadcastradio@2.0":          true,
900	"android.hardware.camera.common@1.0":           true,
901	"android.hardware.camera.device@1.0":           true,
902	"android.hardware.camera.device@3.2":           true,
903	"android.hardware.camera.device@3.3":           true,
904	"android.hardware.camera.device@3.4":           true,
905	"android.hardware.camera.device@3.5":           true,
906	"android.hardware.camera.device@3.6":           true,
907	"android.hardware.camera.device@3.7":           true,
908	"android.hardware.camera.device@3.8":           true,
909	"android.hardware.camera.metadata@3.2":         true,
910	"android.hardware.camera.metadata@3.3":         true,
911	"android.hardware.camera.metadata@3.4":         true,
912	"android.hardware.camera.metadata@3.5":         true,
913	"android.hardware.camera.metadata@3.6":         true,
914	// TODO: Remove metadata@3.8 after AIDL migration b/196432585
915	"android.hardware.camera.metadata@3.7":              true,
916	"android.hardware.camera.metadata@3.8":              true,
917	"android.hardware.camera.provider@2.4":              true,
918	"android.hardware.camera.provider@2.5":              true,
919	"android.hardware.camera.provider@2.6":              true,
920	"android.hardware.camera.provider@2.7":              true,
921	"android.hardware.cas@1.0":                          true,
922	"android.hardware.cas@1.1":                          true,
923	"android.hardware.cas@1.2":                          true,
924	"android.hardware.cas.native@1.0":                   true,
925	"android.hardware.configstore@1.0":                  true,
926	"android.hardware.configstore@1.1":                  true,
927	"android.hardware.confirmationui@1.0":               true,
928	"android.hardware.contexthub@1.0":                   true,
929	"android.hardware.contexthub@1.1":                   true,
930	"android.hardware.contexthub@1.2":                   true,
931	"android.hardware.drm@1.0":                          true,
932	"android.hardware.drm@1.1":                          true,
933	"android.hardware.drm@1.2":                          true,
934	"android.hardware.drm@1.3":                          true,
935	"android.hardware.drm@1.4":                          true,
936	"android.hardware.dumpstate@1.0":                    true,
937	"android.hardware.dumpstate@1.1":                    true,
938	"android.hardware.fastboot@1.0":                     true,
939	"android.hardware.fastboot@1.1":                     true,
940	"android.hardware.gatekeeper@1.0":                   true,
941	"android.hardware.gnss@1.0":                         true,
942	"android.hardware.gnss@1.1":                         true,
943	"android.hardware.gnss@2.0":                         true,
944	"android.hardware.gnss@2.1":                         true,
945	"android.hardware.gnss.measurement_corrections@1.0": true,
946	"android.hardware.gnss.measurement_corrections@1.1": true,
947	"android.hardware.gnss.visibility_control@1.0":      true,
948	"android.hardware.graphics.allocator@2.0":           true,
949	"android.hardware.graphics.allocator@3.0":           true,
950	"android.hardware.graphics.allocator@4.0":           true,
951	"android.hardware.graphics.bufferqueue@1.0":         true,
952	"android.hardware.graphics.bufferqueue@2.0":         true,
953	"android.hardware.graphics.common@1.0":              true,
954	"android.hardware.graphics.common@1.1":              true,
955	"android.hardware.graphics.common@1.2":              true,
956	"android.hardware.graphics.composer@2.1":            true,
957	"android.hardware.graphics.composer@2.2":            true,
958	"android.hardware.graphics.composer@2.3":            true,
959	"android.hardware.graphics.composer@2.4":            true,
960	"android.hardware.graphics.mapper@2.0":              true,
961	"android.hardware.graphics.mapper@2.1":              true,
962	"android.hardware.graphics.mapper@3.0":              true,
963	"android.hardware.graphics.mapper@4.0":              true,
964	"android.hardware.health@1.0":                       true,
965	"android.hardware.health@2.0":                       true,
966	"android.hardware.health@2.1":                       true,
967	"android.hardware.health.storage@1.0":               true,
968	"android.hardware.input.classifier@1.0":             true,
969	"android.hardware.input.common@1.0":                 true,
970	"android.hardware.ir@1.0":                           true,
971	"android.hardware.keymaster@3.0":                    true,
972	"android.hardware.keymaster@4.0":                    true,
973	"android.hardware.keymaster@4.1":                    true,
974	"android.hardware.light@2.0":                        true,
975	"android.hardware.media@1.0":                        true,
976	"android.hardware.media.bufferpool@1.0":             true,
977	"android.hardware.media.bufferpool@2.0":             true,
978	"android.hardware.media.c2@1.0":                     true,
979	"android.hardware.media.c2@1.1":                     true,
980	"android.hardware.media.c2@1.2":                     true,
981	"android.hardware.media.omx@1.0":                    true,
982	"android.hardware.memtrack@1.0":                     true,
983	"android.hardware.neuralnetworks@1.0":               true,
984	"android.hardware.neuralnetworks@1.1":               true,
985	"android.hardware.neuralnetworks@1.2":               true,
986	"android.hardware.neuralnetworks@1.3":               true,
987	"android.hardware.nfc@1.0":                          true,
988	"android.hardware.nfc@1.1":                          true,
989	"android.hardware.nfc@1.2":                          true,
990	"android.hardware.oemlock@1.0":                      true,
991	"android.hardware.power@1.0":                        true,
992	"android.hardware.power@1.1":                        true,
993	"android.hardware.power@1.2":                        true,
994	"android.hardware.power@1.3":                        true,
995	"android.hardware.power.stats@1.0":                  true,
996	"android.hardware.radio@1.0":                        true,
997	"android.hardware.radio@1.1":                        true,
998	"android.hardware.radio@1.2":                        true,
999	"android.hardware.radio@1.3":                        true,
1000	"android.hardware.radio@1.4":                        true,
1001	"android.hardware.radio@1.5":                        true,
1002	"android.hardware.radio@1.6":                        true,
1003	"android.hardware.radio.config@1.0":                 true,
1004	"android.hardware.radio.config@1.1":                 true,
1005	"android.hardware.radio.config@1.2":                 true,
1006	"android.hardware.radio.config@1.3":                 true,
1007	"android.hardware.radio.deprecated@1.0":             true,
1008	"android.hardware.renderscript@1.0":                 true,
1009	"android.hardware.secure_element@1.0":               true,
1010	"android.hardware.secure_element@1.1":               true,
1011	"android.hardware.secure_element@1.2":               true,
1012	"android.hardware.sensors@1.0":                      true,
1013	"android.hardware.sensors@2.0":                      true,
1014	"android.hardware.sensors@2.1":                      true,
1015	"android.hardware.soundtrigger@2.0":                 true,
1016	"android.hardware.soundtrigger@2.1":                 true,
1017	"android.hardware.soundtrigger@2.2":                 true,
1018	"android.hardware.soundtrigger@2.3":                 true,
1019	"android.hardware.soundtrigger@2.4":                 true,
1020	"android.hardware.tests.bar@1.0":                    true,
1021	"android.hardware.tests.baz@1.0":                    true,
1022	"android.hardware.tests.expression@1.0":             true,
1023	"android.hardware.tests.extension.light@2.0":        true,
1024	"android.hardware.tests.foo@1.0":                    true,
1025	"android.hardware.tests.hash@1.0":                   true,
1026	"android.hardware.tests.inheritance@1.0":            true,
1027	"android.hardware.tests.lazy@1.0":                   true,
1028	"android.hardware.tests.lazy@1.1":                   true,
1029	"android.hardware.tests.lazy_cb@1.0":                true,
1030	"android.hardware.tests.libhwbinder@1.0":            true,
1031	"android.hardware.tests.memory@1.0":                 true,
1032	"android.hardware.tests.memory@2.0":                 true,
1033	"android.hardware.tests.msgq@1.0":                   true,
1034	"android.hardware.tests.multithread@1.0":            true,
1035	"android.hardware.tests.safeunion@1.0":              true,
1036	"android.hardware.tests.safeunion.cpp@1.0":          true,
1037	"android.hardware.tests.trie@1.0":                   true,
1038	"android.hardware.tetheroffload.config@1.0":         true,
1039	"android.hardware.tetheroffload.control@1.0":        true,
1040	"android.hardware.tetheroffload.control@1.1":        true,
1041	"android.hardware.thermal@1.0":                      true,
1042	"android.hardware.thermal@1.1":                      true,
1043	"android.hardware.thermal@2.0":                      true,
1044	"android.hardware.tv.cec@1.0":                       true,
1045	"android.hardware.tv.cec@1.1":                       true,
1046	"android.hardware.tv.input@1.0":                     true,
1047	"android.hardware.tv.tuner@1.0":                     true,
1048	"android.hardware.tv.tuner@1.1":                     true,
1049	"android.hardware.usb@1.0":                          true,
1050	"android.hardware.usb@1.1":                          true,
1051	"android.hardware.usb@1.2":                          true,
1052	"android.hardware.usb@1.3":                          true,
1053	"android.hardware.usb.gadget@1.0":                   true,
1054	"android.hardware.usb.gadget@1.1":                   true,
1055	"android.hardware.usb.gadget@1.2":                   true,
1056	"android.hardware.vibrator@1.0":                     true,
1057	"android.hardware.vibrator@1.1":                     true,
1058	"android.hardware.vibrator@1.2":                     true,
1059	"android.hardware.vibrator@1.3":                     true,
1060	"android.hardware.vr@1.0":                           true,
1061	"android.hardware.weaver@1.0":                       true,
1062	"android.hardware.wifi@1.0":                         true,
1063	"android.hardware.wifi@1.1":                         true,
1064	"android.hardware.wifi@1.2":                         true,
1065	"android.hardware.wifi@1.3":                         true,
1066	"android.hardware.wifi@1.4":                         true,
1067	"android.hardware.wifi@1.5":                         true,
1068	"android.hardware.wifi@1.6":                         true,
1069	"android.hardware.wifi.hostapd@1.0":                 true,
1070	"android.hardware.wifi.hostapd@1.1":                 true,
1071	"android.hardware.wifi.hostapd@1.2":                 true,
1072	"android.hardware.wifi.hostapd@1.3":                 true,
1073	"android.hardware.wifi.offload@1.0":                 true,
1074	"android.hardware.wifi.supplicant@1.0":              true,
1075	"android.hardware.wifi.supplicant@1.1":              true,
1076	"android.hardware.wifi.supplicant@1.2":              true,
1077	"android.hardware.wifi.supplicant@1.3":              true,
1078	"android.hardware.wifi.supplicant@1.4":              true,
1079	"android.hidl.allocator@1.0":                        true,
1080	"android.hidl.base@1.0":                             true,
1081	"android.hidl.manager@1.0":                          true,
1082	"android.hidl.manager@1.1":                          true,
1083	"android.hidl.manager@1.2":                          true,
1084	"android.hidl.memory@1.0":                           true,
1085	"android.hidl.memory.block@1.0":                     true,
1086	"android.hidl.memory.token@1.0":                     true,
1087	"android.hidl.safe_union@1.0":                       true,
1088	"android.hidl.token@1.0":                            true,
1089	"android.system.net.netd@1.0":                       true,
1090	"android.system.net.netd@1.1":                       true,
1091	"android.system.suspend@1.0":                        true,
1092	"android.system.wifi.keystore@1.0":                  true,
1093}
1094