HidlBinderSupport.cpp revision b2c9c75b74c87e651dd08a100015eab17319556e
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "HidlSupport" 18 19#include <hidl/HidlBinderSupport.h> 20 21#ifdef LIBHIDL_TARGET_DEBUGGABLE 22#include <android-base/logging.h> 23#endif 24 25namespace android { 26namespace hardware { 27 28const size_t hidl_memory::kOffsetOfHandle = offsetof(hidl_memory, mHandle); 29const size_t hidl_memory::kOffsetOfName = offsetof(hidl_memory, mName); 30 31status_t readEmbeddedFromParcel(hidl_memory * /* memory */, 32 const Parcel &parcel, size_t parentHandle, size_t parentOffset) { 33 ::android::status_t _hidl_err = ::android::OK; 34 const native_handle_t *_hidl_memory_handle = parcel.readEmbeddedNativeHandle( 35 parentHandle, 36 parentOffset + hidl_memory::kOffsetOfHandle); 37 38 if (_hidl_memory_handle == nullptr) { 39 _hidl_err = ::android::UNKNOWN_ERROR; 40 return _hidl_err; 41 } 42 43 _hidl_err = readEmbeddedFromParcel( 44 (hidl_string*) nullptr, 45 parcel, 46 parentHandle, 47 parentOffset + hidl_memory::kOffsetOfName); 48 49 return _hidl_err; 50} 51 52status_t writeEmbeddedToParcel(const hidl_memory &memory, 53 Parcel *parcel, size_t parentHandle, size_t parentOffset) { 54 status_t _hidl_err = parcel->writeEmbeddedNativeHandle( 55 memory.handle(), 56 parentHandle, 57 parentOffset + hidl_memory::kOffsetOfHandle); 58 59 if (_hidl_err == ::android::OK) { 60 _hidl_err = writeEmbeddedToParcel( 61 memory.name(), 62 parcel, 63 parentHandle, 64 parentOffset + hidl_memory::kOffsetOfName); 65 } 66 67 return _hidl_err; 68} 69// static 70const size_t hidl_string::kOffsetOfBuffer = offsetof(hidl_string, mBuffer); 71 72status_t readEmbeddedFromParcel(hidl_string * /* string */, 73 const Parcel &parcel, size_t parentHandle, size_t parentOffset) { 74 const void *ptr = parcel.readEmbeddedBuffer( 75 nullptr /* buffer_handle */, 76 parentHandle, 77 parentOffset + hidl_string::kOffsetOfBuffer); 78 79 return ptr != NULL ? OK : UNKNOWN_ERROR; 80} 81 82status_t writeEmbeddedToParcel(const hidl_string &string, 83 Parcel *parcel, size_t parentHandle, size_t parentOffset) { 84 return parcel->writeEmbeddedBuffer( 85 string.c_str(), 86 string.size() + 1, 87 nullptr /* handle */, 88 parentHandle, 89 parentOffset + hidl_string::kOffsetOfBuffer); 90} 91 92android::status_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel) { 93 return parcel.writeUint32(static_cast<uint32_t>(version.get_major()) << 16 | version.get_minor()); 94} 95 96hidl_version* readFromParcel(const android::hardware::Parcel& parcel) { 97 uint32_t version; 98 android::status_t status = parcel.readUint32(&version); 99 if (status != OK) { 100 return nullptr; 101 } else { 102 return new hidl_version(version >> 16, version & 0xFFFF); 103 } 104} 105 106status_t readFromParcel(Status *s, const Parcel& parcel) { 107 int32_t exception; 108 int32_t errorCode; 109 status_t status = parcel.readInt32(&exception); 110 if (status != OK) { 111 s->setFromStatusT(status); 112 return status; 113 } 114 115 // Skip over fat response headers. Not used (or propagated) in native code. 116 if (exception == Status::EX_HAS_REPLY_HEADER) { 117 // Note that the header size includes the 4 byte size field. 118 const int32_t header_start = parcel.dataPosition(); 119 int32_t header_size; 120 status = parcel.readInt32(&header_size); 121 if (status != OK) { 122 s->setFromStatusT(status); 123 return status; 124 } 125 parcel.setDataPosition(header_start + header_size); 126 // And fat response headers are currently only used when there are no 127 // exceptions, so act like there was no error. 128 exception = Status::EX_NONE; 129 } 130 131 if (exception == Status::EX_NONE) { 132 *s = Status::ok(); 133 return status; 134 } 135 136 // The remote threw an exception. Get the message back. 137 String16 message; 138 status = parcel.readString16(&message); 139 if (status != OK) { 140 s->setFromStatusT(status); 141 return status; 142 } 143 144 if (exception == Status::EX_SERVICE_SPECIFIC) { 145 status = parcel.readInt32(&errorCode); 146 } 147 if (status != OK) { 148 s->setFromStatusT(status); 149 return status; 150 } 151 152 if (exception == Status::EX_SERVICE_SPECIFIC) { 153 s->setServiceSpecificError(errorCode, String8(message)); 154 } else { 155 s->setException(exception, String8(message)); 156 } 157 158 return status; 159} 160 161status_t writeToParcel(const Status &s, Parcel* parcel) { 162 // Something really bad has happened, and we're not going to even 163 // try returning rich error data. 164 if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) { 165 return s.transactionError(); 166 } 167 168 status_t status = parcel->writeInt32(s.exceptionCode()); 169 if (status != OK) { return status; } 170 if (s.exceptionCode() == Status::EX_NONE) { 171 // We have no more information to write. 172 return status; 173 } 174 status = parcel->writeString16(String16(s.exceptionMessage())); 175 if (s.exceptionCode() != Status::EX_SERVICE_SPECIFIC) { 176 // We have no more information to write. 177 return status; 178 } 179 status = parcel->writeInt32(s.serviceSpecificErrorCode()); 180 return status; 181} 182 183} // namespace hardware 184} // namespace android 185