Return<T>::description() provide more descriptive text than numbers
Test: libhidl_test
Change-Id: Ib7c591f261bb335b9fe348dd2fb0695a94bdf468
diff --git a/Android.bp b/Android.bp
index 59edb20..ae04548 100644
--- a/Android.bp
+++ b/Android.bp
@@ -37,7 +37,7 @@
"libutils",
"libcutils",
],
- static_libs: ["libgtest"],
+ static_libs: ["libgtest", "libgmock"],
cflags: [
"-O0",
diff --git a/base/Status.cpp b/base/Status.cpp
index e7320a8..449aff3 100644
--- a/base/Status.cpp
+++ b/base/Status.cpp
@@ -13,15 +13,71 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#define LOG_TAG "HidlStatus"
+#include <android-base/logging.h>
#include <hidl/Status.h>
-#include <android-base/logging.h>
+#include <unordered_map>
namespace android {
namespace hardware {
+static std::string statusToString(status_t s) {
+ const std::unordered_map<status_t, std::string> statusStrings{{
+ #define STATUS_TO_STRING_PAIR(STATUS) {STATUS, #STATUS}
+ STATUS_TO_STRING_PAIR(OK),
+ STATUS_TO_STRING_PAIR(UNKNOWN_ERROR),
+ STATUS_TO_STRING_PAIR(NO_MEMORY),
+ STATUS_TO_STRING_PAIR(INVALID_OPERATION),
+ STATUS_TO_STRING_PAIR(BAD_VALUE),
+ STATUS_TO_STRING_PAIR(BAD_TYPE),
+ STATUS_TO_STRING_PAIR(NAME_NOT_FOUND),
+ STATUS_TO_STRING_PAIR(PERMISSION_DENIED),
+ STATUS_TO_STRING_PAIR(NO_INIT),
+ STATUS_TO_STRING_PAIR(ALREADY_EXISTS),
+ STATUS_TO_STRING_PAIR(DEAD_OBJECT),
+ STATUS_TO_STRING_PAIR(FAILED_TRANSACTION),
+ STATUS_TO_STRING_PAIR(BAD_INDEX),
+ STATUS_TO_STRING_PAIR(NOT_ENOUGH_DATA),
+ STATUS_TO_STRING_PAIR(WOULD_BLOCK),
+ STATUS_TO_STRING_PAIR(TIMED_OUT),
+ STATUS_TO_STRING_PAIR(UNKNOWN_TRANSACTION),
+ STATUS_TO_STRING_PAIR(FDS_NOT_ALLOWED),
+ STATUS_TO_STRING_PAIR(UNEXPECTED_NULL)
+ }};
+ auto it = statusStrings.find(s);
+ if (it != statusStrings.end()) {
+ return it->second;
+ }
+ std::string str = std::to_string(s);
+ char *err = strerror(-s);
+ if (err != NULL) {
+ str.append(1, ' ').append(err);
+ }
+ return str;
+}
+
+static std::string exceptionToString(int32_t ex) {
+ const std::unordered_map<int32_t, std::string> exceptionStrings{{
+ #define EXCEPTION_TO_STRING_PAIR(EXCEPTION) {Status::Exception::EXCEPTION, #EXCEPTION}
+ EXCEPTION_TO_STRING_PAIR(EX_NONE),
+ EXCEPTION_TO_STRING_PAIR(EX_SECURITY),
+ EXCEPTION_TO_STRING_PAIR(EX_BAD_PARCELABLE),
+ EXCEPTION_TO_STRING_PAIR(EX_ILLEGAL_ARGUMENT),
+ EXCEPTION_TO_STRING_PAIR(EX_NULL_POINTER),
+ EXCEPTION_TO_STRING_PAIR(EX_ILLEGAL_STATE),
+ EXCEPTION_TO_STRING_PAIR(EX_NETWORK_MAIN_THREAD),
+ EXCEPTION_TO_STRING_PAIR(EX_UNSUPPORTED_OPERATION),
+ EXCEPTION_TO_STRING_PAIR(EX_SERVICE_SPECIFIC),
+ EXCEPTION_TO_STRING_PAIR(EX_HAS_REPLY_HEADER),
+ EXCEPTION_TO_STRING_PAIR(EX_TRANSACTION_FAILED)
+ }};
+ auto it = exceptionStrings.find(ex);
+ return it == exceptionStrings.end() ? std::to_string(ex) : it->second;
+}
+
Status Status::ok() {
return Status();
}
@@ -86,11 +142,11 @@
if (s.exceptionCode() == Status::EX_NONE) {
stream << "No error";
} else {
- stream << "Status(" << s.exceptionCode() << "): '";
+ stream << "Status(" << exceptionToString(s.exceptionCode()) << "): '";
if (s.exceptionCode() == Status::EX_SERVICE_SPECIFIC) {
stream << s.serviceSpecificErrorCode() << ": ";
} else if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) {
- stream << s.transactionError() << ": ";
+ stream << statusToString(s.transactionError()) << ": ";
}
stream << s.exceptionMessage() << "'";
}
diff --git a/test_main.cpp b/test_main.cpp
index 27d62a0..b799f6e 100644
--- a/test_main.cpp
+++ b/test_main.cpp
@@ -17,8 +17,10 @@
#define LOG_TAG "LibHidlTest"
#include <android-base/logging.h>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <hidl/HidlSupport.h>
+#include <hidl/Status.h>
#include <hidl/TaskRunner.h>
#include <vector>
@@ -344,6 +346,33 @@
ret.isOk();
}
+std::string toString(const ::android::hardware::Status &s) {
+ using ::android::hardware::operator<<;
+ std::ostringstream oss;
+ oss << s;
+ return oss.str();
+}
+
+TEST_F(LibHidlTest, StatusStringTest) {
+ using namespace ::android;
+ using ::android::hardware::Status;
+ using ::testing::HasSubstr;
+
+ EXPECT_EQ(toString(Status::ok()), "No error");
+
+ EXPECT_THAT(toString(Status::fromStatusT(DEAD_OBJECT)), HasSubstr("DEAD_OBJECT"));
+
+ EXPECT_THAT(toString(Status::fromStatusT(-EBUSY)), HasSubstr("busy"));
+
+ auto s = toString(Status::fromServiceSpecificError(20));
+ EXPECT_THAT(s, HasSubstr("EX_SERVICE_SPECIFIC"));
+ EXPECT_THAT(s, HasSubstr("20"));
+
+ EXPECT_THAT(toString(Status::fromExceptionCode(Status::EX_NULL_POINTER)),
+ HasSubstr("EX_NULL_POINTER"));
+
+}
+
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();