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