blob: e4409e453baf856bd23f94bc4448acdca03261e2 [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>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070021#include <dirent.h>
Steven Morelandbdf26662016-09-02 11:03:15 -070022#include <dlfcn.h>
Martijn Coenen72110162016-08-19 14:28:25 +020023#include <hwbinder/Parcel.h>
Andreas Huber00a985c2016-09-28 14:24:53 -070024#include <tuple>
Iliyan Malchev692070a2016-09-12 16:30:44 -070025#include <utils/Errors.h>
26#include <utils/RefBase.h>
27#include <utils/StrongPointer.h>
Martijn Coenen72110162016-08-19 14:28:25 +020028
29namespace android {
30namespace hardware {
31
32struct hidl_string {
33 hidl_string();
34 ~hidl_string();
35
36 hidl_string(const hidl_string &);
37 hidl_string &operator=(const hidl_string &);
38
39 const char *c_str() const;
40 size_t size() const;
41 bool empty() const;
42
43 hidl_string &operator=(const char *s);
44 void clear();
45
46 // Reference an external char array. Ownership is _not_ transferred.
47 // Caller is responsible for ensuring that underlying memory is valid
48 // for the lifetime of this hidl_string.
49 void setToExternal(const char *data, size_t size);
50
51 status_t readEmbeddedFromParcel(
52 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
53
54 status_t writeEmbeddedToParcel(
55 Parcel *parcel, size_t parentHandle, size_t parentOffset) const;
56
Andreas Huberebfeb362016-08-25 13:39:05 -070057 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
58 static const size_t kOffsetOfBuffer;
59
Martijn Coenen72110162016-08-19 14:28:25 +020060private:
61 char *mBuffer;
62 size_t mSize; // NOT including the terminating '\0'.
63 bool mOwnsBuffer;
64
65 hidl_string &setTo(const char *data, size_t size);
66};
67
Andreas Huber20dce082016-09-22 19:39:13 -070068////////////////////////////////////////////////////////////////////////////////
69
Martijn Coenen72110162016-08-19 14:28:25 +020070template<typename T>
71struct hidl_vec {
72 hidl_vec()
73 : mBuffer(NULL),
74 mSize(0),
75 mOwnsBuffer(true) {
76 }
77
78 hidl_vec(const hidl_vec<T> &other)
79 : mBuffer(NULL),
80 mSize(0),
81 mOwnsBuffer(true) {
82 *this = other;
83 }
84
85 ~hidl_vec() {
86 if (mOwnsBuffer) {
87 delete[] mBuffer;
88 }
89 mBuffer = NULL;
90 }
91
92 // Reference an existing array _WITHOUT_ taking ownership. It is the
93 // caller's responsibility to ensure that the underlying memory stays
94 // valid for the lifetime of this hidl_vec.
95 void setToExternal(T *data, size_t size) {
96 if (mOwnsBuffer) {
97 delete [] mBuffer;
98 }
99 mBuffer = data;
100 mSize = size;
101 mOwnsBuffer = false;
102 }
103
104 hidl_vec &operator=(const hidl_vec &other) {
105 if (this != &other) {
106 if (mOwnsBuffer) {
107 delete[] mBuffer;
108 }
109 mBuffer = NULL;
110 mSize = other.mSize;
111 mOwnsBuffer = true;
112 if (mSize > 0) {
113 mBuffer = new T[mSize];
114 for (size_t i = 0; i < mSize; ++i) {
115 mBuffer[i] = other.mBuffer[i];
116 }
117 }
118 }
119
120 return *this;
121 }
122
123 size_t size() const {
124 return mSize;
125 }
126
127 T &operator[](size_t index) {
128 return mBuffer[index];
129 }
130
131 const T &operator[](size_t index) const {
132 return mBuffer[index];
133 }
134
135 void resize(size_t size) {
136 T *newBuffer = new T[size];
137
138 for (size_t i = 0; i < std::min(size, mSize); ++i) {
139 newBuffer[i] = mBuffer[i];
140 }
141
142 if (mOwnsBuffer) {
143 delete[] mBuffer;
144 }
145 mBuffer = newBuffer;
146
147 mSize = size;
148 mOwnsBuffer = true;
149 }
150
151 status_t readEmbeddedFromParcel(
152 const Parcel &parcel,
153 size_t parentHandle,
154 size_t parentOffset,
155 size_t *handle);
156
157 status_t writeEmbeddedToParcel(
158 Parcel *parcel,
159 size_t parentHandle,
160 size_t parentOffset,
161 size_t *handle) const;
162
163private:
164 T *mBuffer;
165 size_t mSize;
166 bool mOwnsBuffer;
167};
168
Andreas Huber20dce082016-09-22 19:39:13 -0700169////////////////////////////////////////////////////////////////////////////////
170
171namespace details {
172
173 template<size_t SIZE1, size_t... SIZES>
174 struct product {
175 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
176 };
177
178 template<size_t SIZE1>
179 struct product<SIZE1> {
180 static constexpr size_t value = SIZE1;
181 };
182
183 template<typename T, size_t SIZE1, size_t... SIZES>
184 struct accessor {
185 explicit accessor(T *base)
186 : mBase(base) {
187 }
188
189 accessor<T, SIZES...> operator[](size_t index) {
190 return accessor<T, SIZES...>(
191 &mBase[index * product<SIZES...>::value]);
192 }
193
194 private:
195 T *mBase;
196 };
197
198 template<typename T, size_t SIZE1>
199 struct accessor<T, SIZE1> {
200 explicit accessor(T *base)
201 : mBase(base) {
202 }
203
204 T &operator[](size_t index) {
205 return mBase[index];
206 }
207
208 private:
209 T *mBase;
210 };
211
212 template<typename T, size_t SIZE1, size_t... SIZES>
213 struct const_accessor {
214 explicit const_accessor(const T *base)
215 : mBase(base) {
216 }
217
218 const_accessor<T, SIZES...> operator[](size_t index) {
219 return const_accessor<T, SIZES...>(
220 &mBase[index * product<SIZES...>::value]);
221 }
222
223 private:
224 const T *mBase;
225 };
226
227 template<typename T, size_t SIZE1>
228 struct const_accessor<T, SIZE1> {
229 explicit const_accessor(const T *base)
230 : mBase(base) {
231 }
232
233 const T &operator[](size_t index) const {
234 return mBase[index];
235 }
236
237 private:
238 const T *mBase;
239 };
240
241} // namespace details
242
243////////////////////////////////////////////////////////////////////////////////
244
245template<typename T, size_t SIZE1, size_t... SIZES>
246struct hidl_array {
247 hidl_array() = default;
248
249 T *data() { return mBuffer; }
250 const T *data() const { return mBuffer; }
251
252 details::accessor<T, SIZES...> operator[](size_t index) {
253 return details::accessor<T, SIZES...>(
254 &mBuffer[index * details::product<SIZES...>::value]);
255 }
256
257 details::const_accessor<T, SIZES...> operator[](size_t index) const {
258 return details::const_accessor<T, SIZES...>(
259 &mBuffer[index * details::product<SIZES...>::value]);
260 }
261
Andreas Huber00a985c2016-09-28 14:24:53 -0700262 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
263
264 static constexpr size_tuple_type size() {
265 return std::make_tuple(SIZE1, SIZES...);
266 }
267
Andreas Huber20dce082016-09-22 19:39:13 -0700268private:
269 T mBuffer[details::product<SIZE1, SIZES...>::value];
270};
271
272template<typename T, size_t SIZE1>
273struct hidl_array<T, SIZE1> {
274 hidl_array() = default;
275
276 T *data() { return mBuffer; }
277 const T *data() const { return mBuffer; }
278
279 T &operator[](size_t index) {
280 return mBuffer[index];
281 }
282
283 const T &operator[](size_t index) const {
284 return mBuffer[index];
285 }
286
Andreas Huber00a985c2016-09-28 14:24:53 -0700287 static constexpr size_t size() { return SIZE1; }
288
Andreas Huber20dce082016-09-22 19:39:13 -0700289private:
290 T mBuffer[SIZE1];
291};
292
293////////////////////////////////////////////////////////////////////////////////
294
Martijn Coenen72110162016-08-19 14:28:25 +0200295template<typename T>
296status_t hidl_vec<T>::readEmbeddedFromParcel(
297 const Parcel &parcel,
298 size_t parentHandle,
299 size_t parentOffset,
300 size_t *handle) {
301 const void *ptr = parcel.readEmbeddedBuffer(
302 handle,
303 parentHandle,
304 parentOffset + offsetof(hidl_vec<T>, mBuffer));
305
306 return ptr != NULL ? OK : UNKNOWN_ERROR;
307}
308
309template<typename T>
310status_t hidl_vec<T>::writeEmbeddedToParcel(
311 Parcel *parcel,
312 size_t parentHandle,
313 size_t parentOffset,
314 size_t *handle) const {
315 return parcel->writeEmbeddedBuffer(
316 mBuffer,
317 sizeof(T) * mSize,
318 handle,
319 parentHandle,
320 parentOffset + offsetof(hidl_vec<T>, mBuffer));
321}
322
323// ----------------------------------------------------------------------
324// Version functions
325struct hidl_version {
326public:
Martijn Coenen097a7672016-09-08 16:56:41 +0200327 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {};
Martijn Coenen72110162016-08-19 14:28:25 +0200328
329 bool operator==(const hidl_version& other) {
330 return (mMajor == other.get_major() && mMinor == other.get_minor());
331 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200332
Martijn Coenen097a7672016-09-08 16:56:41 +0200333 constexpr uint16_t get_major() const { return mMajor; }
334 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200335
336 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
337 return parcel.writeUint32((uint32_t) mMajor << 16 | mMinor);
338 }
339
340 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
341 uint32_t version;
342 android::status_t status = parcel.readUint32(&version);
343 if (status != OK) {
344 return nullptr;
345 } else {
346 return new hidl_version(version >> 16, version & 0xFFFF);
347 }
348 }
349
350private:
351 uint16_t mMajor;
352 uint16_t mMinor;
353};
354
355inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
356 return hidl_version(major,minor);
357}
358
Steven Morelandbdf26662016-09-02 11:03:15 -0700359#if defined(__LP64__)
360#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
361#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
362#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
363#else
364#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
365#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
366#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
367#endif
368
Martijn Coenenc28f1152016-08-22 14:06:56 +0200369#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
370 static ::android::sp<I##INTERFACE> getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700371 const std::string &serviceName, bool getStub=false); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700372 status_t registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200373 const std::string &serviceName); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200374
Steven Morelandbdf26662016-09-02 11:03:15 -0700375#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE, LIB) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200376 ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700377 const std::string &serviceName, bool getStub) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200378 { \
379 sp<I##INTERFACE> iface; \
Iliyan Malchevb42ce262016-09-26 00:09:35 -0700380 const struct timespec DELAY {1,0}; \
381 unsigned retries = 3; \
382 if (!getStub) { \
383 do { \
384 const sp<IServiceManager> sm = defaultServiceManager(); \
385 if (sm != nullptr) { \
386 sp<IBinder> binderIface = \
387 sm->checkService(String16(serviceName.c_str()), \
388 I##INTERFACE::version); \
389 iface = IHw##INTERFACE::asInterface(binderIface); \
390 } \
391 if (iface != nullptr) { \
392 return iface; \
393 } \
394 TEMP_FAILURE_RETRY(nanosleep(&DELAY, nullptr)); \
395 } while (retries--); \
Steven Morelandbdf26662016-09-02 11:03:15 -0700396 } \
397 int dlMode = RTLD_LAZY; \
398 void *handle = dlopen(HAL_LIBRARY_PATH_ODM LIB, dlMode); \
399 if (handle == nullptr) { \
400 handle = dlopen(HAL_LIBRARY_PATH_VENDOR LIB, dlMode); \
401 } \
402 if (handle == nullptr) { \
403 handle = dlopen(HAL_LIBRARY_PATH_SYSTEM LIB, dlMode); \
404 } \
405 if (handle == nullptr) { \
406 return iface; \
407 } \
408 I##INTERFACE* (*generator)(const char* name); \
409 *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE); \
410 if (generator) { \
Martijn Coenenf7a651d2016-09-08 13:38:12 +0200411 iface = (*generator)(serviceName.c_str()); \
Steven Moreland7391bc32016-09-14 10:31:48 -0700412 if (iface != nullptr) { \
413 iface = new Bs##INTERFACE(iface); \
414 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700415 } \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200416 return iface; \
417 } \
Steven Morelandbdf26662016-09-02 11:03:15 -0700418 status_t I##INTERFACE::registerAsService( \
Martijn Coenen097a7672016-09-08 16:56:41 +0200419 const std::string &serviceName) \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200420 { \
421 sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
422 const sp<IServiceManager> sm = defaultServiceManager(); \
Martijn Coenen097a7672016-09-08 16:56:41 +0200423 return sm->addService(String16(serviceName.c_str()), binderIface, \
424 I##INTERFACE::version); \
Martijn Coenenc28f1152016-08-22 14:06:56 +0200425 }
426
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700427// ----------------------------------------------------------------------
428// Hidl instrumentation utilities.
429
430// Event that triggers the instrumentation. e.g. enter of an API call on
431// the server/client side, exit of an API call on the server/client side etc.
432enum InstrumentationEvent {
433 SERVER_API_ENTRY = 0,
434 SERVER_API_EXIT,
435 CLIENT_API_ENTRY,
436 CLIENT_API_EXIT,
437 SYNC_CALLBACK_ENTRY,
438 SYNC_CALLBACK_EXIT,
439 ASYNC_CALLBACK_ENTRY,
440 ASYNC_CALLBACK_EXIT,
441};
442
443// Signature of the instrumentation callback function.
444using InstrumentationCallback = std::function<void(
445 const InstrumentationEvent event,
446 const char *package,
447 const char *version,
448 const char *interface,
449 const char *method,
450 std::vector<void *> *args)>;
451
452// Function that lookup and dynamically loads the hidl instrumentation libraries
453// and registers the instrumentation callback functions.
454//
455// The instrumentation libraries should be stored under any of the following
456// directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
457// HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should follow
458// pattern: ^profilerPrefix(.*).profiler.so$
459//
460// Each instrumentation library is expected to implement the instrumentation
461// function called HIDL_INSTRUMENTATION_FUNCTION.
462//
463// A no-op for user build.
464void registerInstrumentationCallbacks(
465 const std::string &profilerPrefix,
466 std::vector<InstrumentationCallback> *instrumentationCallbacks);
467
468// Utility function to determine whether a give file is a instrumentation
469// library (i.e. the file name follow the expected pattern).
470bool isInstrumentationLib(
471 const std::string &profilerPrefix,
472 const dirent *file);
473
Martijn Coenen72110162016-08-19 14:28:25 +0200474} // namespace hardware
475} // namespace android
476
Martijn Coenenc28f1152016-08-22 14:06:56 +0200477
Martijn Coenen72110162016-08-19 14:28:25 +0200478#endif // ANDROID_HIDL_SUPPORT_H
479