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