1 #ifndef ANDROID_DVR_NATIVE_HANDLE_WRAPPER_H_ 2 #define ANDROID_DVR_NATIVE_HANDLE_WRAPPER_H_ 3 4 #include <cutils/native_handle.h> 5 #include <log/log.h> 6 #include <pdx/rpc/serializable.h> 7 8 #include <vector> 9 10 namespace android { 11 namespace dvr { 12 13 // A PDX-friendly wrapper to maintain the life cycle of a native_handle_t 14 // object. 15 // 16 // See https://source.android.com/devices/architecture/hidl/types#handle_t for 17 // more information about native_handle_t. 18 template <typename FileHandleType> 19 class NativeHandleWrapper { 20 public: 21 NativeHandleWrapper() = default; 22 NativeHandleWrapper(NativeHandleWrapper&& other) = default; 23 NativeHandleWrapper& operator=(NativeHandleWrapper&& other) = default; 24 25 // Create a new NativeHandleWrapper by duplicating the handle. NativeHandleWrapper(const native_handle_t * handle)26 explicit NativeHandleWrapper(const native_handle_t* handle) { 27 const int fd_count = handle->numFds; 28 const int int_count = handle->numInts; 29 30 // Populate the fd and int vectors: native_handle->data[] is an array of fds 31 // followed by an array of opaque ints. 32 for (int i = 0; i < fd_count; i++) { 33 fds_.emplace_back(FileHandleType::AsDuplicate(handle->data[i])); 34 } 35 for (int i = 0; i < int_count; i++) { 36 ints_.push_back(handle->data[fd_count + i]); 37 } 38 } 39 int_count()40 size_t int_count() const { return ints_.size(); } fd_count()41 size_t fd_count() const { return fds_.size(); } IsValid()42 bool IsValid() const { return ints_.size() != 0 || fds_.size() != 0; } 43 44 // Duplicate a native handle from the wrapper. DuplicateHandle()45 native_handle_t* DuplicateHandle() const { 46 if (!IsValid()) { 47 return nullptr; 48 } 49 50 // numFds + numInts ints. 51 std::vector<FileHandleType> fds; 52 for (const auto& fd : fds_) { 53 if (!fd.IsValid()) { 54 return nullptr; 55 } 56 fds.emplace_back(fd.Duplicate()); 57 } 58 59 return FromFdsAndInts(std::move(fds), ints_); 60 } 61 62 // Takes the native handle out of the wrapper. TakeHandle()63 native_handle_t* TakeHandle() { 64 if (!IsValid()) { 65 return nullptr; 66 } 67 68 return FromFdsAndInts(std::move(fds_), std::move(ints_)); 69 } 70 71 private: 72 NativeHandleWrapper(const NativeHandleWrapper&) = delete; 73 void operator=(const NativeHandleWrapper&) = delete; 74 FromFdsAndInts(std::vector<FileHandleType> fds,std::vector<int> ints)75 static native_handle_t* FromFdsAndInts(std::vector<FileHandleType> fds, 76 std::vector<int> ints) { 77 native_handle_t* handle = native_handle_create(fds.size(), ints.size()); 78 if (!handle) { 79 ALOGE("NativeHandleWrapper::TakeHandle: Failed to create new handle."); 80 return nullptr; 81 } 82 83 // numFds + numInts ints. 84 for (int i = 0; i < handle->numFds; i++) { 85 handle->data[i] = fds[i].Release(); 86 } 87 memcpy(&handle->data[handle->numFds], ints.data(), 88 sizeof(int) * handle->numInts); 89 90 return handle; 91 } 92 93 std::vector<int> ints_; 94 std::vector<FileHandleType> fds_; 95 96 PDX_SERIALIZABLE_MEMBERS(NativeHandleWrapper<FileHandleType>, ints_, fds_); 97 }; 98 99 } // namespace dvr 100 } // namespace android 101 102 #endif // ANDROID_DVR_NATIVE_HANDLE_WRAPPER_H_ 103