blob: 4b0e369d9c58a068569f6523202a6fb402f97924 [file] [log] [blame]
Martijn Coenen72110162016-08-19 14:28:25 +02001/*
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#ifndef ANDROID_HIDL_SUPPORT_H
18#define ANDROID_HIDL_SUPPORT_H
19
20#include <hwbinder/Parcel.h>
21
22namespace android {
23namespace hardware {
24
25struct hidl_string {
26 hidl_string();
27 ~hidl_string();
28
29 hidl_string(const hidl_string &);
30 hidl_string &operator=(const hidl_string &);
31
32 const char *c_str() const;
33 size_t size() const;
34 bool empty() const;
35
36 hidl_string &operator=(const char *s);
37 void clear();
38
39 // Reference an external char array. Ownership is _not_ transferred.
40 // Caller is responsible for ensuring that underlying memory is valid
41 // for the lifetime of this hidl_string.
42 void setToExternal(const char *data, size_t size);
43
44 status_t readEmbeddedFromParcel(
45 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
46
47 status_t writeEmbeddedToParcel(
48 Parcel *parcel, size_t parentHandle, size_t parentOffset) const;
49
Andreas Huberebfeb362016-08-25 13:39:05 -070050 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
51 static const size_t kOffsetOfBuffer;
52
Martijn Coenen72110162016-08-19 14:28:25 +020053private:
54 char *mBuffer;
55 size_t mSize; // NOT including the terminating '\0'.
56 bool mOwnsBuffer;
57
58 hidl_string &setTo(const char *data, size_t size);
59};
60
61template<typename T>
62struct hidl_vec {
63 hidl_vec()
64 : mBuffer(NULL),
65 mSize(0),
66 mOwnsBuffer(true) {
67 }
68
69 hidl_vec(const hidl_vec<T> &other)
70 : mBuffer(NULL),
71 mSize(0),
72 mOwnsBuffer(true) {
73 *this = other;
74 }
75
76 ~hidl_vec() {
77 if (mOwnsBuffer) {
78 delete[] mBuffer;
79 }
80 mBuffer = NULL;
81 }
82
83 // Reference an existing array _WITHOUT_ taking ownership. It is the
84 // caller's responsibility to ensure that the underlying memory stays
85 // valid for the lifetime of this hidl_vec.
86 void setToExternal(T *data, size_t size) {
87 if (mOwnsBuffer) {
88 delete [] mBuffer;
89 }
90 mBuffer = data;
91 mSize = size;
92 mOwnsBuffer = false;
93 }
94
95 hidl_vec &operator=(const hidl_vec &other) {
96 if (this != &other) {
97 if (mOwnsBuffer) {
98 delete[] mBuffer;
99 }
100 mBuffer = NULL;
101 mSize = other.mSize;
102 mOwnsBuffer = true;
103 if (mSize > 0) {
104 mBuffer = new T[mSize];
105 for (size_t i = 0; i < mSize; ++i) {
106 mBuffer[i] = other.mBuffer[i];
107 }
108 }
109 }
110
111 return *this;
112 }
113
114 size_t size() const {
115 return mSize;
116 }
117
118 T &operator[](size_t index) {
119 return mBuffer[index];
120 }
121
122 const T &operator[](size_t index) const {
123 return mBuffer[index];
124 }
125
126 void resize(size_t size) {
127 T *newBuffer = new T[size];
128
129 for (size_t i = 0; i < std::min(size, mSize); ++i) {
130 newBuffer[i] = mBuffer[i];
131 }
132
133 if (mOwnsBuffer) {
134 delete[] mBuffer;
135 }
136 mBuffer = newBuffer;
137
138 mSize = size;
139 mOwnsBuffer = true;
140 }
141
142 status_t readEmbeddedFromParcel(
143 const Parcel &parcel,
144 size_t parentHandle,
145 size_t parentOffset,
146 size_t *handle);
147
148 status_t writeEmbeddedToParcel(
149 Parcel *parcel,
150 size_t parentHandle,
151 size_t parentOffset,
152 size_t *handle) const;
153
154private:
155 T *mBuffer;
156 size_t mSize;
157 bool mOwnsBuffer;
158};
159
160template<typename T>
161status_t hidl_vec<T>::readEmbeddedFromParcel(
162 const Parcel &parcel,
163 size_t parentHandle,
164 size_t parentOffset,
165 size_t *handle) {
166 const void *ptr = parcel.readEmbeddedBuffer(
167 handle,
168 parentHandle,
169 parentOffset + offsetof(hidl_vec<T>, mBuffer));
170
171 return ptr != NULL ? OK : UNKNOWN_ERROR;
172}
173
174template<typename T>
175status_t hidl_vec<T>::writeEmbeddedToParcel(
176 Parcel *parcel,
177 size_t parentHandle,
178 size_t parentOffset,
179 size_t *handle) const {
180 return parcel->writeEmbeddedBuffer(
181 mBuffer,
182 sizeof(T) * mSize,
183 handle,
184 parentHandle,
185 parentOffset + offsetof(hidl_vec<T>, mBuffer));
186}
187
188// ----------------------------------------------------------------------
189// Version functions
190struct hidl_version {
191public:
192 hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {};
193
194 bool operator==(const hidl_version& other) {
195 return (mMajor == other.get_major() && mMinor == other.get_minor());
196 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200197
Martijn Coenen72110162016-08-19 14:28:25 +0200198 uint16_t get_major() const { return mMajor; }
199 uint16_t get_minor() const { return mMinor; }
200
201 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
202 return parcel.writeUint32((uint32_t) mMajor << 16 | mMinor);
203 }
204
205 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
206 uint32_t version;
207 android::status_t status = parcel.readUint32(&version);
208 if (status != OK) {
209 return nullptr;
210 } else {
211 return new hidl_version(version >> 16, version & 0xFFFF);
212 }
213 }
214
215private:
216 uint16_t mMajor;
217 uint16_t mMinor;
218};
219
220inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
221 return hidl_version(major,minor);
222}
223
Martijn Coenenc28f1152016-08-22 14:06:56 +0200224#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
225 static ::android::sp<I##INTERFACE> getService( \
226 const ::android::String16 &serviceName, \
227 const hidl_version &version); \
228 status_t registerAsService( \
229 const ::android::String16& serviceName, \
230 const hidl_version &version);
231
232#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE) \
233 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
234 const ::android::String16 &serviceName, \
235 const hidl_version &version /* TODO get version from IFoo directly */) \
236 { \
237 sp<I##INTERFACE> iface; \
238 const sp<IServiceManager> sm = defaultServiceManager(); \
239 if (sm != nullptr) { \
240 sp<IBinder> binderIface = sm->getService(serviceName, version); \
241 iface = IHw##INTERFACE::asInterface(binderIface); \
242 } \
243 /* TODO: if we don't have a binder interface, try to instantiate default */ \
244 return iface; \
245 } \
246 status_t I##INTERFACE::registerAsService( \
247 const ::android::String16& serviceName, \
248 const hidl_version &version) \
249 { \
250 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
251 const sp<IServiceManager> sm = defaultServiceManager(); \
252 return sm->addService(serviceName, binderIface, version); \
253 }
254
Martijn Coenen72110162016-08-19 14:28:25 +0200255} // namespace hardware
256} // namespace android
257
Martijn Coenenc28f1152016-08-22 14:06:56 +0200258
Martijn Coenen72110162016-08-19 14:28:25 +0200259#endif // ANDROID_HIDL_SUPPORT_H
260