blob: ac3e3e2a04669dcca13c679fbbb0d06ee20951f2 [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
Steven Morelandbdf26662016-09-02 11:03:15 -070020#include <dlfcn.h>
Martijn Coenen72110162016-08-19 14:28:25 +020021#include <hwbinder/Parcel.h>
22
23namespace android {
24namespace hardware {
25
26struct hidl_string {
27 hidl_string();
28 ~hidl_string();
29
30 hidl_string(const hidl_string &);
31 hidl_string &operator=(const hidl_string &);
32
33 const char *c_str() const;
34 size_t size() const;
35 bool empty() const;
36
37 hidl_string &operator=(const char *s);
38 void clear();
39
40 // Reference an external char array. Ownership is _not_ transferred.
41 // Caller is responsible for ensuring that underlying memory is valid
42 // for the lifetime of this hidl_string.
43 void setToExternal(const char *data, size_t size);
44
45 status_t readEmbeddedFromParcel(
46 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
47
48 status_t writeEmbeddedToParcel(
49 Parcel *parcel, size_t parentHandle, size_t parentOffset) const;
50
Andreas Huberebfeb362016-08-25 13:39:05 -070051 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
52 static const size_t kOffsetOfBuffer;
53
Martijn Coenen72110162016-08-19 14:28:25 +020054private:
55 char *mBuffer;
56 size_t mSize; // NOT including the terminating '\0'.
57 bool mOwnsBuffer;
58
59 hidl_string &setTo(const char *data, size_t size);
60};
61
62template<typename T>
63struct hidl_vec {
64 hidl_vec()
65 : mBuffer(NULL),
66 mSize(0),
67 mOwnsBuffer(true) {
68 }
69
70 hidl_vec(const hidl_vec<T> &other)
71 : mBuffer(NULL),
72 mSize(0),
73 mOwnsBuffer(true) {
74 *this = other;
75 }
76
77 ~hidl_vec() {
78 if (mOwnsBuffer) {
79 delete[] mBuffer;
80 }
81 mBuffer = NULL;
82 }
83
84 // Reference an existing array _WITHOUT_ taking ownership. It is the
85 // caller's responsibility to ensure that the underlying memory stays
86 // valid for the lifetime of this hidl_vec.
87 void setToExternal(T *data, size_t size) {
88 if (mOwnsBuffer) {
89 delete [] mBuffer;
90 }
91 mBuffer = data;
92 mSize = size;
93 mOwnsBuffer = false;
94 }
95
96 hidl_vec &operator=(const hidl_vec &other) {
97 if (this != &other) {
98 if (mOwnsBuffer) {
99 delete[] mBuffer;
100 }
101 mBuffer = NULL;
102 mSize = other.mSize;
103 mOwnsBuffer = true;
104 if (mSize > 0) {
105 mBuffer = new T[mSize];
106 for (size_t i = 0; i < mSize; ++i) {
107 mBuffer[i] = other.mBuffer[i];
108 }
109 }
110 }
111
112 return *this;
113 }
114
115 size_t size() const {
116 return mSize;
117 }
118
119 T &operator[](size_t index) {
120 return mBuffer[index];
121 }
122
123 const T &operator[](size_t index) const {
124 return mBuffer[index];
125 }
126
127 void resize(size_t size) {
128 T *newBuffer = new T[size];
129
130 for (size_t i = 0; i < std::min(size, mSize); ++i) {
131 newBuffer[i] = mBuffer[i];
132 }
133
134 if (mOwnsBuffer) {
135 delete[] mBuffer;
136 }
137 mBuffer = newBuffer;
138
139 mSize = size;
140 mOwnsBuffer = true;
141 }
142
143 status_t readEmbeddedFromParcel(
144 const Parcel &parcel,
145 size_t parentHandle,
146 size_t parentOffset,
147 size_t *handle);
148
149 status_t writeEmbeddedToParcel(
150 Parcel *parcel,
151 size_t parentHandle,
152 size_t parentOffset,
153 size_t *handle) const;
154
155private:
156 T *mBuffer;
157 size_t mSize;
158 bool mOwnsBuffer;
159};
160
161template<typename T>
162status_t hidl_vec<T>::readEmbeddedFromParcel(
163 const Parcel &parcel,
164 size_t parentHandle,
165 size_t parentOffset,
166 size_t *handle) {
167 const void *ptr = parcel.readEmbeddedBuffer(
168 handle,
169 parentHandle,
170 parentOffset + offsetof(hidl_vec<T>, mBuffer));
171
172 return ptr != NULL ? OK : UNKNOWN_ERROR;
173}
174
175template<typename T>
176status_t hidl_vec<T>::writeEmbeddedToParcel(
177 Parcel *parcel,
178 size_t parentHandle,
179 size_t parentOffset,
180 size_t *handle) const {
181 return parcel->writeEmbeddedBuffer(
182 mBuffer,
183 sizeof(T) * mSize,
184 handle,
185 parentHandle,
186 parentOffset + offsetof(hidl_vec<T>, mBuffer));
187}
188
189// ----------------------------------------------------------------------
190// Version functions
191struct hidl_version {
192public:
193 hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {};
194
195 bool operator==(const hidl_version& other) {
196 return (mMajor == other.get_major() && mMinor == other.get_minor());
197 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200198
Martijn Coenen72110162016-08-19 14:28:25 +0200199 uint16_t get_major() const { return mMajor; }
200 uint16_t get_minor() const { return mMinor; }
201
202 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
203 return parcel.writeUint32((uint32_t) mMajor << 16 | mMinor);
204 }
205
206 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
207 uint32_t version;
208 android::status_t status = parcel.readUint32(&version);
209 if (status != OK) {
210 return nullptr;
211 } else {
212 return new hidl_version(version >> 16, version & 0xFFFF);
213 }
214 }
215
216private:
217 uint16_t mMajor;
218 uint16_t mMinor;
219};
220
221inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
222 return hidl_version(major,minor);
223}
224
Steven Morelandbdf26662016-09-02 11:03:15 -0700225#if defined(__LP64__)
226#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
227#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
228#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
229#else
230#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
231#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
232#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
233#endif
234
Martijn Coenenc28f1152016-08-22 14:06:56 +0200235#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
236 static ::android::sp<I##INTERFACE> getService( \
237 const ::android::String16 &serviceName, \
238 const hidl_version &version); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700239 status_t registerAsService( \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200240 const ::android::String16& serviceName, \
241 const hidl_version &version);
242
Steven Morelandbdf26662016-09-02 11:03:15 -0700243#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200244 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
245 const ::android::String16 &serviceName, \
246 const hidl_version &version /* TODO get version from IFoo directly */) \
247 { \
248 sp<I##INTERFACE> iface; \
249 const sp<IServiceManager> sm = defaultServiceManager(); \
250 if (sm != nullptr) { \
Steven Morelandbdf26662016-09-02 11:03:15 -0700251 sp<IBinder> binderIface = sm->checkService(serviceName, version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200252 iface = IHw##INTERFACE::asInterface(binderIface); \
253 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700254 if (iface != nullptr) { \
255 return iface; \
256 } \
257 int dlMode = RTLD_LAZY; \
258 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
259 if (handle == nullptr) { \
260 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
261 } \
262 if (handle == nullptr) { \
263 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
264 } \
265 if (handle == nullptr) { \
266 return iface; \
267 } \
268 I##INTERFACE* (*generator)(const char* name); \
269 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
270 if (generator) { \
271 iface = (*generator)(String8(serviceName).string()); \
272 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200273 return iface; \
274 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700275 status_t I##INTERFACE::registerAsService( \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200276 const ::android::String16& serviceName, \
277 const hidl_version &version) \
278 { \
279 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
280 const sp<IServiceManager> sm = defaultServiceManager(); \
281 return sm->addService(serviceName, binderIface, version); \
282 }
283
Martijn Coenen72110162016-08-19 14:28:25 +0200284} // namespace hardware
285} // namespace android
286
Martijn Coenenc28f1152016-08-22 14:06:56 +0200287
Martijn Coenen72110162016-08-19 14:28:25 +0200288#endif // ANDROID_HIDL_SUPPORT_H
289