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