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