1bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen/* 2bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * Copyright (C) 2015 The Android Open Source Project 3bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * 4bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * Licensed under the Apache License, Version 2.0 (the "License"); 5bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * you may not use this file except in compliance with the License. 6bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * You may obtain a copy of the License at 7bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * 8bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * http://www.apache.org/licenses/LICENSE-2.0 9bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * 10bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * Unless required by applicable law or agreed to in writing, software 11bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * distributed under the License is distributed on an "AS IS" BASIS, 12bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * See the License for the specific language governing permissions and 14bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen * limitations under the License. 15bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen */ 16bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 17bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen#ifndef ANDROID_HARDWARE_BINDER_STATUS_H 18bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen#define ANDROID_HARDWARE_BINDER_STATUS_H 19bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 20bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen#include <cstdint> 21bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen#include <sstream> 22bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 23a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong#include <hidl/HidlInternal.h> 2443298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong#include <utils/Errors.h> 25d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen#include <utils/StrongPointer.h> 26bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 27bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenennamespace android { 28bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenennamespace hardware { 29bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 30bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// An object similar in function to a status_t except that it understands 31bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// how exceptions are encoded in the prefix of a Parcel. Used like: 32bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// 33bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// Parcel data; 34bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// Parcel reply; 35bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// status_t status; 36bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// binder::Status remote_exception; 37bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// if ((status = data.writeInterfaceToken(interface_descriptor)) != OK || 38bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// (status = data.writeInt32(function_input)) != OK) { 39bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// // We failed to write into the memory of our local parcel? 40bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// } 41bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// if ((status = remote()->transact(transaction, data, &reply)) != OK) { 42bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// // Something has gone wrong in the binder driver or libbinder. 43bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// } 44bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// if ((status = remote_exception.readFromParcel(reply)) != OK) { 45bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// // The remote didn't correctly write the exception header to the 46bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// // reply. 47bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// } 48bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// if (!remote_exception.isOk()) { 49bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// // The transaction went through correctly, but the remote reported an 50bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// // exception during handling. 51bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// } 52bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// 53bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenenclass Status final { 54bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenenpublic: 55bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // Keep the exception codes in sync with android/os/Parcel.java. 56bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen enum Exception { 57bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen EX_NONE = 0, 58bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen EX_SECURITY = -1, 59bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen EX_BAD_PARCELABLE = -2, 60bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen EX_ILLEGAL_ARGUMENT = -3, 61bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen EX_NULL_POINTER = -4, 62bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen EX_ILLEGAL_STATE = -5, 63bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen EX_NETWORK_MAIN_THREAD = -6, 64bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen EX_UNSUPPORTED_OPERATION = -7, 65bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 66bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // This is special and Java specific; see Parcel.java. 67bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen EX_HAS_REPLY_HEADER = -128, 68bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // This is special, and indicates to C++ binder proxies that the 69bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // transaction has failed at a low level. 70bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen EX_TRANSACTION_FAILED = -129, 71bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen }; 72bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 73bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // A more readable alias for the default constructor. 74bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen static Status ok(); 75bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // Authors should explicitly pick whether their integer is: 76bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // - an exception code (EX_* above) 77bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // - status_t 78bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // 7972db40f4a612d04187ae2fc1f9a3766933264bdfSteven Moreland // Prefer a generic exception code when possible or a status_t 8072db40f4a612d04187ae2fc1f9a3766933264bdfSteven Moreland // for low level transport errors. Service specific errors 8172db40f4a612d04187ae2fc1f9a3766933264bdfSteven Moreland // should be at a higher level in HIDL. 82bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen static Status fromExceptionCode(int32_t exceptionCode); 83bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen static Status fromExceptionCode(int32_t exceptionCode, 8443298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong const char *message); 85bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen static Status fromStatusT(status_t status); 86bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 87bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen Status() = default; 88bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen ~Status() = default; 89bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 90bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // Status objects are copyable and contain just simple data. 91bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen Status(const Status& status) = default; 92bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen Status(Status&& status) = default; 93bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen Status& operator=(const Status& status) = default; 94bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 95bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // Set one of the pre-defined exception types defined above. 9643298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong void setException(int32_t ex, const char *message); 97bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // Setting a |status| != OK causes generated code to return |status| 98bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // from Binder transactions, rather than writing an exception into the 99bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // reply Parcel. This is the least preferable way of reporting errors. 100bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen void setFromStatusT(status_t status); 101bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 102bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // Get information about an exception. 103bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen int32_t exceptionCode() const { return mException; } 10443298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong const char *exceptionMessage() const { return mMessage.c_str(); } 105bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen status_t transactionError() const { 106bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen return mException == EX_TRANSACTION_FAILED ? mErrorCode : OK; 107bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen } 108bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 109bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen bool isOk() const { return mException == EX_NONE; } 110bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 11143298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong // For debugging purposes only 11243298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong std::string description() const; 113bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 114bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenenprivate: 115bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen Status(int32_t exceptionCode, int32_t errorCode); 11643298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong Status(int32_t exceptionCode, int32_t errorCode, const char *message); 117bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 118bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // If |mException| == EX_TRANSACTION_FAILED, generated code will return 119bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // |mErrorCode| as the result of the transaction rather than write an 120bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // exception to the reply parcel. 121bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // 122bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // Otherwise, we always write |mException| to the parcel. 123bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen // If |mException| != EX_NONE, we write |mMessage| as well. 124bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen int32_t mException = EX_NONE; 125bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen int32_t mErrorCode = 0; 12643298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong std::string mMessage; 127bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen}; // class Status 128bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 129bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen// For gtest output logging 13043298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hongstd::ostream& operator<< (std::ostream& stream, const Status& s); 131bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 132a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hongtemplate<typename T> class Return; 133a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong 1347596933a1e08ff4c05488229ec84f46f4926e27bSteven Morelandnamespace details { 135e780c45b31a03f318db85b9940bf20f93ac50395Steven Moreland class return_status { 1367596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland private: 1377596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland Status mStatus {}; 1387596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland mutable bool mCheckedStatus = false; 139a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong 140a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong template <typename T, typename U> 141a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong friend Return<U> StatusOf(const Return<T> &other); 142d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen protected: 143af4e43cc5b2eacbfe600f9ab0e459f09c35c0c3fYifan Hong void assertOk() const; 1447596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland public: 1457596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland return_status() {} 1467596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland return_status(Status s) : mStatus(s) {} 1477596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland 148603cde990a56fc03731d9b428d3376dd75936c2eYifan Hong return_status(const return_status &) = delete; 149603cde990a56fc03731d9b428d3376dd75936c2eYifan Hong return_status &operator=(const return_status &) = delete; 1507596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland 151c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong return_status(return_status &&other) { 152c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong *this = std::move(other); 153c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong } 154af4e43cc5b2eacbfe600f9ab0e459f09c35c0c3fYifan Hong return_status &operator=(return_status &&other); 155c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong 156e780c45b31a03f318db85b9940bf20f93ac50395Steven Moreland ~return_status(); 1577596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland 1587596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland bool isOk() const { 1597596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland mCheckedStatus = true; 1607596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland return mStatus.isOk(); 1617596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland } 1627596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland 163a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong // Check if underlying error is DEAD_OBJECT. 16413f7f62af6b04ae4683a1e7189dbb51a9fab3648Steven Moreland // Check mCheckedStatus only if this method returns true. 165a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong bool isDeadObject() const { 16613f7f62af6b04ae4683a1e7189dbb51a9fab3648Steven Moreland bool dead = mStatus.transactionError() == DEAD_OBJECT; 16713f7f62af6b04ae4683a1e7189dbb51a9fab3648Steven Moreland 16813f7f62af6b04ae4683a1e7189dbb51a9fab3648Steven Moreland // This way, if you only check isDeadObject your process will 16913f7f62af6b04ae4683a1e7189dbb51a9fab3648Steven Moreland // only be killed for more serious unchecked errors 17013f7f62af6b04ae4683a1e7189dbb51a9fab3648Steven Moreland if (dead) { 17113f7f62af6b04ae4683a1e7189dbb51a9fab3648Steven Moreland mCheckedStatus = true; 17213f7f62af6b04ae4683a1e7189dbb51a9fab3648Steven Moreland } 17313f7f62af6b04ae4683a1e7189dbb51a9fab3648Steven Moreland 17413f7f62af6b04ae4683a1e7189dbb51a9fab3648Steven Moreland return dead; 175a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong } 176a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong 17743298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong // For debugging purposes only 17843298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong std::string description() const { 17943298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong // Doesn't consider checked. 18043298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong return mStatus.description(); 18143298f90efb47e1ae3589df56b12e9e53f16c53eYifan Hong } 1827596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland }; 1837596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland} // namespace details 1847596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland 1857596933a1e08ff4c05488229ec84f46f4926e27bSteven Morelandtemplate<typename T> class Return : public details::return_status { 186170c189d1d077c21a5dc7aab06e515bd6beee0a9Iliyan Malchevprivate: 187337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland T mVal {}; 188bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenenpublic: 1897596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland Return(T v) : details::return_status(), mVal{v} {} 1907596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland Return(Status s) : details::return_status(s) {} 191337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland 192c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong // move-able. 193c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong // precondition: "this" has checked status 194c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong // postcondition: other is safe to destroy after moving to *this. 195c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong Return(Return &&other) = default; 196c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong Return &operator=(Return &&) = default; 197c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong 1987596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland ~Return() = default; 1991cfaee704c2d20d6d8d7dedf77bd73f61ee905f7Steven Moreland 2001cfaee704c2d20d6d8d7dedf77bd73f61ee905f7Steven Moreland operator T() const { 201af4e43cc5b2eacbfe600f9ab0e459f09c35c0c3fYifan Hong assertOk(); 202337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland return mVal; 203337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland } 204337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland 2054917296debaeb74f48ddac5ce4d8f5e65020ee69Steven Moreland T withDefault(T t) { 2064917296debaeb74f48ddac5ce4d8f5e65020ee69Steven Moreland return isOk() ? mVal : t; 2074917296debaeb74f48ddac5ce4d8f5e65020ee69Steven Moreland } 208170c189d1d077c21a5dc7aab06e515bd6beee0a9Iliyan Malchev}; 209170c189d1d077c21a5dc7aab06e515bd6beee0a9Iliyan Malchev 210d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenentemplate<typename T> class Return<sp<T>> : public details::return_status { 211d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenenprivate: 212d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen sp<T> mVal {}; 213d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenenpublic: 214d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen Return(sp<T> v) : details::return_status(), mVal{v} {} 215d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen Return(T* v) : details::return_status(), mVal{v} {} 216d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen // Constructors matching a different type (that is related by inheritance) 217d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen template<typename U> Return(sp<U> v) : details::return_status(), mVal{v} {} 218d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen template<typename U> Return(U* v) : details::return_status(), mVal{v} {} 219d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen Return(Status s) : details::return_status(s) {} 220d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen 221c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong // move-able. 222c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong // precondition: "this" has checked status 223c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong // postcondition: other is safe to destroy after moving to *this. 224c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong Return(Return &&other) = default; 225c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong Return &operator=(Return &&) = default; 226c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong 227d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen ~Return() = default; 228d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen 229d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen operator sp<T>() const { 230af4e43cc5b2eacbfe600f9ab0e459f09c35c0c3fYifan Hong assertOk(); 231d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen return mVal; 232d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen } 2334917296debaeb74f48ddac5ce4d8f5e65020ee69Steven Moreland 2344917296debaeb74f48ddac5ce4d8f5e65020ee69Steven Moreland sp<T> withDefault(sp<T> t) { 2354917296debaeb74f48ddac5ce4d8f5e65020ee69Steven Moreland return isOk() ? mVal : t; 2364917296debaeb74f48ddac5ce4d8f5e65020ee69Steven Moreland } 237d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen}; 238d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen 239d272cb9e881c0aa23e4964f101131ab68affd85dMartijn Coenen 2407596933a1e08ff4c05488229ec84f46f4926e27bSteven Morelandtemplate<> class Return<void> : public details::return_status { 241170c189d1d077c21a5dc7aab06e515bd6beee0a9Iliyan Malchevpublic: 2427596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland Return() : details::return_status() {} 2437596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland Return(Status s) : details::return_status(s) {} 244337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland 245c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong // move-able. 246c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong // precondition: "this" has checked status 247c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong // postcondition: other is safe to destroy after moving to *this. 248c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong Return(Return &&) = default; 249c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong Return &operator=(Return &&) = default; 250c43bd9dd3a05f121da0c99937382ce6bab8e0b9eYifan Hong 2517596933a1e08ff4c05488229ec84f46f4926e27bSteven Moreland ~Return() = default; 252bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen}; 253bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 254170c189d1d077c21a5dc7aab06e515bd6beee0a9Iliyan Malchevstatic inline Return<void> Void() { 255170c189d1d077c21a5dc7aab06e515bd6beee0a9Iliyan Malchev return Return<void>(); 256170c189d1d077c21a5dc7aab06e515bd6beee0a9Iliyan Malchev} 257170c189d1d077c21a5dc7aab06e515bd6beee0a9Iliyan Malchev 258a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hongnamespace details { 259a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong// Create a Return<U> from the Status of Return<T>. The provided 260a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong// Return<T> must have an error status and have it checked. 261a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hongtemplate <typename T, typename U> 262a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan HongReturn<U> StatusOf(const Return<T> &other) { 263a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong if (other.mStatus.isOk() || !other.mCheckedStatus) { 264a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong details::logAlwaysFatal("cannot call statusOf on an OK Status or an unchecked status"); 265a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong } 266a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong return Return<U>{other.mStatus}; 267a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong} 268a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong} // namespace details 269a7b2bb72eb9ed9345307c80ecc3386338ecddb9fYifan Hong 270bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen} // namespace hardware 271bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen} // namespace android 272bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen 273bb5e9bb1c982a029ebc82e82f3838b6beeb2d108Martijn Coenen#endif // ANDROID_HARDWARE_BINDER_STATUS_H 274