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