blob: f3e99e1338c3f8ddba2ec637c5d7504997435137 [file] [log] [blame]
Yifan Hong7f97f442016-11-14 18:31:05 -08001/*
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
28std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap{};
29
Martijn Coenen30791002016-12-01 15:40:46 +010030const size_t hidl_memory::kOffsetOfHandle = offsetof(hidl_memory, mHandle);
31const size_t hidl_memory::kOffsetOfName = offsetof(hidl_memory, mName);
32
33status_t readEmbeddedFromParcel(hidl_memory * /* memory */,
34 const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
35 ::android::status_t _hidl_err = ::android::OK;
36 const native_handle_t *_hidl_memory_handle = parcel.readEmbeddedNativeHandle(
37 parentHandle,
38 parentOffset + hidl_memory::kOffsetOfHandle);
39
40 if (_hidl_memory_handle == nullptr) {
41 _hidl_err = ::android::UNKNOWN_ERROR;
42 return _hidl_err;
43 }
44
45 _hidl_err = readEmbeddedFromParcel(
46 (hidl_string*) nullptr,
47 parcel,
48 parentHandle,
49 parentOffset + hidl_memory::kOffsetOfName);
50
51 return _hidl_err;
52}
53
54status_t writeEmbeddedToParcel(const hidl_memory &memory,
55 Parcel *parcel, size_t parentHandle, size_t parentOffset) {
56 status_t _hidl_err = parcel->writeEmbeddedNativeHandle(
57 memory.handle(),
58 parentHandle,
59 parentOffset + hidl_memory::kOffsetOfHandle);
60
61 if (_hidl_err == ::android::OK) {
62 _hidl_err = writeEmbeddedToParcel(
63 memory.name(),
64 parcel,
65 parentHandle,
66 parentOffset + hidl_memory::kOffsetOfName);
67 }
68
69 return _hidl_err;
70}
Yifan Hong7f97f442016-11-14 18:31:05 -080071// static
72const size_t hidl_string::kOffsetOfBuffer = offsetof(hidl_string, mBuffer);
73
74status_t readEmbeddedFromParcel(hidl_string * /* string */,
75 const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
76 const void *ptr = parcel.readEmbeddedBuffer(
77 nullptr /* buffer_handle */,
78 parentHandle,
79 parentOffset + hidl_string::kOffsetOfBuffer);
80
81 return ptr != NULL ? OK : UNKNOWN_ERROR;
82}
83
84status_t writeEmbeddedToParcel(const hidl_string &string,
85 Parcel *parcel, size_t parentHandle, size_t parentOffset) {
86 return parcel->writeEmbeddedBuffer(
87 string.c_str(),
88 string.size() + 1,
89 nullptr /* handle */,
90 parentHandle,
91 parentOffset + hidl_string::kOffsetOfBuffer);
92}
93
94android::status_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel) {
95 return parcel.writeUint32(static_cast<uint32_t>(version.get_major()) << 16 | version.get_minor());
96}
97
98hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
99 uint32_t version;
100 android::status_t status = parcel.readUint32(&version);
101 if (status != OK) {
102 return nullptr;
103 } else {
104 return new hidl_version(version >> 16, version & 0xFFFF);
105 }
106}
107
108status_t readFromParcel(Status *s, const Parcel& parcel) {
109 int32_t exception;
110 int32_t errorCode;
111 status_t status = parcel.readInt32(&exception);
112 if (status != OK) {
113 s->setFromStatusT(status);
114 return status;
115 }
116
117 // Skip over fat response headers. Not used (or propagated) in native code.
118 if (exception == Status::EX_HAS_REPLY_HEADER) {
119 // Note that the header size includes the 4 byte size field.
120 const int32_t header_start = parcel.dataPosition();
121 int32_t header_size;
122 status = parcel.readInt32(&header_size);
123 if (status != OK) {
124 s->setFromStatusT(status);
125 return status;
126 }
127 parcel.setDataPosition(header_start + header_size);
128 // And fat response headers are currently only used when there are no
129 // exceptions, so act like there was no error.
130 exception = Status::EX_NONE;
131 }
132
133 if (exception == Status::EX_NONE) {
134 *s = Status::ok();
135 return status;
136 }
137
138 // The remote threw an exception. Get the message back.
139 String16 message;
140 status = parcel.readString16(&message);
141 if (status != OK) {
142 s->setFromStatusT(status);
143 return status;
144 }
145
146 if (exception == Status::EX_SERVICE_SPECIFIC) {
147 status = parcel.readInt32(&errorCode);
148 }
149 if (status != OK) {
150 s->setFromStatusT(status);
151 return status;
152 }
153
154 if (exception == Status::EX_SERVICE_SPECIFIC) {
155 s->setServiceSpecificError(errorCode, String8(message));
156 } else {
157 s->setException(exception, String8(message));
158 }
159
160 return status;
161}
162
163status_t writeToParcel(const Status &s, Parcel* parcel) {
164 // Something really bad has happened, and we're not going to even
165 // try returning rich error data.
166 if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) {
167 return s.transactionError();
168 }
169
170 status_t status = parcel->writeInt32(s.exceptionCode());
171 if (status != OK) { return status; }
172 if (s.exceptionCode() == Status::EX_NONE) {
173 // We have no more information to write.
174 return status;
175 }
176 status = parcel->writeString16(String16(s.exceptionMessage()));
177 if (s.exceptionCode() != Status::EX_SERVICE_SPECIFIC) {
178 // We have no more information to write.
179 return status;
180 }
181 status = parcel->writeInt32(s.serviceSpecificErrorCode());
182 return status;
183}
184
185} // namespace hardware
186} // namespace android