Status.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Copyright (C) 2015 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define LOG_TAG "HidlStatus"
  17. #include <android-base/logging.h>
  18. #include <hidl/Status.h>
  19. #include <utils/CallStack.h>
  20. #include <unordered_map>
  21. namespace android {
  22. namespace hardware {
  23. static std::string statusToString(status_t s) {
  24. const std::unordered_map<status_t, std::string> statusStrings{{
  25. #define STATUS_TO_STRING_PAIR(STATUS) {STATUS, #STATUS}
  26. STATUS_TO_STRING_PAIR(OK),
  27. STATUS_TO_STRING_PAIR(UNKNOWN_ERROR),
  28. STATUS_TO_STRING_PAIR(NO_MEMORY),
  29. STATUS_TO_STRING_PAIR(INVALID_OPERATION),
  30. STATUS_TO_STRING_PAIR(BAD_VALUE),
  31. STATUS_TO_STRING_PAIR(BAD_TYPE),
  32. STATUS_TO_STRING_PAIR(NAME_NOT_FOUND),
  33. STATUS_TO_STRING_PAIR(PERMISSION_DENIED),
  34. STATUS_TO_STRING_PAIR(NO_INIT),
  35. STATUS_TO_STRING_PAIR(ALREADY_EXISTS),
  36. STATUS_TO_STRING_PAIR(DEAD_OBJECT),
  37. STATUS_TO_STRING_PAIR(FAILED_TRANSACTION),
  38. STATUS_TO_STRING_PAIR(BAD_INDEX),
  39. STATUS_TO_STRING_PAIR(NOT_ENOUGH_DATA),
  40. STATUS_TO_STRING_PAIR(WOULD_BLOCK),
  41. STATUS_TO_STRING_PAIR(TIMED_OUT),
  42. STATUS_TO_STRING_PAIR(UNKNOWN_TRANSACTION),
  43. STATUS_TO_STRING_PAIR(FDS_NOT_ALLOWED),
  44. STATUS_TO_STRING_PAIR(UNEXPECTED_NULL)
  45. }};
  46. auto it = statusStrings.find(s);
  47. if (it != statusStrings.end()) {
  48. return it->second;
  49. }
  50. std::string str = std::to_string(s);
  51. char *err = strerror(-s);
  52. if (err != nullptr) {
  53. str.append(1, ' ').append(err);
  54. }
  55. return str;
  56. }
  57. static std::string exceptionToString(int32_t ex) {
  58. const std::unordered_map<int32_t, std::string> exceptionStrings{{
  59. #define EXCEPTION_TO_STRING_PAIR(EXCEPTION) {Status::Exception::EXCEPTION, #EXCEPTION}
  60. EXCEPTION_TO_STRING_PAIR(EX_NONE),
  61. EXCEPTION_TO_STRING_PAIR(EX_SECURITY),
  62. EXCEPTION_TO_STRING_PAIR(EX_BAD_PARCELABLE),
  63. EXCEPTION_TO_STRING_PAIR(EX_ILLEGAL_ARGUMENT),
  64. EXCEPTION_TO_STRING_PAIR(EX_NULL_POINTER),
  65. EXCEPTION_TO_STRING_PAIR(EX_ILLEGAL_STATE),
  66. EXCEPTION_TO_STRING_PAIR(EX_NETWORK_MAIN_THREAD),
  67. EXCEPTION_TO_STRING_PAIR(EX_UNSUPPORTED_OPERATION),
  68. EXCEPTION_TO_STRING_PAIR(EX_HAS_REPLY_HEADER),
  69. EXCEPTION_TO_STRING_PAIR(EX_TRANSACTION_FAILED)
  70. }};
  71. auto it = exceptionStrings.find(ex);
  72. return it == exceptionStrings.end() ? std::to_string(ex) : it->second;
  73. }
  74. Status Status::ok() {
  75. return Status();
  76. }
  77. Status Status::fromExceptionCode(int32_t exceptionCode) {
  78. if (exceptionCode == EX_TRANSACTION_FAILED) {
  79. return Status(exceptionCode, FAILED_TRANSACTION);
  80. }
  81. return Status(exceptionCode, OK);
  82. }
  83. Status Status::fromExceptionCode(int32_t exceptionCode,
  84. const char *message) {
  85. if (exceptionCode == EX_TRANSACTION_FAILED) {
  86. return Status(exceptionCode, FAILED_TRANSACTION, message);
  87. }
  88. return Status(exceptionCode, OK, message);
  89. }
  90. Status Status::fromStatusT(status_t status) {
  91. Status ret;
  92. ret.setFromStatusT(status);
  93. return ret;
  94. }
  95. Status::Status(int32_t exceptionCode, int32_t errorCode)
  96. : mException(exceptionCode),
  97. mErrorCode(errorCode) {}
  98. Status::Status(int32_t exceptionCode, int32_t errorCode, const char *message)
  99. : mException(exceptionCode),
  100. mErrorCode(errorCode),
  101. mMessage(message) {}
  102. void Status::setException(int32_t ex, const char *message) {
  103. mException = ex;
  104. mErrorCode = ex == EX_TRANSACTION_FAILED ? FAILED_TRANSACTION : NO_ERROR;
  105. mMessage = message;
  106. }
  107. void Status::setFromStatusT(status_t status) {
  108. mException = (status == NO_ERROR) ? EX_NONE : EX_TRANSACTION_FAILED;
  109. mErrorCode = status;
  110. mMessage.clear();
  111. }
  112. std::string Status::description() const {
  113. std::ostringstream oss;
  114. oss << (*this);
  115. return oss.str();
  116. }
  117. std::ostream& operator<< (std::ostream& stream, const Status& s) {
  118. if (s.exceptionCode() == Status::EX_NONE) {
  119. stream << "No error";
  120. } else {
  121. stream << "Status(" << exceptionToString(s.exceptionCode()) << "): '";
  122. if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) {
  123. stream << statusToString(s.transactionError()) << ": ";
  124. }
  125. stream << s.exceptionMessage() << "'";
  126. }
  127. return stream;
  128. }
  129. static HidlReturnRestriction gReturnRestriction = HidlReturnRestriction::NONE;
  130. void setProcessHidlReturnRestriction(HidlReturnRestriction restriction) {
  131. gReturnRestriction = restriction;
  132. }
  133. namespace details {
  134. void return_status::assertOk() const {
  135. if (!isOk()) {
  136. LOG(FATAL) << "Attempted to retrieve value from failed HIDL call: " << description();
  137. }
  138. }
  139. return_status::~return_status() {
  140. // mCheckedStatus must be checked before isOk since isOk modifies mCheckedStatus
  141. if (mCheckedStatus) return;
  142. if (!isOk()) {
  143. LOG(FATAL) << "Failed HIDL return status not checked: " << description();
  144. }
  145. if (gReturnRestriction == HidlReturnRestriction::NONE) {
  146. return;
  147. }
  148. if (gReturnRestriction == HidlReturnRestriction::ERROR_IF_UNCHECKED) {
  149. LOG(ERROR) << "Failed to check status of HIDL Return.";
  150. CallStack::logStack("unchecked HIDL return", CallStack::getCurrent(10).get(), ANDROID_LOG_ERROR);
  151. } else {
  152. LOG(FATAL) << "Failed to check status of HIDL Return.";
  153. }
  154. }
  155. return_status& return_status::operator=(return_status&& other) noexcept {
  156. if (!mCheckedStatus && !isOk()) {
  157. LOG(FATAL) << "Failed HIDL return status not checked: " << description();
  158. }
  159. std::swap(mStatus, other.mStatus);
  160. std::swap(mCheckedStatus, other.mCheckedStatus);
  161. return *this;
  162. }
  163. } // namespace details
  164. } // namespace hardware
  165. } // namespace android