blob: 30c2323c3e25a3d00021fdf7e8e067f07791c8ea [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
Yifan Hong777bef92017-02-01 15:50:36 -080021// C includes
22#include <unistd.h>
23
24// C++ includes
25#include <fstream>
26#include <sstream>
27
Yifan Hong7f97f442016-11-14 18:31:05 -080028#ifdef LIBHIDL_TARGET_DEBUGGABLE
29#include <android-base/logging.h>
30#endif
31
32namespace android {
33namespace hardware {
34
Martijn Coenen30791002016-12-01 15:40:46 +010035const size_t hidl_memory::kOffsetOfHandle = offsetof(hidl_memory, mHandle);
36const size_t hidl_memory::kOffsetOfName = offsetof(hidl_memory, mName);
37
38status_t readEmbeddedFromParcel(hidl_memory * /* memory */,
39 const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
Steven Moreland1f535a22017-01-06 19:25:49 -080040 const native_handle_t *handle;
41 ::android::status_t _hidl_err = parcel.readNullableEmbeddedNativeHandle(
Martijn Coenen30791002016-12-01 15:40:46 +010042 parentHandle,
Steven Moreland1f535a22017-01-06 19:25:49 -080043 parentOffset + hidl_memory::kOffsetOfHandle,
44 &handle);
Martijn Coenen30791002016-12-01 15:40:46 +010045
Steven Moreland1f535a22017-01-06 19:25:49 -080046 if (_hidl_err == ::android::OK) {
47 _hidl_err = readEmbeddedFromParcel(
48 (hidl_string*) nullptr,
49 parcel,
50 parentHandle,
51 parentOffset + hidl_memory::kOffsetOfName);
Martijn Coenen30791002016-12-01 15:40:46 +010052 }
53
Martijn Coenen30791002016-12-01 15:40:46 +010054 return _hidl_err;
55}
56
57status_t writeEmbeddedToParcel(const hidl_memory &memory,
58 Parcel *parcel, size_t parentHandle, size_t parentOffset) {
59 status_t _hidl_err = parcel->writeEmbeddedNativeHandle(
60 memory.handle(),
61 parentHandle,
62 parentOffset + hidl_memory::kOffsetOfHandle);
63
64 if (_hidl_err == ::android::OK) {
65 _hidl_err = writeEmbeddedToParcel(
66 memory.name(),
67 parcel,
68 parentHandle,
69 parentOffset + hidl_memory::kOffsetOfName);
70 }
71
72 return _hidl_err;
73}
Yifan Hong7f97f442016-11-14 18:31:05 -080074// static
75const size_t hidl_string::kOffsetOfBuffer = offsetof(hidl_string, mBuffer);
76
77status_t readEmbeddedFromParcel(hidl_string * /* string */,
78 const Parcel &parcel, size_t parentHandle, size_t parentOffset) {
Steven Moreland1f535a22017-01-06 19:25:49 -080079 const void *out;
80 return parcel.readEmbeddedBuffer(
Yifan Hong7f97f442016-11-14 18:31:05 -080081 nullptr /* buffer_handle */,
82 parentHandle,
Steven Moreland1f535a22017-01-06 19:25:49 -080083 parentOffset + hidl_string::kOffsetOfBuffer,
84 &out);
Yifan Hong7f97f442016-11-14 18:31:05 -080085}
86
87status_t writeEmbeddedToParcel(const hidl_string &string,
88 Parcel *parcel, size_t parentHandle, size_t parentOffset) {
89 return parcel->writeEmbeddedBuffer(
90 string.c_str(),
91 string.size() + 1,
92 nullptr /* handle */,
93 parentHandle,
94 parentOffset + hidl_string::kOffsetOfBuffer);
95}
96
97android::status_t writeToParcel(const hidl_version &version, android::hardware::Parcel& parcel) {
98 return parcel.writeUint32(static_cast<uint32_t>(version.get_major()) << 16 | version.get_minor());
99}
100
101hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
102 uint32_t version;
103 android::status_t status = parcel.readUint32(&version);
104 if (status != OK) {
105 return nullptr;
106 } else {
107 return new hidl_version(version >> 16, version & 0xFFFF);
108 }
109}
110
111status_t readFromParcel(Status *s, const Parcel& parcel) {
112 int32_t exception;
113 int32_t errorCode;
114 status_t status = parcel.readInt32(&exception);
115 if (status != OK) {
116 s->setFromStatusT(status);
117 return status;
118 }
119
120 // Skip over fat response headers. Not used (or propagated) in native code.
121 if (exception == Status::EX_HAS_REPLY_HEADER) {
122 // Note that the header size includes the 4 byte size field.
123 const int32_t header_start = parcel.dataPosition();
124 int32_t header_size;
125 status = parcel.readInt32(&header_size);
126 if (status != OK) {
127 s->setFromStatusT(status);
128 return status;
129 }
130 parcel.setDataPosition(header_start + header_size);
131 // And fat response headers are currently only used when there are no
132 // exceptions, so act like there was no error.
133 exception = Status::EX_NONE;
134 }
135
136 if (exception == Status::EX_NONE) {
137 *s = Status::ok();
138 return status;
139 }
140
141 // The remote threw an exception. Get the message back.
142 String16 message;
143 status = parcel.readString16(&message);
144 if (status != OK) {
145 s->setFromStatusT(status);
146 return status;
147 }
148
149 if (exception == Status::EX_SERVICE_SPECIFIC) {
150 status = parcel.readInt32(&errorCode);
151 }
152 if (status != OK) {
153 s->setFromStatusT(status);
154 return status;
155 }
156
157 if (exception == Status::EX_SERVICE_SPECIFIC) {
158 s->setServiceSpecificError(errorCode, String8(message));
159 } else {
160 s->setException(exception, String8(message));
161 }
162
163 return status;
164}
165
166status_t writeToParcel(const Status &s, Parcel* parcel) {
167 // Something really bad has happened, and we're not going to even
168 // try returning rich error data.
169 if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) {
170 return s.transactionError();
171 }
172
173 status_t status = parcel->writeInt32(s.exceptionCode());
174 if (status != OK) { return status; }
175 if (s.exceptionCode() == Status::EX_NONE) {
176 // We have no more information to write.
177 return status;
178 }
179 status = parcel->writeString16(String16(s.exceptionMessage()));
180 if (s.exceptionCode() != Status::EX_SERVICE_SPECIFIC) {
181 // We have no more information to write.
182 return status;
183 }
184 status = parcel->writeInt32(s.serviceSpecificErrorCode());
185 return status;
186}
187
Steven Moreland6cf8fa22017-02-21 13:38:17 -0800188void configureBinderRpcThreadpool(size_t maxThreads, bool callerWillJoin) {
189 ProcessState::self()->setThreadPoolConfiguration(maxThreads, callerWillJoin /*callerJoinsPool*/);
190}
191
192void joinBinderRpcThreadpool() {
193 IPCThreadState::self()->joinThreadPool();
194}
195
Yifan Hong7f97f442016-11-14 18:31:05 -0800196} // namespace hardware
197} // namespace android