1 /* 2 * Copyright (C) 2019 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 17 #pragma once 18 19 #include <android-base/strings.h> 20 #include <fmt/format.h> 21 22 #ifdef ANDROID_BINDER_STATUS_H 23 #define IS_BINDER_OK(__ex__) (__ex__ == ::android::binder::Status::EX_NONE) 24 25 #define EXCEPTION_TO_STRING(__ex__, str) \ 26 case ::android::binder::Status::__ex__: \ 27 return str; 28 29 #define TO_EXCEPTION(__ex__) __ex__; 30 31 #else 32 #define IS_BINDER_OK(__ex__) (AStatus_isOk(AStatus_fromExceptionCode(__ex__))) 33 34 #define EXCEPTION_TO_STRING(__ex__, str) \ 35 case __ex__: \ 36 return str; 37 38 #define TO_EXCEPTION(__ex__) AStatus_getExceptionCode(AStatus_fromExceptionCode(__ex__)); 39 40 #endif 41 42 std::string exceptionToString(int32_t exception) { 43 switch (exception) { 44 EXCEPTION_TO_STRING(EX_SECURITY, "SecurityException") 45 EXCEPTION_TO_STRING(EX_BAD_PARCELABLE, "BadParcelableException") 46 EXCEPTION_TO_STRING(EX_ILLEGAL_ARGUMENT, "IllegalArgumentException") 47 EXCEPTION_TO_STRING(EX_NULL_POINTER, "NullPointerException") 48 EXCEPTION_TO_STRING(EX_ILLEGAL_STATE, "IllegalStateException") 49 EXCEPTION_TO_STRING(EX_NETWORK_MAIN_THREAD, "NetworkMainThreadException") 50 EXCEPTION_TO_STRING(EX_UNSUPPORTED_OPERATION, "UnsupportedOperationException") 51 EXCEPTION_TO_STRING(EX_SERVICE_SPECIFIC, "ServiceSpecificException") 52 EXCEPTION_TO_STRING(EX_PARCELABLE, "ParcelableException") 53 EXCEPTION_TO_STRING(EX_TRANSACTION_FAILED, "TransactionFailedException") 54 default: 55 return "UnknownException"; 56 } 57 } 58 59 using LogFn = std::function<void(const std::string& msg)>; 60 61 template <typename LogType> 62 void binderCallLogFn(const LogType& log, const LogFn& logFn) { 63 using namespace std::string_literals; 64 65 bool hasReturnArgs; 66 std::string output; 67 68 hasReturnArgs = !log.result.empty(); 69 output.append(log.method_name + "("s); 70 71 // input args 72 for (size_t i = 0; i < log.input_args.size(); ++i) { 73 output.append(log.input_args[i].second); 74 if (i != log.input_args.size() - 1) { 75 output.append(", "s); 76 } 77 } 78 output.append(")"s); 79 80 const int exceptionCode = TO_EXCEPTION(log.exception_code); 81 82 if (hasReturnArgs || !IS_BINDER_OK(exceptionCode)) { 83 output.append(" -> "s); 84 } 85 86 // return status 87 if (!IS_BINDER_OK(exceptionCode)) { 88 // an exception occurred 89 const int errCode = log.service_specific_error_code; 90 output.append(fmt::format("{}({}, \"{}\")", exceptionToString(exceptionCode), 91 (errCode != 0) ? errCode : exceptionCode, log.exception_message)); 92 } 93 // return args 94 if (hasReturnArgs) { 95 output.append("{" + log.result + "}"); 96 } 97 // duration time 98 output.append(fmt::format(" <{:.2f}ms>", log.duration_ms)); 99 100 // escape newline characters to avoid multiline log entries 101 logFn(::android::base::StringReplace(output, "\n", "\\n", true)); 102 } 103