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. "[email protected]::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			Is_stubs_module: proptools.BoolPtr(true),
631		}
632
633		mctx.CreateModule(java.LibraryFactory, &javaProperties{
634			Name:        proptools.StringPtr(name.javaName()),
635			Static_libs: javaDependencies,
636		}, &commonJavaProperties)
637		mctx.CreateModule(java.LibraryFactory, &javaProperties{
638			Name: proptools.StringPtr(name.javaSharedName()),
639			Libs: javaDependencies,
640		}, &commonJavaProperties)
641	}
642
643	if shouldGenerateJavaConstants {
644		mctx.CreateModule(hidlGenFactory, &nameProperties{
645			Name: proptools.StringPtr(name.javaConstantsSourcesName()),
646		}, &hidlGenProperties{
647			Language:   "java-constants",
648			FqName:     name.string(),
649			Root:       i.properties.Root,
650			Interfaces: i.properties.Interfaces,
651			Inputs:     i.properties.Srcs,
652			Outputs:    []string{name.sanitizedDir() + "Constants.java"},
653		})
654		mctx.CreateModule(java.LibraryFactory, &javaProperties{
655			Name:            proptools.StringPtr(name.javaConstantsName()),
656			Defaults:        []string{"hidl-java-module-defaults"},
657			Sdk_version:     proptools.StringPtr("core_current"),
658			Srcs:            []string{":" + name.javaConstantsSourcesName()},
659			Apex_available:  i.properties.Apex_available,
660			Min_sdk_version: getMinSdkVersion(name.string()),
661			Is_stubs_module: proptools.BoolPtr(true),
662		})
663	}
664
665	mctx.CreateModule(hidlGenFactory, &nameProperties{
666		Name: proptools.StringPtr(name.lintName()),
667	}, &hidlGenProperties{
668		Language:   "lint",
669		FqName:     name.string(),
670		Root:       i.properties.Root,
671		Interfaces: i.properties.Interfaces,
672		Inputs:     i.properties.Srcs,
673	})
674
675	mctx.CreateModule(hidlGenFactory, &nameProperties{
676		Name: proptools.StringPtr(name.inheritanceHierarchyName()),
677	}, &hidlGenProperties{
678		Language:   "inheritance-hierarchy",
679		FqName:     name.string(),
680		Root:       i.properties.Root,
681		Interfaces: i.properties.Interfaces,
682		Inputs:     i.properties.Srcs,
683	})
684}
685
686func (h *hidlInterface) Name() string {
687	return h.ModuleBase.Name() + hidlInterfaceSuffix
688}
689func (h *hidlInterface) GenerateAndroidBuildActions(ctx android.ModuleContext) {
690	visited := false
691	ctx.VisitDirectDeps(func(dep android.Module) {
692		if r, ok := dep.(*hidlPackageRoot); ok {
693			if visited {
694				panic("internal error, multiple dependencies found but only one added")
695			}
696			visited = true
697			h.properties.Full_root_option = r.getFullPackageRoot()
698		}
699	})
700	if !visited {
701		panic("internal error, no dependencies found but dependency added")
702	}
703
704}
705func (h *hidlInterface) DepsMutator(ctx android.BottomUpMutatorContext) {
706	ctx.AddDependency(ctx.Module(), nil, h.properties.Root)
707}
708
709func HidlInterfaceFactory() android.Module {
710	i := &hidlInterface{}
711	i.AddProperties(&i.properties)
712	android.InitAndroidModule(i)
713	android.AddLoadHook(i, func(ctx android.LoadHookContext) { hidlInterfaceMutator(ctx, i) })
714
715	return i
716}
717
718var minSdkVersion = map[string]string{
719	"[email protected]":            "30",
720	"[email protected]":            "31",
721	"[email protected]": "31",
722	"[email protected]": "31",
723	"[email protected]":      "31",
724	"[email protected]":          "30",
725	"[email protected]":         "30",
726	"[email protected]":         "30",
727	"[email protected]":         "30",
728	"[email protected]":               "30",
729	"[email protected]":               "30",
730	"[email protected]":                  "31",
731	"[email protected]":                  "31",
732	"[email protected]":          "30",
733	"[email protected]":          "30",
734	"[email protected]":          "30",
735	"[email protected]":          "30",
736	"[email protected]":                    "30",
737	"[email protected]":                    "30",
738	"[email protected]":                    "30",
739	"[email protected]":                    "30",
740	"[email protected]":                    "30",
741	"[email protected]":                    "30",
742	"[email protected]":                    "30",
743	"[email protected]":            "30",
744	"[email protected]":            "30",
745	"[email protected]":            "30",
746	"[email protected]":            "30",
747	"[email protected]":         "30",
748	"[email protected]":         "30",
749	"[email protected]":         "30",
750	"[email protected]":         "30",
751	"[email protected]":         "30",
752	"[email protected]":                     "30",
753	"[email protected]":                     "30",
754	"[email protected]":                     "30",
755}
756
757func getMinSdkVersion(name string) *string {
758	if ver, ok := minSdkVersion[name]; ok {
759		return proptools.StringPtr(ver)
760	}
761	// legacy, as used
762	if name == "[email protected]" ||
763		name == "[email protected]" ||
764		name == "[email protected]" ||
765		name == "[email protected]" ||
766		name == "[email protected]" {
767
768		return nil
769	}
770	return proptools.StringPtr("29")
771}
772
773var doubleLoadablePackageNames = []string{
774	"[email protected]",
775	"[email protected]",
776	"[email protected]",
777	"android.hardware.configstore@",
778	"android.hardware.drm@",
779	"android.hardware.graphics.allocator@",
780	"android.hardware.graphics.bufferqueue@",
781	"android.hardware.graphics.common@",
782	"android.hardware.graphics.mapper@",
783	"android.hardware.media@",
784	"android.hardware.media.bufferpool@",
785	"android.hardware.media.c2@",
786	"android.hardware.media.omx@",
787	"[email protected]",
788	"android.hardware.neuralnetworks@",
789	"android.hidl.allocator@",
790	"android.hidl.memory@",
791	"android.hidl.memory.token@",
792	"android.hidl.safe_union@",
793	"android.hidl.token@",
794	"android.hardware.renderscript@",
795	"[email protected]",
796}
797
798func isDoubleLoadable(name string) bool {
799	for _, pkgname := range doubleLoadablePackageNames {
800		if strings.HasPrefix(name, pkgname) {
801			return true
802		}
803	}
804	return false
805}
806
807// packages in libhidlbase
808var coreDependencyPackageNames = []string{
809	"android.hidl.base@",
810	"android.hidl.manager@",
811}
812
813func isCorePackage(name string) bool {
814	for _, pkgname := range coreDependencyPackageNames {
815		if strings.HasPrefix(name, pkgname) {
816			return true
817		}
818	}
819	return false
820}
821
822var fuzzerPackageNameBlacklist = []string{
823	"android.hardware.keymaster@", // to avoid deleteAllKeys()
824	// Same-process HALs are always opened in the same process as their client.
825	// So stability guarantees don't apply to them, e.g. it's OK to crash on
826	// NULL input from client. Disable corresponding fuzzers as they create too
827	// much noise.
828	"android.hardware.graphics.mapper@",
829	"android.hardware.renderscript@",
830	"android.hidl.memory@",
831}
832
833func isFuzzerEnabled(name string) bool {
834	// TODO(151338797): re-enable fuzzers
835	return false
836}
837
838func canInterfaceExist(name string) bool {
839	if strings.HasPrefix(name, "android.") {
840		return allAospHidlInterfaces[name]
841	}
842
843	return true
844}
845
846var allAospHidlInterfaces = map[string]bool{
847	"[email protected]":    true,
848	"[email protected]":             true,
849	"[email protected]":  true,
850	"[email protected]":  true,
851	"[email protected]":  true,
852	"[email protected]": true,
853	"[email protected]": true,
854	"[email protected]": true,
855	"[email protected]":        true,
856	"[email protected]":      true,
857	"[email protected]":         true,
858	"[email protected]":                 true,
859	"[email protected]":           true,
860	"[email protected]":           true,
861	"[email protected]":                  true,
862	"[email protected]":                   true,
863	"[email protected]":                   true,
864	"[email protected]":                   true,
865	"[email protected]":                   true,
866	"[email protected]":                   true,
867	"[email protected]":                   true,
868	"[email protected]":            true,
869	"[email protected]":            true,
870	"[email protected]":            true,
871	"[email protected]":            true,
872	"[email protected]":            true,
873	"[email protected]":            true,
874	"[email protected]":            true,
875	"[email protected]":            true,
876	"[email protected]":            true,
877	"[email protected]":            true,
878	"[email protected]":              true,
879	"[email protected]": true,
880	"[email protected]": true,
881	"[email protected]":          true,
882	"[email protected]":          true,
883	"[email protected]":          true,
884	"[email protected]":           true,
885	"[email protected]":      true,
886	"[email protected]":         true,
887	"[email protected]":  true,
888	"[email protected]":  true,
889	"[email protected]":  true,
890	"[email protected]":               true,
891	"[email protected]":               true,
892	"[email protected]":          true,
893	"[email protected]":         true,
894	"[email protected]":         true,
895	"[email protected]":         true,
896	"[email protected]":                    true,
897	"[email protected]":                    true,
898	"[email protected]":                    true,
899	"[email protected]":          true,
900	"[email protected]":          true,
901	"[email protected]":          true,
902	"[email protected]":           true,
903	"[email protected]":           true,
904	"[email protected]":           true,
905	"[email protected]":           true,
906	"[email protected]":           true,
907	"[email protected]":           true,
908	"[email protected]":           true,
909	"[email protected]":           true,
910	"[email protected]":           true,
911	"[email protected]":         true,
912	"[email protected]":         true,
913	"[email protected]":         true,
914	"[email protected]":         true,
915	"[email protected]":         true,
916	// TODO: Remove [email protected] after AIDL migration b/196432585
917	"[email protected]":              true,
918	"[email protected]":              true,
919	"[email protected]":              true,
920	"[email protected]":              true,
921	"[email protected]":              true,
922	"[email protected]":              true,
923	"[email protected]":                          true,
924	"[email protected]":                          true,
925	"[email protected]":                          true,
926	"[email protected]":                   true,
927	"[email protected]":                  true,
928	"[email protected]":                  true,
929	"[email protected]":               true,
930	"[email protected]":                   true,
931	"[email protected]":                   true,
932	"[email protected]":                   true,
933	"[email protected]":                          true,
934	"[email protected]":                          true,
935	"[email protected]":                          true,
936	"[email protected]":                          true,
937	"[email protected]":                          true,
938	"[email protected]":                    true,
939	"[email protected]":                    true,
940	"[email protected]":                     true,
941	"[email protected]":                     true,
942	"[email protected]":                   true,
943	"[email protected]":                         true,
944	"[email protected]":                         true,
945	"[email protected]":                         true,
946	"[email protected]":                         true,
947	"[email protected]": true,
948	"[email protected]": true,
949	"[email protected]":      true,
950	"[email protected]":           true,
951	"[email protected]":           true,
952	"[email protected]":           true,
953	"[email protected]":         true,
954	"[email protected]":         true,
955	"[email protected]":              true,
956	"[email protected]":              true,
957	"[email protected]":              true,
958	"[email protected]":            true,
959	"[email protected]":            true,
960	"[email protected]":            true,
961	"[email protected]":            true,
962	"[email protected]":              true,
963	"[email protected]":              true,
964	"[email protected]":              true,
965	"[email protected]":              true,
966	"[email protected]":                       true,
967	"[email protected]":                       true,
968	"[email protected]":                       true,
969	"[email protected]":               true,
970	"[email protected]":             true,
971	"[email protected]":                 true,
972	"[email protected]":                           true,
973	"[email protected]":                    true,
974	"[email protected]":                    true,
975	"[email protected]":                    true,
976	"[email protected]":                        true,
977	"[email protected]":                        true,
978	"[email protected]":             true,
979	"[email protected]":             true,
980	"[email protected]":                     true,
981	"[email protected]":                     true,
982	"[email protected]":                     true,
983	"[email protected]":                    true,
984	"[email protected]":                     true,
985	"[email protected]":               true,
986	"[email protected]":               true,
987	"[email protected]":               true,
988	"[email protected]":               true,
989	"[email protected]":                          true,
990	"[email protected]":                          true,
991	"[email protected]":                          true,
992	"[email protected]":                      true,
993	"[email protected]":                        true,
994	"[email protected]":                        true,
995	"[email protected]":                        true,
996	"[email protected]":                        true,
997	"[email protected]":                  true,
998	"[email protected]":                        true,
999	"[email protected]":                        true,
1000	"[email protected]":                        true,
1001	"[email protected]":                        true,
1002	"[email protected]":                        true,
1003	"[email protected]":                        true,
1004	"[email protected]":                        true,
1005	"[email protected]":                 true,
1006	"[email protected]":                 true,
1007	"[email protected]":                 true,
1008	"[email protected]":                 true,
1009	"[email protected]":             true,
1010	"[email protected]":                 true,
1011	"[email protected]":               true,
1012	"[email protected]":               true,
1013	"[email protected]":               true,
1014	"[email protected]":                      true,
1015	"[email protected]":                      true,
1016	"[email protected]":                      true,
1017	"[email protected]":                 true,
1018	"[email protected]":                 true,
1019	"[email protected]":                 true,
1020	"[email protected]":                 true,
1021	"[email protected]":                 true,
1022	"[email protected]":                    true,
1023	"[email protected]":                    true,
1024	"[email protected]":             true,
1025	"[email protected]":        true,
1026	"[email protected]":                    true,
1027	"[email protected]":                   true,
1028	"[email protected]":            true,
1029	"[email protected]":                   true,
1030	"[email protected]":                   true,
1031	"[email protected]":                true,
1032	"[email protected]":            true,
1033	"[email protected]":                 true,
1034	"[email protected]":                 true,
1035	"[email protected]":                   true,
1036	"[email protected]":            true,
1037	"[email protected]":              true,
1038	"[email protected]":          true,
1039	"[email protected]":                   true,
1040	"[email protected]":         true,
1041	"[email protected]":        true,
1042	"[email protected]":        true,
1043	"[email protected]":                      true,
1044	"[email protected]":                      true,
1045	"[email protected]":                      true,
1046	"[email protected]":                       true,
1047	"[email protected]":                       true,
1048	"[email protected]":                     true,
1049	"[email protected]":                     true,
1050	"[email protected]":                     true,
1051	"[email protected]":                          true,
1052	"[email protected]":                          true,
1053	"[email protected]":                          true,
1054	"[email protected]":                          true,
1055	"[email protected]":                   true,
1056	"[email protected]":                   true,
1057	"[email protected]":                   true,
1058	"[email protected]":                     true,
1059	"[email protected]":                     true,
1060	"[email protected]":                     true,
1061	"[email protected]":                     true,
1062	"[email protected]":                           true,
1063	"[email protected]":                       true,
1064	"[email protected]":                         true,
1065	"[email protected]":                         true,
1066	"[email protected]":                         true,
1067	"[email protected]":                         true,
1068	"[email protected]":                         true,
1069	"[email protected]":                         true,
1070	"[email protected]":                         true,
1071	"[email protected]":                 true,
1072	"[email protected]":                 true,
1073	"[email protected]":                 true,
1074	"[email protected]":                 true,
1075	"[email protected]":                 true,
1076	"[email protected]":              true,
1077	"[email protected]":              true,
1078	"[email protected]":              true,
1079	"[email protected]":              true,
1080	"[email protected]":              true,
1081	"[email protected]":                        true,
1082	"[email protected]":                             true,
1083	"[email protected]":                          true,
1084	"[email protected]":                          true,
1085	"[email protected]":                          true,
1086	"[email protected]":                           true,
1087	"[email protected]":                     true,
1088	"[email protected]":                     true,
1089	"[email protected]":                       true,
1090	"[email protected]":                            true,
1091	"[email protected]":                       true,
1092	"[email protected]":                       true,
1093	"[email protected]":                        true,
1094	"[email protected]":                  true,
1095}
1096