check_vintf: write all error messages before exiting.
Allow developers to see all error messages instead of
fixing them one by one.
Test: m check-vintf-all
Test: m check-vintf-all with the following change:
- manually use health 1.0 HAL instead of 2.1
(both incompatible and unused)
- manually use vibrator HIDL 1.3 HAL instead of AIDL
(unused 1.3 HAL)
See error message for both.
Bug: 153370844
Change-Id: I8f77d1aae5df2cb309e72d1e18d3fdb3b7ed76da
(cherry picked from commit af3bb3b018b6395947a9feca0cf216673e8afed7)
Merged-In: I8f77d1aae5df2cb309e72d1e18d3fdb3b7ed76da
diff --git a/check_vintf.cpp b/check_vintf.cpp
index 8ef1ca8..ce32730 100644
--- a/check_vintf.cpp
+++ b/check_vintf.cpp
@@ -20,6 +20,7 @@
#include <iostream>
#include <map>
+#include <optional>
#include <android-base/file.h>
#include <android-base/logging.h>
@@ -347,6 +348,30 @@
return EX_USAGE;
}
+// If |result| is already an error, don't do anything. Otherwise, set it to
+// an error with |errorCode|. Return reference to Error object for appending
+// additional error messages.
+android::base::Error& SetErrorCode(std::optional<android::base::Error>* retError,
+ int errorCode = 0) {
+ if (!retError->has_value()) {
+ retError->emplace(errorCode);
+ } else {
+ // Use existing error code.
+ // There should already been an error message appended. Add a new line char for
+ // additional messages.
+ (**retError) << "\n";
+ }
+ return **retError;
+}
+
+// If |other| is an error, add it to |retError|.
+template <typename T>
+void AddResult(std::optional<android::base::Error>* retError,
+ const android::base::Result<T>& other) {
+ if (other.ok()) return;
+ SetErrorCode(retError, other.error().code()) << other.error();
+}
+
android::base::Result<void> checkAllFiles(const Dirmap& dirmap, const Properties& props,
std::shared_ptr<StaticRuntimeInfo> runtimeInfo) {
auto hostPropertyFetcher = std::make_unique<PresetPropertyFetcher>();
@@ -362,30 +387,39 @@
.setRuntimeInfoFactory(std::make_unique<StaticRuntimeInfoFactory>(runtimeInfo))
.build();
- std::string error;
- int compatibleResult = vintfObject->checkCompatibility(&error, flags);
+ std::optional<android::base::Error> retError = std::nullopt;
+
+ std::string compatibleError;
+ int compatibleResult = vintfObject->checkCompatibility(&compatibleError, flags);
if (compatibleResult == INCOMPATIBLE) {
- return android::base::Error() << error;
- }
- if (compatibleResult != COMPATIBLE) {
- return android::base::Error(-compatibleResult) << error;
+ SetErrorCode(&retError) << compatibleError;
+ } else if (compatibleResult != COMPATIBLE) {
+ SetErrorCode(&retError, -compatibleResult) << compatibleError;
}
auto hasFcmExt = vintfObject->hasFrameworkCompatibilityMatrixExtensions();
- if (!hasFcmExt.has_value()) {
- return hasFcmExt.error();
- }
+ AddResult(&retError, hasFcmExt);
+
auto deviceManifest = vintfObject->getDeviceHalManifest();
+ Level targetFcm = Level::UNSPECIFIED;
if (deviceManifest == nullptr) {
- return android::base::Error(-NAME_NOT_FOUND) << "No device HAL manifest";
+ SetErrorCode(&retError, -NAME_NOT_FOUND) << "No device HAL manifest";
+ } else {
+ targetFcm = deviceManifest->level();
}
- auto targetFcm = deviceManifest->level();
- if (*hasFcmExt || (targetFcm != Level::UNSPECIFIED && targetFcm >= Level::R)) {
+
+ if (hasFcmExt.value_or(false) || (targetFcm != Level::UNSPECIFIED && targetFcm >= Level::R)) {
auto hidlMetadata = HidlInterfaceMetadata::all();
- return vintfObject->checkUnusedHals(hidlMetadata);
+ AddResult(&retError, vintfObject->checkUnusedHals(hidlMetadata));
+ } else {
+ LOG(INFO) << "Skip checking unused HALs.";
}
- LOG(INFO) << "Skip checking unused HALs.";
- return {};
+
+ if (retError.has_value()) {
+ return *retError;
+ } else {
+ return {};
+ }
}
int checkDirmaps(const Dirmap& dirmap, const Properties& props) {