blob: 8c864ca93893ab663080dbcf7adebd080b8184d2 [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:
Martijn Coenen097a7672016-09-08 16:56:41 +0200193 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {};
Martijn Coenen72110162016-08-19 14:28:25 +0200194
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 Coenen097a7672016-09-08 16:56:41 +0200199 constexpr uint16_t get_major() const { return mMajor; }
200 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200201
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( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200237 const std::string &serviceName); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700238 status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200239 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200240
Steven Morelandbdf26662016-09-02 11:03:15 -0700241#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200242 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200243 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200244 { \
245 sp<I##INTERFACE> iface; \
246 const sp<IServiceManager> sm = defaultServiceManager(); \
247 if (sm != nullptr) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200248 sp<IBinder> binderIface = sm->checkService(String16(serviceName.c_str()), \
Martijn Coenen097a7672016-09-08 16:56:41 +0200249 I##INTERFACE::version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200250 iface = IHw##INTERFACE::asInterface(binderIface); \
251 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700252 if (iface != nullptr) { \
253 return iface; \
254 } \
255 int dlMode = RTLD_LAZY; \
256 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
257 if (handle == nullptr) { \
258 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
259 } \
260 if (handle == nullptr) { \
261 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
262 } \
263 if (handle == nullptr) { \
264 return iface; \
265 } \
266 I##INTERFACE* (*generator)(const char* name); \
267 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
268 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200269 iface = (*generator)(serviceName.c_str()); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700270 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200271 return iface; \
272 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700273 status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200274 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200275 { \
276 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
277 const sp<IServiceManager> sm = defaultServiceManager(); \
Martijn Coenen097a7672016-09-08 16:56:41 +0200278 return sm->addService(String16(serviceName.c_str()), binderIface, \
279 I##INTERFACE::version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200280 }
281
Martijn Coenen72110162016-08-19 14:28:25 +0200282} // namespace hardware
283} // namespace android
284
Martijn Coenenc28f1152016-08-22 14:06:56 +0200285
Martijn Coenen72110162016-08-19 14:28:25 +0200286#endif // ANDROID_HIDL_SUPPORT_H
287