Add checkMatrixHalsHasDefinition
This function checks that all HALs in the FCM is defined in
lib*idlmetadata.
Bug: 179099519
Test: vintf_object_test
Test: m check-vintf-all
Change-Id: Ib20ae90cbfe0292f6aaf96566ce9b02a7dbf8491
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 9d33c5d..59d8d30 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -1073,6 +1073,28 @@
return ret;
}
+// android.hardware.foo@1.0::IFoo.
+// Note that UDTs are not filtered out, so there might be non-interface types.
+std::set<std::string> HidlMetadataToNames(const std::vector<HidlInterfaceMetadata>& hidlMetadata) {
+ std::set<std::string> ret;
+ for (const auto& item : hidlMetadata) {
+ ret.insert(item.name);
+ }
+ return ret;
+}
+
+// android.hardware.foo.IFoo
+// Note that UDTs are not filtered out, so there might be non-interface types.
+std::set<std::string> AidlMetadataToNames(const std::vector<AidlInterfaceMetadata>& aidlMetadata) {
+ std::set<std::string> ret;
+ for (const auto& item : aidlMetadata) {
+ for (const auto& type : item.types) {
+ ret.insert(type);
+ }
+ }
+ return ret;
+}
+
} // anonymous namespace
android::base::Result<std::vector<CompatibilityMatrix>> VintfObject::getAllFrameworkMatrixLevels() {
@@ -1157,6 +1179,68 @@
return {};
}
+android::base::Result<void> VintfObject::checkMatrixHalsHasDefinition(
+ const std::vector<HidlInterfaceMetadata>& hidlMetadata,
+ const std::vector<AidlInterfaceMetadata>& aidlMetadata) {
+ auto matrixFragments = getAllFrameworkMatrixLevels();
+ if (!matrixFragments.ok()) return matrixFragments.error();
+
+ auto allAidlNames = AidlMetadataToNames(aidlMetadata);
+ auto allHidlNames = HidlMetadataToNames(hidlMetadata);
+ std::set<std::string> badAidlInterfaces;
+ std::set<std::string> badHidlInterfaces;
+
+ std::vector<std::string> errors;
+ for (const auto& matrix : matrixFragments.value()) {
+ if (matrix.level() == Level::UNSPECIFIED) {
+ LOG(INFO) << "Skip checkMatrixHalsHasDefinition() on " << matrix.fileName()
+ << " with no level.";
+ continue;
+ }
+
+ matrix.forEachInstance([&](const MatrixInstance& matrixInstance) {
+ switch (matrixInstance.format()) {
+ case HalFormat::AIDL: {
+ auto matrixInterface =
+ toAidlFqnameString(matrixInstance.package(), matrixInstance.interface());
+ if (allAidlNames.find(matrixInterface) == allAidlNames.end()) {
+ errors.push_back(
+ "AIDL interface " + matrixInterface + " is referenced in " +
+ matrix.fileName() +
+ ", but there is no corresponding .aidl definition associated with an "
+ "aidl_interface module in this build. Typo?");
+ }
+ return true; // continue to next instance
+ }
+ case HalFormat::HIDL: {
+ for (Version v = matrixInstance.versionRange().minVer();
+ v <= matrixInstance.versionRange().maxVer(); ++v.minorVer) {
+ auto matrixInterface = matrixInstance.interfaceDescription(v);
+ if (allHidlNames.find(matrixInterface) == allHidlNames.end()) {
+ errors.push_back(
+ "HIDL interface " + matrixInterface + " is referenced in " +
+ matrix.fileName() +
+ ", but there is no corresponding .hal definition associated with "
+ "a hidl_interface module in this build. Typo?");
+ }
+ }
+ return true; // continue to next instance
+ }
+ default: {
+ // We do not have data for native HALs.
+ return true; // continue to next instance
+ }
+ }
+ });
+ }
+
+ if (!errors.empty()) {
+ return android::base::Error() << android::base::Join(errors, "\n");
+ }
+
+ return {};
+}
+
// make_unique does not work because VintfObject constructor is private.
VintfObject::Builder::Builder() : mObject(std::unique_ptr<VintfObject>(new VintfObject())) {}