Status.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. #include <binder/Status.h>
  17. namespace android {
  18. namespace binder {
  19. Status Status::ok() {
  20. return Status();
  21. }
  22. Status Status::fromExceptionCode(int32_t exceptionCode) {
  23. if (exceptionCode == EX_TRANSACTION_FAILED) {
  24. return Status(exceptionCode, FAILED_TRANSACTION);
  25. }
  26. return Status(exceptionCode, OK);
  27. }
  28. Status Status::fromExceptionCode(int32_t exceptionCode,
  29. const String8& message) {
  30. if (exceptionCode == EX_TRANSACTION_FAILED) {
  31. return Status(exceptionCode, FAILED_TRANSACTION, message);
  32. }
  33. return Status(exceptionCode, OK, message);
  34. }
  35. Status Status::fromExceptionCode(int32_t exceptionCode,
  36. const char* message) {
  37. return fromExceptionCode(exceptionCode, String8(message));
  38. }
  39. Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode) {
  40. return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode);
  41. }
  42. Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode,
  43. const String8& message) {
  44. return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode, message);
  45. }
  46. Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode,
  47. const char* message) {
  48. return fromServiceSpecificError(serviceSpecificErrorCode, String8(message));
  49. }
  50. Status Status::fromStatusT(status_t status) {
  51. Status ret;
  52. ret.setFromStatusT(status);
  53. return ret;
  54. }
  55. std::string Status::exceptionToString(int32_t exceptionCode) {
  56. switch (exceptionCode) {
  57. #define EXCEPTION_TO_CASE(EXCEPTION) case EXCEPTION: return #EXCEPTION;
  58. EXCEPTION_TO_CASE(EX_NONE)
  59. EXCEPTION_TO_CASE(EX_SECURITY)
  60. EXCEPTION_TO_CASE(EX_BAD_PARCELABLE)
  61. EXCEPTION_TO_CASE(EX_ILLEGAL_ARGUMENT)
  62. EXCEPTION_TO_CASE(EX_NULL_POINTER)
  63. EXCEPTION_TO_CASE(EX_ILLEGAL_STATE)
  64. EXCEPTION_TO_CASE(EX_NETWORK_MAIN_THREAD)
  65. EXCEPTION_TO_CASE(EX_UNSUPPORTED_OPERATION)
  66. EXCEPTION_TO_CASE(EX_SERVICE_SPECIFIC)
  67. EXCEPTION_TO_CASE(EX_PARCELABLE)
  68. EXCEPTION_TO_CASE(EX_HAS_REPLY_HEADER)
  69. EXCEPTION_TO_CASE(EX_TRANSACTION_FAILED)
  70. #undef EXCEPTION_TO_CASE
  71. default: return std::to_string(exceptionCode);
  72. }
  73. }
  74. Status::Status(int32_t exceptionCode, int32_t errorCode)
  75. : mException(exceptionCode),
  76. mErrorCode(errorCode) {}
  77. Status::Status(int32_t exceptionCode, int32_t errorCode, const String8& message)
  78. : mException(exceptionCode),
  79. mErrorCode(errorCode),
  80. mMessage(message) {}
  81. status_t Status::readFromParcel(const Parcel& parcel) {
  82. status_t status = parcel.readInt32(&mException);
  83. if (status != OK) {
  84. setFromStatusT(status);
  85. return status;
  86. }
  87. // Skip over fat response headers. Not used (or propagated) in native code.
  88. if (mException == EX_HAS_REPLY_HEADER) {
  89. // Note that the header size includes the 4 byte size field.
  90. const size_t header_start = parcel.dataPosition();
  91. // Get available size before reading more
  92. const size_t header_avail = parcel.dataAvail();
  93. int32_t header_size;
  94. status = parcel.readInt32(&header_size);
  95. if (status != OK) {
  96. setFromStatusT(status);
  97. return status;
  98. }
  99. if (header_size < 0 || static_cast<size_t>(header_size) > header_avail) {
  100. android_errorWriteLog(0x534e4554, "132650049");
  101. setFromStatusT(UNKNOWN_ERROR);
  102. return UNKNOWN_ERROR;
  103. }
  104. parcel.setDataPosition(header_start + header_size);
  105. // And fat response headers are currently only used when there are no
  106. // exceptions, so act like there was no error.
  107. mException = EX_NONE;
  108. }
  109. if (mException == EX_NONE) {
  110. return status;
  111. }
  112. // The remote threw an exception. Get the message back.
  113. String16 message;
  114. status = parcel.readString16(&message);
  115. if (status != OK) {
  116. setFromStatusT(status);
  117. return status;
  118. }
  119. mMessage = String8(message);
  120. // Skip over the remote stack trace data
  121. int32_t remote_stack_trace_header_size;
  122. status = parcel.readInt32(&remote_stack_trace_header_size);
  123. if (status != OK) {
  124. setFromStatusT(status);
  125. return status;
  126. }
  127. if (remote_stack_trace_header_size < 0 ||
  128. static_cast<size_t>(remote_stack_trace_header_size) > parcel.dataAvail()) {
  129. android_errorWriteLog(0x534e4554, "132650049");
  130. setFromStatusT(UNKNOWN_ERROR);
  131. return UNKNOWN_ERROR;
  132. }
  133. parcel.setDataPosition(parcel.dataPosition() + remote_stack_trace_header_size);
  134. if (mException == EX_SERVICE_SPECIFIC) {
  135. status = parcel.readInt32(&mErrorCode);
  136. } else if (mException == EX_PARCELABLE) {
  137. // Skip over the blob of Parcelable data
  138. const size_t header_start = parcel.dataPosition();
  139. // Get available size before reading more
  140. const size_t header_avail = parcel.dataAvail();
  141. int32_t header_size;
  142. status = parcel.readInt32(&header_size);
  143. if (status != OK) {
  144. setFromStatusT(status);
  145. return status;
  146. }
  147. if (header_size < 0 || static_cast<size_t>(header_size) > header_avail) {
  148. android_errorWriteLog(0x534e4554, "132650049");
  149. setFromStatusT(UNKNOWN_ERROR);
  150. return UNKNOWN_ERROR;
  151. }
  152. parcel.setDataPosition(header_start + header_size);
  153. }
  154. if (status != OK) {
  155. setFromStatusT(status);
  156. return status;
  157. }
  158. return status;
  159. }
  160. status_t Status::writeToParcel(Parcel* parcel) const {
  161. // Something really bad has happened, and we're not going to even
  162. // try returning rich error data.
  163. if (mException == EX_TRANSACTION_FAILED) {
  164. return mErrorCode;
  165. }
  166. status_t status = parcel->writeInt32(mException);
  167. if (status != OK) { return status; }
  168. if (mException == EX_NONE) {
  169. // We have no more information to write.
  170. return status;
  171. }
  172. status = parcel->writeString16(String16(mMessage));
  173. status = parcel->writeInt32(0); // Empty remote stack trace header
  174. if (mException == EX_SERVICE_SPECIFIC) {
  175. status = parcel->writeInt32(mErrorCode);
  176. } else if (mException == EX_PARCELABLE) {
  177. // Sending Parcelable blobs currently not supported
  178. status = parcel->writeInt32(0);
  179. }
  180. return status;
  181. }
  182. void Status::setException(int32_t ex, const String8& message) {
  183. mException = ex;
  184. mErrorCode = ex == EX_TRANSACTION_FAILED ? FAILED_TRANSACTION : NO_ERROR;
  185. mMessage.setTo(message);
  186. }
  187. void Status::setServiceSpecificError(int32_t errorCode, const String8& message) {
  188. setException(EX_SERVICE_SPECIFIC, message);
  189. mErrorCode = errorCode;
  190. }
  191. void Status::setFromStatusT(status_t status) {
  192. mException = (status == NO_ERROR) ? EX_NONE : EX_TRANSACTION_FAILED;
  193. mErrorCode = status;
  194. mMessage.clear();
  195. }
  196. String8 Status::toString8() const {
  197. String8 ret;
  198. if (mException == EX_NONE) {
  199. ret.append("No error");
  200. } else {
  201. ret.appendFormat("Status(%d, %s): '", mException, exceptionToString(mException).c_str());
  202. if (mException == EX_SERVICE_SPECIFIC ||
  203. mException == EX_TRANSACTION_FAILED) {
  204. ret.appendFormat("%d: ", mErrorCode);
  205. }
  206. ret.append(String8(mMessage));
  207. ret.append("'");
  208. }
  209. return ret;
  210. }
  211. std::stringstream& operator<< (std::stringstream& stream, const Status& s) {
  212. stream << s.toString8().string();
  213. return stream;
  214. }
  215. } // namespace binder
  216. } // namespace android