109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley/* 209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * Copyright (C) 2015 The Android Open Source Project 309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * 409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * Licensed under the Apache License, Version 2.0 (the "License"); 509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * you may not use this file except in compliance with the License. 609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * You may obtain a copy of the License at 709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * 809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * http://www.apache.org/licenses/LICENSE-2.0 909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * 1009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * Unless required by applicable law or agreed to in writing, software 1109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * distributed under the License is distributed on an "AS IS" BASIS, 1209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * See the License for the specific language governing permissions and 1409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley * limitations under the License. 1509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley */ 1609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 1709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley#ifndef ANDROID_BINDER_STATUS_H 1809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley#define ANDROID_BINDER_STATUS_H 1909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 2009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley#include <cstdint> 2100cb980fcb6032f3a5ae124dc64ee2df8fb79a31Ralph Nathan#include <sstream> 2209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 2309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley#include <binder/Parcel.h> 2409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley#include <utils/String8.h> 2509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 2609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wileynamespace android { 2709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wileynamespace binder { 2809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 2909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// An object similar in function to a status_t except that it understands 3009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// how exceptions are encoded in the prefix of a Parcel. Used like: 3109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// 3209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// Parcel data; 3309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// Parcel reply; 3409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// status_t status; 3509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// binder::Status remote_exception; 3609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// if ((status = data.writeInterfaceToken(interface_descriptor)) != OK || 3709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// (status = data.writeInt32(function_input)) != OK) { 3809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// // We failed to write into the memory of our local parcel? 3909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// } 4009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// if ((status = remote()->transact(transaction, data, &reply)) != OK) { 4109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// // Something has gone wrong in the binder driver or libbinder. 4209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// } 4309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// if ((status = remote_exception.readFromParcel(reply)) != OK) { 4409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// // The remote didn't correctly write the exception header to the 4509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// // reply. 4609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// } 4709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// if (!remote_exception.isOk()) { 4809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// // The transaction went through correctly, but the remote reported an 4909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// // exception during handling. 5009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// } 5109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley// 5209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wileyclass Status final { 5309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wileypublic: 5409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley // Keep the exception codes in sync with android/os/Parcel.java. 5509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley enum Exception { 5609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley EX_NONE = 0, 5709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley EX_SECURITY = -1, 5809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley EX_BAD_PARCELABLE = -2, 5909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley EX_ILLEGAL_ARGUMENT = -3, 6009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley EX_NULL_POINTER = -4, 6109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley EX_ILLEGAL_STATE = -5, 6209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley EX_NETWORK_MAIN_THREAD = -6, 6309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley EX_UNSUPPORTED_OPERATION = -7, 64c1e491d5a4923298b612de919537d4293574b443Christopher Wiley EX_SERVICE_SPECIFIC = -8, 65c8dc4f0af9f8847be9cdd2b9cbb5b8a7767982c4Jeff Sharkey EX_PARCELABLE = -9, 6609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 6709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley // This is special and Java specific; see Parcel.java. 6809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley EX_HAS_REPLY_HEADER = -128, 69cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // This is special, and indicates to C++ binder proxies that the 70cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // transaction has failed at a low level. 71cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley EX_TRANSACTION_FAILED = -129, 7209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley }; 7309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 74cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // A more readable alias for the default constructor. 75cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley static Status ok(); 761651ced6a84b3ba5b62917e88b981e6bac3e7e3fChristopher Wiley 77c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // Authors should explicitly pick whether their integer is: 78c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // - an exception code (EX_* above) 79c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // - service specific error code 80c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // - status_t 81c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // 82c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // Prefer a generic exception code when possible, then a service specific 83c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // code, and finally a status_t for low level failures or legacy support. 84c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // Exception codes and service specific errors map to nicer exceptions for 85c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // Java clients. 86cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley static Status fromExceptionCode(int32_t exceptionCode); 87cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley static Status fromExceptionCode(int32_t exceptionCode, 88cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley const String8& message); 891651ced6a84b3ba5b62917e88b981e6bac3e7e3fChristopher Wiley static Status fromExceptionCode(int32_t exceptionCode, 901651ced6a84b3ba5b62917e88b981e6bac3e7e3fChristopher Wiley const char* message); 911651ced6a84b3ba5b62917e88b981e6bac3e7e3fChristopher Wiley 92c1e491d5a4923298b612de919537d4293574b443Christopher Wiley static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode); 93c1e491d5a4923298b612de919537d4293574b443Christopher Wiley static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode, 94c1e491d5a4923298b612de919537d4293574b443Christopher Wiley const String8& message); 951651ced6a84b3ba5b62917e88b981e6bac3e7e3fChristopher Wiley static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode, 961651ced6a84b3ba5b62917e88b981e6bac3e7e3fChristopher Wiley const char* message); 971651ced6a84b3ba5b62917e88b981e6bac3e7e3fChristopher Wiley 9809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley static Status fromStatusT(status_t status); 9909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 10009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley Status() = default; 101cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley ~Status() = default; 10209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 10309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley // Status objects are copyable and contain just simple data. 10409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley Status(const Status& status) = default; 10509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley Status(Status&& status) = default; 10609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley Status& operator=(const Status& status) = default; 10709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 10809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley // Bear in mind that if the client or service is a Java endpoint, this 10909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley // is not the logic which will provide/interpret the data here. 11009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley status_t readFromParcel(const Parcel& parcel); 11109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley status_t writeToParcel(Parcel* parcel) const; 11209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 11309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley // Set one of the pre-defined exception types defined above. 11409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley void setException(int32_t ex, const String8& message); 115c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // Set a service specific exception with error code. 116c1e491d5a4923298b612de919537d4293574b443Christopher Wiley void setServiceSpecificError(int32_t errorCode, const String8& message); 117cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // Setting a |status| != OK causes generated code to return |status| 118cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // from Binder transactions, rather than writing an exception into the 119c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // reply Parcel. This is the least preferable way of reporting errors. 12009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley void setFromStatusT(status_t status); 12109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 12209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley // Get information about an exception. 12309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley int32_t exceptionCode() const { return mException; } 12409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley const String8& exceptionMessage() const { return mMessage; } 125cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley status_t transactionError() const { 126cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley return mException == EX_TRANSACTION_FAILED ? mErrorCode : OK; 127cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley } 128c1e491d5a4923298b612de919537d4293574b443Christopher Wiley int32_t serviceSpecificErrorCode() const { 129c1e491d5a4923298b612de919537d4293574b443Christopher Wiley return mException == EX_SERVICE_SPECIFIC ? mErrorCode : 0; 130c1e491d5a4923298b612de919537d4293574b443Christopher Wiley } 13109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 13209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley bool isOk() const { return mException == EX_NONE; } 13309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 13409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley // For logging. 13509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley String8 toString8() const; 13609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 13709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wileyprivate: 138c1e491d5a4923298b612de919537d4293574b443Christopher Wiley Status(int32_t exceptionCode, int32_t errorCode); 139c1e491d5a4923298b612de919537d4293574b443Christopher Wiley Status(int32_t exceptionCode, int32_t errorCode, const String8& message); 140cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley 141cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // If |mException| == EX_TRANSACTION_FAILED, generated code will return 142cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // |mErrorCode| as the result of the transaction rather than write an 143cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // exception to the reply parcel. 144cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // 145cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // Otherwise, we always write |mException| to the parcel. 146cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley // If |mException| != EX_NONE, we write |mMessage| as well. 147c1e491d5a4923298b612de919537d4293574b443Christopher Wiley // If |mException| == EX_SERVICE_SPECIFIC we write |mErrorCode| as well. 14809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley int32_t mException = EX_NONE; 149cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley int32_t mErrorCode = 0; 15009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley String8 mMessage; 15109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley}; // class Status 15209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 153bbab196fe58e5657d90f6f40a19fb93c2a91a8acEino-Ville Talvala// For gtest output logging 15400cb980fcb6032f3a5ae124dc64ee2df8fb79a31Ralph Nathanstd::stringstream& operator<< (std::stringstream& stream, const Status& s); 155bbab196fe58e5657d90f6f40a19fb93c2a91a8acEino-Ville Talvala 15609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley} // namespace binder 15709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley} // namespace android 15809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley 15909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley#endif // ANDROID_BINDER_STATUS_H 160