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