blob: 17951f776878b015c6ecfa8529af69d9070a611f [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>
Yifan Hong44ab6232016-11-22 16:28:24 -080021#include <array>
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -070022#include <dirent.h>
Scott Randolphbb840f72016-11-21 14:39:26 -080023#include <iterator>
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +010024#include <cutils/native_handle.h>
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -070025#include <cutils/properties.h>
Yifan Hong1e265bb2016-11-08 12:33:44 -080026#include <functional>
Steven Moreland337c3ae2016-11-22 13:37:32 -080027#include <hidl/HidlInternal.h>
Yifan Honga3c31842016-10-21 10:33:14 -070028#include <hidl/Status.h>
Yifan Hong1e265bb2016-11-08 12:33:44 -080029#include <map>
Yifan Hongbe7a6882017-01-05 17:30:17 -080030#include <sstream>
Yifan Hong64fdf4d2016-12-09 16:22:45 -080031#include <stddef.h>
Andreas Huber00a985c2016-09-28 14:24:53 -070032#include <tuple>
Yifan Hong64fdf4d2016-12-09 16:22:45 -080033#include <type_traits>
Iliyan Malchev692070a2016-09-12 16:30:44 -070034#include <utils/Errors.h>
35#include <utils/RefBase.h>
36#include <utils/StrongPointer.h>
Yifan Hong44c0e572017-01-20 15:41:52 -080037#include <vintf/Transport.h>
Yifan Hong7f97f442016-11-14 18:31:05 -080038#include <vector>
Martijn Coenen72110162016-08-19 14:28:25 +020039
40namespace android {
Martijn Coenen30791002016-12-01 15:40:46 +010041
Martijn Coenen9b8f9c32016-12-09 15:51:06 +010042// this file is included by all hidl interface, so we must forward declare the
43// IMemory and IBase types.
Martijn Coenen30791002016-12-01 15:40:46 +010044namespace hidl {
45namespace memory {
46namespace V1_0 {
47 struct IMemory;
48}; // namespace V1_0
49}; // namespace manager
50}; // namespace hidl
51
Martijn Coenen9b8f9c32016-12-09 15:51:06 +010052namespace hidl {
53namespace base {
54namespace V1_0 {
55 struct IBase;
56}; // namespace V1_0
57}; // namespace base
58}; // namespace hidl
59
Martijn Coenen72110162016-08-19 14:28:25 +020060namespace hardware {
61
Yifan Hong44c0e572017-01-20 15:41:52 -080062// Get transport method from vendor interface manifest.
Yifan Hong20273f92017-01-30 14:13:19 -080063// name has the format "android.hardware.foo@1.0::IFoo"
64// If it starts with "android.hidl.", a static map is looked up instead.
65vintf::Transport getTransport(const std::string &name);
Yifan Hong44c0e572017-01-20 15:41:52 -080066
Martijn Coenen9b8f9c32016-12-09 15:51:06 +010067// hidl_death_recipient is a callback interfaced that can be used with
68// linkToDeath() / unlinkToDeath()
69struct hidl_death_recipient : public virtual RefBase {
70 virtual void serviceDied(uint64_t cookie,
71 const ::android::wp<::android::hidl::base::V1_0::IBase>& who) = 0;
72};
73
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +010074// hidl_handle wraps a pointer to a native_handle_t in a hidl_pointer,
75// so that it can safely be transferred between 32-bit and 64-bit processes.
Martijn Coenen04b91c02017-01-19 14:14:21 +010076// The ownership semantics for this are:
77// 1) The conversion constructor and assignment operator taking a const native_handle_t*
78// do not take ownership of the handle; this is because these operations are usually
79// just done for IPC, and cloning by default is a waste of resources. If you want
80// a hidl_handle to take ownership, call setTo(handle, true /*shouldOwn*/);
81// 2) The copy constructor/assignment operator taking a hidl_handle *DO* take ownership;
82// that is because it's not intuitive that this class encapsulates a native_handle_t
83// which needs cloning to be valid; in particular, this allows constructs like this:
84// hidl_handle copy;
85// foo->someHidlCall([&](auto incoming_handle) {
86// copy = incoming_handle;
87// });
88// // copy and its enclosed file descriptors will remain valid here.
89// 3) The move constructor does what you would expect; it only owns the handle if the
90// original did.
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +010091struct hidl_handle {
Martijn Coenen04b91c02017-01-19 14:14:21 +010092 hidl_handle();
93 ~hidl_handle();
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +010094
Martijn Coenen04b91c02017-01-19 14:14:21 +010095 hidl_handle(const native_handle_t *handle);
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +010096
Martijn Coenen04b91c02017-01-19 14:14:21 +010097 // copy constructor.
98 hidl_handle(const hidl_handle &other);
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +010099
100 // move constructor.
Martijn Coenen04b91c02017-01-19 14:14:21 +0100101 hidl_handle(hidl_handle &&other);
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +0100102
Steven Moreland6ffdc2a2017-01-23 12:34:33 -0800103 // assignment operators
Martijn Coenen04b91c02017-01-19 14:14:21 +0100104 hidl_handle &operator=(const hidl_handle &other);
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +0100105
Martijn Coenen04b91c02017-01-19 14:14:21 +0100106 hidl_handle &operator=(const native_handle_t *native_handle);
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +0100107
Martijn Coenen04b91c02017-01-19 14:14:21 +0100108 hidl_handle &operator=(hidl_handle &&other);
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +0100109
Martijn Coenen04b91c02017-01-19 14:14:21 +0100110 void setTo(native_handle_t* handle, bool shouldOwn = false);
111
112 const native_handle_t* operator->() const;
113
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +0100114 // implicit conversion to const native_handle_t*
Martijn Coenen04b91c02017-01-19 14:14:21 +0100115 operator const native_handle_t *() const;
116
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +0100117 // explicit conversion
Martijn Coenen04b91c02017-01-19 14:14:21 +0100118 const native_handle_t *getNativeHandle() const;
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +0100119private:
Martijn Coenen04b91c02017-01-19 14:14:21 +0100120 void freeHandle();
121
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +0100122 details::hidl_pointer<const native_handle_t> mHandle;
Martijn Coenen04b91c02017-01-19 14:14:21 +0100123 bool mOwnsHandle;
Martijn Coenen4d1e9cc2016-11-18 15:20:18 +0100124};
125
Martijn Coenen72110162016-08-19 14:28:25 +0200126struct hidl_string {
127 hidl_string();
128 ~hidl_string();
129
Yifan Hong602b85a2016-10-24 13:40:01 -0700130 // copy constructor.
Martijn Coenen72110162016-08-19 14:28:25 +0200131 hidl_string(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -0700132 // copy from a C-style string.
Steven Morelande03c0872016-10-24 10:43:50 -0700133 hidl_string(const char *);
Steven Moreland53120f72017-01-12 09:39:26 -0800134 // copy the first length characters from a C-style string.
135 hidl_string(const char *, size_t length);
Yifan Hong602b85a2016-10-24 13:40:01 -0700136 // copy from an std::string.
137 hidl_string(const std::string &);
138
139 // move constructor.
140 hidl_string(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +0200141
142 const char *c_str() const;
143 size_t size() const;
144 bool empty() const;
145
Yifan Hong602b85a2016-10-24 13:40:01 -0700146 // copy assignment operator.
Steven Morelande03c0872016-10-24 10:43:50 -0700147 hidl_string &operator=(const hidl_string &);
Yifan Hong602b85a2016-10-24 13:40:01 -0700148 // copy from a C-style string.
Martijn Coenen72110162016-08-19 14:28:25 +0200149 hidl_string &operator=(const char *s);
Yifan Hong602b85a2016-10-24 13:40:01 -0700150 // copy from an std::string.
151 hidl_string &operator=(const std::string &);
152 // move assignment operator.
153 hidl_string &operator=(hidl_string &&other);
154 // cast to std::string.
155 operator std::string() const;
156 // cast to C-style string. Caller is responsible
157 // to maintain this hidl_string alive.
158 operator const char *() const;
Steven Morelande03c0872016-10-24 10:43:50 -0700159
Steven Morelanda2a81842017-01-20 14:48:15 -0800160 bool operator< (const hidl_string &rhs) const;
161
Martijn Coenen72110162016-08-19 14:28:25 +0200162 void clear();
163
164 // Reference an external char array. Ownership is _not_ transferred.
165 // Caller is responsible for ensuring that underlying memory is valid
166 // for the lifetime of this hidl_string.
167 void setToExternal(const char *data, size_t size);
168
Andreas Huberebfeb362016-08-25 13:39:05 -0700169 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
170 static const size_t kOffsetOfBuffer;
171
Martijn Coenen72110162016-08-19 14:28:25 +0200172private:
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100173 details::hidl_pointer<const char> mBuffer;
174 uint32_t mSize; // NOT including the terminating '\0'.
Yifan Hong602b85a2016-10-24 13:40:01 -0700175 bool mOwnsBuffer; // if true then mBuffer is a mutable char *
Martijn Coenen72110162016-08-19 14:28:25 +0200176
Yifan Hong602b85a2016-10-24 13:40:01 -0700177 // copy from data with size. Assume that my memory is freed
178 // (through clear(), for example)
179 void copyFrom(const char *data, size_t size);
180 // move from another hidl_string
181 void moveFrom(hidl_string &&);
Martijn Coenen72110162016-08-19 14:28:25 +0200182};
183
Scott Randolphbb840f72016-11-21 14:39:26 -0800184inline bool operator==(const hidl_string &hs1, const hidl_string &hs2) {
185 return strcmp(hs1.c_str(), hs2.c_str()) == 0;
186}
187
188inline bool operator!=(const hidl_string &hs1, const hidl_string &hs2) {
189 return !(hs1 == hs2);
190}
191
Yifan Hong5708fb42016-10-26 17:50:29 -0700192inline bool operator==(const hidl_string &hs, const char *s) {
193 return strcmp(hs.c_str(), s) == 0;
194}
195
196inline bool operator!=(const hidl_string &hs, const char *s) {
197 return !(hs == s);
198}
199
200inline bool operator==(const char *s, const hidl_string &hs) {
201 return strcmp(hs.c_str(), s) == 0;
202}
203
204inline bool operator!=(const char *s, const hidl_string &hs) {
205 return !(s == hs);
206}
207
Martijn Coenen30791002016-12-01 15:40:46 +0100208// hidl_memory is a structure that can be used to transfer
209// pieces of shared memory between processes. The assumption
210// of this object is that the memory remains accessible as
211// long as the file descriptors in the enclosed mHandle
212// - as well as all of its cross-process dups() - remain opened.
213struct hidl_memory {
214
Martijn Coenen04b91c02017-01-19 14:14:21 +0100215 hidl_memory() : mHandle(nullptr), mSize(0), mName("") {
Martijn Coenen30791002016-12-01 15:40:46 +0100216 }
217
218 /**
Martijn Coenen04b91c02017-01-19 14:14:21 +0100219 * Creates a hidl_memory object, but doesn't take ownership of
220 * the passed in native_handle_t; callers are responsible for
221 * making sure the handle remains valid while this object is
222 * used.
Martijn Coenen30791002016-12-01 15:40:46 +0100223 */
Martijn Coenen04b91c02017-01-19 14:14:21 +0100224 hidl_memory(const hidl_string &name, const native_handle_t *handle, size_t size)
225 : mHandle(handle),
Martijn Coenen30791002016-12-01 15:40:46 +0100226 mSize(size),
227 mName(name)
228 {}
229
230 // copy constructor
231 hidl_memory(const hidl_memory& other) {
232 *this = other;
233 }
234
235 // copy assignment
236 hidl_memory &operator=(const hidl_memory &other) {
237 if (this != &other) {
Martijn Coenen04b91c02017-01-19 14:14:21 +0100238 mHandle = other.mHandle;
Martijn Coenen30791002016-12-01 15:40:46 +0100239 mSize = other.mSize;
240 mName = other.mName;
241 }
242
243 return *this;
244 }
245
246 // TODO move constructor/move assignment
247
248 ~hidl_memory() {
Martijn Coenen30791002016-12-01 15:40:46 +0100249 }
250
251 const native_handle_t* handle() const {
252 return mHandle;
253 }
254
255 const hidl_string &name() const {
256 return mName;
257 }
258
259 size_t size() const {
260 return mSize;
261 }
262
263 // offsetof(hidl_memory, mHandle) exposed since mHandle is private.
264 static const size_t kOffsetOfHandle;
265 // offsetof(hidl_memory, mName) exposed since mHandle is private.
266 static const size_t kOffsetOfName;
Jeff Tinker0f3461d2017-01-03 10:40:55 -0800267
Martijn Coenen30791002016-12-01 15:40:46 +0100268private:
Martijn Coenen30791002016-12-01 15:40:46 +0100269 hidl_handle mHandle;
270 size_t mSize;
271 hidl_string mName;
272};
273
Andreas Huber20dce082016-09-22 19:39:13 -0700274////////////////////////////////////////////////////////////////////////////////
275
Martijn Coenen72110162016-08-19 14:28:25 +0200276template<typename T>
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100277struct hidl_vec : private details::hidl_log_base {
Martijn Coenen72110162016-08-19 14:28:25 +0200278 hidl_vec()
279 : mBuffer(NULL),
280 mSize(0),
281 mOwnsBuffer(true) {
282 }
283
Yifan Hong602b85a2016-10-24 13:40:01 -0700284 hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
Martijn Coenen72110162016-08-19 14:28:25 +0200285 *this = other;
286 }
287
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100288 hidl_vec(hidl_vec<T> &&other)
Steven Moreland9fbfe472016-11-14 16:49:17 -0800289 : mOwnsBuffer(false) {
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100290 *this = std::move(other);
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700291 }
292
Steven Morelandb69926a2016-11-15 10:02:57 -0800293 hidl_vec(const std::initializer_list<T> list)
Yifan Hongca1d1bf2016-12-19 14:26:19 -0800294 : mOwnsBuffer(true) {
295 if (list.size() > UINT32_MAX) {
296 logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
297 }
298 mSize = static_cast<uint32_t>(list.size());
Steven Moreland9fbfe472016-11-14 16:49:17 -0800299 mBuffer = new T[mSize];
300
Steven Morelandb69926a2016-11-15 10:02:57 -0800301 size_t idx = 0;
Steven Moreland9fbfe472016-11-14 16:49:17 -0800302 for (auto it = list.begin(); it != list.end(); ++it) {
303 mBuffer[idx++] = *it;
304 }
305 }
306
Yifan Hong602b85a2016-10-24 13:40:01 -0700307 hidl_vec(const std::vector<T> &other) : hidl_vec() {
308 *this = other;
309 }
310
Martijn Coenen72110162016-08-19 14:28:25 +0200311 ~hidl_vec() {
312 if (mOwnsBuffer) {
313 delete[] mBuffer;
314 }
315 mBuffer = NULL;
316 }
317
Alexey Polyudove2299012016-10-19 09:52:00 -0700318 // Reference an existing array, optionally taking ownership. It is the
Martijn Coenen72110162016-08-19 14:28:25 +0200319 // caller's responsibility to ensure that the underlying memory stays
320 // valid for the lifetime of this hidl_vec.
Alexey Polyudove2299012016-10-19 09:52:00 -0700321 void setToExternal(T *data, size_t size, bool shouldOwn = false) {
Martijn Coenen72110162016-08-19 14:28:25 +0200322 if (mOwnsBuffer) {
323 delete [] mBuffer;
324 }
325 mBuffer = data;
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100326 if (size > UINT32_MAX) {
327 logAlwaysFatal("external vector size exceeds 2^32 elements.");
328 }
329 mSize = static_cast<uint32_t>(size);
Alexey Polyudove2299012016-10-19 09:52:00 -0700330 mOwnsBuffer = shouldOwn;
Martijn Coenen72110162016-08-19 14:28:25 +0200331 }
332
Alexey Polyudov6f0c9a12016-10-18 09:37:35 -0700333 T *data() {
334 return mBuffer;
335 }
336
337 const T *data() const {
338 return mBuffer;
339 }
340
Alexey Polyudovc98a99c2016-10-18 09:43:56 -0700341 T *releaseData() {
342 if (!mOwnsBuffer && mSize > 0) {
343 resize(mSize);
344 }
345 mOwnsBuffer = false;
346 return mBuffer;
347 }
348
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700349 hidl_vec &operator=(hidl_vec &&other) {
Janis Danisevskisd3ddf622016-10-24 11:40:50 +0100350 if (mOwnsBuffer) {
351 delete[] mBuffer;
352 }
Alexey Polyudov0ebdbe82016-10-18 09:31:46 -0700353 mBuffer = other.mBuffer;
354 mSize = other.mSize;
355 mOwnsBuffer = other.mOwnsBuffer;
356 other.mOwnsBuffer = false;
357 return *this;
358 }
359
Martijn Coenen72110162016-08-19 14:28:25 +0200360 hidl_vec &operator=(const hidl_vec &other) {
361 if (this != &other) {
362 if (mOwnsBuffer) {
363 delete[] mBuffer;
364 }
Yifan Hong602b85a2016-10-24 13:40:01 -0700365 copyFrom(other, other.mSize);
Martijn Coenen72110162016-08-19 14:28:25 +0200366 }
367
368 return *this;
369 }
370
Yifan Hong602b85a2016-10-24 13:40:01 -0700371 // copy from an std::vector.
372 hidl_vec &operator=(const std::vector<T> &other) {
373 if (mOwnsBuffer) {
374 delete[] mBuffer;
375 }
376 copyFrom(other, other.size());
377 return *this;
378 }
379
380 // cast to an std::vector.
381 operator std::vector<T>() const {
382 std::vector<T> v(mSize);
383 for (size_t i = 0; i < mSize; ++i) {
384 v[i] = mBuffer[i];
385 }
386 return v;
387 }
388
Yifan Hong9fcbb362016-12-20 16:46:41 -0800389 // equality check, assuming that T::operator== is defined.
390 bool operator==(const hidl_vec &other) const {
391 if (mSize != other.size()) {
392 return false;
393 }
394 for (size_t i = 0; i < mSize; ++i) {
395 if (!(mBuffer[i] == other.mBuffer[i])) {
396 return false;
397 }
398 }
399 return true;
400 }
401
402 // inequality check, assuming that T::operator== is defined.
403 inline bool operator!=(const hidl_vec &other) const {
404 return !((*this) == other);
405 }
406
Martijn Coenen72110162016-08-19 14:28:25 +0200407 size_t size() const {
408 return mSize;
409 }
410
411 T &operator[](size_t index) {
412 return mBuffer[index];
413 }
414
415 const T &operator[](size_t index) const {
416 return mBuffer[index];
417 }
418
419 void resize(size_t size) {
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100420 if (size > UINT32_MAX) {
421 logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
422 }
Martijn Coenen72110162016-08-19 14:28:25 +0200423 T *newBuffer = new T[size];
424
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100425 for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
Martijn Coenen72110162016-08-19 14:28:25 +0200426 newBuffer[i] = mBuffer[i];
427 }
428
429 if (mOwnsBuffer) {
430 delete[] mBuffer;
431 }
432 mBuffer = newBuffer;
433
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100434 mSize = static_cast<uint32_t>(size);
Martijn Coenen72110162016-08-19 14:28:25 +0200435 mOwnsBuffer = true;
436 }
437
Yifan Hong089ae132016-11-11 11:32:52 -0800438 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
439 static const size_t kOffsetOfBuffer;
Scott Randolphbb840f72016-11-21 14:39:26 -0800440
Yifan Hong64fdf4d2016-12-09 16:22:45 -0800441private:
Scott Randolphbb840f72016-11-21 14:39:26 -0800442 // Define std interator interface for walking the array contents
Yifan Hong64fdf4d2016-12-09 16:22:45 -0800443 template<bool is_const>
444 class iter : public std::iterator<
445 std::random_access_iterator_tag, /* Category */
446 T,
447 ptrdiff_t, /* Distance */
448 typename std::conditional<is_const, const T *, T *>::type /* Pointer */,
449 typename std::conditional<is_const, const T &, T &>::type /* Reference */>
Scott Randolphbb840f72016-11-21 14:39:26 -0800450 {
Yifan Hong64fdf4d2016-12-09 16:22:45 -0800451 using traits = std::iterator_traits<iter>;
452 using ptr_type = typename traits::pointer;
453 using ref_type = typename traits::reference;
454 using diff_type = typename traits::difference_type;
Scott Randolphbb840f72016-11-21 14:39:26 -0800455 public:
Yifan Hong64fdf4d2016-12-09 16:22:45 -0800456 iter(ptr_type ptr) : mPtr(ptr) { }
457 inline iter &operator++() { mPtr++; return *this; }
458 inline iter operator++(int) { iter i = *this; mPtr++; return i; }
459 inline iter &operator--() { mPtr--; return *this; }
460 inline iter operator--(int) { iter i = *this; mPtr--; return i; }
461 inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; }
462 inline iter operator+(diff_type n) const { return mPtr + n; }
463 inline iter operator-(diff_type n) const { return mPtr - n; }
464 inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; }
465 inline iter &operator+=(diff_type n) { mPtr += n; return *this; }
466 inline iter &operator-=(diff_type n) { mPtr -= n; return *this; }
467 inline ref_type operator*() const { return *mPtr; }
468 inline ptr_type operator->() const { return mPtr; }
469 inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
470 inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
471 inline bool operator< (const iter &rhs) const { return mPtr < rhs.mPtr; }
472 inline bool operator> (const iter &rhs) const { return mPtr > rhs.mPtr; }
473 inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; }
474 inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; }
475 inline ref_type operator[](size_t n) const { return mPtr[n]; }
Scott Randolphbb840f72016-11-21 14:39:26 -0800476 private:
Yifan Hong64fdf4d2016-12-09 16:22:45 -0800477 ptr_type mPtr;
Scott Randolphbb840f72016-11-21 14:39:26 -0800478 };
Yifan Hong64fdf4d2016-12-09 16:22:45 -0800479public:
480 using iterator = iter<false /* is_const */>;
481 using const_iterator = iter<true /* is_const */>;
482
Scott Randolphbb840f72016-11-21 14:39:26 -0800483 iterator begin() { return data(); }
484 iterator end() { return data()+mSize; }
Yifan Hong64fdf4d2016-12-09 16:22:45 -0800485 const_iterator begin() const { return data(); }
486 const_iterator end() const { return data()+mSize; }
Scott Randolphbb840f72016-11-21 14:39:26 -0800487
Martijn Coenen72110162016-08-19 14:28:25 +0200488private:
Martijn Coenen4ca39a02016-11-11 15:58:51 +0100489 details::hidl_pointer<T> mBuffer;
490 uint32_t mSize;
Martijn Coenen72110162016-08-19 14:28:25 +0200491 bool mOwnsBuffer;
Yifan Hong602b85a2016-10-24 13:40:01 -0700492
493 // copy from an array-like object, assuming my resources are freed.
494 template <typename Array>
495 void copyFrom(const Array &data, size_t size) {
Chia-I Wu4b48edc2016-12-07 22:31:17 +0800496 mSize = static_cast<uint32_t>(size);
Yifan Hong602b85a2016-10-24 13:40:01 -0700497 mOwnsBuffer = true;
498 if (mSize > 0) {
499 mBuffer = new T[size];
500 for (size_t i = 0; i < size; ++i) {
501 mBuffer[i] = data[i];
502 }
503 } else {
504 mBuffer = NULL;
505 }
506 }
Martijn Coenen72110162016-08-19 14:28:25 +0200507};
508
Yifan Hong089ae132016-11-11 11:32:52 -0800509template <typename T>
510const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
511
Andreas Huber20dce082016-09-22 19:39:13 -0700512////////////////////////////////////////////////////////////////////////////////
513
514namespace details {
515
516 template<size_t SIZE1, size_t... SIZES>
517 struct product {
518 static constexpr size_t value = SIZE1 * product<SIZES...>::value;
519 };
520
521 template<size_t SIZE1>
522 struct product<SIZE1> {
523 static constexpr size_t value = SIZE1;
524 };
525
526 template<typename T, size_t SIZE1, size_t... SIZES>
Yifan Hong44ab6232016-11-22 16:28:24 -0800527 struct std_array {
528 using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
529 };
530
531 template<typename T, size_t SIZE1>
532 struct std_array<T, SIZE1> {
533 using type = std::array<T, SIZE1>;
534 };
535
536 template<typename T, size_t SIZE1, size_t... SIZES>
Andreas Huber20dce082016-09-22 19:39:13 -0700537 struct accessor {
Yifan Hong44ab6232016-11-22 16:28:24 -0800538
539 using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
540
Andreas Huber20dce082016-09-22 19:39:13 -0700541 explicit accessor(T *base)
542 : mBase(base) {
543 }
544
545 accessor<T, SIZES...> operator[](size_t index) {
546 return accessor<T, SIZES...>(
547 &mBase[index * product<SIZES...>::value]);
548 }
549
Yifan Hong44ab6232016-11-22 16:28:24 -0800550 accessor &operator=(const std_array_type &other) {
551 for (size_t i = 0; i < SIZE1; ++i) {
552 (*this)[i] = other[i];
553 }
554 return *this;
555 }
556
Andreas Huber20dce082016-09-22 19:39:13 -0700557 private:
558 T *mBase;
559 };
560
561 template<typename T, size_t SIZE1>
562 struct accessor<T, SIZE1> {
Yifan Hong44ab6232016-11-22 16:28:24 -0800563
564 using std_array_type = typename std_array<T, SIZE1>::type;
565
Andreas Huber20dce082016-09-22 19:39:13 -0700566 explicit accessor(T *base)
567 : mBase(base) {
568 }
569
570 T &operator[](size_t index) {
571 return mBase[index];
572 }
573
Yifan Hong44ab6232016-11-22 16:28:24 -0800574 accessor &operator=(const std_array_type &other) {
575 for (size_t i = 0; i < SIZE1; ++i) {
576 (*this)[i] = other[i];
577 }
578 return *this;
579 }
580
Andreas Huber20dce082016-09-22 19:39:13 -0700581 private:
582 T *mBase;
583 };
584
585 template<typename T, size_t SIZE1, size_t... SIZES>
586 struct const_accessor {
Yifan Hong44ab6232016-11-22 16:28:24 -0800587
588 using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
589
Andreas Huber20dce082016-09-22 19:39:13 -0700590 explicit const_accessor(const T *base)
591 : mBase(base) {
592 }
593
Yifan Hongbe7a6882017-01-05 17:30:17 -0800594 const_accessor<T, SIZES...> operator[](size_t index) const {
Andreas Huber20dce082016-09-22 19:39:13 -0700595 return const_accessor<T, SIZES...>(
596 &mBase[index * product<SIZES...>::value]);
597 }
598
Yifan Hong44ab6232016-11-22 16:28:24 -0800599 operator std_array_type() {
600 std_array_type array;
601 for (size_t i = 0; i < SIZE1; ++i) {
602 array[i] = (*this)[i];
603 }
604 return array;
605 }
606
Andreas Huber20dce082016-09-22 19:39:13 -0700607 private:
608 const T *mBase;
609 };
610
611 template<typename T, size_t SIZE1>
612 struct const_accessor<T, SIZE1> {
Yifan Hong44ab6232016-11-22 16:28:24 -0800613
614 using std_array_type = typename std_array<T, SIZE1>::type;
615
Andreas Huber20dce082016-09-22 19:39:13 -0700616 explicit const_accessor(const T *base)
617 : mBase(base) {
618 }
619
620 const T &operator[](size_t index) const {
621 return mBase[index];
622 }
623
Yifan Hong44ab6232016-11-22 16:28:24 -0800624 operator std_array_type() {
625 std_array_type array;
626 for (size_t i = 0; i < SIZE1; ++i) {
627 array[i] = (*this)[i];
628 }
629 return array;
630 }
631
Andreas Huber20dce082016-09-22 19:39:13 -0700632 private:
633 const T *mBase;
634 };
635
636} // namespace details
637
638////////////////////////////////////////////////////////////////////////////////
639
Yifan Hong44ab6232016-11-22 16:28:24 -0800640// A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
Andreas Huber20dce082016-09-22 19:39:13 -0700641template<typename T, size_t SIZE1, size_t... SIZES>
642struct hidl_array {
Yifan Hong44ab6232016-11-22 16:28:24 -0800643
644 using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
645
Andreas Huber20dce082016-09-22 19:39:13 -0700646 hidl_array() = default;
647
Yifan Hong44ab6232016-11-22 16:28:24 -0800648 // Copies the data from source, using T::operator=(const T &).
649 hidl_array(const T *source) {
650 for (size_t i = 0; i < elementCount(); ++i) {
651 mBuffer[i] = source[i];
652 }
653 }
654
655 // Copies the data from the given std::array, using T::operator=(const T &).
656 hidl_array(const std_array_type &array) {
657 details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
658 modifier = array;
659 }
660
Andreas Huber20dce082016-09-22 19:39:13 -0700661 T *data() { return mBuffer; }
662 const T *data() const { return mBuffer; }
663
664 details::accessor<T, SIZES...> operator[](size_t index) {
665 return details::accessor<T, SIZES...>(
666 &mBuffer[index * details::product<SIZES...>::value]);
667 }
668
669 details::const_accessor<T, SIZES...> operator[](size_t index) const {
670 return details::const_accessor<T, SIZES...>(
671 &mBuffer[index * details::product<SIZES...>::value]);
672 }
673
Yifan Hong9fcbb362016-12-20 16:46:41 -0800674 // equality check, assuming that T::operator== is defined.
675 bool operator==(const hidl_array &other) const {
676 for (size_t i = 0; i < elementCount(); ++i) {
677 if (!(mBuffer[i] == other.mBuffer[i])) {
678 return false;
679 }
680 }
681 return true;
682 }
683
684 inline bool operator!=(const hidl_array &other) const {
685 return !((*this) == other);
686 }
687
Andreas Huber00a985c2016-09-28 14:24:53 -0700688 using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
689
690 static constexpr size_tuple_type size() {
691 return std::make_tuple(SIZE1, SIZES...);
692 }
693
Yifan Hong44ab6232016-11-22 16:28:24 -0800694 static constexpr size_t elementCount() {
695 return details::product<SIZE1, SIZES...>::value;
696 }
697
698 operator std_array_type() const {
699 return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
700 }
701
Andreas Huber20dce082016-09-22 19:39:13 -0700702private:
Yifan Hong44ab6232016-11-22 16:28:24 -0800703 T mBuffer[elementCount()];
Andreas Huber20dce082016-09-22 19:39:13 -0700704};
705
Yifan Hong44ab6232016-11-22 16:28:24 -0800706// An array of T's. Assumes that T::operator=(const T &) is defined.
Andreas Huber20dce082016-09-22 19:39:13 -0700707template<typename T, size_t SIZE1>
708struct hidl_array<T, SIZE1> {
Yifan Hong44ab6232016-11-22 16:28:24 -0800709
710 using std_array_type = typename details::std_array<T, SIZE1>::type;
711
Andreas Huber20dce082016-09-22 19:39:13 -0700712 hidl_array() = default;
Yifan Hong44ab6232016-11-22 16:28:24 -0800713
714 // Copies the data from source, using T::operator=(const T &).
Sasha Levitskiy3da68482016-11-17 16:48:43 -0800715 hidl_array(const T *source) {
Yifan Hong44ab6232016-11-22 16:28:24 -0800716 for (size_t i = 0; i < elementCount(); ++i) {
717 mBuffer[i] = source[i];
718 }
Sasha Levitskiy3da68482016-11-17 16:48:43 -0800719 }
Andreas Huber20dce082016-09-22 19:39:13 -0700720
Yifan Hong44ab6232016-11-22 16:28:24 -0800721 // Copies the data from the given std::array, using T::operator=(const T &).
722 hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
723
Andreas Huber20dce082016-09-22 19:39:13 -0700724 T *data() { return mBuffer; }
725 const T *data() const { return mBuffer; }
726
727 T &operator[](size_t index) {
728 return mBuffer[index];
729 }
730
731 const T &operator[](size_t index) const {
732 return mBuffer[index];
733 }
734
Yifan Hong9fcbb362016-12-20 16:46:41 -0800735 // equality check, assuming that T::operator== is defined.
736 bool operator==(const hidl_array &other) const {
737 for (size_t i = 0; i < elementCount(); ++i) {
738 if (!(mBuffer[i] == other.mBuffer[i])) {
739 return false;
740 }
741 }
742 return true;
743 }
744
745 inline bool operator!=(const hidl_array &other) const {
746 return !((*this) == other);
747 }
748
Andreas Huber00a985c2016-09-28 14:24:53 -0700749 static constexpr size_t size() { return SIZE1; }
Yifan Hong44ab6232016-11-22 16:28:24 -0800750 static constexpr size_t elementCount() { return SIZE1; }
751
752 // Copies the data to an std::array, using T::operator=(T).
753 operator std_array_type() const {
754 std_array_type array;
755 for (size_t i = 0; i < SIZE1; ++i) {
756 array[i] = mBuffer[i];
757 }
758 return array;
759 }
Andreas Huber00a985c2016-09-28 14:24:53 -0700760
Andreas Huber20dce082016-09-22 19:39:13 -0700761private:
762 T mBuffer[SIZE1];
763};
764
Martijn Coenen72110162016-08-19 14:28:25 +0200765// ----------------------------------------------------------------------
766// Version functions
767struct hidl_version {
768public:
Chia-I Wu666b76b2016-10-06 14:15:59 +0800769 constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
Martijn Coenen72110162016-08-19 14:28:25 +0200770
Steven Moreland5d5ef7f2016-10-20 19:19:55 -0700771 bool operator==(const hidl_version& other) const {
Martijn Coenen72110162016-08-19 14:28:25 +0200772 return (mMajor == other.get_major() && mMinor == other.get_minor());
773 }
Martijn Coenenc28f1152016-08-22 14:06:56 +0200774
Eino-Ville Talvala19f4db52016-12-14 15:19:28 -0800775 bool operator<(const hidl_version& other) const {
776 return (mMajor < other.get_major() ||
777 (mMajor == other.get_major() && mMinor < other.get_minor()));
778 }
779
780 bool operator>(const hidl_version& other) const {
781 return other < *this;
782 }
783
784 bool operator<=(const hidl_version& other) const {
785 return !(*this > other);
786 }
787
788 bool operator>=(const hidl_version& other) const {
789 return !(*this < other);
790 }
791
Martijn Coenen097a7672016-09-08 16:56:41 +0200792 constexpr uint16_t get_major() const { return mMajor; }
793 constexpr uint16_t get_minor() const { return mMinor; }
Martijn Coenen72110162016-08-19 14:28:25 +0200794
Martijn Coenen72110162016-08-19 14:28:25 +0200795private:
796 uint16_t mMajor;
797 uint16_t mMinor;
798};
799
800inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
801 return hidl_version(major,minor);
802}
803
Steven Morelandbdf26662016-09-02 11:03:15 -0700804#if defined(__LP64__)
805#define HAL_LIBRARY_PATH_SYSTEM "/system/lib64/hw/"
806#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib64/hw/"
807#define HAL_LIBRARY_PATH_ODM "/odm/lib64/hw/"
808#else
809#define HAL_LIBRARY_PATH_SYSTEM "/system/lib/hw/"
810#define HAL_LIBRARY_PATH_VENDOR "/vendor/lib/hw/"
811#define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
812#endif
813
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700814// ----------------------------------------------------------------------
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700815// Class that provides Hidl instrumentation utilities.
816struct HidlInstrumentor {
817 // Event that triggers the instrumentation. e.g. enter of an API call on
818 // the server/client side, exit of an API call on the server/client side
819 // etc.
820 enum InstrumentationEvent {
821 SERVER_API_ENTRY = 0,
822 SERVER_API_EXIT,
823 CLIENT_API_ENTRY,
824 CLIENT_API_EXIT,
825 SYNC_CALLBACK_ENTRY,
826 SYNC_CALLBACK_EXIT,
827 ASYNC_CALLBACK_ENTRY,
828 ASYNC_CALLBACK_EXIT,
Steven Morelandcefbd6e2016-11-01 10:14:30 -0700829 PASSTHROUGH_ENTRY,
830 PASSTHROUGH_EXIT,
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700831 };
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700832
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700833 // Signature of the instrumentation callback function.
834 using InstrumentationCallback = std::function<void(
835 const InstrumentationEvent event,
836 const char *package,
837 const char *version,
838 const char *interface,
839 const char *method,
840 std::vector<void *> *args)>;
841
Zhuoyao Zhang93c1e3a2017-01-23 17:37:49 -0800842 explicit HidlInstrumentor(
843 const std::string &package,
844 const std::string &insterface);
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700845 virtual ~HidlInstrumentor();
846
847 protected:
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800848 // Set mEnableInstrumentation based on system property
849 // hal.instrumentation.enable, register/de-register instrumentation
850 // callbacks if mEnableInstrumentation is true/false.
851 void configureInstrumentation(bool log=true);
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700852 // Function that lookup and dynamically loads the hidl instrumentation
853 // libraries and registers the instrumentation callback functions.
854 //
855 // The instrumentation libraries should be stored under any of the following
856 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VENDOR and
857 // HAL_LIBRARY_PATH_ODM. The name of instrumentation libraries should
858 // follow pattern: ^profilerPrefix(.*).profiler.so$
859 //
860 // Each instrumentation library is expected to implement the instrumentation
861 // function called HIDL_INSTRUMENTATION_FUNCTION.
862 //
863 // A no-op for user build.
864 void registerInstrumentationCallbacks(
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700865 std::vector<InstrumentationCallback> *instrumentationCallbacks);
866
867 // Utility function to determine whether a give file is a instrumentation
868 // library (i.e. the file name follow the expected pattern).
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800869 bool isInstrumentationLib(const dirent *file);
870
Zhuoyao Zhang28e03af2016-10-21 11:25:49 -0700871 // A list of registered instrumentation callbacks.
872 std::vector<InstrumentationCallback> mInstrumentationCallbacks;
873 // Flag whether to enable instrumentation.
874 bool mEnableInstrumentation;
Zhuoyao Zhang5a643b92017-01-03 17:31:53 -0800875 // Prefix to lookup the instrumentation libraries.
Zhuoyao Zhang93c1e3a2017-01-23 17:37:49 -0800876 std::string mInstrumentationLibPackage;
877 // Used for dlsym to load the profiling method for given interface.
878 std::string mInterfaceName;
879
Zhuoyao Zhang7e1286c2016-09-12 17:28:48 -0700880};
881
Yifan Hongbe7a6882017-01-05 17:30:17 -0800882///////////////////// toString functions
883
884namespace details {
885
886// toString alias for numeric types
887template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
888inline std::string toString(T t) {
889 return std::to_string(t);
890}
891
892template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
893inline std::string toHexString(T t, bool prefix = true) {
894 std::ostringstream os;
895 if (prefix) { os << std::showbase; }
896 os << std::hex << t;
897 return os.str();
898}
899
900template<>
901inline std::string toHexString(uint8_t t, bool prefix) {
902 return toHexString(static_cast<int32_t>(t), prefix);
903}
904
905template<>
906inline std::string toHexString(int8_t t, bool prefix) {
907 return toHexString(static_cast<int32_t>(t), prefix);
908}
909
910inline std::string toString(const void *t, bool prefix = true) {
911 return toHexString(reinterpret_cast<uintptr_t>(t), prefix);
912}
913
914// debug string dump. There will be quotes around the string!
915inline std::string toString(const hidl_string &hs) {
916 return std::string{"\""} + hs.c_str() + "\"";
917}
918
919// debug string dump
920inline std::string toString(const hidl_handle &hs) {
921 return toString(hs.getNativeHandle());
922}
923
924inline std::string toString(const hidl_memory &mem) {
925 return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = "
926 + toString(mem.size())
927 + ", .handle = " + toString(mem.handle()) + "}";
928}
929
930inline std::string toString(const sp<hidl_death_recipient> &dr) {
931 return std::string{"death_recipient@"} + toString(dr.get());
932}
933
934template<typename Array>
935std::string arrayToString(const Array &a, size_t size);
936
937// debug string dump, assuming that toString(T) is defined.
938template<typename T>
939std::string toString(const hidl_vec<T> &a) {
940 std::string os;
941 os += "[" + toString(a.size()) + "]";
942 os += arrayToString(a, a.size());
943 return os;
944}
945
946template<size_t SIZE1>
947std::string arraySizeToString() {
948 return std::string{"["} + toString(SIZE1) + "]";
949}
950
951template<typename T, size_t SIZE1>
952std::string toString(const_accessor<T, SIZE1> a) {
953 return arrayToString(a, SIZE1);
954}
955
956template<typename T, size_t SIZE1>
957std::string toString(const hidl_array<T, SIZE1> &a) {
958 return arraySizeToString<SIZE1>()
959 + toString(const_accessor<T, SIZE1>(a.data()));
960}
961
962template<size_t SIZE1, size_t SIZE2, size_t... SIZES>
963std::string arraySizeToString() {
964 return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>();
965}
966
967
968template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
969std::string toString(const_accessor<T, SIZE1, SIZE2, SIZES...> a) {
970 return arrayToString(a, SIZE1);
971}
972
973template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
974std::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) {
975 return arraySizeToString<SIZE1, SIZE2, SIZES...>()
976 + toString(const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data()));
977}
978
979template<typename Array>
980std::string arrayToString(const Array &a, size_t size) {
981 std::string os;
982 os += "{";
983 for (size_t i = 0; i < size; ++i) {
984 if (i > 0) {
985 os += ", ";
986 }
987 os += toString(a[i]);
988 }
989 os += "}";
990 return os;
991}
992
993} // namespace details
994
995
Martijn Coenen72110162016-08-19 14:28:25 +0200996} // namespace hardware
997} // namespace android
998
Martijn Coenenc28f1152016-08-22 14:06:56 +0200999
Martijn Coenen72110162016-08-19 14:28:25 +02001000#endif // ANDROID_HIDL_SUPPORT_H