1*8222fbe1SAndroid Build Coastguard Worker /*
2*8222fbe1SAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*8222fbe1SAndroid Build Coastguard Worker *
4*8222fbe1SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8222fbe1SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8222fbe1SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8222fbe1SAndroid Build Coastguard Worker *
8*8222fbe1SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8222fbe1SAndroid Build Coastguard Worker *
10*8222fbe1SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8222fbe1SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8222fbe1SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8222fbe1SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8222fbe1SAndroid Build Coastguard Worker * limitations under the License.
15*8222fbe1SAndroid Build Coastguard Worker */
16*8222fbe1SAndroid Build Coastguard Worker
17*8222fbe1SAndroid Build Coastguard Worker #ifndef ANDROID_HARDWARE_BINDER_STATUS_H
18*8222fbe1SAndroid Build Coastguard Worker #define ANDROID_HARDWARE_BINDER_STATUS_H
19*8222fbe1SAndroid Build Coastguard Worker
20*8222fbe1SAndroid Build Coastguard Worker #include <cstdint>
21*8222fbe1SAndroid Build Coastguard Worker #include <sstream>
22*8222fbe1SAndroid Build Coastguard Worker
23*8222fbe1SAndroid Build Coastguard Worker #include <hidl/HidlInternal.h>
24*8222fbe1SAndroid Build Coastguard Worker #include <utils/Errors.h>
25*8222fbe1SAndroid Build Coastguard Worker #include <utils/StrongPointer.h>
26*8222fbe1SAndroid Build Coastguard Worker
27*8222fbe1SAndroid Build Coastguard Worker namespace android {
28*8222fbe1SAndroid Build Coastguard Worker namespace hardware {
29*8222fbe1SAndroid Build Coastguard Worker
30*8222fbe1SAndroid Build Coastguard Worker // HIDL formally separates transport error codes from interface error codes. When developing a HIDL
31*8222fbe1SAndroid Build Coastguard Worker // interface, errors relevant to a service should be placed in the interface design for that HAL.
32*8222fbe1SAndroid Build Coastguard Worker //
33*8222fbe1SAndroid Build Coastguard Worker // For instance:
34*8222fbe1SAndroid Build Coastguard Worker //
35*8222fbe1SAndroid Build Coastguard Worker // interface I* {
36*8222fbe1SAndroid Build Coastguard Worker // enum FooStatus { NO_FOO, NO_BAR }; // service-specific errors
37*8222fbe1SAndroid Build Coastguard Worker // doFoo(...) generates (FooStatus foo);
38*8222fbe1SAndroid Build Coastguard Worker // };
39*8222fbe1SAndroid Build Coastguard Worker //
40*8222fbe1SAndroid Build Coastguard Worker // When calling into this interface, a Return<*> (in this case Return<FooStatus> object will be
41*8222fbe1SAndroid Build Coastguard Worker // returned). For most clients, it's expected that they'll just get the result from this function
42*8222fbe1SAndroid Build Coastguard Worker // and use it directly. If there is a transport error, the process will just abort. In general,
43*8222fbe1SAndroid Build Coastguard Worker // transport errors are expected only in extremely rare circumstances (bug in the
44*8222fbe1SAndroid Build Coastguard Worker // code/cosmic radiation/etc..). Aborting allows process to restart using their normal happy path
45*8222fbe1SAndroid Build Coastguard Worker // code.
46*8222fbe1SAndroid Build Coastguard Worker //
47*8222fbe1SAndroid Build Coastguard Worker // For certain processes though which are critical to the functionality of the phone (e.g.
48*8222fbe1SAndroid Build Coastguard Worker // hwservicemanager/init), these errors must be handled. Return<*>::isOk and
49*8222fbe1SAndroid Build Coastguard Worker // Return<*>::isDeadObject are provided for these cases. Whenever this is done, special attention
50*8222fbe1SAndroid Build Coastguard Worker // should be paid to testing the unhappy paths to make sure that error handling is handled
51*8222fbe1SAndroid Build Coastguard Worker // properly.
52*8222fbe1SAndroid Build Coastguard Worker
53*8222fbe1SAndroid Build Coastguard Worker // Transport implementation detail. HIDL implementors, see Return below. HAL implementations should
54*8222fbe1SAndroid Build Coastguard Worker // return HIDL-defined errors rather than use this.
55*8222fbe1SAndroid Build Coastguard Worker class Status final {
56*8222fbe1SAndroid Build Coastguard Worker public:
57*8222fbe1SAndroid Build Coastguard Worker // Note: forked from
58*8222fbe1SAndroid Build Coastguard Worker // - frameworks/base/core/java/android/os/android/os/Parcel.java.
59*8222fbe1SAndroid Build Coastguard Worker // - frameworks/native/libs/binder/include/binder/Status.h
60*8222fbe1SAndroid Build Coastguard Worker enum Exception {
61*8222fbe1SAndroid Build Coastguard Worker EX_NONE = 0,
62*8222fbe1SAndroid Build Coastguard Worker EX_SECURITY = -1,
63*8222fbe1SAndroid Build Coastguard Worker EX_BAD_PARCELABLE = -2,
64*8222fbe1SAndroid Build Coastguard Worker EX_ILLEGAL_ARGUMENT = -3,
65*8222fbe1SAndroid Build Coastguard Worker EX_NULL_POINTER = -4,
66*8222fbe1SAndroid Build Coastguard Worker EX_ILLEGAL_STATE = -5,
67*8222fbe1SAndroid Build Coastguard Worker EX_NETWORK_MAIN_THREAD = -6,
68*8222fbe1SAndroid Build Coastguard Worker EX_UNSUPPORTED_OPERATION = -7,
69*8222fbe1SAndroid Build Coastguard Worker
70*8222fbe1SAndroid Build Coastguard Worker // This is special and Java specific; see Parcel.java.
71*8222fbe1SAndroid Build Coastguard Worker EX_HAS_REPLY_HEADER = -128,
72*8222fbe1SAndroid Build Coastguard Worker // This is special, and indicates to C++ binder proxies that the
73*8222fbe1SAndroid Build Coastguard Worker // transaction has failed at a low level.
74*8222fbe1SAndroid Build Coastguard Worker EX_TRANSACTION_FAILED = -129,
75*8222fbe1SAndroid Build Coastguard Worker };
76*8222fbe1SAndroid Build Coastguard Worker
77*8222fbe1SAndroid Build Coastguard Worker // A more readable alias for the default constructor.
78*8222fbe1SAndroid Build Coastguard Worker static Status ok();
79*8222fbe1SAndroid Build Coastguard Worker // Authors should explicitly pick whether their integer is:
80*8222fbe1SAndroid Build Coastguard Worker // - an exception code (EX_* above)
81*8222fbe1SAndroid Build Coastguard Worker // - status_t
82*8222fbe1SAndroid Build Coastguard Worker //
83*8222fbe1SAndroid Build Coastguard Worker // Prefer a generic exception code when possible or a status_t
84*8222fbe1SAndroid Build Coastguard Worker // for low level transport errors. Service specific errors
85*8222fbe1SAndroid Build Coastguard Worker // should be at a higher level in HIDL.
86*8222fbe1SAndroid Build Coastguard Worker static Status fromExceptionCode(int32_t exceptionCode);
87*8222fbe1SAndroid Build Coastguard Worker static Status fromExceptionCode(int32_t exceptionCode,
88*8222fbe1SAndroid Build Coastguard Worker const char *message);
89*8222fbe1SAndroid Build Coastguard Worker static Status fromStatusT(status_t status);
90*8222fbe1SAndroid Build Coastguard Worker
91*8222fbe1SAndroid Build Coastguard Worker Status() = default;
92*8222fbe1SAndroid Build Coastguard Worker ~Status() = default;
93*8222fbe1SAndroid Build Coastguard Worker
94*8222fbe1SAndroid Build Coastguard Worker // Status objects are copyable and contain just simple data.
95*8222fbe1SAndroid Build Coastguard Worker Status(const Status& status) = default;
96*8222fbe1SAndroid Build Coastguard Worker Status(Status&& status) = default;
97*8222fbe1SAndroid Build Coastguard Worker Status& operator=(const Status& status) = default;
98*8222fbe1SAndroid Build Coastguard Worker
99*8222fbe1SAndroid Build Coastguard Worker // Set one of the pre-defined exception types defined above.
100*8222fbe1SAndroid Build Coastguard Worker void setException(int32_t ex, const char *message);
101*8222fbe1SAndroid Build Coastguard Worker // Setting a |status| != OK causes generated code to return |status|
102*8222fbe1SAndroid Build Coastguard Worker // from Binder transactions, rather than writing an exception into the
103*8222fbe1SAndroid Build Coastguard Worker // reply Parcel. This is the least preferable way of reporting errors.
104*8222fbe1SAndroid Build Coastguard Worker void setFromStatusT(status_t status);
105*8222fbe1SAndroid Build Coastguard Worker
106*8222fbe1SAndroid Build Coastguard Worker // Get information about an exception.
exceptionCode()107*8222fbe1SAndroid Build Coastguard Worker int32_t exceptionCode() const { return mException; }
exceptionMessage()108*8222fbe1SAndroid Build Coastguard Worker const char *exceptionMessage() const { return mMessage.c_str(); }
transactionError()109*8222fbe1SAndroid Build Coastguard Worker status_t transactionError() const {
110*8222fbe1SAndroid Build Coastguard Worker return mException == EX_TRANSACTION_FAILED ? mErrorCode : OK;
111*8222fbe1SAndroid Build Coastguard Worker }
112*8222fbe1SAndroid Build Coastguard Worker
isOk()113*8222fbe1SAndroid Build Coastguard Worker bool isOk() const { return mException == EX_NONE; }
114*8222fbe1SAndroid Build Coastguard Worker
115*8222fbe1SAndroid Build Coastguard Worker // For debugging purposes only
116*8222fbe1SAndroid Build Coastguard Worker std::string description() const;
117*8222fbe1SAndroid Build Coastguard Worker
118*8222fbe1SAndroid Build Coastguard Worker private:
119*8222fbe1SAndroid Build Coastguard Worker Status(int32_t exceptionCode, int32_t errorCode);
120*8222fbe1SAndroid Build Coastguard Worker Status(int32_t exceptionCode, int32_t errorCode, const char *message);
121*8222fbe1SAndroid Build Coastguard Worker
122*8222fbe1SAndroid Build Coastguard Worker // If |mException| == EX_TRANSACTION_FAILED, generated code will return
123*8222fbe1SAndroid Build Coastguard Worker // |mErrorCode| as the result of the transaction rather than write an
124*8222fbe1SAndroid Build Coastguard Worker // exception to the reply parcel.
125*8222fbe1SAndroid Build Coastguard Worker //
126*8222fbe1SAndroid Build Coastguard Worker // Otherwise, we always write |mException| to the parcel.
127*8222fbe1SAndroid Build Coastguard Worker // If |mException| != EX_NONE, we write |mMessage| as well.
128*8222fbe1SAndroid Build Coastguard Worker int32_t mException = EX_NONE;
129*8222fbe1SAndroid Build Coastguard Worker int32_t mErrorCode = 0;
130*8222fbe1SAndroid Build Coastguard Worker std::string mMessage;
131*8222fbe1SAndroid Build Coastguard Worker }; // class Status
132*8222fbe1SAndroid Build Coastguard Worker
133*8222fbe1SAndroid Build Coastguard Worker // For gtest output logging
134*8222fbe1SAndroid Build Coastguard Worker std::ostream& operator<< (std::ostream& stream, const Status& s);
135*8222fbe1SAndroid Build Coastguard Worker
136*8222fbe1SAndroid Build Coastguard Worker template<typename T> class Return;
137*8222fbe1SAndroid Build Coastguard Worker
138*8222fbe1SAndroid Build Coastguard Worker namespace details {
139*8222fbe1SAndroid Build Coastguard Worker class return_status {
140*8222fbe1SAndroid Build Coastguard Worker private:
141*8222fbe1SAndroid Build Coastguard Worker Status mStatus {};
142*8222fbe1SAndroid Build Coastguard Worker mutable bool mCheckedStatus = false;
143*8222fbe1SAndroid Build Coastguard Worker
144*8222fbe1SAndroid Build Coastguard Worker // called when an unchecked status is discarded
145*8222fbe1SAndroid Build Coastguard Worker // makes sure this status is checked according to the preference
146*8222fbe1SAndroid Build Coastguard Worker // set by setProcessHidlReturnRestriction
147*8222fbe1SAndroid Build Coastguard Worker void onIgnored() const;
148*8222fbe1SAndroid Build Coastguard Worker
149*8222fbe1SAndroid Build Coastguard Worker template <typename T, typename U>
150*8222fbe1SAndroid Build Coastguard Worker friend Return<U> StatusOf(const Return<T> &other);
151*8222fbe1SAndroid Build Coastguard Worker protected:
152*8222fbe1SAndroid Build Coastguard Worker void onValueRetrieval() const;
153*8222fbe1SAndroid Build Coastguard Worker public:
154*8222fbe1SAndroid Build Coastguard Worker void assertOk() const;
return_status()155*8222fbe1SAndroid Build Coastguard Worker return_status() {}
return_status(const Status & s)156*8222fbe1SAndroid Build Coastguard Worker return_status(const Status& s) : mStatus(s) {}
157*8222fbe1SAndroid Build Coastguard Worker
158*8222fbe1SAndroid Build Coastguard Worker return_status(const return_status &) = delete;
159*8222fbe1SAndroid Build Coastguard Worker return_status &operator=(const return_status &) = delete;
160*8222fbe1SAndroid Build Coastguard Worker
return_status(return_status && other)161*8222fbe1SAndroid Build Coastguard Worker return_status(return_status&& other) noexcept { *this = std::move(other); }
162*8222fbe1SAndroid Build Coastguard Worker return_status& operator=(return_status&& other) noexcept;
163*8222fbe1SAndroid Build Coastguard Worker
164*8222fbe1SAndroid Build Coastguard Worker ~return_status();
165*8222fbe1SAndroid Build Coastguard Worker
isOkUnchecked()166*8222fbe1SAndroid Build Coastguard Worker bool isOkUnchecked() const {
167*8222fbe1SAndroid Build Coastguard Worker // someone else will have to check
168*8222fbe1SAndroid Build Coastguard Worker return mStatus.isOk();
169*8222fbe1SAndroid Build Coastguard Worker }
170*8222fbe1SAndroid Build Coastguard Worker
isOk()171*8222fbe1SAndroid Build Coastguard Worker bool isOk() const {
172*8222fbe1SAndroid Build Coastguard Worker mCheckedStatus = true;
173*8222fbe1SAndroid Build Coastguard Worker return mStatus.isOk();
174*8222fbe1SAndroid Build Coastguard Worker }
175*8222fbe1SAndroid Build Coastguard Worker
176*8222fbe1SAndroid Build Coastguard Worker // Check if underlying error is DEAD_OBJECT.
177*8222fbe1SAndroid Build Coastguard Worker // Check mCheckedStatus only if this method returns true.
isDeadObject()178*8222fbe1SAndroid Build Coastguard Worker bool isDeadObject() const {
179*8222fbe1SAndroid Build Coastguard Worker bool dead = mStatus.transactionError() == DEAD_OBJECT;
180*8222fbe1SAndroid Build Coastguard Worker
181*8222fbe1SAndroid Build Coastguard Worker // This way, if you only check isDeadObject your process will
182*8222fbe1SAndroid Build Coastguard Worker // only be killed for more serious unchecked errors
183*8222fbe1SAndroid Build Coastguard Worker if (dead) {
184*8222fbe1SAndroid Build Coastguard Worker mCheckedStatus = true;
185*8222fbe1SAndroid Build Coastguard Worker }
186*8222fbe1SAndroid Build Coastguard Worker
187*8222fbe1SAndroid Build Coastguard Worker return dead;
188*8222fbe1SAndroid Build Coastguard Worker }
189*8222fbe1SAndroid Build Coastguard Worker
190*8222fbe1SAndroid Build Coastguard Worker // For debugging purposes only
description()191*8222fbe1SAndroid Build Coastguard Worker std::string description() const {
192*8222fbe1SAndroid Build Coastguard Worker // Doesn't consider checked.
193*8222fbe1SAndroid Build Coastguard Worker return mStatus.description();
194*8222fbe1SAndroid Build Coastguard Worker }
195*8222fbe1SAndroid Build Coastguard Worker };
196*8222fbe1SAndroid Build Coastguard Worker } // namespace details
197*8222fbe1SAndroid Build Coastguard Worker
198*8222fbe1SAndroid Build Coastguard Worker enum class HidlReturnRestriction {
199*8222fbe1SAndroid Build Coastguard Worker // Okay to ignore checking transport errors. This would instead rely on init to reset state
200*8222fbe1SAndroid Build Coastguard Worker // after an error in the underlying transport. This is the default and expected for most
201*8222fbe1SAndroid Build Coastguard Worker // usecases.
202*8222fbe1SAndroid Build Coastguard Worker NONE,
203*8222fbe1SAndroid Build Coastguard Worker // Log when there is an unchecked error.
204*8222fbe1SAndroid Build Coastguard Worker ERROR_IF_UNCHECKED,
205*8222fbe1SAndroid Build Coastguard Worker // Fatal when there is an unchecked error.
206*8222fbe1SAndroid Build Coastguard Worker FATAL_IF_UNCHECKED,
207*8222fbe1SAndroid Build Coastguard Worker };
208*8222fbe1SAndroid Build Coastguard Worker
209*8222fbe1SAndroid Build Coastguard Worker /**
210*8222fbe1SAndroid Build Coastguard Worker * This should be called during process initialization (e.g. before binder threadpool is created).
211*8222fbe1SAndroid Build Coastguard Worker *
212*8222fbe1SAndroid Build Coastguard Worker * Note: default of HidlReturnRestriction::NONE should be good for most usecases. See above.
213*8222fbe1SAndroid Build Coastguard Worker *
214*8222fbe1SAndroid Build Coastguard Worker * The restriction will be applied when Return objects are deconstructed.
215*8222fbe1SAndroid Build Coastguard Worker */
216*8222fbe1SAndroid Build Coastguard Worker void setProcessHidlReturnRestriction(HidlReturnRestriction restriction);
217*8222fbe1SAndroid Build Coastguard Worker
218*8222fbe1SAndroid Build Coastguard Worker template<typename T> class Return : public details::return_status {
219*8222fbe1SAndroid Build Coastguard Worker private:
220*8222fbe1SAndroid Build Coastguard Worker T mVal {};
221*8222fbe1SAndroid Build Coastguard Worker public:
Return(T v)222*8222fbe1SAndroid Build Coastguard Worker Return(T v) : details::return_status(), mVal{v} {}
Return(Status s)223*8222fbe1SAndroid Build Coastguard Worker Return(Status s) : details::return_status(s) {}
224*8222fbe1SAndroid Build Coastguard Worker
225*8222fbe1SAndroid Build Coastguard Worker // move-able.
226*8222fbe1SAndroid Build Coastguard Worker // precondition: "this" has checked status
227*8222fbe1SAndroid Build Coastguard Worker // postcondition: other is safe to destroy after moving to *this.
228*8222fbe1SAndroid Build Coastguard Worker Return(Return&& other) noexcept = default;
229*8222fbe1SAndroid Build Coastguard Worker Return& operator=(Return&&) noexcept = default;
230*8222fbe1SAndroid Build Coastguard Worker
231*8222fbe1SAndroid Build Coastguard Worker ~Return() = default;
232*8222fbe1SAndroid Build Coastguard Worker
T()233*8222fbe1SAndroid Build Coastguard Worker operator T() const {
234*8222fbe1SAndroid Build Coastguard Worker onValueRetrieval(); // assert okay
235*8222fbe1SAndroid Build Coastguard Worker return mVal;
236*8222fbe1SAndroid Build Coastguard Worker }
237*8222fbe1SAndroid Build Coastguard Worker
withDefault(T t)238*8222fbe1SAndroid Build Coastguard Worker T withDefault(T t) const { return isOk() ? mVal : t; }
239*8222fbe1SAndroid Build Coastguard Worker };
240*8222fbe1SAndroid Build Coastguard Worker
241*8222fbe1SAndroid Build Coastguard Worker template<typename T> class Return<sp<T>> : public details::return_status {
242*8222fbe1SAndroid Build Coastguard Worker private:
243*8222fbe1SAndroid Build Coastguard Worker sp<T> mVal {};
244*8222fbe1SAndroid Build Coastguard Worker public:
Return(sp<T> v)245*8222fbe1SAndroid Build Coastguard Worker Return(sp<T> v) : details::return_status(), mVal{v} {}
Return(T * v)246*8222fbe1SAndroid Build Coastguard Worker Return(T* v) : details::return_status(), mVal{v} {}
247*8222fbe1SAndroid Build Coastguard Worker // Constructors matching a different type (that is related by inheritance)
Return(sp<U> v)248*8222fbe1SAndroid Build Coastguard Worker template<typename U> Return(sp<U> v) : details::return_status(), mVal{v} {}
Return(U * v)249*8222fbe1SAndroid Build Coastguard Worker template<typename U> Return(U* v) : details::return_status(), mVal{v} {}
Return(Status s)250*8222fbe1SAndroid Build Coastguard Worker Return(Status s) : details::return_status(s) {}
251*8222fbe1SAndroid Build Coastguard Worker
252*8222fbe1SAndroid Build Coastguard Worker // move-able.
253*8222fbe1SAndroid Build Coastguard Worker // precondition: "this" has checked status
254*8222fbe1SAndroid Build Coastguard Worker // postcondition: other is safe to destroy after moving to *this.
255*8222fbe1SAndroid Build Coastguard Worker Return(Return&& other) noexcept = default;
256*8222fbe1SAndroid Build Coastguard Worker Return& operator=(Return&&) noexcept = default;
257*8222fbe1SAndroid Build Coastguard Worker
258*8222fbe1SAndroid Build Coastguard Worker ~Return() = default;
259*8222fbe1SAndroid Build Coastguard Worker
260*8222fbe1SAndroid Build Coastguard Worker operator sp<T>() const {
261*8222fbe1SAndroid Build Coastguard Worker onValueRetrieval(); // assert okay
262*8222fbe1SAndroid Build Coastguard Worker return mVal;
263*8222fbe1SAndroid Build Coastguard Worker }
264*8222fbe1SAndroid Build Coastguard Worker
withDefault(sp<T> t)265*8222fbe1SAndroid Build Coastguard Worker sp<T> withDefault(sp<T> t) const { return isOk() ? mVal : t; }
266*8222fbe1SAndroid Build Coastguard Worker };
267*8222fbe1SAndroid Build Coastguard Worker
268*8222fbe1SAndroid Build Coastguard Worker
269*8222fbe1SAndroid Build Coastguard Worker template<> class Return<void> : public details::return_status {
270*8222fbe1SAndroid Build Coastguard Worker public:
Return()271*8222fbe1SAndroid Build Coastguard Worker Return() : details::return_status() {}
Return(const Status & s)272*8222fbe1SAndroid Build Coastguard Worker Return(const Status& s) : details::return_status(s) {}
273*8222fbe1SAndroid Build Coastguard Worker
274*8222fbe1SAndroid Build Coastguard Worker // move-able.
275*8222fbe1SAndroid Build Coastguard Worker // precondition: "this" has checked status
276*8222fbe1SAndroid Build Coastguard Worker // postcondition: other is safe to destroy after moving to *this.
277*8222fbe1SAndroid Build Coastguard Worker Return(Return &&) = default;
278*8222fbe1SAndroid Build Coastguard Worker Return &operator=(Return &&) = default;
279*8222fbe1SAndroid Build Coastguard Worker
280*8222fbe1SAndroid Build Coastguard Worker ~Return() = default;
281*8222fbe1SAndroid Build Coastguard Worker };
282*8222fbe1SAndroid Build Coastguard Worker
Void()283*8222fbe1SAndroid Build Coastguard Worker static inline Return<void> Void() {
284*8222fbe1SAndroid Build Coastguard Worker return Return<void>();
285*8222fbe1SAndroid Build Coastguard Worker }
286*8222fbe1SAndroid Build Coastguard Worker
287*8222fbe1SAndroid Build Coastguard Worker namespace details {
288*8222fbe1SAndroid Build Coastguard Worker // Create a Return<U> from the Status of Return<T>. The provided
289*8222fbe1SAndroid Build Coastguard Worker // Return<T> must have an error status and have it checked.
290*8222fbe1SAndroid Build Coastguard Worker template <typename T, typename U>
StatusOf(const Return<T> & other)291*8222fbe1SAndroid Build Coastguard Worker Return<U> StatusOf(const Return<T> &other) {
292*8222fbe1SAndroid Build Coastguard Worker if (other.mStatus.isOk() || !other.mCheckedStatus) {
293*8222fbe1SAndroid Build Coastguard Worker details::logAlwaysFatal("cannot call statusOf on an OK Status or an unchecked status");
294*8222fbe1SAndroid Build Coastguard Worker }
295*8222fbe1SAndroid Build Coastguard Worker return Return<U>{other.mStatus};
296*8222fbe1SAndroid Build Coastguard Worker }
297*8222fbe1SAndroid Build Coastguard Worker } // namespace details
298*8222fbe1SAndroid Build Coastguard Worker
299*8222fbe1SAndroid Build Coastguard Worker } // namespace hardware
300*8222fbe1SAndroid Build Coastguard Worker } // namespace android
301*8222fbe1SAndroid Build Coastguard Worker
302*8222fbe1SAndroid Build Coastguard Worker #endif // ANDROID_HARDWARE_BINDER_STATUS_H
303