Fix lshal not to squash HAL entries incorrectly.
Bug: 37311367
Test: lshal --init-vintf
Change-Id: I693b53f5f342c7600e4031d020792fd347e3ae83
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 33bc43c..4b698c0 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -163,6 +163,7 @@
return true;
}
+// Must process hwbinder services first, then passthrough services.
void Lshal::forEachTable(const std::function<void(Table &)> &f) {
f(mServicesTable);
f(mPassthroughRefTable);
@@ -243,6 +244,18 @@
}
void Lshal::dumpVintf() const {
+ mOut << "<!-- " << std::endl
+ << " This is a skeleton device manifest. Notes: " << std::endl
+ << " 1. android.hidl.*, android.frameworks.*, android.system.* are not included." << std::endl
+ << " 2. If a HAL is supported in both hwbinder and passthrough transport, " << std::endl
+ << " only hwbinder is shown." << std::endl
+ << " 3. It is likely that HALs in passthrough transport does not have" << std::endl
+ << " <interface> declared; users will have to write them by hand." << std::endl
+ << " 4. sepolicy version is set to 0.0. It is recommended that the entry" << std::endl
+ << " is removed from the manifest file and written by assemble_vintf" << std::endl
+ << " at build time." << std::endl
+ << "-->" << std::endl;
+
vintf::HalManifest manifest;
forEachTable([this, &manifest] (const Table &table) {
for (const TableEntry &entry : table) {
@@ -271,6 +284,8 @@
std::string instanceName =
&table == &mImplementationsTable ? "" : splittedFqInstanceName.second;
+ vintf::Version version{fqName.getPackageMajorVersion(),
+ fqName.getPackageMinorVersion()};
vintf::Transport transport;
vintf::Arch arch;
if (entry.transport == "hwbinder") {
@@ -296,34 +311,33 @@
continue;
}
- vintf::ManifestHal *hal = manifest.getAnyHal(fqName.package());
- if (hal == nullptr) {
- if (!manifest.add(vintf::ManifestHal{
+ bool done = false;
+ for (vintf::ManifestHal *hal : manifest.getHals(fqName.package())) {
+ if (hal->transport() != transport) {
+ if (transport != vintf::Transport::PASSTHROUGH) {
+ mErr << "Fatal: should not reach here. Generated result may be wrong."
+ << std::endl;
+ }
+ done = true;
+ break;
+ }
+ if (hal->hasVersion(version)) {
+ hal->interfaces[interfaceName].name = interfaceName;
+ hal->interfaces[interfaceName].instances.insert(instanceName);
+ done = true;
+ break;
+ }
+ }
+ if (done) {
+ continue; // to next TableEntry
+ }
+ if (!manifest.add(vintf::ManifestHal{
.format = vintf::HalFormat::HIDL,
.name = fqName.package(),
- .transportArch = {transport, arch}
- })) {
- mErr << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
- continue;
- }
- hal = manifest.getAnyHal(fqName.package());
- }
- if (hal == nullptr) {
- mErr << "Warning: cannot get hal '" << fqInstanceName
- << "' after adding it" << std::endl;
- continue;
- }
- vintf::Version version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()};
- if (std::find(hal->versions.begin(), hal->versions.end(), version) == hal->versions.end()) {
- hal->versions.push_back(version);
- }
- if (&table != &mImplementationsTable) {
- auto it = hal->interfaces.find(interfaceName);
- if (it == hal->interfaces.end()) {
- hal->interfaces.insert({interfaceName, {interfaceName, {{instanceName}}}});
- } else {
- it->second.instances.insert(instanceName);
- }
+ .versions = {version},
+ .transportArch = {transport, arch},
+ .interfaces = {{interfaceName, {interfaceName, {{instanceName}}}}}})) {
+ mErr << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
}
}
});