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#include <binder/Status.h>
1809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
1909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wileynamespace android {
2009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wileynamespace binder {
2109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
22cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher WileyStatus Status::ok() {
23cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    return Status();
24cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley}
25cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley
26cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher WileyStatus Status::fromExceptionCode(int32_t exceptionCode) {
27c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    return Status(exceptionCode, OK);
28cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley}
29cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley
30cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher WileyStatus Status::fromExceptionCode(int32_t exceptionCode,
31cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley                                 const String8& message) {
32c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    return Status(exceptionCode, OK, message);
33c1e491d5a4923298b612de919537d4293574b443Christopher Wiley}
34c1e491d5a4923298b612de919537d4293574b443Christopher Wiley
35c1e491d5a4923298b612de919537d4293574b443Christopher WileyStatus Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode) {
36c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode);
37c1e491d5a4923298b612de919537d4293574b443Christopher Wiley}
38c1e491d5a4923298b612de919537d4293574b443Christopher Wiley
39c1e491d5a4923298b612de919537d4293574b443Christopher WileyStatus Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode,
40c1e491d5a4923298b612de919537d4293574b443Christopher Wiley                                        const String8& message) {
41c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode, message);
4209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley}
4309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
4409eb749704afd9e226e1347cb20c90be2016cd21Christopher WileyStatus Status::fromStatusT(status_t status) {
4509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    Status ret;
4609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    ret.setFromStatusT(status);
4709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    return ret;
4809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley}
4909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
50c1e491d5a4923298b612de919537d4293574b443Christopher WileyStatus::Status(int32_t exceptionCode, int32_t errorCode)
51cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    : mException(exceptionCode),
52c1e491d5a4923298b612de919537d4293574b443Christopher Wiley      mErrorCode(errorCode) {}
53c1e491d5a4923298b612de919537d4293574b443Christopher Wiley
54c1e491d5a4923298b612de919537d4293574b443Christopher WileyStatus::Status(int32_t exceptionCode, int32_t errorCode, const String8& message)
55c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    : mException(exceptionCode),
56c1e491d5a4923298b612de919537d4293574b443Christopher Wiley      mErrorCode(errorCode),
5709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley      mMessage(message) {}
5809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
5909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wileystatus_t Status::readFromParcel(const Parcel& parcel) {
6009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    status_t status = parcel.readInt32(&mException);
6109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    if (status != OK) {
6209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        setFromStatusT(status);
6309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        return status;
6409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    }
6509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
6609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    // Skip over fat response headers.  Not used (or propagated) in native code.
6709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    if (mException == EX_HAS_REPLY_HEADER) {
6809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        // Note that the header size includes the 4 byte size field.
6909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        const int32_t header_start = parcel.dataPosition();
7009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        int32_t header_size;
7109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        status = parcel.readInt32(&header_size);
7209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        if (status != OK) {
7309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley            setFromStatusT(status);
7409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley            return status;
7509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        }
7609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        parcel.setDataPosition(header_start + header_size);
7709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        // And fat response headers are currently only used when there are no
7809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        // exceptions, so act like there was no error.
7909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        mException = EX_NONE;
8009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    }
8109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
8209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    if (mException == EX_NONE) {
8309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        return status;
8409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    }
8509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
8609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    // The remote threw an exception.  Get the message back.
87cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    String16 message;
88cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    status = parcel.readString16(&message);
89cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    if (status != OK) {
90cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley        setFromStatusT(status);
91cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley        return status;
92cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    }
93cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    mMessage = String8(message);
9409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
95c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    if (mException == EX_SERVICE_SPECIFIC) {
96c1e491d5a4923298b612de919537d4293574b443Christopher Wiley        status = parcel.readInt32(&mErrorCode);
97c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    }
98c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    if (status != OK) {
99c1e491d5a4923298b612de919537d4293574b443Christopher Wiley        setFromStatusT(status);
100c1e491d5a4923298b612de919537d4293574b443Christopher Wiley        return status;
101c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    }
102c1e491d5a4923298b612de919537d4293574b443Christopher Wiley
10309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    return status;
10409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley}
10509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
10609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wileystatus_t Status::writeToParcel(Parcel* parcel) const {
107cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    // Something really bad has happened, and we're not going to even
108cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    // try returning rich error data.
109cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    if (mException == EX_TRANSACTION_FAILED) {
110cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley        return mErrorCode;
111cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    }
112cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley
11309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    status_t status = parcel->writeInt32(mException);
11409eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    if (status != OK) { return status; }
11509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    if (mException == EX_NONE) {
11609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        // We have no more information to write.
11709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        return status;
11809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    }
11909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    status = parcel->writeString16(String16(mMessage));
120c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    if (mException != EX_SERVICE_SPECIFIC) {
121c1e491d5a4923298b612de919537d4293574b443Christopher Wiley        // We have no more information to write.
122c1e491d5a4923298b612de919537d4293574b443Christopher Wiley        return status;
123c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    }
124c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    status = parcel->writeInt32(mErrorCode);
12509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    return status;
12609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley}
12709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
12809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wileyvoid Status::setException(int32_t ex, const String8& message) {
12909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    mException = ex;
130cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley    mErrorCode = NO_ERROR;  // an exception, not a transaction failure.
13109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    mMessage.setTo(message);
13209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley}
13309eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
134c1e491d5a4923298b612de919537d4293574b443Christopher Wileyvoid Status::setServiceSpecificError(int32_t errorCode, const String8& message) {
135c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    setException(EX_SERVICE_SPECIFIC, message);
136c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    mErrorCode = errorCode;
137c1e491d5a4923298b612de919537d4293574b443Christopher Wiley}
138c1e491d5a4923298b612de919537d4293574b443Christopher Wiley
139c1e491d5a4923298b612de919537d4293574b443Christopher Wileyvoid Status::setFromStatusT(status_t status) {
140c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    mException = (status == NO_ERROR) ? EX_NONE : EX_TRANSACTION_FAILED;
141c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    mErrorCode = status;
142c1e491d5a4923298b612de919537d4293574b443Christopher Wiley    mMessage.clear();
143c1e491d5a4923298b612de919537d4293574b443Christopher Wiley}
144c1e491d5a4923298b612de919537d4293574b443Christopher Wiley
14509eb749704afd9e226e1347cb20c90be2016cd21Christopher WileyString8 Status::toString8() const {
14609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    String8 ret;
14709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    if (mException == EX_NONE) {
14809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        ret.append("No error");
14909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    } else {
15009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        ret.appendFormat("Status(%d): '", mException);
151c1e491d5a4923298b612de919537d4293574b443Christopher Wiley        if (mException == EX_SERVICE_SPECIFIC ||
152c1e491d5a4923298b612de919537d4293574b443Christopher Wiley            mException == EX_TRANSACTION_FAILED) {
153cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley            ret.appendFormat("%d: ", mErrorCode);
154cff7f175c1a4f790fdc64a56695c5b4b08b6bb6eChristopher Wiley        }
15509eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        ret.append(String8(mMessage));
15609eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley        ret.append("'");
15709eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    }
15809eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley    return ret;
15909eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley}
16009eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley
16109eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley}  // namespace binder
16209eb749704afd9e226e1347cb20c90be2016cd21Christopher Wiley}  // namespace android
163